#ifndef __RECOMP_PORT__ #define __RECOMP_PORT__ #include #include #include #include #include #include #include #include "elfio/elfio.hpp" #ifdef _MSC_VER inline uint32_t byteswap(uint32_t val) { return _byteswap_ulong(val); } #else constexpr uint32_t byteswap(uint32_t val) { return __builtin_bswap32(val); } #endif namespace RecompPort { struct JumpTable { uint32_t vram; uint32_t addend_reg; uint32_t rom; uint32_t lw_vram; uint32_t addu_vram; uint32_t jr_vram; std::vector entries; }; struct AbsoluteJump { uint32_t jump_target; uint32_t instruction_vram; }; struct Function { uint32_t vram; uint32_t rom; const std::span words; std::string name; ELFIO::Elf_Half section_index; bool ignored; bool reimplemented; }; enum class RelocType : uint8_t { R_MIPS_NONE = 0, R_MIPS_16, R_MIPS_32, R_MIPS_REL32, R_MIPS_26, R_MIPS_HI16, R_MIPS_LO16, R_MIPS_GPREL16, }; struct Reloc { uint32_t address; uint32_t target_address; uint32_t symbol_index; uint32_t target_section; RelocType type; bool needs_relocation; }; struct Section { ELFIO::Elf_Xword rom_addr; ELFIO::Elf64_Addr ram_addr; ELFIO::Elf_Xword size; std::vector function_addrs; std::vector relocs; std::string name; bool executable; bool relocatable; }; struct FunctionStats { std::vector jump_tables; std::vector absolute_jumps; }; struct Context { // ROM address of each section std::vector
sections; std::vector functions; std::unordered_map> functions_by_vram; std::vector rom; // A list of the list of each function (by index in `functions`) in a given section std::vector> section_functions; // The section names that were specified as relocatable std::unordered_set relocatable_sections; int executable_section_count; Context(const ELFIO::elfio& elf_file) { sections.resize(elf_file.sections.size()); section_functions.resize(elf_file.sections.size()); functions.reserve(1024); functions_by_vram.reserve(1024); rom.reserve(8 * 1024 * 1024); executable_section_count = 0; } }; bool analyze_function(const Context& context, const Function& function, const std::vector& instructions, FunctionStats& stats); bool recompile_function(const Context& context, const Function& func, std::string_view output_path, std::span> static_funcs); } #endif