diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/loader/3dsx.cpp | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 1c10740a0..09266e8b0 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -177,18 +177,34 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, | |||
| 177 | pos += table.skip; | 177 | pos += table.skip; |
| 178 | s32 num_patches = table.patch; | 178 | s32 num_patches = table.patch; |
| 179 | while (0 < num_patches && pos < end_pos) { | 179 | while (0 < num_patches && pos < end_pos) { |
| 180 | u32 in_addr = | 180 | u32 in_addr = base_addr + static_cast<u32>(reinterpret_cast<u8*>(pos) - |
| 181 | static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data()); | 181 | program_image.data()); |
| 182 | u32 addr = TranslateAddr(*pos, &loadinfo, offsets); | 182 | u32 orig_data = *pos; |
| 183 | LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)", | 183 | u32 sub_type = orig_data >> (32 - 4); |
| 184 | base_addr + in_addr, addr, current_segment_reloc_table, *pos); | 184 | u32 addr = TranslateAddr(orig_data & ~0xF0000000, &loadinfo, offsets); |
| 185 | LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)", in_addr, addr, | ||
| 186 | current_segment_reloc_table, *pos); | ||
| 185 | switch (current_segment_reloc_table) { | 187 | switch (current_segment_reloc_table) { |
| 186 | case 0: | 188 | case 0: { |
| 187 | *pos = (addr); | 189 | if (sub_type != 0) |
| 190 | return ERROR_READ; | ||
| 191 | *pos = addr; | ||
| 188 | break; | 192 | break; |
| 189 | case 1: | 193 | } |
| 190 | *pos = static_cast<u32>(addr - in_addr); | 194 | case 1: { |
| 195 | u32 data = addr - in_addr; | ||
| 196 | switch (sub_type) { | ||
| 197 | case 0: // 32-bit signed offset | ||
| 198 | *pos = data; | ||
| 199 | break; | ||
| 200 | case 1: // 31-bit signed offset | ||
| 201 | *pos = data & ~(1U << 31); | ||
| 202 | break; | ||
| 203 | default: | ||
| 204 | return ERROR_READ; | ||
| 205 | } | ||
| 191 | break; | 206 | break; |
| 207 | } | ||
| 192 | default: | 208 | default: |
| 193 | break; // this should never happen | 209 | break; // this should never happen |
| 194 | } | 210 | } |