summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2017-01-19 01:30:59 -0300
committerGravatar GitHub2017-01-19 01:30:59 -0300
commitebe0150635340ff79a0323245b40b082fe380360 (patch)
tree5e97ceef016df9eabafa34688314430d0afc6206
parentMerge pull request #2442 from wwylele/hid-signal (diff)
parentloader: Add support for 3DSX special relocation types, fixes citra-emu/citra#... (diff)
downloadyuzu-ebe0150635340ff79a0323245b40b082fe380360.tar.gz
yuzu-ebe0150635340ff79a0323245b40b082fe380360.tar.xz
yuzu-ebe0150635340ff79a0323245b40b082fe380360.zip
Merge pull request #2450 from Xtansia/master
loader: Add support for 3DSX special relocation types
Diffstat (limited to '')
-rw-r--r--src/core/loader/3dsx.cpp34
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 }