summaryrefslogtreecommitdiff
path: root/src/core/loader/nso.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2020-03-20 23:44:28 -0400
committerGravatar bunnei2020-04-17 00:59:27 -0400
commit7aa0e4a7ca08357df9123e303256a95cb24cb954 (patch)
tree1771c5061d0e422af0b57a8732782879cbbee864 /src/core/loader/nso.cpp
parentcommon: common_funcs: Add a macro for defining enum flag operators. (diff)
downloadyuzu-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.cpp28
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;