Merge pull request #2015 from tpunix/master

Module load bug fix
This commit is contained in:
Henrik Rydgård 2013-06-01 08:25:08 -07:00
commit 6db586e12f
2 changed files with 10 additions and 6 deletions

View File

@ -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:

View File

@ -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);