diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index f8c59d4183..d6dde0a2b9 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -22,6 +22,7 @@ #include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/SymbolMap.h" #include "Core/HLE/sceKernelMemory.h" +#include "Core/HLE/sceKernelModule.h" const char *ElfReader::GetSectionName(int section) @@ -376,6 +377,22 @@ int ElfReader::LoadInto(u32 loadAddress, bool fromTop) // Should we relocate? bRelocate = (header->e_type != ET_EXEC); + // Look for the module info - we need to know whether this is kernel or user. + const PspModuleInfo *modInfo = 0; + for (int i = 0; i < GetNumSections(); i++) { + Elf32_Shdr *s = §ions[i]; + const char *name = GetSectionName(i); + if (name && !strcmp(name, ".rodata.sceModuleInfo")) { + modInfo = (const PspModuleInfo *)GetPtr(s->sh_offset); + } + } + if (!modInfo && GetNumSegments() >= 1) { + modInfo = (const PspModuleInfo *)GetPtr(segments[0].p_paddr & 0x7FFFFFFF); + } + + bool kernelModule = modInfo ? (modInfo->moduleAttrs & 0x1000) != 0 : false; + BlockAllocator &memblock = kernelModule ? kernelMemory : userMemory; + entryPoint = header->e_entry; u32 totalStart = 0xFFFFFFFF; u32 totalEnd = 0; @@ -392,17 +409,17 @@ int ElfReader::LoadInto(u32 loadAddress, bool fromTop) if (!bRelocate) { // Binary is prerelocated, load it where the first segment starts - vaddr = userMemory.AllocAt(totalStart, totalSize, "ELF"); + vaddr = memblock.AllocAt(totalStart, totalSize, "ELF"); } else if (loadAddress) { // Binary needs to be relocated: add loadAddress to the binary start address - vaddr = userMemory.AllocAt(loadAddress + totalStart, totalSize, "ELF"); + vaddr = memblock.AllocAt(loadAddress + totalStart, totalSize, "ELF"); } else { // Just put it where there is room - vaddr = userMemory.Alloc(totalSize, fromTop, "ELF"); + vaddr = memblock.Alloc(totalSize, fromTop, "ELF"); } if (vaddr == (u32)-1) { @@ -447,7 +464,7 @@ int ElfReader::LoadInto(u32 loadAddress, bool fromTop) DEBUG_LOG(LOADER,"Loadable Segment Copied to %08x, size %08x", writeAddr, (u32)p->p_memsz); } } - userMemory.ListBlocks(); + memblock.ListBlocks(); DEBUG_LOG(LOADER,"%i sections:", header->e_shnum); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 609200170e..2b204f644f 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -217,7 +217,11 @@ public: Module() : textStart(0), textEnd(0), memoryBlockAddr(0), isFake(false) {} ~Module() { if (memoryBlockAddr) { - userMemory.Free(memoryBlockAddr); + if (memoryBlockAddr < PSP_GetUserMemoryBase()) { + kernelMemory.Free(memoryBlockAddr); + } else { + userMemory.Free(memoryBlockAddr); + } symbolMap.UnloadModule(memoryBlockAddr, memoryBlockSize); } } @@ -921,19 +925,6 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromTop, std module->memoryBlockAddr = reader.GetVaddr(); module->memoryBlockSize = reader.GetTotalSize(); - struct PspModuleInfo { - // 0, 0, 1, 1 ? - u16_le moduleAttrs; //0x0000 User Mode, 0x1000 Kernel Mode - u16_le moduleVersion; - // 28 bytes of module name, packed with 0's. - char name[28]; - u32_le gp; // ptr to MIPS GOT data (global offset table) - u32_le libent; // ptr to .lib.ent section - u32_le libentend; // ptr to end of .lib.ent section - u32_le libstub; // ptr to .lib.stub section - u32_le libstubend; // ptr to end of .lib.stub section - }; - SectionID sceModuleInfoSection = reader.GetSectionByName(".rodata.sceModuleInfo"); PspModuleInfo *modinfo; if (sceModuleInfoSection != -1) diff --git a/Core/HLE/sceKernelModule.h b/Core/HLE/sceKernelModule.h index ff495e6283..ee56d1203d 100644 --- a/Core/HLE/sceKernelModule.h +++ b/Core/HLE/sceKernelModule.h @@ -20,6 +20,18 @@ #include #include "Core/HLE/sceKernel.h" +struct PspModuleInfo { + u16_le moduleAttrs; //0x0000 User Mode, 0x1000 Kernel Mode + u16_le moduleVersion; + // 28 bytes of module name, packed with 0's. + char name[28]; + u32_le gp; // ptr to MIPS GOT data (global offset table) + u32_le libent; // ptr to .lib.ent section + u32_le libentend; // ptr to end of .lib.ent section + u32_le libstub; // ptr to .lib.stub section + u32_le libstubend; // ptr to end of .lib.stub section +}; + class PointerWrap; KernelObject *__KernelModuleObject();