summaryrefslogtreecommitdiff
path: root/src/core/loader/nso.cpp
diff options
context:
space:
mode:
authorGravatar Michael Scire2020-01-22 20:14:06 -0800
committerGravatar Michael Scire2020-01-22 20:14:06 -0800
commit5a7eecc3adfb179335d921725a3b60c622e92836 (patch)
tree5be51ae470df6428478da91f1e8454e3c18b0955 /src/core/loader/nso.cpp
parentMerge pull request #3339 from Simek/dark-theme-update (diff)
downloadyuzu-5a7eecc3adfb179335d921725a3b60c622e92836.tar.gz
yuzu-5a7eecc3adfb179335d921725a3b60c622e92836.tar.xz
yuzu-5a7eecc3adfb179335d921725a3b60c622e92836.zip
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,
97 if (nso_header.IsSegmentCompressed(i)) { 97 if (nso_header.IsSegmentCompressed(i)) {
98 data = DecompressSegment(data, nso_header.segments[i]); 98 data = DecompressSegment(data, nso_header.segments[i]);
99 } 99 }
100 program_image.resize(nso_header.segments[i].location + data.size()); 100 program_image.resize(nso_header.segments[i].location +
101 PageAlignSize(static_cast<u32>(data.size())));
101 std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(), 102 std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(),
102 data.size()); 103 data.size());
103 codeset.segments[i].addr = nso_header.segments[i].location; 104 codeset.segments[i].addr = nso_header.segments[i].location;
@@ -105,8 +106,12 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
105 codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size())); 106 codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size()));
106 } 107 }
107 108
108 if (should_pass_arguments && !Settings::values.program_args.empty()) { 109 if (should_pass_arguments) {
109 const auto arg_data = Settings::values.program_args; 110 std::vector<u8> arg_data{Settings::values.program_args.begin(),
111 Settings::values.program_args.end()};
112 if (arg_data.empty()) {
113 arg_data.resize(NSO_ARGUMENT_DEFAULT_SIZE);
114 }
110 codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; 115 codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE;
111 NSOArgumentHeader args_header{ 116 NSOArgumentHeader args_header{
112 NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}}; 117 NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}};