diff options
| author | 2015-01-07 01:21:50 +0000 | |
|---|---|---|
| committer | 2015-01-15 22:23:08 +0100 | |
| commit | 84e52a944d0c5dba8c5c9c6c9a0b106f571c7041 (patch) | |
| tree | 14b010f64fc925980901d99fa2307e006cc57c77 /src/core/loader/3dsx.cpp | |
| parent | Loader: Clean up the NCCH AppLoader. (diff) | |
| download | yuzu-84e52a944d0c5dba8c5c9c6c9a0b106f571c7041.tar.gz yuzu-84e52a944d0c5dba8c5c9c6c9a0b106f571c7041.tar.xz yuzu-84e52a944d0c5dba8c5c9c6c9a0b106f571c7041.zip | |
Loader: Clean up the 3DSX AppLoader.
Diffstat (limited to 'src/core/loader/3dsx.cpp')
| -rw-r--r-- | src/core/loader/3dsx.cpp | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index f3e09ecd6..c3ac1f417 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -85,7 +85,7 @@ struct THREEloadinfo | |||
| 85 | u32 seg_sizes[3]; | 85 | u32 seg_sizes[3]; |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | static u32 TranslateAddr(u32 addr, THREEloadinfo *loadinfo, u32* offsets) | 88 | static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets) |
| 89 | { | 89 | { |
| 90 | if (addr < offsets[0]) | 90 | if (addr < offsets[0]) |
| 91 | return loadinfo->seg_addrs[0] + addr; | 91 | return loadinfo->seg_addrs[0] + addr; |
| @@ -130,8 +130,9 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr) | |||
| 130 | // Read the relocation headers | 130 | // Read the relocation headers |
| 131 | u32* relocs = (u32*)(loadinfo.seg_ptrs[2] + hdr.data_seg_size); | 131 | u32* relocs = (u32*)(loadinfo.seg_ptrs[2] + hdr.data_seg_size); |
| 132 | 132 | ||
| 133 | for (u32 current_segment = 0; current_segment < 3; current_segment++) { | 133 | for (unsigned current_segment = 0; current_segment < 3; current_segment++) { |
| 134 | if (file.ReadBytes(&relocs[current_segment*n_reloc_tables], n_reloc_tables * 4) != n_reloc_tables * 4) | 134 | size_t size = n_reloc_tables * 4; |
| 135 | if (file.ReadBytes(&relocs[current_segment * n_reloc_tables], size) != size) | ||
| 135 | return ERROR_READ; | 136 | return ERROR_READ; |
| 136 | } | 137 | } |
| 137 | 138 | ||
| @@ -147,9 +148,9 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr) | |||
| 147 | memset((char*)loadinfo.seg_ptrs[2] + hdr.data_seg_size - hdr.bss_size, 0, hdr.bss_size); | 148 | memset((char*)loadinfo.seg_ptrs[2] + hdr.data_seg_size - hdr.bss_size, 0, hdr.bss_size); |
| 148 | 149 | ||
| 149 | // Relocate the segments | 150 | // Relocate the segments |
| 150 | for (u32 current_segment = 0; current_segment < 3; current_segment++) { | 151 | for (unsigned current_segment = 0; current_segment < 3; current_segment++) { |
| 151 | for (u32 current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) { | 152 | for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) { |
| 152 | u32 n_relocs = relocs[current_segment*n_reloc_tables + current_segment_reloc_table]; | 153 | u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table]; |
| 153 | if (current_segment_reloc_table >= 2) { | 154 | if (current_segment_reloc_table >= 2) { |
| 154 | // We are not using this table - ignore it because we don't know what it dose | 155 | // We are not using this table - ignore it because we don't know what it dose |
| 155 | file.Seek(n_relocs*sizeof(THREEDSX_Reloc), SEEK_CUR); | 156 | file.Seek(n_relocs*sizeof(THREEDSX_Reloc), SEEK_CUR); |
| @@ -158,29 +159,35 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr) | |||
| 158 | static THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; | 159 | static THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; |
| 159 | 160 | ||
| 160 | u32* pos = (u32*)loadinfo.seg_ptrs[current_segment]; | 161 | u32* pos = (u32*)loadinfo.seg_ptrs[current_segment]; |
| 161 | u32* end_pos = pos + (loadinfo.seg_sizes[current_segment] / 4); | 162 | const u32* end_pos = pos + (loadinfo.seg_sizes[current_segment] / 4); |
| 162 | 163 | ||
| 163 | while (n_relocs) { | 164 | while (n_relocs) { |
| 164 | u32 remaining = std::min(RELOCBUFSIZE, n_relocs); | 165 | u32 remaining = std::min(RELOCBUFSIZE, n_relocs); |
| 165 | n_relocs -= remaining; | 166 | n_relocs -= remaining; |
| 166 | 167 | ||
| 167 | if (file.ReadBytes(reloc_table, remaining*sizeof(THREEDSX_Reloc)) != remaining*sizeof(THREEDSX_Reloc)) | 168 | if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != remaining * sizeof(THREEDSX_Reloc)) |
| 168 | return ERROR_READ; | 169 | return ERROR_READ; |
| 169 | 170 | ||
| 170 | for (u32 current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { | 171 | for (unsigned current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { |
| 171 | LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)\n", | 172 | const auto& table = reloc_table[current_inprogress]; |
| 172 | current_segment_reloc_table, (u32)reloc_table[current_inprogress].skip, (u32)reloc_table[current_inprogress].patch); | 173 | LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)\n", current_segment_reloc_table, |
| 173 | pos += reloc_table[current_inprogress].skip; | 174 | (u32)table.skip, (u32)table.patch); |
| 174 | s32 num_patches = reloc_table[current_inprogress].patch; | 175 | pos += table.skip; |
| 176 | s32 num_patches = table.patch; | ||
| 175 | while (0 < num_patches && pos < end_pos) { | 177 | while (0 < num_patches && pos < end_pos) { |
| 176 | u32 in_addr = (char*)pos - (char*)&all_mem[0]; | 178 | u32 in_addr = (char*)pos - (char*)&all_mem[0]; |
| 177 | u32 addr = TranslateAddr(*pos, &loadinfo, offsets); | 179 | u32 addr = TranslateAddr(*pos, &loadinfo, offsets); |
| 178 | LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)\n", | 180 | LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)\n", |
| 179 | base_addr + in_addr, addr, current_segment_reloc_table, *pos); | 181 | base_addr + in_addr, addr, current_segment_reloc_table, *pos); |
| 180 | switch (current_segment_reloc_table) { | 182 | switch (current_segment_reloc_table) { |
| 181 | case 0: *pos = (addr); break; | 183 | case 0: |
| 182 | case 1: *pos = (addr - in_addr); break; | 184 | *pos = (addr); |
| 183 | default: break; //this should never happen | 185 | break; |
| 186 | case 1: | ||
| 187 | *pos = (addr - in_addr); | ||
| 188 | break; | ||
| 189 | default: | ||
| 190 | break; //this should never happen | ||
| 184 | } | 191 | } |
| 185 | pos++; | 192 | pos++; |
| 186 | num_patches--; | 193 | num_patches--; |