diff options
| author | 2020-03-20 23:44:28 -0400 | |
|---|---|---|
| committer | 2020-04-17 00:59:27 -0400 | |
| commit | 7aa0e4a7ca08357df9123e303256a95cb24cb954 (patch) | |
| tree | 1771c5061d0e422af0b57a8732782879cbbee864 /src/core/loader/nso.cpp | |
| parent | common: common_funcs: Add a macro for defining enum flag operators. (diff) | |
| download | yuzu-7aa0e4a7ca08357df9123e303256a95cb24cb954.tar.gz yuzu-7aa0e4a7ca08357df9123e303256a95cb24cb954.tar.xz yuzu-7aa0e4a7ca08357df9123e303256a95cb24cb954.zip | |
loader: nso: Fix loading of static objects to be properly sized and aligned.
Diffstat (limited to 'src/core/loader/nso.cpp')
| -rw-r--r-- | src/core/loader/nso.cpp | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 044067a5b..5fe798bf0 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -97,13 +97,12 @@ 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 + | 100 | program_image.resize(nso_header.segments[i].location + static_cast<u32>(data.size())); |
| 101 | PageAlignSize(static_cast<u32>(data.size()))); | ||
| 102 | std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(), | 101 | std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(), |
| 103 | data.size()); | 102 | data.size()); |
| 104 | codeset.segments[i].addr = nso_header.segments[i].location; | 103 | codeset.segments[i].addr = nso_header.segments[i].location; |
| 105 | codeset.segments[i].offset = nso_header.segments[i].location; | 104 | codeset.segments[i].offset = nso_header.segments[i].location; |
| 106 | codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size())); | 105 | codeset.segments[i].size = nso_header.segments[i].size; |
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | if (should_pass_arguments) { | 108 | if (should_pass_arguments) { |
| @@ -123,24 +122,15 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, | |||
| 123 | arg_data.size()); | 122 | arg_data.size()); |
| 124 | } | 123 | } |
| 125 | 124 | ||
| 126 | // MOD header pointer is at .text offset + 4 | 125 | codeset.DataSegment().size += nso_header.segments[2].bss_size; |
| 127 | u32 module_offset; | 126 | const u32 image_size{ |
| 128 | std::memcpy(&module_offset, program_image.data() + 4, sizeof(u32)); | 127 | PageAlignSize(static_cast<u32>(program_image.size()) + nso_header.segments[2].bss_size)}; |
| 129 | |||
| 130 | // Read MOD header | ||
| 131 | MODHeader mod_header{}; | ||
| 132 | // Default .bss to size in segment header if MOD0 section doesn't exist | ||
| 133 | u32 bss_size{PageAlignSize(nso_header.segments[2].bss_size)}; | ||
| 134 | std::memcpy(&mod_header, program_image.data() + module_offset, sizeof(MODHeader)); | ||
| 135 | const bool has_mod_header{mod_header.magic == Common::MakeMagic('M', 'O', 'D', '0')}; | ||
| 136 | if (has_mod_header) { | ||
| 137 | // Resize program image to include .bss section and page align each section | ||
| 138 | bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); | ||
| 139 | } | ||
| 140 | codeset.DataSegment().size += bss_size; | ||
| 141 | const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; | ||
| 142 | program_image.resize(image_size); | 128 | program_image.resize(image_size); |
| 143 | 129 | ||
| 130 | for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { | ||
| 131 | codeset.segments[i].size = PageAlignSize(codeset.segments[i].size); | ||
| 132 | } | ||
| 133 | |||
| 144 | // Apply patches if necessary | 134 | // Apply patches if necessary |
| 145 | if (pm && (pm->HasNSOPatch(nso_header.build_id) || Settings::values.dump_nso)) { | 135 | if (pm && (pm->HasNSOPatch(nso_header.build_id) || Settings::values.dump_nso)) { |
| 146 | std::vector<u8> pi_header; | 136 | std::vector<u8> pi_header; |