From 4e7ae82b38d2a841453a3c767807490b6a4f5a94 Mon Sep 17 00:00:00 2001 From: SciresM Date: Sun, 14 May 2023 03:06:52 -0700 Subject: [PATCH] romfs/ams.mitm/pm: refactor to dynamically steal heap for certain games. (#2122) * fs.mitm: skeleton the use of special allocation in romfs build * pm: add api for ams.mitm to steal application memory * pm/mitm: okay, that api won't work, try a different one * romfs: revert memory usage increases; we'll handle torture games case-by-case. * pm/romfs: first (broken?) pass at dynamic heap. I cannot wait to figure out all the ways this is wrong. * Release the dynamic heap a little more eagerly * romfs: animal crossing is also not a nice game * romfs: fix issues in close-during-build * romfs: zelda is a blight upon this earth --- libstratosphere/include/stratosphere.hpp | 1 + libstratosphere/include/stratosphere/mitm.hpp | 20 ++++++++ .../mitm/impl/mitm_pm_interface.hpp | 27 +++++++++++ .../include/stratosphere/mitm/mitm_pm_api.hpp | 29 ++++++++++++ .../pm/impl/pm_shell_interface.hpp | 47 ++++++++++--------- .../source/mitm/mitm_pm.os.horizon.c | 44 +++++++++++++++++ .../source/mitm/mitm_pm.os.horizon.h | 37 +++++++++++++++ libstratosphere/source/mitm/mitm_pm_api.cpp | 37 +++++++++++++++ libstratosphere/source/pm/pm_shell_api.cpp | 1 + .../include/vapours/results/fs_results.hpp | 5 +- 10 files changed, 223 insertions(+), 25 deletions(-) create mode 100644 libstratosphere/include/stratosphere/mitm.hpp create mode 100644 libstratosphere/include/stratosphere/mitm/impl/mitm_pm_interface.hpp create mode 100644 libstratosphere/include/stratosphere/mitm/mitm_pm_api.hpp create mode 100644 libstratosphere/source/mitm/mitm_pm.os.horizon.c create mode 100644 libstratosphere/source/mitm/mitm_pm.os.horizon.h create mode 100644 libstratosphere/source/mitm/mitm_pm_api.cpp diff --git a/libstratosphere/include/stratosphere.hpp b/libstratosphere/include/stratosphere.hpp index bc5547f9..92ac1def 100644 --- a/libstratosphere/include/stratosphere.hpp +++ b/libstratosphere/include/stratosphere.hpp @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include diff --git a/libstratosphere/include/stratosphere/mitm.hpp b/libstratosphere/include/stratosphere/mitm.hpp new file mode 100644 index 00000000..c4e7afe6 --- /dev/null +++ b/libstratosphere/include/stratosphere/mitm.hpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include diff --git a/libstratosphere/include/stratosphere/mitm/impl/mitm_pm_interface.hpp b/libstratosphere/include/stratosphere/mitm/impl/mitm_pm_interface.hpp new file mode 100644 index 00000000..704fdb3a --- /dev/null +++ b/libstratosphere/include/stratosphere/mitm/impl/mitm_pm_interface.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include +#include + +#define AMS_MITM_PM_IMPL_I_PM_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 65000, Result, PrepareLaunchProgram, (sf::Out out_boost_size, ncm::ProgramId program_id, const cfg::OverrideStatus &override_status, bool is_application), (out_boost_size, program_id, override_status, is_application)) + +AMS_SF_DEFINE_INTERFACE(ams::mitm::pm::impl, IPmInterface, AMS_MITM_PM_IMPL_I_PM_INTERFACE_INFO, 0xEA88789C) + diff --git a/libstratosphere/include/stratosphere/mitm/mitm_pm_api.hpp b/libstratosphere/include/stratosphere/mitm/mitm_pm_api.hpp new file mode 100644 index 00000000..feab8db6 --- /dev/null +++ b/libstratosphere/include/stratosphere/mitm/mitm_pm_api.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include + +namespace ams::mitm::pm { + + /* PM API. */ + void Initialize(); + void Finalize(); + + Result PrepareLaunchProgram(u64 *out, ncm::ProgramId program_id, const cfg::OverrideStatus &status, bool is_application); + +} diff --git a/libstratosphere/include/stratosphere/pm/impl/pm_shell_interface.hpp b/libstratosphere/include/stratosphere/pm/impl/pm_shell_interface.hpp index 1da93af4..1cccdab6 100644 --- a/libstratosphere/include/stratosphere/pm/impl/pm_shell_interface.hpp +++ b/libstratosphere/include/stratosphere/pm/impl/pm_shell_interface.hpp @@ -19,31 +19,32 @@ #include #include -#define AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \ - AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 5, void, NotifyBootFinished, (), ()) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, GetApplicationProcessIdForShell, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size)) \ - AMS_SF_METHOD_INFO(C, H, 8, Result, BoostApplicationThreadResourceLimit, (), ()) \ - AMS_SF_METHOD_INFO(C, H, 9, void, GetBootFinishedEventHandle, (sf::OutCopyHandle out), (out), hos::Version_8_0_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ()) +#define AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \ + AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 5, void, NotifyBootFinished, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, GetApplicationProcessIdForShell, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size)) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, BoostApplicationThreadResourceLimit, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 9, void, GetBootFinishedEventHandle, (sf::OutCopyHandle out), (out), hos::Version_8_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ()) AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IShellInterface, AMS_PM_I_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0) -#define AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \ - AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, CleanupProcess, (os::ProcessId process_id), (process_id)) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, ClearExceptionOccurred, (os::ProcessId process_id), (process_id)) \ - AMS_SF_METHOD_INFO(C, H, 7, void, NotifyBootFinished, (), ()) \ - AMS_SF_METHOD_INFO(C, H, 8, Result, GetApplicationProcessIdForShell, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 9, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size), hos::Version_4_0_0) +#define AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (sf::Out out_process_id, const ncm::ProgramLocation &loc, u32 flags), (out_process_id, loc, flags)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, TerminateProgram, (ncm::ProgramId program_id), (program_id)) \ + AMS_SF_METHOD_INFO(C, H, 3, void, GetProcessEventHandle, (sf::OutCopyHandle out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 4, void, GetProcessEventInfo, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, CleanupProcess, (os::ProcessId process_id), (process_id)) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, ClearExceptionOccurred, (os::ProcessId process_id), (process_id)) \ + AMS_SF_METHOD_INFO(C, H, 7, void, NotifyBootFinished, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, GetApplicationProcessIdForShell, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, BoostSystemMemoryResourceLimit, (u64 boost_size), (boost_size), hos::Version_4_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, BoostSystemThreadResourceLimit, (), ()) AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IDeprecatedShellInterface, AMS_PM_I_DEPRECATED_SHELL_INTERFACE_INTERFACE_INFO, 0x387D60C0) diff --git a/libstratosphere/source/mitm/mitm_pm.os.horizon.c b/libstratosphere/source/mitm/mitm_pm.os.horizon.c new file mode 100644 index 00000000..adfabd4f --- /dev/null +++ b/libstratosphere/source/mitm/mitm_pm.os.horizon.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "../service_guard.h" +#include "mitm_pm.os.horizon.h" + +static Service g_amsMitmPmSrv; + +NX_GENERATE_SERVICE_GUARD(amsMitmPm); + +Result _amsMitmPmInitialize(void) { + return smGetService(&g_amsMitmPmSrv, "mitm:pm"); +} + +void _amsMitmPmCleanup(void) { + serviceClose(&g_amsMitmPmSrv); +} + +Service *amsMitmPmGetServiceSession(void) { + return &g_amsMitmPmSrv; +} + +Result amsMitmPmPrepareLaunchProgram(u64 *out, u64 program_id, const CfgOverrideStatus *status, bool is_application) { + const struct { + u8 is_application; + u64 program_id; + CfgOverrideStatus status; + } in = { is_application ? 1 : 0, program_id, *status }; + + return serviceDispatchInOut(&g_amsMitmPmSrv, 65000, in, *out); +} diff --git a/libstratosphere/source/mitm/mitm_pm.os.horizon.h b/libstratosphere/source/mitm/mitm_pm.os.horizon.h new file mode 100644 index 00000000..2d8da12c --- /dev/null +++ b/libstratosphere/source/mitm/mitm_pm.os.horizon.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + u64 keys_down; + u64 flags; +} CfgOverrideStatus; + +Result amsMitmPmInitialize(void); +void amsMitmPmExit(void); +Service *amsMitmPmGetServiceSession(void); + +Result amsMitmPmPrepareLaunchProgram(u64 *out, u64 program_id, const CfgOverrideStatus *status, bool is_application); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libstratosphere/source/mitm/mitm_pm_api.cpp b/libstratosphere/source/mitm/mitm_pm_api.cpp new file mode 100644 index 00000000..a49cf9ce --- /dev/null +++ b/libstratosphere/source/mitm/mitm_pm_api.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "mitm_pm.os.horizon.h" + +namespace ams::mitm::pm { + + /* PM API. */ + #if defined(ATMOSPHERE_OS_HORIZON) + void Initialize() { + R_ABORT_UNLESS(amsMitmPmInitialize()); + } + + void Finalize() { + amsMitmPmExit(); + } + + Result PrepareLaunchProgram(u64 *out, ncm::ProgramId program_id, const cfg::OverrideStatus &status, bool is_application) { + static_assert(sizeof(status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!"); + R_RETURN(amsMitmPmPrepareLaunchProgram(out, program_id.value, reinterpret_cast(std::addressof(status)), is_application)); + } + #endif + +} diff --git a/libstratosphere/source/pm/pm_shell_api.cpp b/libstratosphere/source/pm/pm_shell_api.cpp index 03470e47..247d88cb 100644 --- a/libstratosphere/source/pm/pm_shell_api.cpp +++ b/libstratosphere/source/pm/pm_shell_api.cpp @@ -14,6 +14,7 @@ * along with this program. If not, see . */ #include +#include "pm_ams.os.horizon.h" namespace ams::pm::shell { diff --git a/libvapours/include/vapours/results/fs_results.hpp b/libvapours/include/vapours/results/fs_results.hpp index e47e9f55..104a299f 100644 --- a/libvapours/include/vapours/results/fs_results.hpp +++ b/libvapours/include/vapours/results/fs_results.hpp @@ -41,8 +41,9 @@ namespace ams::fs { R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60); R_DEFINE_ERROR_RANGE(HandledBySystemProcess, 1000, 2999); - R_DEFINE_ERROR_RESULT(PartitionNotFound, 1001); - R_DEFINE_ERROR_RESULT(TargetNotFound, 1002); + R_DEFINE_ERROR_RESULT(PartitionNotFound, 1001); + R_DEFINE_ERROR_RESULT(TargetNotFound, 1002); + R_DEFINE_ERROR_RESULT(NcaExternalKeyNotFound, 1004); R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499); R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001);