Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions ps2xAnalyzer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@ project(PS2Analyzer VERSION 0.1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

file(GLOB_RECURSE PS2ANALYZER_SOURCES
"src/*.cpp"
)

add_executable(ps2_analyzer ${PS2ANALYZER_SOURCES})

target_include_directories(ps2_analyzer PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/ps2xRecomp/include
)

target_link_libraries(ps2_analyzer PRIVATE
fmt::fmt
ps2_recomp
rabbitizer
)

install(TARGETS ps2_analyzer
RUNTIME DESTINATION bin
)
15 changes: 7 additions & 8 deletions ps2xAnalyzer/include/ps2recomp/elf_analyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#define PS2RECOMP_ELF_ANALYZER_H

#include "ps2recomp/elf_parser.h"
#include "ps2recomp/r5900_decoder.h"
#include "ps2recomp/types.h"
#include "ps2recomp/instructions.h"
#include <string>
#include <vector>
#include <unordered_set>
Expand All @@ -26,25 +26,24 @@ namespace ps2recomp
private:
std::string m_elfPath;
std::unique_ptr<ElfParser> m_elfParser;
std::unique_ptr<R5900Decoder> m_decoder;

std::vector<Function> m_functions;
std::vector<Symbol> m_symbols;
std::vector<Section> m_sections;
std::vector<Relocation> m_relocations;

std::unordered_set<std::string> m_libFunctions;
std::unordered_set<std::string> m_skipFunctions;
std::unordered_map<std::string, std::set<std::string>> m_functionDataUsage;
std::unordered_map<uint32_t, std::string> m_commonDataAccess;

std::map<uint32_t, uint32_t> m_patches;
std::map<uint32_t, std::string> m_patchReasons;

std::unordered_map<uint32_t, CFG> m_functionCFGs;
std::vector<JumpTable> m_jumpTables;
std::unordered_map<uint32_t, std::vector<FunctionCall>> m_functionCalls;

void initializeLibraryFunctions();
void analyzeEntryPoint();
void analyzeLibraryFunctions();
Expand All @@ -57,12 +56,12 @@ namespace ps2recomp
void analyzeRegisterUsage();
void analyzeFunctionSignatures();
void optimizePatches();

bool identifyMemcpyPattern(const Function &func);
bool identifyMemsetPattern(const Function &func);
bool identifyStringOperationPattern(const Function &func);
bool identifyMathPattern(const Function &func);

bool isSystemFunction(const std::string &name) const;
bool isLibraryFunction(const std::string &name) const;
std::vector<Instruction> decodeFunction(const Function &function);
Expand Down
51 changes: 34 additions & 17 deletions ps2xAnalyzer/src/elf_analyzer.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "ps2recomp/elf_analyzer.h"
#include <rabbitizer.h>
#include <iostream>
#include <sstream>
#include <algorithm>
Expand All @@ -20,7 +21,6 @@ namespace ps2recomp
: m_elfPath(elfPath)
{
m_elfParser = std::make_unique<ElfParser>(elfPath);
m_decoder = std::make_unique<R5900Decoder>();

initializeLibraryFunctions();
}
Expand Down Expand Up @@ -192,7 +192,7 @@ namespace ps2recomp
const std::vector<std::string> stdLibFuncs = {
// I/O functions
"printf", "sprintf", "snprintf", "fprintf", "vprintf", "vfprintf", "vsprintf", "vsnprintf",
"puts", "putchar", "getchar", "gets", "fgets", "fputs", "scanf", "fscanf", "sscanf",
"puts", "putchar", "getchar", "gets", "fgets", "fputs", "scanf", "fscanf", "sscanf",
"sprint", "sbprintf",

// Memory management
Expand Down Expand Up @@ -255,7 +255,7 @@ namespace ps2recomp
{
if (inst.opcode == OPCODE_JAL)
{
uint32_t target = (inst.address & 0xF0000000) | (inst.target << 2);
uint32_t target = inst.target;

for (const auto &func : m_functions)
{
Expand Down Expand Up @@ -537,7 +537,7 @@ namespace ps2recomp

if (nextInst.opcode == OPCODE_J || nextInst.opcode == OPCODE_JAL)
{
uint32_t jumpTarget = (nextInst.address & 0xF0000000) | (nextInst.target << 2);
uint32_t jumpTarget = nextInst.target;

for (const auto &section : m_sections)
{
Expand Down Expand Up @@ -652,7 +652,7 @@ namespace ps2recomp

if (inst.opcode == OPCODE_JAL)
{
targetAddr = (inst.address & 0xF0000000) | (inst.target << 2);
targetAddr = inst.target;
}
else
{
Expand Down Expand Up @@ -1358,7 +1358,7 @@ namespace ps2recomp
// Jump target for J/JAL
if ((inst.opcode == OPCODE_J || inst.opcode == OPCODE_JAL) && !inst.isCall)
{
uint32_t target = (inst.address & 0xF0000000) | (inst.target << 2);
uint32_t target = inst.target;
leaders.insert(target);
}
}
Expand Down Expand Up @@ -1439,7 +1439,7 @@ namespace ps2recomp
if (lastInst.opcode == OPCODE_J || lastInst.opcode == OPCODE_JAL)
{
// Direct jump
uint32_t targetAddr = (lastInst.address & 0xF0000000) | (lastInst.target << 2);
uint32_t targetAddr = lastInst.target;

// Only add successor if it's within this function
if (targetAddr >= function.start && targetAddr < function.end &&
Expand Down Expand Up @@ -1580,16 +1580,33 @@ namespace ps2recomp

uint32_t rawInstruction = m_elfParser->readWord(addr);

try
{
Instruction inst = m_decoder->decodeInstruction(addr, rawInstruction);
instructions.push_back(inst);
}
catch (const std::exception &e)
{
std::cerr << "Error decoding instruction at " << formatAddress(addr)
<< ": " << e.what() << std::endl;
}
RabbitizerInstruction instr;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use decodeInstruction function here ?

RabbitizerInstruction_init(&instr, rawInstruction, addr);

Instruction inst;
inst.address = addr;
inst.raw = rawInstruction;
inst.opcode = RAB_INSTR_GET_opcode(&instr);
inst.rs = RAB_INSTR_GET_rs(&instr);
inst.rt = RAB_INSTR_GET_rt(&instr);
inst.rd = RAB_INSTR_GET_rd(&instr);
inst.sa = RAB_INSTR_GET_sa(&instr);
inst.function = RAB_INSTR_GET_function(&instr);
inst.immediate = RAB_INSTR_GET_immediate(&instr);
inst.simmediate = static_cast<uint32_t>(RabbitizerInstruction_getProcessedImmediate(&instr));
inst.target = RabbitizerInstruction_getInstrIndexAsVram(&instr);
inst.hasDelaySlot = RabbitizerInstruction_hasDelaySlot(&instr);
inst.isCall = RabbitizerInstruction_isFunctionCall(&instr);
inst.isReturn = RabbitizerInstruction_isReturn(&instr);
inst.isBranch = (RabbitizerInstruction_getBranchOffsetGeneric(&instr) != 0) ||
RabbitizerInstruction_isJumptableJump(&instr);
inst.isJump = RabbitizerInstruction_isUnconditionalBranch(&instr) ||
RabbitizerInstruction_isJumptableJump(&instr);
inst.isMMI = (inst.opcode == OPCODE_MMI);
inst.isVU = (inst.opcode == OPCODE_COP2);

instructions.push_back(inst);
RabbitizerInstruction_destroy(&instr);
}

return instructions;
Expand Down
24 changes: 24 additions & 0 deletions ps2xRecomp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(fmt)

FetchContent_Declare(
rabbitizer
GIT_REPOSITORY https://github.com/Decompollaborate/rabbitizer.git
GIT_TAG 1.x
)
FetchContent_MakeAvailable(rabbitizer)

file(GLOB_RECURSE RABBITIZER_SOURCES CONFIGURE_DEPENDS
"${rabbitizer_SOURCE_DIR}/src/analysis/*.c"
"${rabbitizer_SOURCE_DIR}/src/common/*.c"
"${rabbitizer_SOURCE_DIR}/src/instructions/*.c"
"${rabbitizer_SOURCE_DIR}/src/instructions/*/*.c"
)

add_library(rabbitizer STATIC ${RABBITIZER_SOURCES})

target_include_directories(rabbitizer PUBLIC
"${rabbitizer_SOURCE_DIR}/include"
"${rabbitizer_SOURCE_DIR}/tables"
"${rabbitizer_SOURCE_DIR}/tables/tables"
)

file(GLOB_RECURSE PS2RECOMP_SOURCES
"src/*.cpp"
)
Expand Down Expand Up @@ -60,11 +82,13 @@ target_include_directories(ps2_recomp PRIVATE
target_link_libraries(ps2recomp PRIVATE
fmt::fmt
toml11::toml11
rabbitizer
)

target_link_libraries(ps2_recomp PUBLIC
fmt::fmt
toml11::toml11
rabbitizer
)

install(TARGETS ps2recomp ps2_recomp
Expand Down
4 changes: 2 additions & 2 deletions ps2xRecomp/example_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ instructions = [
function = "printf"
code = '''
// Custom printf implementation
void printf(uint8_t* rdram, R5900Context* ctx) {
void printf(uint8_t* rdram, Ps2CpuContext* ctx) {
// Implementation here
}
'''
Expand All @@ -40,7 +40,7 @@ void printf(uint8_t* rdram, R5900Context* ctx) {
address = "0x100000"
code = '''
// Custom implementation for function at 0x100000
void func_00100000(uint8_t* rdram, R5900Context* ctx) {
void func_00100000(uint8_t* rdram, Ps2CpuContext* ctx) {
// Implementation here
}
'''
1 change: 1 addition & 0 deletions ps2xRecomp/include/ps2recomp/code_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ namespace ps2recomp

Symbol *findSymbolByAddress(uint32_t address);
std::string getFunctionName(uint32_t address);
std::string sanitizeFunctionName(const std::string &name);
std::string getGeneratedFunctionName(const Function &function);
};

Expand Down
15 changes: 15 additions & 0 deletions ps2xRecomp/include/ps2recomp/decoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef PS2RECOMP_DECODER_H
#define PS2RECOMP_DECODER_H

#include "ps2recomp/types.h"
#include "ps2recomp/instructions.h"
#include <cstdint>

namespace ps2recomp
{
Instruction decodeInstruction(uint32_t address, uint32_t rawInstruction);
uint32_t getBranchTarget(const Instruction &inst);
uint32_t getJumpTarget(const Instruction &inst);
}

#endif // PS2RECOMP_DECODER_H
2 changes: 0 additions & 2 deletions ps2xRecomp/include/ps2recomp/ps2_recompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#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 <string>
Expand All @@ -28,7 +27,6 @@ namespace ps2recomp
private:
ConfigManager m_configManager;
std::unique_ptr<ElfParser> m_elfParser;
std::unique_ptr<R5900Decoder> m_decoder;
std::unique_ptr<CodeGenerator> m_codeGenerator;
RecompilerConfig m_config;

Expand Down
55 changes: 0 additions & 55 deletions ps2xRecomp/include/ps2recomp/r5900_decoder.h

This file was deleted.

Loading