From 632c8984c888a12772f374c37131a476903a2840 Mon Sep 17 00:00:00 2001
From: Michael Scire <SciresM@gmail.com>
Date: Mon, 30 Nov 2020 22:06:52 -0800
Subject: [PATCH] loader: update for 11.0.0 (anti-dg + set program args abi)

---
 .../include/stratosphere/hos/hos_types.hpp    |  2 +
 .../ldr/impl/ldr_debug_monitor_interface.hpp  | 11 +--
 .../ldr/impl/ldr_shell_interface.hpp          |  9 ++-
 .../pgl/sf/pgl_sf_i_shell_interface.hpp       | 28 +++----
 .../source/ldr_anti_downgrade_tables.inc      | 73 +++++++++++++++++++
 .../loader/source/ldr_loader_service.cpp      |  6 +-
 .../loader/source/ldr_loader_service.hpp      |  3 +-
 .../loader/source/ldr_process_creation.cpp    |  5 +-
 8 files changed, 111 insertions(+), 26 deletions(-)

diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp
index 961fc2805..e7017d824 100644
--- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp
+++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp
@@ -57,6 +57,8 @@ namespace ams::hos {
         Version_10_0_3  = ::ams::TargetFirmware_10_0_3,
         Version_10_0_4  = ::ams::TargetFirmware_10_0_4,
         Version_10_1_0  = ::ams::TargetFirmware_10_1_0,
+        Version_10_2_0  = ::ams::TargetFirmware_10_2_0,
+        Version_11_0_0  = ::ams::TargetFirmware_11_0_0,
 
         Version_Current = ::ams::TargetFirmware_Current,
 
diff --git a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_debug_monitor_interface.hpp b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_debug_monitor_interface.hpp
index 328ae400c..3ecfdb7e8 100644
--- a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_debug_monitor_interface.hpp
+++ b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_debug_monitor_interface.hpp
@@ -21,11 +21,12 @@
 
 namespace ams::ldr::impl {
 
-    #define AMS_LDR_I_DEBUG_MONITOR_INTERFACE_INTERFACE_INFO(C, H)                                                                                                        \
-        AMS_SF_METHOD_INFO(C, H,     0, Result, SetProgramArguments,          (ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size))                \
-        AMS_SF_METHOD_INFO(C, H,     1, Result, FlushArguments,               ())                                                                                         \
-        AMS_SF_METHOD_INFO(C, H,     2, Result, GetProcessModuleInfo,         (sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id)) \
-        AMS_SF_METHOD_INFO(C, H, 65000, void,   AtmosphereHasLaunchedProgram, (sf::Out<bool> out, ncm::ProgramId program_id))
+    #define AMS_LDR_I_DEBUG_MONITOR_INTERFACE_INTERFACE_INFO(C, H)                                                                                                                                                   \
+        AMS_SF_METHOD_INFO(C, H,     0, Result, SetProgramArgumentsDeprecated, (ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size),                hos::Version_Min,    hos::Version_10_2_0) \
+        AMS_SF_METHOD_INFO(C, H,     0, Result, SetProgramArguments,           (ncm::ProgramId program_id, const sf::InPointerBuffer &args),                               hos::Version_11_0_0                     ) \
+        AMS_SF_METHOD_INFO(C, H,     1, Result, FlushArguments,                ())                                                                                                                                   \
+        AMS_SF_METHOD_INFO(C, H,     2, Result, GetProcessModuleInfo,          (sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id))                                           \
+        AMS_SF_METHOD_INFO(C, H, 65000, void,   AtmosphereHasLaunchedProgram,  (sf::Out<bool> out, ncm::ProgramId program_id))
 
     AMS_SF_DEFINE_INTERFACE(IDebugMonitorInterface, AMS_LDR_I_DEBUG_MONITOR_INTERFACE_INTERFACE_INFO)
 
diff --git a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_shell_interface.hpp b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_shell_interface.hpp
index 5e3e31188..6f8984eec 100644
--- a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_shell_interface.hpp
+++ b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_shell_interface.hpp
@@ -21,10 +21,11 @@
 
 namespace ams::ldr::impl {
 
-    #define AMS_LDR_I_SHELL_INTERFACE_INTERFACE_INFO(C, H)                                                                                                     \
-        AMS_SF_METHOD_INFO(C, H,     0, Result, SetProgramArguments,              (ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size)) \
-        AMS_SF_METHOD_INFO(C, H,     1, Result, FlushArguments,                   ())                                                                          \
-        AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereRegisterExternalCode,   (sf::OutMoveHandle out, ncm::ProgramId program_id))                          \
+    #define AMS_LDR_I_SHELL_INTERFACE_INTERFACE_INFO(C, H)                                                                                                                                               \
+        AMS_SF_METHOD_INFO(C, H,     0, Result, SetProgramArgumentsDeprecated,    (ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size), hos::Version_Min,    hos::Version_10_2_0) \
+        AMS_SF_METHOD_INFO(C, H,     0, Result, SetProgramArguments,              (ncm::ProgramId program_id, const sf::InPointerBuffer &args),                hos::Version_11_0_0                     ) \
+        AMS_SF_METHOD_INFO(C, H,     1, Result, FlushArguments,                   ())                                                                                                                    \
+        AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereRegisterExternalCode,   (sf::OutMoveHandle out, ncm::ProgramId program_id))                                                                    \
         AMS_SF_METHOD_INFO(C, H, 65001, void,   AtmosphereUnregisterExternalCode, (ncm::ProgramId program_id))
 
     AMS_SF_DEFINE_INTERFACE(IShellInterface, AMS_LDR_I_SHELL_INTERFACE_INTERFACE_INFO)
diff --git a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp
index e4339411c..d202f4f72 100644
--- a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp
+++ b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp
@@ -23,20 +23,20 @@
 
 namespace ams::pgl::sf {
 
-    #define AMS_PGL_I_SHELL_INTERFACE_INTERFACE_INFO(C, H)                                                                                                                          \
-        AMS_SF_METHOD_INFO(C, H,  0, Result, LaunchProgram,                         (ams::sf::Out<os::ProcessId> out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags)) \
-        AMS_SF_METHOD_INFO(C, H,  1, Result, TerminateProcess,                      (os::ProcessId process_id))                                                                     \
-        AMS_SF_METHOD_INFO(C, H,  2, Result, LaunchProgramFromHost,                 (ams::sf::Out<os::ProcessId> out, const ams::sf::InBuffer &content_path, u32 pm_flags))         \
-        AMS_SF_METHOD_INFO(C, H,  4, Result, GetHostContentMetaInfo,                (ams::sf::Out<pgl::ContentMetaInfo> out, const ams::sf::InBuffer &content_path))                \
-        AMS_SF_METHOD_INFO(C, H,  5, Result, GetApplicationProcessId,               (ams::sf::Out<os::ProcessId> out))                                                              \
-        AMS_SF_METHOD_INFO(C, H,  6, Result, BoostSystemMemoryResourceLimit,        (u64 size))                                                                                     \
-        AMS_SF_METHOD_INFO(C, H,  7, Result, IsProcessTracked,                      (ams::sf::Out<bool> out, os::ProcessId process_id))                                             \
-        AMS_SF_METHOD_INFO(C, H,  8, Result, EnableApplicationCrashReport,          (bool enabled))                                                                                 \
-        AMS_SF_METHOD_INFO(C, H,  9, Result, IsApplicationCrashReportEnabled,       (ams::sf::Out<bool> out))                                                                       \
-        AMS_SF_METHOD_INFO(C, H, 10, Result, EnableApplicationAllThreadDumpOnCrash, (bool enabled))                                                                                 \
-        AMS_SF_METHOD_INFO(C, H, 12, Result, TriggerApplicationSnapShotDumper,      (SnapShotDumpType dump_type, const ams::sf::InBuffer &arg))                                     \
-        AMS_SF_METHOD_INFO(C, H, 20, Result, GetShellEventObserver,                 (ams::sf::Out<std::shared_ptr<pgl::sf::IEventObserver>> out))                                   \
-        AMS_SF_METHOD_INFO(C, H, 21, Result, Command21NotImplemented,               (ams::sf::Out<u64> out, u32 in, const ams::sf::InBuffer &buf1, const ams::sf::InBuffer &buf2))
+    #define AMS_PGL_I_SHELL_INTERFACE_INTERFACE_INFO(C, H)                                                                                                                                               \
+        AMS_SF_METHOD_INFO(C, H,  0, Result, LaunchProgram,                         (ams::sf::Out<os::ProcessId> out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags))                      \
+        AMS_SF_METHOD_INFO(C, H,  1, Result, TerminateProcess,                      (os::ProcessId process_id))                                                                                          \
+        AMS_SF_METHOD_INFO(C, H,  2, Result, LaunchProgramFromHost,                 (ams::sf::Out<os::ProcessId> out, const ams::sf::InBuffer &content_path, u32 pm_flags))                              \
+        AMS_SF_METHOD_INFO(C, H,  4, Result, GetHostContentMetaInfo,                (ams::sf::Out<pgl::ContentMetaInfo> out, const ams::sf::InBuffer &content_path))                                     \
+        AMS_SF_METHOD_INFO(C, H,  5, Result, GetApplicationProcessId,               (ams::sf::Out<os::ProcessId> out))                                                                                   \
+        AMS_SF_METHOD_INFO(C, H,  6, Result, BoostSystemMemoryResourceLimit,        (u64 size))                                                                                                          \
+        AMS_SF_METHOD_INFO(C, H,  7, Result, IsProcessTracked,                      (ams::sf::Out<bool> out, os::ProcessId process_id))                                                                  \
+        AMS_SF_METHOD_INFO(C, H,  8, Result, EnableApplicationCrashReport,          (bool enabled))                                                                                                      \
+        AMS_SF_METHOD_INFO(C, H,  9, Result, IsApplicationCrashReportEnabled,       (ams::sf::Out<bool> out))                                                                                            \
+        AMS_SF_METHOD_INFO(C, H, 10, Result, EnableApplicationAllThreadDumpOnCrash, (bool enabled))                                                                                                      \
+        AMS_SF_METHOD_INFO(C, H, 12, Result, TriggerApplicationSnapShotDumper,      (SnapShotDumpType dump_type, const ams::sf::InBuffer &arg))                                                          \
+        AMS_SF_METHOD_INFO(C, H, 20, Result, GetShellEventObserver,                 (ams::sf::Out<std::shared_ptr<pgl::sf::IEventObserver>> out))                                                        \
+        AMS_SF_METHOD_INFO(C, H, 21, Result, Command21NotImplemented,               (ams::sf::Out<u64> out, u32 in, const ams::sf::InBuffer &buf1, const ams::sf::InBuffer &buf2),  hos::Version_11_0_0)
 
     AMS_SF_DEFINE_INTERFACE(IShellInterface, AMS_PGL_I_SHELL_INTERFACE_INTERFACE_INFO);
 
diff --git a/stratosphere/loader/source/ldr_anti_downgrade_tables.inc b/stratosphere/loader/source/ldr_anti_downgrade_tables.inc
index 0d57586ae..a137b5072 100644
--- a/stratosphere/loader/source/ldr_anti_downgrade_tables.inc
+++ b/stratosphere/loader/source/ldr_anti_downgrade_tables.inc
@@ -324,3 +324,76 @@ constexpr MinimumProgramVersion g_MinimumProgramVersions1010[] = {
     {ncm::WebAppletId::WifiWebAuth,   MakeSystemVersion(10, 0, 0)},
 };
 constexpr size_t g_MinimumProgramVersionsCount1010 = util::size(g_MinimumProgramVersions1010);
+
+constexpr MinimumProgramVersion g_MinimumProgramVersions1100[] = {
+    /* All non-Development System Modules. */
+    {ncm::SystemProgramId::Usb,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Tma,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Boot2,       MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Settings,    MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Bus,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Bluetooth,   MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Bcat,        MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Dmnt,        MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::Friends,     MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Nifm,        MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Ptm,         MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Shell,       MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::BsdSockets,  MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Hid,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Audio,       MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::LogManager,  MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Wlan,        MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Cs,          MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::Ldn,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::NvServices,  MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Pcv,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Ppc,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::NvnFlinger,  MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Pcie,        MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Account,     MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Ns,          MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Nfc,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Psc,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::CapSrv,      MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Am,          MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Ssl,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Nim,         MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Cec,         MakeSystemVersion(11, 0, 0)}, */
+ /* {ncm::SystemProgramId::Tspm,        MakeSystemVersion(11, 0, 0)}, */
+ /* {ncm::SystemProgramId::Spl,         MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::Lbl,         MakeSystemVersion(10, 0, 0)},
+    {ncm::SystemProgramId::Btm,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Erpt,        MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Time,        MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::Vi,          MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Pctl,        MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Npns,        MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Eupld,       MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Glue,        MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Eclct,       MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Es,          MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Fatal,       MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Grc,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Creport,     MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Ro,          MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Profiler,    MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::Sdb,         MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Migration,   MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Jit,         MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::JpegDec,     MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::SafeMode,    MakeSystemVersion(11, 0, 0)},
+    {ncm::SystemProgramId::Olsc,        MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Dt,          MakeSystemVersion(11, 0, 0)}, */
+ /* {ncm::SystemProgramId::Nd,          MakeSystemVersion(11, 0, 0)}, */
+    {ncm::SystemProgramId::Ngct,        MakeSystemVersion(11, 0, 0)},
+ /* {ncm::SystemProgramId::Pgl,         MakeSystemVersion(11, 0, 0)}, */
+
+    /* All Web Applets. */
+    {ncm::WebAppletId::Web,           MakeSystemVersion(11, 0, 0)},
+    {ncm::WebAppletId::Shop,          MakeSystemVersion(11, 0, 0)},
+    {ncm::WebAppletId::OfflineWeb,    MakeSystemVersion(11, 0, 0)},
+    {ncm::WebAppletId::LoginShare,    MakeSystemVersion(11, 0, 0)},
+    {ncm::WebAppletId::WifiWebAuth,   MakeSystemVersion(11, 0, 0)},
+};
+constexpr size_t g_MinimumProgramVersionsCount1100 = util::size(g_MinimumProgramVersions1100);
diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp
index 9b3a0e1c0..2f3f725be 100644
--- a/stratosphere/loader/source/ldr_loader_service.cpp
+++ b/stratosphere/loader/source/ldr_loader_service.cpp
@@ -84,10 +84,14 @@ namespace ams::ldr {
         return ldr::ro::UnpinProgram(id);
     }
 
-    Result LoaderService::SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size) {
+    Result LoaderService::SetProgramArgumentsDeprecated(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size) {
         return args::Set(program_id, args.GetPointer(), std::min(args.GetSize(), size_t(args_size)));
     }
 
+    Result LoaderService::SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args) {
+        return args::Set(program_id, args.GetPointer(), args.GetSize());
+    }
+
     Result LoaderService::FlushArguments() {
         return args::Flush();
     }
diff --git a/stratosphere/loader/source/ldr_loader_service.hpp b/stratosphere/loader/source/ldr_loader_service.hpp
index 289c384a7..ceb7fc3c6 100644
--- a/stratosphere/loader/source/ldr_loader_service.hpp
+++ b/stratosphere/loader/source/ldr_loader_service.hpp
@@ -25,7 +25,8 @@ namespace ams::ldr {
             Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc);
             Result PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc);
             Result UnpinProgram(PinId id);
-            Result SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size);
+            Result SetProgramArgumentsDeprecated(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size);
+            Result SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args);
             Result FlushArguments();
             Result GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id);
             Result SetEnabledProgramVerification(bool enabled);
diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp
index d04a68fc5..f1163d36a 100644
--- a/stratosphere/loader/source/ldr_process_creation.cpp
+++ b/stratosphere/loader/source/ldr_process_creation.cpp
@@ -96,7 +96,10 @@ namespace ams::ldr {
             size_t num_entries = 0;
 
             const auto hos_version = hos::GetVersion();
-            if (hos_version >= hos::Version_10_1_0) {
+            if (hos_version >= hos::Version_11_0_0) {
+                entries = g_MinimumProgramVersions1100;
+                num_entries = g_MinimumProgramVersionsCount1100;
+            } else if (hos_version >= hos::Version_10_1_0) {
                 entries = g_MinimumProgramVersions1010;
                 num_entries = g_MinimumProgramVersionsCount1010;
             } else if (hos_version >= hos::Version_10_0_0) {