#ifndef PS2RECOMP_ELF_ANALYZER_H #define PS2RECOMP_ELF_ANALYZER_H #include "ps2recomp/elf_analysis_context.h" #include "ps2recomp/function_classifier.h" #include #include #include #include #include #include #include #include #include namespace ps2recomp { struct CFGNode; struct Instruction; struct FunctionCall; struct JumpTable; struct Relocation; struct Section; struct Symbol; struct Function; class R5900Decoder; class ElfParser; using CFG = std::unordered_map; class ElfAnalyzer { public: explicit ElfAnalyzer(const std::string &elfPath); ~ElfAnalyzer(); public: void setSceSymbolDatabasePath(const std::string &databasePath); bool analyze(); bool generateToml(const std::string &outputPath); bool importGhidraMap(const std::string &csvPath); public: const std::vector &getFunctions() const; public: bool isLibrarySymbolNameForHeuristics(const std::string &name) const; static bool isReliableSymbolNameForHeuristics(const std::string &name); public: static int findEntryFunctionIndexForHeuristics(const std::vector &functions, uint32_t entryAddress); static int findFallbackEntryFunctionIndexForHeuristics(const std::vector &functions); public: static bool hasHardwareIOSignalForHeuristics(const std::vector &instructions); static bool hasLargeComplexMMISignalForHeuristics(const std::vector &instructions, size_t largeInstructionThreshold = 500); static bool hasSelfModifyingSignalForHeuristics(const std::vector &instructions, const std::vector
§ions); public: static std::vector detectJumpTablesForHeuristics(const std::vector &instructions, const std::vector
§ions, const std::function &readWord); static std::unordered_set findRecursiveFunctionsForHeuristics(const std::unordered_map> &callGraph); private: std::string m_elfPath; std::unique_ptr m_elfParser; std::unique_ptr m_decoder; ElfAnalysisContext m_context; std::unordered_set m_libFunctions; std::unordered_set m_untrackedStubFunctions; std::unordered_set m_forceRecompileStarts; std::unordered_set m_sceSdkFunctionNames; FunctionClassifier m_classifier; std::unordered_map> m_functionDataUsage; std::unordered_map m_commonDataAccess; std::map m_patches; std::map m_patchReasons; std::unordered_map m_functionCFGs; std::vector m_jumpTables; std::unordered_map> m_functionCalls; std::map m_performanceCriticalReasons; std::unordered_map m_mmioByInstructionAddress; std::string m_sceSymbolDatabasePath; bool loadElf(); void buildFunctionIndex(); void decodeAllFunctionsOnce(); void classifyFunctions(); void runDataUsagePass(); void runPatchDetectionPass(); void runControlFlowPass(); void runJumpTablePass(); void runPerformancePass(); void runSignaturePass() const; void printAnalysisSummary() const; void discoverSceSdkSymbols(); void analyzeEntryPoint(); void analyzeLibraryFunctions(); void analyzeDataUsage(); void identifyPotentialPatches(); bool tryPatchSelfModifyingStore(const Function &func, const std::vector &instructions, size_t index); bool tryResolveBasePlusOffset(const std::vector &instructions, size_t index, uint32_t reg, int16_t offset, uint32_t &baseAddr) const; bool tryResolveLuiBase(const std::vector &instructions, size_t index, uint32_t reg, uint32_t &baseAddr) const; bool isCodeAddress(uint32_t addr) const; void analyzeControlFlow(); void detectJumpTables(); void analyzePerformanceCriticalPaths(); void identifyRecursiveFunctions(); void analyzeRegisterUsage() const; void analyzeFunctionSignatures() const; void optimizePatches(); bool identifyMemcpyPattern(const Function &func) const; bool identifyMemsetPattern(const Function &func) const; bool identifyStringOperationPattern(const Function &func) const; bool identifyMathPattern(const Function &func) const; bool isLibraryFunction(const std::string &name) const; void clearDecodedInstructionCache(); const std::vector &getDecodedInstructions(const Function &function) const; std::vector decodeFunction(const Function &function) const; CFG buildCFG(const Function &function) const; std::string formatAddress(uint32_t address) const; bool hasMMIInstructions(const Function &function) const; bool hasVUInstructions(const Function &function) const; void identifyFunctionType(const Function &function) const; void categorizeFunction(Function &function); uint32_t getSuccessor(const Instruction &inst, uint32_t currentAddr); bool isSelfModifyingCode(const Function &function) const; bool isLoopHeavyFunction(const Function &function) const; }; } #endif // PS2RECOMP_ELF_ANALYZER_H