From c218c64348e75626d421e2fa4957228761a0b294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2E=20Sami=20G=C3=BCrp=C4=B1nar?= Date: Sat, 31 Jan 2026 19:14:56 +0300 Subject: [PATCH] Made member methods const (#34) * refactor: update function name checks to use contains method * refactor: update code generation to use static_cast * refactor: made member methods const * refactor: made range-based loop * refactor: make one variable constructor explicit * refactor: remove redundant else * refactor: turn includes to forward declarations * refactor: brace placements turned into allman style --- ps2xAnalyzer/include/ps2recomp/elf_analyzer.h | 47 ++++---- ps2xAnalyzer/src/elf_analyzer.cpp | 106 +++++++++--------- ps2xRecomp/include/ps2recomp/code_generator.h | 10 +- ps2xRecomp/include/ps2recomp/config_manager.h | 6 +- ps2xRecomp/include/ps2recomp/elf_parser.h | 17 +-- ps2xRecomp/include/ps2recomp/ps2_recompiler.h | 17 ++- ps2xRecomp/include/ps2recomp/r5900_decoder.h | 2 +- ps2xRecomp/include/ps2recomp/types.h | 2 - ps2xRecomp/src/code_generator.cpp | 1 + ps2xRecomp/src/config_manager.cpp | 14 +-- ps2xRecomp/src/elf_parser.cpp | 17 +-- ps2xRecomp/src/ps2_recompiler.cpp | 9 +- ps2xRecomp/src/r5900_decoder.cpp | 4 +- ps2xTest/src/code_generator_tests.cpp | 1 + 14 files changed, 134 insertions(+), 119 deletions(-) diff --git a/ps2xAnalyzer/include/ps2recomp/elf_analyzer.h b/ps2xAnalyzer/include/ps2recomp/elf_analyzer.h index ab3c02b..e1a81a2 100644 --- a/ps2xAnalyzer/include/ps2recomp/elf_analyzer.h +++ b/ps2xAnalyzer/include/ps2recomp/elf_analyzer.h @@ -1,9 +1,6 @@ #ifndef PS2RECOMP_ELF_ANALYZER_H #define PS2RECOMP_ELF_ANALYZER_H -#include "ps2recomp/elf_parser.h" -#include "ps2recomp/r5900_decoder.h" -#include "ps2recomp/types.h" #include #include #include @@ -14,10 +11,23 @@ namespace ps2recomp { - class ElfAnalyzer + 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: - ElfAnalyzer(const std::string &elfPath); + explicit ElfAnalyzer(const std::string &elfPath); ~ElfAnalyzer(); bool analyze(); @@ -40,7 +50,6 @@ namespace ps2recomp std::map m_patches; std::map m_patchReasons; - std::unordered_map m_functionCFGs; std::vector m_jumpTables; std::unordered_map> m_functionCalls; @@ -52,30 +61,30 @@ namespace ps2recomp void identifyPotentialPatches(); void analyzeControlFlow(); void detectJumpTables(); - void analyzePerformanceCriticalPaths(); + void analyzePerformanceCriticalPaths() const; void identifyRecursiveFunctions(); - void analyzeRegisterUsage(); - void analyzeFunctionSignatures(); + void analyzeRegisterUsage() const; + void analyzeFunctionSignatures() const; void optimizePatches(); - bool identifyMemcpyPattern(const Function &func); - bool identifyMemsetPattern(const Function &func); - bool identifyStringOperationPattern(const Function &func); - bool identifyMathPattern(const Function &func); + 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 isSystemFunction(const std::string &name) const; bool isLibraryFunction(const std::string &name) const; - std::vector decodeFunction(const Function &function); - CFG buildCFG(const Function &function); + std::vector decodeFunction(const Function &function) const; + CFG buildCFG(const Function &function) const; std::string formatAddress(uint32_t address) const; std::string escapeBackslashes(const std::string &path); - bool hasMMIInstructions(const Function &function); - bool hasVUInstructions(const Function &function); + bool hasMMIInstructions(const Function &function) const; + bool hasVUInstructions(const Function &function) const; bool identifyFunctionType(const Function &function); void categorizeFunction(Function &function); uint32_t getSuccessor(const Instruction &inst, uint32_t currentAddr); - bool isSelfModifyingCode(const Function &function); - bool isLoopHeavyFunction(const Function &function); + bool isSelfModifyingCode(const Function &function) const; + bool isLoopHeavyFunction(const Function &function) const; }; } diff --git a/ps2xAnalyzer/src/elf_analyzer.cpp b/ps2xAnalyzer/src/elf_analyzer.cpp index 6919d61..63a491a 100644 --- a/ps2xAnalyzer/src/elf_analyzer.cpp +++ b/ps2xAnalyzer/src/elf_analyzer.cpp @@ -1,4 +1,7 @@ #include "ps2recomp/elf_analyzer.h" +#include "ps2recomp/elf_parser.h" +#include "ps2recomp/r5900_decoder.h" +#include "ps2recomp/types.h" #include #include #include @@ -133,18 +136,17 @@ namespace ps2recomp file << "# Jump tables detected in the program\n"; file << "[jump_tables]\n"; - for (size_t i = 0; i < m_jumpTables.size(); ++i) + for (const auto & jt : m_jumpTables) { - const auto &jt = m_jumpTables[i]; file << "[[jump_tables.table]]\n"; file << "address = \"0x" << std::hex << jt.address << "\"\n" << std::dec; file << "entries = [\n"; - for (const auto &entry : jt.entries) + for (const auto & [index, target] : jt.entries) { - file << " { index = " << entry.index << ", target = \"0x" - << std::hex << entry.target << "\" },\n" + file << " { index = " << index << ", target = \"0x" + << std::hex << target << "\" },\n" << std::dec; } @@ -779,8 +781,8 @@ namespace ps2recomp } } - void ElfAnalyzer::analyzePerformanceCriticalPaths() - { + void ElfAnalyzer::analyzePerformanceCriticalPaths() const + { std::cout << "Analyzing performance-critical paths..." << std::endl; for (const auto &func : m_functions) @@ -793,11 +795,9 @@ namespace ps2recomp std::vector instructions = decodeFunction(func); - for (size_t i = 0; i < instructions.size(); i++) + for (const auto& inst : instructions) { - const auto &inst = instructions[i]; - - if (inst.isBranch) + if (inst.isBranch) { int32_t offset = static_cast(inst.immediate) << 2; uint32_t targetAddr = inst.address + 4 + offset; @@ -814,11 +814,11 @@ namespace ps2recomp << " (size: " << loopSize << " instructions)" << std::endl; bool hasMultimedia = false; - for (size_t j = 0; j < instructions.size(); j++) + for (const auto& instruction : instructions) { - if (instructions[j].address >= targetAddr && instructions[j].address <= inst.address) + if (instruction.address >= targetAddr && instruction.address <= inst.address) { - if (instructions[j].isMultimedia) + if (instruction.isMultimedia) { hasMultimedia = true; break; @@ -901,8 +901,8 @@ namespace ps2recomp } } - void ElfAnalyzer::analyzeRegisterUsage() - { + void ElfAnalyzer::analyzeRegisterUsage() const + { std::cout << "Analyzing register usage patterns..." << std::endl; for (const auto &func : m_functions) @@ -1000,8 +1000,8 @@ namespace ps2recomp } } - void ElfAnalyzer::analyzeFunctionSignatures() - { + void ElfAnalyzer::analyzeFunctionSignatures() const + { std::cout << "Analyzing function signatures..." << std::endl; for (const auto &func : m_functions) @@ -1160,8 +1160,8 @@ namespace ps2recomp } } - bool ElfAnalyzer::identifyMemcpyPattern(const Function &func) - { + bool ElfAnalyzer::identifyMemcpyPattern(const Function &func) const + { std::vector instructions = decodeFunction(func); bool hasLoop = false; @@ -1169,10 +1169,8 @@ namespace ps2recomp bool storesData = false; bool incrementsPointers = false; - for (size_t i = 0; i < instructions.size(); i++) + for (const auto & inst : instructions) { - const auto &inst = instructions[i]; - if (inst.isBranch) { int32_t offset = static_cast(inst.immediate) << 2; @@ -1206,8 +1204,8 @@ namespace ps2recomp return hasLoop && loadsData && storesData && incrementsPointers; } - bool ElfAnalyzer::identifyMemsetPattern(const Function &func) - { + bool ElfAnalyzer::identifyMemsetPattern(const Function &func) const + { std::vector instructions = decodeFunction(func); bool hasLoop = false; @@ -1215,10 +1213,8 @@ namespace ps2recomp bool storesData = false; bool incrementsPointer = false; - for (size_t i = 0; i < instructions.size(); i++) + for (const auto & inst : instructions) { - const auto &inst = instructions[i]; - if (inst.isBranch) { int32_t offset = static_cast(inst.immediate) << 2; @@ -1251,8 +1247,8 @@ namespace ps2recomp return hasLoop && usesConstant && storesData && incrementsPointer; } - bool ElfAnalyzer::identifyStringOperationPattern(const Function &func) - { + bool ElfAnalyzer::identifyStringOperationPattern(const Function &func) const + { std::vector instructions = decodeFunction(func); bool hasLoop = false; @@ -1260,10 +1256,8 @@ namespace ps2recomp bool loadsByte = false; bool storesByte = false; - for (size_t i = 0; i < instructions.size(); i++) + for (const auto & inst : instructions) { - const auto &inst = instructions[i]; - if (inst.isBranch) { int32_t offset = static_cast(inst.immediate) << 2; @@ -1293,8 +1287,8 @@ namespace ps2recomp return hasLoop && checksZero && (loadsByte || storesByte); } - bool ElfAnalyzer::identifyMathPattern(const Function &func) - { + bool ElfAnalyzer::identifyMathPattern(const Function &func) const + { std::vector instructions = decodeFunction(func); int mathOps = 0; @@ -1324,8 +1318,8 @@ namespace ps2recomp return mathOps > instructions.size() * 0.3 || usesFPU; } - CFG ElfAnalyzer::buildCFG(const Function &function) - { + CFG ElfAnalyzer::buildCFG(const Function &function) const + { CFG cfg; std::vector instructions = decodeFunction(function); std::map addrToIndex; @@ -1567,8 +1561,8 @@ namespace ps2recomp return false; } - std::vector ElfAnalyzer::decodeFunction(const Function &function) - { + std::vector ElfAnalyzer::decodeFunction(const Function &function) const + { std::vector instructions; for (uint32_t addr = function.start; addr < function.end; addr += 4) @@ -1602,8 +1596,8 @@ namespace ps2recomp return ss.str(); } - bool ElfAnalyzer::hasMMIInstructions(const Function &function) - { + bool ElfAnalyzer::hasMMIInstructions(const Function &function) const + { std::vector instructions = decodeFunction(function); for (const auto &inst : instructions) @@ -1617,8 +1611,8 @@ namespace ps2recomp return false; } - bool ElfAnalyzer::hasVUInstructions(const Function &function) - { + bool ElfAnalyzer::hasVUInstructions(const Function &function) const + { std::vector instructions = decodeFunction(function); for (const auto &inst : instructions) @@ -1685,11 +1679,12 @@ namespace ps2recomp std::cout << "Skipping function " << function.name << " due to hardware I/O" << std::endl; return true; } - else if (hasComplexMMI && isVeryLarge) + + if (hasComplexMMI && isVeryLarge) { - m_skipFunctions.insert(function.name); - std::cout << "Skipping large function " << function.name << " with complex MMI" << std::endl; - return true; + m_skipFunctions.insert(function.name); + std::cout << "Skipping large function " << function.name << " with complex MMI" << std::endl; + return true; } return false; @@ -1714,8 +1709,8 @@ namespace ps2recomp } } - bool ElfAnalyzer::isSelfModifyingCode(const Function &function) - { + bool ElfAnalyzer::isSelfModifyingCode(const Function &function) const + { std::vector instructions = decodeFunction(function); for (size_t i = 0; i < instructions.size(); i++) @@ -1760,15 +1755,13 @@ namespace ps2recomp return false; } - bool ElfAnalyzer::isLoopHeavyFunction(const Function &function) - { + bool ElfAnalyzer::isLoopHeavyFunction(const Function &function) const + { std::vector instructions = decodeFunction(function); int loopCount = 0; - for (size_t i = 0; i < instructions.size(); i++) + for (const auto & inst : instructions) { - const auto &inst = instructions[i]; - if (inst.isBranch) { int32_t offset = static_cast(inst.immediate) << 2; @@ -1790,9 +1783,10 @@ namespace ps2recomp int32_t offset = static_cast(inst.immediate) << 2; return currentAddr + 4 + offset; } - else if (inst.opcode == OPCODE_J || inst.opcode == OPCODE_JAL) + + if (inst.opcode == OPCODE_J || inst.opcode == OPCODE_JAL) { - return (currentAddr & 0xF0000000) | (inst.target << 2); + return (currentAddr & 0xF0000000) | (inst.target << 2); } return currentAddr + 4; diff --git a/ps2xRecomp/include/ps2recomp/code_generator.h b/ps2xRecomp/include/ps2recomp/code_generator.h index 1a3ff02..5aa3280 100644 --- a/ps2xRecomp/include/ps2recomp/code_generator.h +++ b/ps2xRecomp/include/ps2recomp/code_generator.h @@ -1,7 +1,6 @@ #ifndef PS2RECOMP_CODE_GENERATOR_H #define PS2RECOMP_CODE_GENERATOR_H -#include "ps2recomp/types.h" #include #include #include @@ -10,12 +9,17 @@ namespace ps2recomp { - extern const std::unordered_set kKeywords; + struct JumpTableEntry; + struct Instruction; + struct Function; + struct Symbol; + + extern const std::unordered_set kKeywords; class CodeGenerator { public: - CodeGenerator(const std::vector &symbols); + explicit CodeGenerator(const std::vector &symbols); ~CodeGenerator(); struct BootstrapInfo diff --git a/ps2xRecomp/include/ps2recomp/config_manager.h b/ps2xRecomp/include/ps2recomp/config_manager.h index 9a53d38..38be56c 100644 --- a/ps2xRecomp/include/ps2recomp/config_manager.h +++ b/ps2xRecomp/include/ps2recomp/config_manager.h @@ -10,11 +10,11 @@ namespace ps2recomp class ConfigManager { public: - ConfigManager(const std::string &configPath); + explicit ConfigManager(const std::string &configPath); ~ConfigManager(); - RecompilerConfig loadConfig(); - void saveConfig(const RecompilerConfig &config); + RecompilerConfig loadConfig() const; + void saveConfig(const RecompilerConfig &config) const; private: std::string m_configPath; diff --git a/ps2xRecomp/include/ps2recomp/elf_parser.h b/ps2xRecomp/include/ps2recomp/elf_parser.h index a236511..8ee9da0 100644 --- a/ps2xRecomp/include/ps2recomp/elf_parser.h +++ b/ps2xRecomp/include/ps2recomp/elf_parser.h @@ -1,7 +1,6 @@ #ifndef PS2RECOMP_ELF_PARSER_H #define PS2RECOMP_ELF_PARSER_H -#include "ps2recomp/types.h" #include #include #include @@ -9,16 +8,20 @@ namespace ps2recomp { + struct Relocation; + struct Section; + struct Function; + struct Symbol; - class ElfParser + class ElfParser { public: - ElfParser(const std::string &filePath); + explicit ElfParser(const std::string &filePath); ~ElfParser(); bool parse(); - std::vector extractFunctions(); + std::vector extractFunctions() const; std::vector extractSymbols(); std::vector
getSections(); std::vector getRelocations(); @@ -26,9 +29,9 @@ namespace ps2recomp // Helper methods bool isValidAddress(uint32_t address) const; uint32_t readWord(uint32_t address) const; - uint8_t *getSectionData(const std::string §ionName); - uint32_t getSectionAddress(const std::string §ionName); - uint32_t getSectionSize(const std::string §ionName); + uint8_t *getSectionData(const std::string §ionName) const; + uint32_t getSectionAddress(const std::string §ionName) const; + uint32_t getSectionSize(const std::string §ionName) const; uint32_t getEntryPoint() const; private: diff --git a/ps2xRecomp/include/ps2recomp/ps2_recompiler.h b/ps2xRecomp/include/ps2recomp/ps2_recompiler.h index 049e241..89dc6d0 100644 --- a/ps2xRecomp/include/ps2recomp/ps2_recompiler.h +++ b/ps2xRecomp/include/ps2recomp/ps2_recompiler.h @@ -1,11 +1,8 @@ #ifndef PS2RECOMP_PS2_RECOMPILER_H #define PS2RECOMP_PS2_RECOMPILER_H -#include "ps2recomp/types.h" -#include "ps2recomp/elf_parser.h" -#include "ps2recomp/r5900_decoder.h" -#include "ps2recomp/code_generator.h" -#include "ps2recomp/config_manager.h" +#include "code_generator.h" +#include "config_manager.h" #include #include #include @@ -14,12 +11,14 @@ namespace ps2recomp { + class R5900Decoder; + class ElfParser; - class PS2Recompiler + class PS2Recompiler { public: - PS2Recompiler(const std::string &configPath); - ~PS2Recompiler() = default; + explicit PS2Recompiler(const std::string &configPath); + ~PS2Recompiler(); bool initialize(); bool recompile(); @@ -48,7 +47,7 @@ namespace ps2recomp void discoverAdditionalEntryPoints(); bool shouldSkipFunction(const std::string &name) const; bool isStubFunction(const std::string &name) const; - std::string generateRuntimeHeader(); + std::string generateRuntimeHeader() const; bool generateFunctionHeader(); bool generateStubHeader(); bool writeToFile(const std::string &path, const std::string &content); diff --git a/ps2xRecomp/include/ps2recomp/r5900_decoder.h b/ps2xRecomp/include/ps2recomp/r5900_decoder.h index 80f0fa7..1b3d178 100644 --- a/ps2xRecomp/include/ps2recomp/r5900_decoder.h +++ b/ps2xRecomp/include/ps2recomp/r5900_decoder.h @@ -14,7 +14,7 @@ namespace ps2recomp R5900Decoder(); ~R5900Decoder(); - Instruction decodeInstruction(uint32_t address, uint32_t rawInstruction); + Instruction decodeInstruction(uint32_t address, uint32_t rawInstruction) const; bool isBranchInstruction(const Instruction &inst) const; bool isJumpInstruction(const Instruction &inst) const; diff --git a/ps2xRecomp/include/ps2recomp/types.h b/ps2xRecomp/include/ps2recomp/types.h index 0e5527b..7855ccd 100644 --- a/ps2xRecomp/include/ps2recomp/types.h +++ b/ps2xRecomp/include/ps2recomp/types.h @@ -152,8 +152,6 @@ namespace ps2recomp JumpTable jumpTable; }; - using CFG = std::unordered_map; - // Function call struct FunctionCall { diff --git a/ps2xRecomp/src/code_generator.cpp b/ps2xRecomp/src/code_generator.cpp index 95d7e7b..1afb7ff 100644 --- a/ps2xRecomp/src/code_generator.cpp +++ b/ps2xRecomp/src/code_generator.cpp @@ -1,5 +1,6 @@ #include "ps2recomp/code_generator.h" #include "ps2recomp/instructions.h" +#include "ps2recomp/types.h" #include #include #include diff --git a/ps2xRecomp/src/config_manager.cpp b/ps2xRecomp/src/config_manager.cpp index d61f4dc..adbafbe 100644 --- a/ps2xRecomp/src/config_manager.cpp +++ b/ps2xRecomp/src/config_manager.cpp @@ -14,8 +14,8 @@ namespace ps2recomp ConfigManager::~ConfigManager() = default; - RecompilerConfig ConfigManager::loadConfig() - { + RecompilerConfig ConfigManager::loadConfig() const + { RecompilerConfig config; try @@ -58,8 +58,8 @@ namespace ps2recomp return config; } - void ConfigManager::saveConfig(const RecompilerConfig &config) - { + void ConfigManager::saveConfig(const RecompilerConfig &config) const + { toml::value data; toml::table general; @@ -77,11 +77,11 @@ namespace ps2recomp toml::table patches; toml::array instPatches; - for (const auto &patch : config.patches) + for (const auto & [addr, value] : config.patches) { toml::table p; - p["address"] = "0x" + std::to_string(patch.first); - p["value"] = patch.second; + p["address"] = "0x" + std::to_string(addr); + p["value"] = value; instPatches.push_back(p); } patches["instructions"] = instPatches; diff --git a/ps2xRecomp/src/elf_parser.cpp b/ps2xRecomp/src/elf_parser.cpp index 9722621..143a04c 100644 --- a/ps2xRecomp/src/elf_parser.cpp +++ b/ps2xRecomp/src/elf_parser.cpp @@ -1,4 +1,5 @@ #include "ps2recomp/elf_parser.h" +#include "ps2recomp/types.h" #include #include @@ -21,8 +22,8 @@ namespace ps2recomp !(section->get_flags() & ELFIO::SHF_EXECINSTR); } - std::vector ElfParser::extractFunctions() - { + std::vector ElfParser::extractFunctions() const + { std::vector functions; for (const auto &symbol : m_symbols) @@ -92,8 +93,8 @@ namespace ps2recomp throw std::runtime_error("Invalid address for readWord: " + std::to_string(address)); } - uint8_t *ElfParser::getSectionData(const std::string §ionName) - { + uint8_t *ElfParser::getSectionData(const std::string §ionName) const + { for (const auto §ion : m_sections) { if (section.name == sectionName) @@ -105,8 +106,8 @@ namespace ps2recomp return nullptr; } - uint32_t ElfParser::getSectionAddress(const std::string §ionName) - { + uint32_t ElfParser::getSectionAddress(const std::string §ionName) const + { for (const auto §ion : m_sections) { if (section.name == sectionName) @@ -118,8 +119,8 @@ namespace ps2recomp return 0; } - uint32_t ElfParser::getSectionSize(const std::string §ionName) - { + uint32_t ElfParser::getSectionSize(const std::string §ionName) const + { for (const auto §ion : m_sections) { if (section.name == sectionName) diff --git a/ps2xRecomp/src/ps2_recompiler.cpp b/ps2xRecomp/src/ps2_recompiler.cpp index df78859..81db3a8 100644 --- a/ps2xRecomp/src/ps2_recompiler.cpp +++ b/ps2xRecomp/src/ps2_recompiler.cpp @@ -1,5 +1,8 @@ #include "ps2recomp/ps2_recompiler.h" #include "ps2recomp/instructions.h" +#include "ps2recomp/types.h" +#include "ps2recomp/elf_parser.h" +#include "ps2recomp/r5900_decoder.h" #include "ps2_runtime_calls.h" #include #include @@ -44,6 +47,8 @@ namespace ps2recomp { } + PS2Recompiler::~PS2Recompiler() = default; + bool PS2Recompiler::initialize() { try @@ -672,8 +677,8 @@ namespace ps2recomp return ps2_runtime_calls::isStubName(name); } - std::string PS2Recompiler::generateRuntimeHeader() - { + std::string PS2Recompiler::generateRuntimeHeader() const + { return m_codeGenerator->generateMacroHeader(); } diff --git a/ps2xRecomp/src/r5900_decoder.cpp b/ps2xRecomp/src/r5900_decoder.cpp index bb45ce4..dcafb3a 100644 --- a/ps2xRecomp/src/r5900_decoder.cpp +++ b/ps2xRecomp/src/r5900_decoder.cpp @@ -12,8 +12,8 @@ namespace ps2recomp { } - Instruction R5900Decoder::decodeInstruction(uint32_t address, uint32_t rawInstruction) - { + Instruction R5900Decoder::decodeInstruction(uint32_t address, uint32_t rawInstruction) const + { Instruction inst; inst.address = address; diff --git a/ps2xTest/src/code_generator_tests.cpp b/ps2xTest/src/code_generator_tests.cpp index b0c9f72..4a72cc5 100644 --- a/ps2xTest/src/code_generator_tests.cpp +++ b/ps2xTest/src/code_generator_tests.cpp @@ -1,6 +1,7 @@ #include "MiniTest.h" #include "ps2recomp/code_generator.h" #include "ps2recomp/instructions.h" +#include "ps2recomp/types.h" using namespace ps2recomp;