diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index e1fe1c6aaa..25357479ac 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -570,6 +570,26 @@ SectionID ElfReader::GetSectionByName(const char *name, int firstSection) return -1; } +u32 ElfReader::GetTotalTextSize() const { + u32 total = 0; + for (int i = 0; i < GetNumSections(); ++i) { + if (!(sections[i].sh_flags & SHF_WRITE) && (sections[i].sh_flags & SHF_ALLOC)) { + total += sections[i].sh_size; + } + } + return total; +} + +u32 ElfReader::GetTotalDataSize() const { + u32 total = 0; + for (int i = 0; i < GetNumSections(); ++i) { + if ((sections[i].sh_flags & SHF_WRITE) && (sections[i].sh_flags & SHF_ALLOC) && !(sections[i].sh_flags & SHF_MASKPROC)) { + total += sections[i].sh_size; + } + } + return total; +} + bool ElfReader::LoadSymbols() { bool hasSymbols = false; diff --git a/Core/ELF/ElfReader.h b/Core/ELF/ElfReader.h index d9052638d1..7ee169ef91 100644 --- a/Core/ELF/ElfReader.h +++ b/Core/ELF/ElfReader.h @@ -77,8 +77,8 @@ public: u32 GetEntryPoint() { return entryPoint; } u32 GetFlags() { return (u32)(header->e_flags); } - int GetNumSegments() { return (int)(header->e_phnum); } - int GetNumSections() { return (int)(header->e_shnum); } + int GetNumSegments() const { return (int)(header->e_phnum); } + int GetNumSections() const { return (int)(header->e_shnum); } const char *GetSectionName(int section); u8 *GetPtr(u32 offset) const { return (u8*)base + offset; @@ -130,6 +130,9 @@ public: return totalSize; } + u32 GetTotalTextSize() const; + u32 GetTotalDataSize() const; + // More indepth stuff:) int LoadInto(u32 vaddr); bool LoadSymbols(); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 2590390b3d..e9b816aaf6 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -966,10 +966,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro module->textEnd = module->textStart + textSize; module->nm.text_addr = module->textStart; - // TODO: This value appears to be wrong. In one example, the PSP has a value > 0x1000 bigger. - module->nm.text_size = textSize; - // TODO: It seems like the data size excludes the text size, which kinda makes sense? - module->nm.data_size -= textSize; + module->nm.text_size = reader.GetTotalTextSize(); if (!module->isFake) { #if !defined(MOBILE_DEVICE) @@ -984,6 +981,14 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro } } + SectionID bssSection = reader.GetSectionByName(".bss"); + if (bssSection != -1) { + module->nm.bss_size = reader.GetSectionSize(bssSection); + module->nm.data_size = reader.GetTotalDataSize() - module->nm.bss_size; + } else { + module->nm.data_size = reader.GetTotalDataSize(); + } + INFO_LOG(LOADER, "Module %s: %08x %08x %08x", modinfo->name, modinfo->gp, modinfo->libent, modinfo->libstub); struct PspLibStubEntry {