From acac847af2107e7486887ce1f332cca90d457058 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 10 Apr 2013 21:03:43 -0700 Subject: [PATCH 1/2] Cleanup sceKernelGetModuleIdByAddress(). Actual firmware seems to accept any address in the range, and also correct the error result. Now people won't think this is broken anymore. --- Core/ELF/ElfReader.cpp | 2 +- Core/ELF/ElfReader.h | 6 +++++ Core/HLE/sceKernel.h | 18 +++++++-------- Core/HLE/sceKernelModule.cpp | 43 ++++++++++++++++++++++++------------ 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index ea037a40c..3a934c413 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -200,7 +200,7 @@ bool ElfReader::LoadInto(u32 loadAddress) totalEnd = p->p_vaddr + p->p_memsz; } } - u32 totalSize = totalEnd - totalStart; + totalSize = totalEnd - totalStart; if (!bRelocate) { // Binary is prerelocated, load it where the first segment starts diff --git a/Core/ELF/ElfReader.h b/Core/ELF/ElfReader.h index 561543a10..11de4fcc9 100644 --- a/Core/ELF/ElfReader.h +++ b/Core/ELF/ElfReader.h @@ -111,6 +111,11 @@ public: return vaddr; } + u32 GetTotalSize() + { + return totalSize; + } + // More indepth stuff:) bool LoadInto(u32 vaddr); bool LoadSymbols(); @@ -127,6 +132,7 @@ private: u32 *sectionAddrs; bool bRelocate; u32 entryPoint; + u32 totalSize; u32 vaddr; u32 segmentVAddr[32]; }; diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index ffedb37e3..6b66a1e91 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -397,22 +397,20 @@ public: return static_cast(pool[realHandle]); } - template - T* GetByModuleByEntryAddr(u32 entryAddr) + template + void Iterate(bool func(T *, ArgT), ArgT arg) { - for (int i = 0; i < maxCount; ++i) + for (int i = 0; i < maxCount; i++) { - T* t = dynamic_cast(pool[i]); - + if (!occupied[i]) + continue; + T *t = dynamic_cast(pool[i]); if (t) { - if (t->nm.entry_addr == entryAddr) - { - return t; - } + if (!func(t, arg)) + break; } } - return 0; } static u32 GetMissingErrorCode() { return -1; } // TODO diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 48af444ee..bc0b85494 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -165,12 +165,14 @@ public: { p.Do(nm); p.Do(memoryBlockAddr); + p.Do(memoryBlockSize); p.DoMarker("Module"); } NativeModule nm; u32 memoryBlockAddr; + u32 memoryBlockSize; bool isFake; }; @@ -316,6 +318,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro return 0; } module->memoryBlockAddr = reader.GetVaddr(); + module->memoryBlockSize = reader.GetTotalSize(); struct libent { @@ -893,24 +896,36 @@ u32 sceKernelStopUnloadSelfModuleWithStatus(u32 moduleId, u32 argSize, u32 argp, return 0; } +struct GetModuleIdByAddressArg +{ + u32 addr; + SceUID result; +}; + +bool __GetModuleIdByAddressIterator(Module *module, GetModuleIdByAddressArg *state) +{ + const u32 start = module->memoryBlockAddr, size = module->memoryBlockSize; + printf("%08x - %08x ? %08x\n", start, start + size, state->addr); + if (start <= state->addr && start + size > state->addr) + { + state->result = module->GetUID(); + return false; + } + return true; +} + u32 sceKernelGetModuleIdByAddress(u32 moduleAddr) { - ERROR_LOG(HLE,"HACKIMPL sceKernelGetModuleIdByAddress(%08x)", moduleAddr); + GetModuleIdByAddressArg state; + state.addr = moduleAddr; + state.result = SCE_KERNEL_ERROR_UNKNOWN_MODULE; - if ((moduleAddr & 0xFFFF0000) == 0x08800000) - { - return mainModuleID; - } + kernelObjects.Iterate(&__GetModuleIdByAddressIterator, &state); + if (state.result == SCE_KERNEL_ERROR_UNKNOWN_MODULE) + ERROR_LOG(HLE, "sceKernelGetModuleIdByAddress(%08x): module not found", moduleAddr) else - { - Module* foundMod= kernelObjects.GetByModuleByEntryAddr(moduleAddr); - - if(foundMod) - { - return foundMod->GetUID(); - } - } - return 0; + DEBUG_LOG(HLE, "%x=sceKernelGetModuleIdByAddress(%08x)", state.result, moduleAddr); + return state.result; } u32 sceKernelGetModuleId() From 5aceceecd3a948935f6efbafba3de0b99ea2a97f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 10 Apr 2013 21:16:31 -0700 Subject: [PATCH 2/2] Remove global module id var hacks. Nothing needs them anymore. --- Core/HLE/sceKernelModule.cpp | 5 +---- Core/HLE/sceKernelThread.cpp | 15 +++------------ Core/HLE/sceKernelThread.h | 2 +- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index bc0b85494..41667bee0 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -234,7 +234,6 @@ struct SceKernelSMOption { ////////////////////////////////////////////////////////////////////////// // STATE BEGIN static int actionAfterModule; -static SceUID mainModuleID; // hack // STATE END ////////////////////////////////////////////////////////////////////////// @@ -245,7 +244,6 @@ void __KernelModuleInit() void __KernelModuleDoState(PointerWrap &p) { - p.Do(mainModuleID); p.Do(actionAfterModule); __KernelRestoreActionType(actionAfterModule, AfterModuleEntryCall::Create); p.DoMarker("sceKernelModule"); @@ -657,7 +655,6 @@ void __KernelStartModule(Module *m, int args, const char *argp, SceKernelSMOptio } __KernelSetupRootThread(m->GetUID(), args, argp, options->priority, options->stacksize, options->attribute); - mainModuleID = m->GetUID(); //TODO: if current thread, put it in wait state, waiting for the new thread } @@ -725,7 +722,7 @@ bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std:: __KernelStartModule(module, (u32)strlen(filename) + 1, filename, &option); - __KernelStartIdleThreads(); + __KernelStartIdleThreads(module->GetUID()); return true; } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index f97c2ef82..7b2cfd051 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -722,9 +722,6 @@ MipsCallManager mipsCalls; int actionAfterCallback; int actionAfterMipsCall; -// This seems nasty -SceUID curModule; - // Doesn't need state saving. WaitTypeFuncs waitTypeFuncs[NUM_WAITTYPES]; @@ -869,7 +866,6 @@ void __KernelThreadingDoState(PointerWrap &p) p.Do(threadqueue, dv); p.DoArray(threadIdleID, ARRAY_SIZE(threadIdleID)); p.Do(dispatchEnabled); - p.Do(curModule); p.Do(threadReadyQueue); @@ -948,13 +944,13 @@ void __KernelChangeReadyState(SceUID threadID, bool ready) WARN_LOG(HLE, "Trying to change the ready state of an unknown thread?"); } -void __KernelStartIdleThreads() +void __KernelStartIdleThreads(SceUID moduleId) { for (int i = 0; i < 2; i++) { u32 error; Thread *t = kernelObjects.Get(threadIdleID[i], error); - t->nt.gpreg = __KernelGetModuleGP(curModule); + t->nt.gpreg = __KernelGetModuleGP(moduleId); t->context.r[MIPS_REG_GP] = t->nt.gpreg; //t->context.pc += 4; // ADJUSTPC threadReadyQueue.prepare(t->nt.currentPriority); @@ -1063,7 +1059,6 @@ void __KernelThreadingShutdown() cbReturnHackAddr = 0; currentThread = 0; intReturnHackAddr = 0; - curModule = 0; hleCurrentThreadName = NULL; } @@ -1701,7 +1696,6 @@ Thread *__KernelCreateThread(SceUID &id, SceUID moduleId, const char *name, u32 void __KernelSetupRootThread(SceUID moduleID, int args, const char *argp, int prio, int stacksize, int attr) { - curModule = moduleID; //grab mips regs SceUID id; Thread *thread = __KernelCreateThread(id, moduleID, "root", currentMIPS->pc, prio, stacksize, attr); @@ -1758,10 +1752,7 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) { - SceUID moduleId = curModule; - if (__GetCurrentThread()) - moduleId = __GetCurrentThread()->moduleId; - return __KernelCreateThread(threadName, moduleId, entry, prio, stacksize, attr, optionAddr); + return __KernelCreateThread(threadName, __KernelGetCurThreadModuleId(), entry, prio, stacksize, attr, optionAddr); } diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index cea8b431d..9c01f3115 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -185,7 +185,7 @@ u32 __KernelNotifyCallbackType(RegisteredCallbackType type, SceUID cbId, int not SceUID __KernelGetCurThread(); SceUID __KernelGetCurThreadModuleId(); void __KernelSetupRootThread(SceUID moduleId, int args, const char *argp, int prio, int stacksize, int attr); //represents the real PSP elf loader, run before execution -void __KernelStartIdleThreads(); +void __KernelStartIdleThreads(SceUID moduleId); void __KernelReturnFromThread(); // Called as HLE function u32 __KernelGetThreadPrio(SceUID id); bool __KernelThreadSortPriority(SceUID thread1, SceUID thread2);