summaryrefslogtreecommitdiff
path: root/src/core/loader/nso.cpp
diff options
context:
space:
mode:
authorMichael Scire <SciresM@gmail.com>2020-01-22 20:14:06 -0800
committerMichael Scire <SciresM@gmail.com>2020-01-22 20:14:06 -0800
commit5a7eecc3adfb179335d921725a3b60c622e92836 (patch)
tree5be51ae470df6428478da91f1e8454e3c18b0955 /src/core/loader/nso.cpp
parentd8e0d839bd9c958233e6c57ff7e35b783daaf2d5 (diff)
loader: provide default arguments (zero byte) to NSOs
Certain newer unity games (Terraria, Pokemon Mystery Dungeon) require that the argument region be populated. Failure to do so results in an integer underflow in argument count, and eventually an unmapped read at 0x800000000. Providing this default fixes this. Note that the behavior of official software is as yet unverified, arguments-wise.
Diffstat (limited to 'src/core/loader/nso.cpp')
-rw-r--r--src/core/loader/nso.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 515c5accb..044067a5b 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -97,7 +97,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
if (nso_header.IsSegmentCompressed(i)) {
data = DecompressSegment(data, nso_header.segments[i]);
}
- program_image.resize(nso_header.segments[i].location + data.size());
+ program_image.resize(nso_header.segments[i].location +
+ PageAlignSize(static_cast<u32>(data.size())));
std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(),
data.size());
codeset.segments[i].addr = nso_header.segments[i].location;
@@ -105,8 +106,12 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size()));
}
- if (should_pass_arguments && !Settings::values.program_args.empty()) {
- const auto arg_data = Settings::values.program_args;
+ if (should_pass_arguments) {
+ std::vector<u8> arg_data{Settings::values.program_args.begin(),
+ Settings::values.program_args.end()};
+ if (arg_data.empty()) {
+ arg_data.resize(NSO_ARGUMENT_DEFAULT_SIZE);
+ }
codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE;
NSOArgumentHeader args_header{
NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}};