mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
WriteVarSymbol bug fix
This commit is contained in:
parent
cf8309b783
commit
934196109e
@ -274,7 +274,7 @@ void ElfReader::LoadRelocations2(int rel_seg)
|
||||
}
|
||||
|
||||
op = Memory::ReadUnchecked_U32(rel_offset);
|
||||
DEBUG_LOG(LOADER, "Rel2: %5d: CMD=0x%04X type=%d off_seg=%d offset=%08x addr_seg=%d op=%08x\n", rcount, cmd, type, off_seg, rel_base, addr_seg, op);
|
||||
DEBUG_LOG(LOADER, "Rel2: %5d: CMD=0x%04X type=%d off_seg=%d offset=%08x addr_seg=%d op=%08x", rcount, cmd, type, off_seg, rel_base, addr_seg, op);
|
||||
|
||||
switch(type){
|
||||
case 0:
|
||||
|
@ -303,6 +303,7 @@ void WriteVarSymbol(u32 exportAddress, u32 relocAddress, u8 type)
|
||||
{
|
||||
static u32 lastHI16RelocAddress = 0;
|
||||
static u32 lastHI16ExportAddress = 0;
|
||||
static u32 lastHI16Processed = 0;
|
||||
|
||||
u32 relocData = Memory::Read_Instruction(relocAddress);
|
||||
|
||||
@ -331,6 +332,7 @@ void WriteVarSymbol(u32 exportAddress, u32 relocAddress, u8 type)
|
||||
// The R_MIPS_LO16 and R_MIPS_HI16 will often be *different* relocAddress values.
|
||||
lastHI16RelocAddress = relocAddress;
|
||||
lastHI16ExportAddress = exportAddress;
|
||||
lastHI16Processed = 0;
|
||||
break;
|
||||
|
||||
case R_MIPS_LO16:
|
||||
@ -341,15 +343,17 @@ void WriteVarSymbol(u32 exportAddress, u32 relocAddress, u8 type)
|
||||
ERROR_LOG_REPORT(LOADER, "HI16 and LO16 imports do not match for %08x => %08x/%08x (hi16 export: %08x)", exportAddress, lastHI16RelocAddress, relocAddress, lastHI16ExportAddress);
|
||||
break;
|
||||
}
|
||||
|
||||
u32 relocDataHi = Memory::Read_Instruction(lastHI16RelocAddress);
|
||||
// Sign extend the existing low value (e.g. from addiu.)
|
||||
u32 full = (relocDataHi << 16) + (s16)(u16)(relocData & 0xFFFF) + exportAddress;
|
||||
|
||||
// The low instruction will be a signed add, which means (full & 0x8000) will subtract.
|
||||
// We add 1 in that case so that it ends up the right value.
|
||||
u16 high = (full >> 16) + ((full & 0x8000) ? 1 : 0);
|
||||
Memory::Write_U32((relocDataHi & ~0xFFFF) | high, lastHI16RelocAddress);
|
||||
if(!lastHI16Processed){
|
||||
// The low instruction will be a signed add, which means (full & 0x8000) will subtract.
|
||||
// We add 1 in that case so that it ends up the right value.
|
||||
u16 high = (full >> 16) + ((full & 0x8000) ? 1 : 0);
|
||||
Memory::Write_U32((relocDataHi & ~0xFFFF) | high, lastHI16RelocAddress);
|
||||
lastHI16Processed = 1;
|
||||
}
|
||||
|
||||
// And then this is the low relocation, hurray.
|
||||
relocData = (relocData & ~0xFFFF) | (full & 0xFFFF);
|
||||
|
Loading…
Reference in New Issue
Block a user