From 1d2f1efd069701a6066f875e76b53101cff127c2 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 18 Dec 2013 00:09:08 +0100 Subject: [PATCH] Fix function replacement on ARM --- Core/HLE/sceKernel.h | 2 +- Core/HLE/sceKernelModule.cpp | 21 ++++++++++++++------- Core/MIPS/ARM/ArmAsm.cpp | 4 ++-- Core/MIPS/ARM/ArmJit.cpp | 7 ++++++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 75c99ea6a4..5e3acdeee5 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -452,7 +452,7 @@ public: if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset]) { // Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP - if (handle != 0 && handle != 0x80020001) + if (handle != 0 && (u32)handle != 0x80020001) { WARN_LOG(SCEKERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); } diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 95a40d7817..eb83cc7d2b 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -21,6 +21,7 @@ #include "native/base/stringutil.h" #include "Common/FileUtil.h" +#include "Core/Config.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" #include "Core/Reporting.h" @@ -235,13 +236,13 @@ public: p.Do(isStarted); ModuleWaitingThread mwt = {0}; p.Do(waitingThreads, mwt); - FuncSymbolExport fsx = {0}; + FuncSymbolExport fsx = {{0}}; p.Do(exportedFuncs, fsx); - FuncSymbolImport fsi = {0}; + FuncSymbolImport fsi = {{0}}; p.Do(importedFuncs, fsi); - VarSymbolExport vsx = {0}; + VarSymbolExport vsx = {{0}}; p.Do(exportedVars, vsx); - VarSymbolImport vsi = {0}; + VarSymbolImport vsi = {{0}}; p.Do(importedVars, vsi); RebuildImpExpModuleNames(); } @@ -824,9 +825,10 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro bool gotSymbols = reader.LoadSymbols(); MIPSAnalyst::ScanForFunctions(textStart, textStart + textSize, !gotSymbols); #else - // Scan for functions (for the analysis results which can help the JIT). - // But don't insert into the symbol map. - // MIPSAnalyst::ScanForFunctions(textStart, textStart + textSize, false); + if (g_Config.bFuncHashMap) { + bool gotSymbols = reader.LoadSymbols(); + MIPSAnalyst::ScanForFunctions(textStart, textStart + textSize, !gotSymbols); + } #endif } @@ -983,6 +985,11 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro #if !defined(USING_GLES2) bool gotSymbols = reader.LoadSymbols(); MIPSAnalyst::ScanForFunctions(textStart, textEnd, !gotSymbols); +#else + if (g_Config.bFuncHashMap) { + bool gotSymbols = reader.LoadSymbols(); + MIPSAnalyst::ScanForFunctions(textStart, textEnd, !gotSymbols); + } #endif } diff --git a/Core/MIPS/ARM/ArmAsm.cpp b/Core/MIPS/ARM/ArmAsm.cpp index 3f66ecc35d..95f4368074 100644 --- a/Core/MIPS/ARM/ArmAsm.cpp +++ b/Core/MIPS/ARM/ArmAsm.cpp @@ -151,8 +151,8 @@ void Jit::GenerateFixedCode() // TODO: In practice, do we ever run code from uncached space (| 0x40000000)? If not, we can remove this BIC. BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF LDR(R0, MEMBASEREG, R0); - AND(R1, R0, Operand2(0xFC, 4)); // rotation is to the right, in 2-bit increments. - BIC(R0, R0, Operand2(0xFC, 4)); + AND(R1, R0, Operand2(0xFF, 4)); // rotation is to the right, in 2-bit increments. + BIC(R0, R0, Operand2(0xFF, 4)); CMP(R1, Operand2(MIPS_EMUHACK_OPCODE >> 24, 4)); SetCC(CC_EQ); // IDEA - we have 26 bits, why not just use offsets from base of code? diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 0b87d9e87c..1aaf07c63c 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -366,7 +366,12 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op) FlushAll(); // Standard function call, nothing fancy. // The function returns the number of cycles it took in EAX. - BL((const void *)(entry->replaceFunc)); + if (BLInRange((const void *)(entry->replaceFunc))) { + BL((const void *)(entry->replaceFunc)); + } else { + MOVI2R(R0, (u32)entry->replaceFunc); + BL(R0); + } // Alternatively, we could inline it here, instead of calling out, if it's a function // we can emit.