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 c1d953808..6f666231d 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 @@ -19,11 +19,11 @@ #include #include -#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), (program_id, args, 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), (program_id, 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 count, const sf::OutPointerArray &out, os::ProcessId process_id), (count, out, process_id)) \ - AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedProgram, (sf::Out out, ncm::ProgramId program_id), (out, 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), (program_id, args, 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), (program_id, 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 count, const sf::OutPointerArray &out, os::ProcessId process_id), (count, out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) AMS_SF_DEFINE_INTERFACE(ams::ldr::impl, IDebugMonitorInterface, AMS_LDR_I_DEBUG_MONITOR_INTERFACE_INTERFACE_INFO) diff --git a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp index b73cb5f53..3beda4384 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp @@ -19,14 +19,14 @@ #include #include -#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle reslimit_h), (proc_h, id, flags, reslimit_h)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out out_program_info, const ncm::ProgramLocation &loc), (out_program_info, loc)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \ - AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ - AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc), (out_program_info, out_status, loc)) \ - AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status)) +#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle reslimit_h), (proc_h, id, flags, reslimit_h)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out out_program_info, const ncm::ProgramLocation &loc), (out_program_info, loc)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \ + AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ + AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc), (out_program_info, out_status, loc)) \ + AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status)) AMS_SF_DEFINE_INTERFACE(ams::ldr::impl, IProcessManagerInterface, AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO) diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp index a541310b7..efe5f39d1 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp @@ -25,7 +25,7 @@ namespace ams::ldr::pm { Result PinProgram(PinId *out, const ncm::ProgramLocation &loc); Result UnpinProgram(PinId pin_id); Result SetEnabledProgramVerification(bool enabled); - Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id); + Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); /* Atmosphere extension API. */ Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc); diff --git a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp index 6cdfc2f95..5e05a1e85 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp @@ -19,10 +19,10 @@ #include #include -#define AMS_PM_I_INFORMATION_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ - AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereGetProcessId, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ - AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereHasLaunchedProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ - AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmosphereGetProcessInfo, (sf::Out out_loc, sf::Out out_status, os::ProcessId process_id), (out_loc, out_status, process_id)) +#define AMS_PM_I_INFORMATION_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereGetProcessId, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ + AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ + AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmosphereGetProcessInfo, (sf::Out out_loc, sf::Out out_status, os::ProcessId process_id), (out_loc, out_status, process_id)) AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IInformationInterface, AMS_PM_I_INFORMATION_INTERFACE_INTERFACE_INFO) diff --git a/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp b/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp index 940621f05..16cba105a 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp @@ -27,12 +27,12 @@ namespace ams::pm::info { /* Information API. */ Result GetProgramId(ncm::ProgramId *out_program_id, os::ProcessId process_id); Result GetProcessId(os::ProcessId *out_process_id, ncm::ProgramId program_id); - Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id); + Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); Result GetProcessInfo(ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id); /* Information convenience API. */ - bool HasLaunchedProgram(ncm::ProgramId program_id); + bool HasLaunchedBootProgram(ncm::ProgramId program_id); Result IsHblProcessId(bool *out, os::ProcessId process_id); Result IsHblProgramId(bool *out, ncm::ProgramId program_id); diff --git a/libraries/libstratosphere/source/boot2/boot2_api.cpp b/libraries/libstratosphere/source/boot2/boot2_api.cpp index c089267b7..2c085abdd 100644 --- a/libraries/libstratosphere/source/boot2/boot2_api.cpp +++ b/libraries/libstratosphere/source/boot2/boot2_api.cpp @@ -294,7 +294,7 @@ namespace ams::boot2 { void LaunchFlaggedProgramsOnSdCard() { IterateOverFlaggedProgramsOnSdCard([](ncm::ProgramId program_id) { /* Check if we've already launched the program. */ - if (pm::info::HasLaunchedProgram(program_id)) { + if (pm::info::HasLaunchedBootProgram(program_id)) { return; } diff --git a/libraries/libstratosphere/source/cfg/cfg_override.cpp b/libraries/libstratosphere/source/cfg/cfg_override.cpp index d7ffd145c..234223736 100644 --- a/libraries/libstratosphere/source/cfg/cfg_override.cpp +++ b/libraries/libstratosphere/source/cfg/cfg_override.cpp @@ -388,7 +388,7 @@ namespace ams::cfg { } /* For system modules and anything launched before the home menu, always override. */ - if (program_id < ncm::SystemAppletId::Start || !pm::info::HasLaunchedProgram(ncm::SystemAppletId::Qlaunch)) { + if (program_id < ncm::SystemAppletId::Start || !pm::info::HasLaunchedBootProgram(ncm::SystemAppletId::Qlaunch)) { status.SetProgramSpecific(); return status; } diff --git a/libraries/libstratosphere/source/hid/hid_api.cpp b/libraries/libstratosphere/source/hid/hid_api.cpp index 3ef35f95b..ece8133f2 100644 --- a/libraries/libstratosphere/source/hid/hid_api.cpp +++ b/libraries/libstratosphere/source/hid/hid_api.cpp @@ -53,7 +53,7 @@ namespace ams::hid { Result EnsureHidInitialized() { if (!g_initialized_hid) { if (!serviceIsActive(hidGetServiceSession())) { - if (!pm::info::HasLaunchedProgram(ncm::SystemProgramId::Hid)) { + if (!pm::info::HasLaunchedBootProgram(ncm::SystemProgramId::Hid)) { return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID); } InitializeHid(); diff --git a/libraries/libstratosphere/source/ldr/ldr_ams.c b/libraries/libstratosphere/source/ldr/ldr_ams.c index 9b39f9cd7..b33559d3f 100644 --- a/libraries/libstratosphere/source/ldr/ldr_ams.c +++ b/libraries/libstratosphere/source/ldr/ldr_ams.c @@ -17,19 +17,19 @@ #include #include "ldr_ams.h" -static Result _ldrAtmosphereHasLaunchedProgram(Service *srv, bool *out, u64 program_id) { +static Result _ldrAtmosphereHasLaunchedBootProgram(Service *srv, bool *out, u64 program_id) { u8 tmp; Result rc = serviceDispatchInOut(srv, 65000, program_id, tmp); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; return rc; } -Result ldrDmntAtmosphereHasLaunchedProgram(bool *out, u64 program_id) { - return _ldrAtmosphereHasLaunchedProgram(ldrDmntGetServiceSession(), out, program_id); +Result ldrDmntAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id) { + return _ldrAtmosphereHasLaunchedBootProgram(ldrDmntGetServiceSession(), out, program_id); } -Result ldrPmAtmosphereHasLaunchedProgram(bool *out, u64 program_id) { - return _ldrAtmosphereHasLaunchedProgram(ldrPmGetServiceSession(), out, program_id); +Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id) { + return _ldrAtmosphereHasLaunchedBootProgram(ldrPmGetServiceSession(), out, program_id); } Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) { diff --git a/libraries/libstratosphere/source/ldr/ldr_ams.h b/libraries/libstratosphere/source/ldr/ldr_ams.h index feff70e4a..30a5e4163 100644 --- a/libraries/libstratosphere/source/ldr/ldr_ams.h +++ b/libraries/libstratosphere/source/ldr/ldr_ams.h @@ -16,8 +16,8 @@ typedef struct { u64 flags; } CfgOverrideStatus; -Result ldrPmAtmosphereHasLaunchedProgram(bool *out, u64 program_id); -Result ldrDmntAtmosphereHasLaunchedProgram(bool *out, u64 program_id); +Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); +Result ldrDmntAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc); Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status); diff --git a/libraries/libstratosphere/source/ldr/ldr_pm_api.cpp b/libraries/libstratosphere/source/ldr/ldr_pm_api.cpp index d6d1c190e..046e6a954 100644 --- a/libraries/libstratosphere/source/ldr/ldr_pm_api.cpp +++ b/libraries/libstratosphere/source/ldr/ldr_pm_api.cpp @@ -36,8 +36,8 @@ namespace ams::ldr::pm { return ldrPmUnpinProgram(pin_id.value); } - Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) { - return ldrPmAtmosphereHasLaunchedProgram(out, static_cast(program_id)); + Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id) { + return ldrPmAtmosphereHasLaunchedBootProgram(out, static_cast(program_id)); } Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { diff --git a/libraries/libstratosphere/source/pm/pm_ams.c b/libraries/libstratosphere/source/pm/pm_ams.c index 5ca42261c..92798753b 100644 --- a/libraries/libstratosphere/source/pm/pm_ams.c +++ b/libraries/libstratosphere/source/pm/pm_ams.c @@ -21,7 +21,7 @@ Result pminfoAtmosphereGetProcessId(u64 *out_pid, u64 program_id) { return serviceDispatchInOut(pminfoGetServiceSession(), 65000, program_id, *out_pid); } -Result pminfoAtmosphereHasLaunchedProgram(bool *out, u64 program_id) { +Result pminfoAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id) { u8 tmp; Result rc = serviceDispatchInOut(pminfoGetServiceSession(), 65001, program_id, tmp); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; diff --git a/libraries/libstratosphere/source/pm/pm_ams.h b/libraries/libstratosphere/source/pm/pm_ams.h index 74e2a015e..c66c75994 100644 --- a/libraries/libstratosphere/source/pm/pm_ams.h +++ b/libraries/libstratosphere/source/pm/pm_ams.h @@ -17,7 +17,7 @@ typedef struct { } CfgOverrideStatus; Result pminfoAtmosphereGetProcessId(u64 *out_pid, u64 program_id); -Result pminfoAtmosphereHasLaunchedProgram(bool *out, u64 program_id); +Result pminfoAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); Result pminfoAtmosphereGetProcessInfo(NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid); Result pmdmntAtmosphereGetProcessInfo(Handle *out, NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid); diff --git a/libraries/libstratosphere/source/pm/pm_info_api.cpp b/libraries/libstratosphere/source/pm/pm_info_api.cpp index 3c550d0f7..e1d7998c4 100644 --- a/libraries/libstratosphere/source/pm/pm_info_api.cpp +++ b/libraries/libstratosphere/source/pm/pm_info_api.cpp @@ -18,58 +18,32 @@ namespace ams::pm::info { - namespace { - - /* Global lock. */ - os::Mutex g_info_lock(false); - /* TODO: Less memory-intensive storage? */ - std::set g_cached_launched_programs; - - } - /* Information API. */ Result GetProgramId(ncm::ProgramId *out_program_id, os::ProcessId process_id) { - std::scoped_lock lk(g_info_lock); - return pminfoGetProgramId(reinterpret_cast(out_program_id), static_cast(process_id)); } Result GetProcessId(os::ProcessId *out_process_id, ncm::ProgramId program_id) { - std::scoped_lock lk(g_info_lock); - return pminfoAtmosphereGetProcessId(reinterpret_cast(out_process_id), static_cast(program_id)); } Result GetProcessInfo(ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) { - std::scoped_lock lk(g_info_lock); - *out_loc = {}; *out_status = {}; static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus)); return pminfoAtmosphereGetProcessInfo(reinterpret_cast(out_loc), reinterpret_cast(out_status), static_cast(process_id)); } - Result WEAK_SYMBOL HasLaunchedProgram(bool *out, ncm::ProgramId program_id) { - std::scoped_lock lk(g_info_lock); - - if (g_cached_launched_programs.find(static_cast(program_id)) != g_cached_launched_programs.end()) { - *out = true; - return ResultSuccess(); - } - + Result WEAK_SYMBOL HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id) { bool has_launched = false; - R_TRY(pminfoAtmosphereHasLaunchedProgram(&has_launched, static_cast(program_id))); - if (has_launched) { - g_cached_launched_programs.insert(static_cast(program_id)); - } - + R_TRY(pminfoAtmosphereHasLaunchedBootProgram(&has_launched, static_cast(program_id))); *out = has_launched; return ResultSuccess(); } - bool HasLaunchedProgram(ncm::ProgramId program_id) { + bool HasLaunchedBootProgram(ncm::ProgramId program_id) { bool has_launched = false; - R_ABORT_UNLESS(HasLaunchedProgram(&has_launched, program_id)); + R_ABORT_UNLESS(HasLaunchedBootProgram(&has_launched, program_id)); return has_launched; } diff --git a/stratosphere/loader/source/ldr_launch_record.cpp b/stratosphere/loader/source/ldr_launch_record.cpp index ec97f813c..fd0b35cbd 100644 --- a/stratosphere/loader/source/ldr_launch_record.cpp +++ b/stratosphere/loader/source/ldr_launch_record.cpp @@ -20,18 +20,49 @@ namespace ams::ldr { namespace { - /* Global cache. */ - std::set g_launched_programs; + static constexpr size_t MaxBootPrograms = 0x50; + constinit std::array g_launched_boot_programs = [] { + std::array arr = {}; + for (size_t i = 0; i < MaxBootPrograms; ++i) { + arr[i] = ncm::InvalidProgramId; + } + return arr; + }(); + + constinit bool g_boot_programs_done = false; + + bool HasLaunchedBootProgramImpl(ncm::ProgramId program_id) { + for (const auto &launched : g_launched_boot_programs) { + if (launched == program_id) { + return true; + } + } + return false; + } + + void SetLaunchedBootProgramImpl(ncm::ProgramId program_id) { + for (size_t i = 0; i < MaxBootPrograms; ++i) { + if (g_launched_boot_programs[i] == ncm::InvalidProgramId) { + g_launched_boot_programs[i] = program_id; + } + } + AMS_ABORT("Too many boot programs"); + } } /* Launch Record API. */ - bool HasLaunchedProgram(ncm::ProgramId program_id) { - return g_launched_programs.find(program_id.value) != g_launched_programs.end(); + bool HasLaunchedBootProgram(ncm::ProgramId program_id) { + return HasLaunchedBootProgramImpl(program_id); } - void SetLaunchedProgram(ncm::ProgramId program_id) { - g_launched_programs.insert(program_id.value); + void SetLaunchedBootProgram(ncm::ProgramId program_id) { + if (!g_boot_programs_done) { + SetLaunchedBootProgramImpl(program_id); + if (program_id == ncm::SystemAppletId::Qlaunch) { + g_boot_programs_done = true; + } + } } } @@ -40,8 +71,8 @@ namespace ams::ldr { /* This is necessary to prevent circular dependencies. */ namespace ams::pm::info { - Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) { - *out = ldr::HasLaunchedProgram(program_id); + Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id) { + *out = ldr::HasLaunchedBootProgram(program_id); return ResultSuccess(); } diff --git a/stratosphere/loader/source/ldr_launch_record.hpp b/stratosphere/loader/source/ldr_launch_record.hpp index 9c272741b..e92297482 100644 --- a/stratosphere/loader/source/ldr_launch_record.hpp +++ b/stratosphere/loader/source/ldr_launch_record.hpp @@ -19,7 +19,7 @@ namespace ams::ldr { /* Launch Record API. */ - bool HasLaunchedProgram(ncm::ProgramId program_id); - void SetLaunchedProgram(ncm::ProgramId program_id); + bool HasLaunchedBootProgram(ncm::ProgramId program_id); + void SetLaunchedBootProgram(ncm::ProgramId program_id); } \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp index 2f3f725be..fbe6be582 100644 --- a/stratosphere/loader/source/ldr_loader_service.cpp +++ b/stratosphere/loader/source/ldr_loader_service.cpp @@ -115,8 +115,8 @@ namespace ams::ldr { fssystem::DestroyExternalCode(program_id); } - void LoaderService::AtmosphereHasLaunchedProgram(sf::Out out, ncm::ProgramId program_id) { - out.SetValue(ldr::HasLaunchedProgram(program_id)); + void LoaderService::AtmosphereHasLaunchedBootProgram(sf::Out out, ncm::ProgramId program_id) { + out.SetValue(ldr::HasLaunchedBootProgram(program_id)); } Result LoaderService::AtmosphereGetProgramInfo(sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc) { diff --git a/stratosphere/loader/source/ldr_loader_service.hpp b/stratosphere/loader/source/ldr_loader_service.hpp index ceb7fc3c6..b525fda29 100644 --- a/stratosphere/loader/source/ldr_loader_service.hpp +++ b/stratosphere/loader/source/ldr_loader_service.hpp @@ -34,7 +34,7 @@ namespace ams::ldr { /* Atmosphere commands. */ Result AtmosphereRegisterExternalCode(sf::OutMoveHandle out, ncm::ProgramId program_id); void AtmosphereUnregisterExternalCode(ncm::ProgramId program_id); - void AtmosphereHasLaunchedProgram(sf::Out out, ncm::ProgramId program_id); + void AtmosphereHasLaunchedBootProgram(sf::Out out, ncm::ProgramId program_id); Result AtmosphereGetProgramInfo(sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc); Result AtmospherePinProgram(sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); }; diff --git a/stratosphere/pm/source/pm_info_service.cpp b/stratosphere/pm/source/pm_info_service.cpp index 5ec0f23a4..9f70a0a04 100644 --- a/stratosphere/pm/source/pm_info_service.cpp +++ b/stratosphere/pm/source/pm_info_service.cpp @@ -22,8 +22,8 @@ namespace ams::pm { /* Overrides for libstratosphere pm::info commands. */ namespace info { - Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) { - return ldr::pm::HasLaunchedProgram(out, program_id); + Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id) { + return ldr::pm::HasLaunchedBootProgram(out, program_id); } } @@ -38,8 +38,8 @@ namespace ams::pm { return impl::GetProcessId(out.GetPointer(), program_id); } - Result InformationService::AtmosphereHasLaunchedProgram(sf::Out out, ncm::ProgramId program_id) { - return pm::info::HasLaunchedProgram(out.GetPointer(), program_id); + Result InformationService::AtmosphereHasLaunchedBootProgram(sf::Out out, ncm::ProgramId program_id) { + return pm::info::HasLaunchedBootProgram(out.GetPointer(), program_id); } Result InformationService::AtmosphereGetProcessInfo(sf::Out out_loc, sf::Out out_status, os::ProcessId process_id) { diff --git a/stratosphere/pm/source/pm_info_service.hpp b/stratosphere/pm/source/pm_info_service.hpp index f46639b27..c22380f6b 100644 --- a/stratosphere/pm/source/pm_info_service.hpp +++ b/stratosphere/pm/source/pm_info_service.hpp @@ -25,7 +25,7 @@ namespace ams::pm { /* Atmosphere extension commands. */ Result AtmosphereGetProcessId(sf::Out out, ncm::ProgramId program_id); - Result AtmosphereHasLaunchedProgram(sf::Out out, ncm::ProgramId program_id); + Result AtmosphereHasLaunchedBootProgram(sf::Out out, ncm::ProgramId program_id); Result AtmosphereGetProcessInfo(sf::Out out_loc, sf::Out out_status, os::ProcessId process_id); }; static_assert(pm::impl::IsIInformationInterface); diff --git a/stratosphere/ro/source/ro_debug_monitor_service.hpp b/stratosphere/ro/source/ro_debug_monitor_service.hpp index 58b634e43..57b6a48f3 100644 --- a/stratosphere/ro/source/ro_debug_monitor_service.hpp +++ b/stratosphere/ro/source/ro_debug_monitor_service.hpp @@ -18,7 +18,7 @@ namespace ams::ro { - class DebugMonitorService final { + class DebugMonitorService { public: Result GetProcessModuleInfo(sf::Out out_count, const sf::OutArray &out_infos, os::ProcessId process_id); }; diff --git a/stratosphere/ro/source/ro_main.cpp b/stratosphere/ro/source/ro_main.cpp index a7d71adf8..77083ebfc 100644 --- a/stratosphere/ro/source/ro_main.cpp +++ b/stratosphere/ro/source/ro_main.cpp @@ -23,7 +23,7 @@ extern "C" { u32 __nx_applet_type = AppletType_None; u32 __nx_fs_num_sessions = 1; - #define INNER_HEAP_SIZE 0x4000 + #define INNER_HEAP_SIZE 0x0 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; @@ -46,6 +46,88 @@ namespace ams { using namespace ams; +namespace ams::ro { + + namespace { + + /* ldr:ro, ro:dmnt, ro:1. */ + enum PortIndex { + PortIndex_DebugMonitor, + PortIndex_User, + PortIndex_JitPlugin, + PortIndex_Count, + }; + + constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("ro:dmnt"); + constexpr size_t DebugMonitorMaxSessions = 2; + + /* NOTE: Official code passes 32 for ldr:ro max sessions. We will pass 2, because that's the actual limit. */ + constexpr sm::ServiceName UserServiceName = sm::ServiceName::Encode("ldr:ro"); + constexpr size_t UserMaxSessions = 2; + + constexpr sm::ServiceName JitPluginServiceName = sm::ServiceName::Encode("ro:1"); + constexpr size_t JitPluginMaxSessions = 2; + + static constexpr size_t MaxSessions = DebugMonitorMaxSessions + UserMaxSessions + JitPluginMaxSessions; + + using ServerOptions = sf::hipc::DefaultServerManagerOptions; + + class ServerManager final : public sf::hipc::ServerManager { + private: + virtual ams::Result OnNeedsToAccept(int port_index, Server *server) override; + }; + + using Allocator = sf::ExpHeapAllocator; + using ObjectFactory = sf::ObjectFactory; + + alignas(0x40) constinit u8 g_server_allocator_buffer[4_KB]; + lmem::HeapHandle g_server_heap_handle; + Allocator g_server_allocator; + + ServerManager g_server_manager; + + ams::Result ServerManager::OnNeedsToAccept(int port_index, Server *server) { + switch (port_index) { + case PortIndex_DebugMonitor: + return this->AcceptImpl(server, ObjectFactory::CreateSharedEmplaced(std::addressof(g_server_allocator))); + case PortIndex_User: + return this->AcceptImpl(server, ObjectFactory::CreateSharedEmplaced(std::addressof(g_server_allocator), ro::NrrKind_User)); + case PortIndex_JitPlugin: + return this->AcceptImpl(server, ObjectFactory::CreateSharedEmplaced(std::addressof(g_server_allocator), ro::NrrKind_JitPlugin)); + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + + void *Allocate(size_t size) { + return lmem::AllocateFromExpHeap(g_server_heap_handle, size); + } + + void Deallocate(void *p, size_t size) { + return lmem::FreeToExpHeap(g_server_heap_handle, p); + } + + void InitializeHeap() { + /* Setup server allocator. */ + g_server_heap_handle = lmem::CreateExpHeap(g_server_allocator_buffer, sizeof(g_server_allocator_buffer), lmem::CreateOption_None); + } + + void LoopServer() { + /* Create services. */ + R_ABORT_UNLESS(ro::g_server_manager.RegisterServer(PortIndex_DebugMonitor, DebugMonitorServiceName, DebugMonitorMaxSessions)); + + R_ABORT_UNLESS(ro::g_server_manager.RegisterServer(PortIndex_User, UserServiceName, UserMaxSessions)); + if (hos::GetVersion() >= hos::Version_7_0_0) { + R_ABORT_UNLESS(ro::g_server_manager.RegisterServer(PortIndex_JitPlugin, JitPluginServiceName, JitPluginMaxSessions)); + } + + /* Loop forever, servicing our services. */ + ro::g_server_manager.LoopProcess(); + } + + } + +} + void __libnx_initheap(void) { void* addr = nx_inner_heap; size_t size = nx_inner_heap_size; @@ -56,11 +138,15 @@ void __libnx_initheap(void) { fake_heap_start = (char*)addr; fake_heap_end = (char*)addr + size; + + ams::ro::InitializeHeap(); } void __appInit(void) { hos::InitializeForStratosphere(); + fs::SetAllocator(ro::Allocate, ro::Deallocate); + sm::DoWithSession([&]() { R_ABORT_UNLESS(setsysInitialize()); R_ABORT_UNLESS(fsInitialize()); @@ -86,21 +172,15 @@ void __appExit(void) { namespace { - /* ldr:ro, ro:dmnt, ro:1. */ - /* TODO: Consider max sessions enforcement? */ - constexpr size_t NumServers = 3; - sf::hipc::ServerManager g_server_manager; - constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("ro:dmnt"); - constexpr size_t DebugMonitorMaxSessions = 2; +} - /* NOTE: Official code passes 32 for ldr:ro max sessions. We will pass 2, because that's the actual limit. */ - constexpr sm::ServiceName UserServiceName = sm::ServiceName::Encode("ldr:ro"); - constexpr size_t UserMaxSessions = 2; - - constexpr sm::ServiceName JitPluginServiceName = sm::ServiceName::Encode("ro:1"); - constexpr size_t JitPluginMaxSessions = 2; +void *operator new(size_t size) { + AMS_ABORT("operator new(size_t) was called"); +} +void operator delete(void *p) { + AMS_ABORT("operator delete(void *) was called"); } int main(int argc, char **argv) @@ -109,6 +189,12 @@ int main(int argc, char **argv) os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ro, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ro, Main)); + /* Attach the server allocator. */ + ro::g_server_allocator.Attach(ro::g_server_heap_handle); + + /* Disable auto-abort in fs operations. */ + fs::SetEnabledAutoAbort(false); + /* Initialize Debug config. */ { ON_SCOPE_EXIT { spl::Finalize(); }; @@ -117,16 +203,8 @@ int main(int argc, char **argv) ro::SetDevelopmentFunctionEnabled(spl::IsDevelopmentFunctionEnabled()); } - /* Create services. */ - R_ABORT_UNLESS((g_server_manager.RegisterServer(DebugMonitorServiceName, DebugMonitorMaxSessions))); - - R_ABORT_UNLESS((g_server_manager.RegisterServer(UserServiceName, UserMaxSessions))); - if (hos::GetVersion() >= hos::Version_7_0_0) { - R_ABORT_UNLESS((g_server_manager.RegisterServer(JitPluginServiceName, JitPluginMaxSessions))); - } - - /* Loop forever, servicing our services. */ - g_server_manager.LoopProcess(); + /* Run the ro server. */ + ro::LoopServer(); /* Cleanup */ return 0; diff --git a/stratosphere/ro/source/ro_ro_service.hpp b/stratosphere/ro/source/ro_ro_service.hpp index 8e1702568..5f83ab084 100644 --- a/stratosphere/ro/source/ro_ro_service.hpp +++ b/stratosphere/ro/source/ro_ro_service.hpp @@ -42,14 +42,4 @@ namespace ams::ro { }; static_assert(ro::impl::IsIRoInterface); - class RoUserService final : public RoService { - public: - RoUserService() : RoService(NrrKind_User) { /* ... */ } - }; - - class RoJitPluginService final : public RoService { - public: - RoJitPluginService() : RoService(NrrKind_JitPlugin) { /* ... */ } - }; - }