MCPcopy Create free account
hub / github.com/amwatson/CitraVR / Load3DSXFile

Function Load3DSXFile

src/core/loader/3dsx.cpp:97–249  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

95using Kernel::CodeSet;
96
97static THREEDSX_Error Load3DSXFile(Core::System& system, FileUtil::IOFile& file, u32 base_addr,
98 std::shared_ptr<CodeSet>* out_codeset) {
99 if (!file.IsOpen())
100 return ERROR_FILE;
101
102 // Reset read pointer in case this file has been read before.
103 file.Seek(0, SEEK_SET);
104
105 THREEDSX_Header hdr;
106 if (file.ReadBytes(&hdr, sizeof(hdr)) != sizeof(hdr))
107 return ERROR_READ;
108
109 THREEloadinfo loadinfo;
110 // loadinfo segments must be a multiple of 0x1000
111 loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) & ~0xFFF;
112 loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) & ~0xFFF;
113 loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) & ~0xFFF;
114 // prevent integer overflow leading to heap-buffer-overflow
115 if (loadinfo.seg_sizes[0] < hdr.code_seg_size || loadinfo.seg_sizes[1] < hdr.rodata_seg_size ||
116 loadinfo.seg_sizes[2] < hdr.data_seg_size) {
117 return ERROR_READ;
118 }
119 u32 offsets[2] = {loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1]};
120 u32 n_reloc_tables = hdr.reloc_hdr_size / sizeof(u32);
121 std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] +
122 loadinfo.seg_sizes[2]);
123
124 loadinfo.seg_addrs[0] = base_addr;
125 loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0];
126 loadinfo.seg_addrs[2] = loadinfo.seg_addrs[1] + loadinfo.seg_sizes[1];
127 loadinfo.seg_ptrs[0] = program_image.data();
128 loadinfo.seg_ptrs[1] = loadinfo.seg_ptrs[0] + loadinfo.seg_sizes[0];
129 loadinfo.seg_ptrs[2] = loadinfo.seg_ptrs[1] + loadinfo.seg_sizes[1];
130
131 // Skip header for future compatibility
132 file.Seek(hdr.header_size, SEEK_SET);
133
134 // Read the relocation headers
135 std::vector<u32> relocs(n_reloc_tables * NUM_SEGMENTS);
136 for (unsigned int current_segment = 0; current_segment < NUM_SEGMENTS; ++current_segment) {
137 std::size_t size = n_reloc_tables * sizeof(u32);
138 if (file.ReadBytes(&relocs[current_segment * n_reloc_tables], size) != size)
139 return ERROR_READ;
140 }
141
142 // Read the segments
143 if (file.ReadBytes(loadinfo.seg_ptrs[0], hdr.code_seg_size) != hdr.code_seg_size)
144 return ERROR_READ;
145 if (file.ReadBytes(loadinfo.seg_ptrs[1], hdr.rodata_seg_size) != hdr.rodata_seg_size)
146 return ERROR_READ;
147 if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) !=
148 hdr.data_seg_size - hdr.bss_size)
149 return ERROR_READ;
150
151 // BSS clear
152 std::memset((char*)loadinfo.seg_ptrs[2] + hdr.data_seg_size - hdr.bss_size, 0, hdr.bss_size);
153
154 // Relocate the segments

Callers 1

LoadMethod · 0.85

Calls 6

TranslateAddrFunction · 0.85
ReadBytesMethod · 0.80
CreateCodeSetMethod · 0.80
IsOpenMethod · 0.45
SeekMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected