Permalink
Browse files

Merge pull request #10501 from unknownbrackets/analyst

Scan the correct sections of modules for code
  • Loading branch information...
hrydgard committed Jan 3, 2018
2 parents 690a409 + 29ed48c commit 2e2d76e1090cf16ee5cfb32cbef3784769833b90
Showing with 56 additions and 26 deletions.
  1. +11 −0 Core/ELF/ElfReader.cpp
  2. +4 −2 Core/ELF/ElfReader.h
  3. +37 −22 Core/HLE/sceKernelModule.cpp
  4. +4 −2 Core/MIPS/MIPSAnalyst.cpp
View
@@ -633,6 +633,17 @@ u32 ElfReader::GetTotalSectionSizeByPrefix(const std::string &prefix) const {
return total;
}
std::vector<SectionID> ElfReader::GetCodeSections() const {
std::vector<SectionID> ids;
for (int i = 0; i < GetNumSections(); ++i) {
u32 flags = sections[i].sh_flags;
if ((flags & (SHF_ALLOC | SHF_EXECINSTR)) == (SHF_ALLOC | SHF_EXECINSTR)) {
ids.push_back(i);
}
}
return ids;
}
bool ElfReader::LoadSymbols()
{
bool hasSymbols = false;
View
@@ -17,9 +17,9 @@
#pragma once
#include <vector>
#include "Common/CommonTypes.h"
#include "ElfTypes.h"
#include "Core/ELF/ElfTypes.h"
enum {
R_MIPS_NONE,
@@ -130,6 +130,8 @@ class ElfReader {
u32 GetTotalDataSize() const;
u32 GetTotalSectionSizeByPrefix(const std::string &prefix) const;
std::vector<SectionID> GetCodeSections() const;
int LoadInto(u32 vaddr, bool fromTop);
bool LoadSymbols();
bool LoadRelocations(const Elf32_Rel *rels, int numRelocs);
@@ -1234,22 +1234,10 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd
if (textSection != -1) {
module->textStart = reader.GetSectionAddr(textSection);
u32 textSize = reader.GetSectionSize(textSection);
module->textEnd = module->textStart + textSize;
module->textEnd = module->textStart + textSize - 4;
module->nm.text_addr = module->textStart;
module->nm.text_size = reader.GetTotalTextSize();
if (!module->isFake) {
#if !defined(MOBILE_DEVICE)
bool gotSymbols = reader.LoadSymbols();
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
#else
if (g_Config.bFuncReplacements) {
bool gotSymbols = reader.LoadSymbols();
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
}
#endif
}
} else {
module->nm.text_addr = 0;
module->nm.text_size = 0;
@@ -1269,17 +1257,44 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd
if (textSection == -1) {
module->textStart = reader.GetVaddr();
module->textEnd = firstImportStubAddr - 4;
}
if (!module->isFake) {
#if !defined(MOBILE_DEVICE)
bool gotSymbols = reader.LoadSymbols();
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
#else
if (g_Config.bFuncReplacements) {
bool gotSymbols = reader.LoadSymbols();
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
}
if (!module->isFake) {
bool scan = true;
#if defined(MOBILE_DEVICE)
scan = g_Config.bFuncReplacements;
#endif
bool gotSymbols = scan && reader.LoadSymbols();
std::vector<SectionID> codeSections = reader.GetCodeSections();
for (SectionID id : codeSections) {
u32 start = reader.GetSectionAddr(id);
// Note: scan end is inclusive.
u32 end = start + reader.GetSectionSize(id) - 4;
if (start < module->textStart)
module->textStart = start;
if (end > module->textEnd)
module->textEnd = end;
if (scan)
MIPSAnalyst::ScanForFunctions(start, end, !gotSymbols);
}
// Some games don't have any sections at all.
if (scan && codeSections.empty()) {
u32 scanStart = module->textStart;
u32 scanEnd = module->textEnd;
// Skip the exports and imports sections, they're not code.
if (scanEnd >= std::min(modinfo->libent, modinfo->libstub)) {
MIPSAnalyst::ScanForFunctions(scanStart, std::min(modinfo->libent, modinfo->libstub) - 4, !gotSymbols);
scanStart = std::min(modinfo->libentend, modinfo->libstubend);
}
if (scanEnd >= std::max(modinfo->libent, modinfo->libstub)) {
MIPSAnalyst::ScanForFunctions(scanStart, std::max(modinfo->libent, modinfo->libstub) - 4, !gotSymbols);
scanStart = std::max(modinfo->libentend, modinfo->libstubend);
}
MIPSAnalyst::ScanForFunctions(scanStart, scanEnd, !gotSymbols);
}
}
@@ -1124,8 +1124,10 @@ namespace MIPSAnalyst {
}
}
currentFunction.end = addr + 4;
functions.push_back(currentFunction);
if (addr <= endAddr) {
currentFunction.end = addr + 4;
functions.push_back(currentFunction);
}
for (auto iter = functions.begin(); iter != functions.end(); iter++) {
iter->size = iter->end - iter->start + 4;

0 comments on commit 2e2d76e

Please sign in to comment.