From 934196109eb84c2ad7b17ae37748af9fba89b340 Mon Sep 17 00:00:00 2001 From: tpu Date: Sat, 1 Jun 2013 22:43:23 +0800 Subject: [PATCH] WriteVarSymbol bug fix --- Core/ELF/ElfReader.cpp | 2 +- Core/HLE/sceKernelModule.cpp | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index 96bd82e6c8..9137cc721a 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -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: diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index a99d272b21..d27d454271 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -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);