diff --git a/CMakeLists.txt b/CMakeLists.txt index a15270f..184ab29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required (VERSION 3.20) + +include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) set(THIRDPARTY_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty) -set(CMAKE_CXX_STANDARD 23) + +set(CMAKE_CXX_STANDARD 17) set(BUILD_SHARED_LIBS OFF) # Enable Hot Reload for MSVC compilers if supported. @@ -12,20 +15,6 @@ endif() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") include("cmake/bin2h.cmake") -include(FetchContent) -FetchContent_Declare( - tomlplusplus - GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git - GIT_TAG v3.4.0 -) -FetchContent_Declare( - xxHash - GIT_REPOSITORY https://github.com/Cyan4973/xxHash.git - GIT_TAG v0.8.2 - SOURCE_SUBDIR "cmake_unofficial" -) -FetchContent_MakeAvailable(tomlplusplus) -FetchContent_MakeAvailable(xxHash) add_subdirectory(${THIRDPARTY_ROOT}/disasm) set(POWERANALYSE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/PowerAnalyse) diff --git a/PowerAnalyse/CMakeLists.txt b/PowerAnalyse/CMakeLists.txt index 78499dc..2937470 100644 --- a/PowerAnalyse/CMakeLists.txt +++ b/PowerAnalyse/CMakeLists.txt @@ -5,7 +5,9 @@ project("PowerAnalyse") add_executable(PowerAnalyse "main.cpp" "function.h" "function.cpp") add_library(LibPowerAnalyse "function.h" "function.cpp") +find_package(fmt CONFIG REQUIRED) + target_include_directories(LibPowerAnalyse PUBLIC .) target_link_libraries(LibPowerAnalyse PUBLIC PowerUtils) -target_link_libraries(PowerAnalyse PRIVATE PowerUtils) +target_link_libraries(PowerAnalyse PRIVATE PowerUtils fmt::fmt) diff --git a/PowerAnalyse/function.cpp b/PowerAnalyse/function.cpp index 0737a2c..34add40 100644 --- a/PowerAnalyse/function.cpp +++ b/PowerAnalyse/function.cpp @@ -4,6 +4,7 @@ #include #include #include +#include size_t Function::SearchBlock(size_t address) const { @@ -63,7 +64,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base) // TODO: Branch fallthrough for (; data <= dataEnd ; ++data) { - const auto addr = base + ((data - dataStart) * sizeof(*data)); + const size_t addr = base + ((data - dataStart) * sizeof(*data)); if (blockStack.empty()) { break; // it's hideover @@ -71,11 +72,11 @@ Function Function::Analyze(const void* code, size_t size, size_t base) auto& curBlock = blocks[blockStack.back()]; DEBUG(const auto blockBase = curBlock.base); - const auto instruction = std::byteswap(*data); + const uint32_t instruction = ByteSwap(*data); - const auto op = PPC_OP(instruction); - const auto xop = PPC_XOP(instruction); - const auto isLink = PPC_BL(instruction); // call + const uint32_t op = PPC_OP(instruction); + const uint32_t xop = PPC_XOP(instruction); + const uint32_t isLink = PPC_BL(instruction); // call ppc_insn insn; ppc::Disassemble(data, addr, insn); @@ -103,13 +104,13 @@ Function Function::Analyze(const void* code, size_t size, size_t base) // TODO: Handle absolute branches? assert(!PPC_BA(instruction)); - const auto branchDest = addr + PPC_BD(instruction); + const size_t branchDest = addr + PPC_BD(instruction); // true/false paths // left block: false case // right block: true case - const auto lBase = (addr - base) + 4; - const auto rBase = (addr + PPC_BD(instruction)) - base; + const size_t lBase = (addr - base) + 4; + const size_t rBase = (addr + PPC_BD(instruction)) - base; // these will be -1 if it's our first time seeing these blocks auto lBlock = fn.SearchBlock(base + lBase); @@ -124,7 +125,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base) blockStack.emplace_back(lBlock); } - auto rBlock = fn.SearchBlock(base + rBase); + size_t rBlock = fn.SearchBlock(base + rBase); if (rBlock == -1) { blocks.emplace_back(branchDest - base, 0); @@ -145,10 +146,10 @@ Function Function::Analyze(const void* code, size_t size, size_t base) if (op == PPC_OP_B) { assert(!PPC_BA(instruction)); - const auto branchDest = addr + PPC_BI(instruction); + const size_t branchDest = addr + PPC_BI(instruction); - const auto branchBase = branchDest - base; - const auto branchBlock = fn.SearchBlock(branchDest); + const size_t branchBase = branchDest - base; + const size_t branchBlock = fn.SearchBlock(branchDest); if (branchDest < base) { @@ -158,8 +159,8 @@ Function Function::Analyze(const void* code, size_t size, size_t base) } // carry over our projection if blocks are next to each other - const auto isContinuous = branchBase == curBlock.base + curBlock.size; - auto sizeProjection = (size_t)-1; + const bool isContinuous = branchBase == curBlock.base + curBlock.size; + size_t sizeProjection = (size_t)-1; if (curBlock.projectedSize != -1 && isContinuous) { @@ -180,12 +181,12 @@ Function Function::Analyze(const void* code, size_t size, size_t base) else if (op == PPC_OP_CTR) { // 5th bit of BO tells cpu to ignore the counter, which is a blr/bctr otherwise it's conditional - const auto conditional = !(PPC_BO(instruction) & 0x10); + const bool conditional = !(PPC_BO(instruction) & 0x10); if (conditional) { // right block's just going to return - const auto lBase = (addr - base) + 4; - auto lBlock = fn.SearchBlock(lBase); + const size_t lBase = (addr - base) + 4; + size_t lBlock = fn.SearchBlock(lBase); if (lBlock == -1) { blocks.emplace_back(lBase, 0); @@ -212,7 +213,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base) // Sort and invalidate discontinuous blocks if (blocks.size() > 1) { - std::ranges::sort(blocks, [](const Block& a, const Block& b) + std::sort(blocks.begin(), blocks.end(), [](const Block& a, const Block& b) { return a.base < b.base; }); diff --git a/PowerAnalyse/function.h b/PowerAnalyse/function.h index 3395b34..26b095d 100644 --- a/PowerAnalyse/function.h +++ b/PowerAnalyse/function.h @@ -1,7 +1,7 @@ #pragma once #include -#ifdef _DEBUG(X) +#ifdef _DEBUG #define DEBUG(X) X #else #define DEBUG(X) @@ -13,15 +13,36 @@ struct Function { size_t base{}; size_t size{}; + size_t projectedSize{ static_cast(-1) }; // scratch DEBUG(size_t parent{}); - // scratch - size_t projectedSize{ static_cast(-1) }; + Block() + { + } + + Block(size_t base, size_t size) + : base(base), size(size) + { + } + + Block(size_t base, size_t size, size_t projectedSize) + : base(base), size(size), projectedSize(projectedSize) + { + } }; size_t base{}; size_t size{}; std::vector blocks{}; + + Function() + { + } + + Function(size_t base, size_t size) + : base(base), size(size) + { + } size_t SearchBlock(size_t address) const; static Function Analyze(const void* code, size_t size, size_t base); diff --git a/PowerAnalyse/main.cpp b/PowerAnalyse/main.cpp index a7520ce..be77ef2 100644 --- a/PowerAnalyse/main.cpp +++ b/PowerAnalyse/main.cpp @@ -1,10 +1,11 @@ #include +#include #include #include #include -#include "function.h" -#include #include +#include +#include "function.h" #define SWITCH_ABSOLUTE 0 #define SWITCH_COMPUTED 1 @@ -139,7 +140,7 @@ void MakeMask(const uint32_t* instructions, size_t count) for (size_t i = 0; i < count; i++) { ppc::Disassemble(&instructions[i], 0, insn); - std::println("0x{:X}, // {}", std::byteswap(insn.opcode->opcode | (insn.instruction & insn.opcode->mask)), insn.opcode->name); + fmt::println("0x{:X}, // {}", ByteSwap(insn.opcode->opcode | (insn.instruction & insn.opcode->mask)), insn.opcode->name); } } @@ -173,13 +174,13 @@ void* SearchMask(const void* source, const uint32_t* compare, size_t compareCoun int main() { - const auto file = LoadFile("private/default.xex").value(); - auto image = Image::ParseImage(file.data(), file.size()).value(); + const auto file = LoadFile("private/default.xex"); + auto image = Image::ParseImage(file.data(), file.size()); std::string out; - auto println = [&](std::format_string fmt, Args&&... args) + auto println = [&](fmt::format_string fmt, Args&&... args) { - std::vformat_to(std::back_inserter(out), fmt.get(), std::make_format_args(args...)); + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); out += '\n'; }; //for (const auto& section : image.sections) @@ -190,7 +191,7 @@ int main() // MakeMask((uint32_t*)image.Find(0x82C40D84), 6); //auto data = "\x4D\x99\x00\x20"; - //auto data2 = std::byteswap((2129)); + //auto data2 = ByteSwap((2129)); //ppc_insn insn; //ppc_insn insn2; //ppc::Disassemble(data, 0, insn); @@ -261,7 +262,7 @@ int main() table.type = type; ScanTable((uint32_t*)data, base + (data - dataStart), table); - // std::println("{:X} ; jmptable - {}", base + (data - dataStart), table.labels.size()); + // fmt::println("{:X} ; jmptable - {}", base + (data - dataStart), table.labels.size()); if (table.base != 0) { ReadTable(image, table); @@ -335,15 +336,15 @@ int main() fwrite(out.data(), 1, out.size(), f); fclose(f); - uint32_t cxxFrameHandler = std::byteswap(0x831B1C90); - uint32_t cSpecificFrameHandler = std::byteswap(0x8324B3BC); + uint32_t cxxFrameHandler = ByteSwap(0x831B1C90); + uint32_t cSpecificFrameHandler = ByteSwap(0x8324B3BC); image.symbols.emplace("__CxxFrameHandler", 0x831B1C90, 0x38, Symbol_Function); image.symbols.emplace("__C_specific_handler", 0x8324B3BC, 0x38, Symbol_Function); image.symbols.emplace("memcpy", 0x831B0ED0, 0x488, Symbol_Function); image.symbols.emplace("memset", 0x831B0BA0, 0xA0, Symbol_Function); image.symbols.emplace("blkmov", 0x831B1358, 0xA8, Symbol_Function); - image.symbols.emplace(std::format("sub_{:X}", 0x82EF5D78), 0x82EF5D78, 0x3F8, Symbol_Function); + image.symbols.emplace(fmt::format("sub_{:X}", 0x82EF5D78), 0x82EF5D78, 0x3F8, Symbol_Function); // auto fnd = Function::Analyze(image.Find(0x82C40D58), image.size, 0x82C40D58); @@ -354,8 +355,8 @@ int main() for (size_t i = 0; i < count; i++) { auto fn = pf[i]; - fn.BeginAddress = std::byteswap(fn.BeginAddress); - fn.Data = std::byteswap(fn.Data); + fn.BeginAddress = ByteSwap(fn.BeginAddress); + fn.Data = ByteSwap(fn.Data); auto& f = functions.emplace_back(); f.base = fn.BeginAddress; @@ -366,7 +367,7 @@ int main() __debugbreak(); } - image.symbols.emplace(std::format("sub_{:X}", f.base), f.base, f.size, Symbol_Function); + image.symbols.emplace(fmt::format("sub_{:X}", f.base), f.base, f.size, Symbol_Function); } auto sym = image.symbols.find(0x82BD7420); @@ -413,7 +414,7 @@ int main() base += missingFn.size; data += missingFn.size; - std::println("sub_{:X}", missingFn.base); + fmt::println("sub_{:X}", missingFn.base); } } } @@ -421,7 +422,7 @@ int main() //ppc_insn insn; //uint8_t c[4] = { 0x10, 0x00, 0x59, 0xC3 }; //ppc::Disassemble(c, 0x831D6C64, insn); - //std::println("{:20}{}", insn.opcode->name, insn.op_str); + //fmt::println("{:20}{}", insn.opcode->name, insn.op_str); const auto entrySymbol = image.symbols.find(image.entry_point); @@ -432,21 +433,21 @@ int main() image.symbols.emplace("_start", image.entry_point, entrySize, Symbol_Function); - std::println("FUNCTIONS"); + fmt::println("FUNCTIONS"); for (const auto& fn : functions) { - std::println("\tsub_{:X}", fn.base); + fmt::println("\tsub_{:X}", fn.base); } - std::println(""); + fmt::println(""); - std::println("SECTIONS"); + fmt::println("SECTIONS"); for (const auto& section : image.sections) { - std::printf("Section %.8s\n", section.name.c_str()); - std::printf("\t%X-%X\n", section.base, section.base + section.size); + printf("Section %.8s\n", section.name.c_str()); + printf("\t%X-%X\n", section.base, section.base + section.size); } - std::println(""); + fmt::println(""); return 0; } diff --git a/PowerRecomp/CMakeLists.txt b/PowerRecomp/CMakeLists.txt index 81569bf..a0b8bee 100644 --- a/PowerRecomp/CMakeLists.txt +++ b/PowerRecomp/CMakeLists.txt @@ -6,7 +6,13 @@ BIN2H(SOURCE_FILE ${POWERUTILS_ROOT}/ppc_context.h HEADER_FILE "generated/ppc_co add_executable(PowerRecomp "main.cpp" "pch.h" "recompiler.cpp" "recompiler.h" "test_recompiler.cpp" "test_recompiler.h" "recompiler_config.h" "recompiler_config.cpp") target_precompile_headers(PowerRecomp PUBLIC "pch.h") -target_link_libraries(PowerRecomp PRIVATE LibPowerAnalyse tomlplusplus::tomlplusplus xxHash::xxhash) + +find_package(fmt CONFIG REQUIRED) +find_package(PkgConfig REQUIRED) +pkg_check_modules(tomlplusplus REQUIRED IMPORTED_TARGET tomlplusplus) +find_package(xxHash CONFIG REQUIRED) + +target_link_libraries(PowerRecomp PRIVATE LibPowerAnalyse fmt::fmt PkgConfig::tomlplusplus xxHash::xxhash) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(PowerRecomp PRIVATE -Wno-switch -Wno-unused-variable) diff --git a/PowerRecomp/pch.h b/PowerRecomp/pch.h index 0ec0b71..44208ac 100644 --- a/PowerRecomp/pch.h +++ b/PowerRecomp/pch.h @@ -1,22 +1,17 @@ #pragma once -// Workaround for the intellisense for some reason not seeing C++23 features -#ifdef __INTELLISENSE__ -#undef __cplusplus -#define __cplusplus 202302L -#endif - #include +#include #include #include #include -#include +#include #include #include -#include #include #include #include #include #include +#include #include "generated/ppc_context.gen.h" diff --git a/PowerRecomp/recompiler.cpp b/PowerRecomp/recompiler.cpp index e330293..81c90d3 100644 --- a/PowerRecomp/recompiler.cpp +++ b/PowerRecomp/recompiler.cpp @@ -13,8 +13,8 @@ void Recompiler::LoadConfig(const std::string_view& configFilePath) { config.Load(configFilePath); - const auto file = LoadFile((config.directoryPath + config.filePath).c_str()).value(); - image = Image::ParseImage(file.data(), file.size()).value(); + const auto file = LoadFile((config.directoryPath + config.filePath).c_str()); + image = Image::ParseImage(file.data(), file.size()); } void Recompiler::Analyse() @@ -26,32 +26,32 @@ void Recompiler::Analyse() auto& restgpr = functions.emplace_back(); restgpr.base = config.restGpr14Address + (i - 14) * 4; restgpr.size = (32 - i) * 4 + 12; - image.symbols.emplace(std::format("__restgprlr_{}", i), restgpr.base, restgpr.size, Symbol_Function); + image.symbols.emplace(Symbol{ fmt::format("__restgprlr_{}", i), restgpr.base, restgpr.size, Symbol_Function }); auto& savegpr = functions.emplace_back(); savegpr.base = config.saveGpr14Address + (i - 14) * 4; savegpr.size = (32 - i) * 4 + 8; - image.symbols.emplace(std::format("__savegprlr_{}", i), savegpr.base, savegpr.size, Symbol_Function); + image.symbols.emplace(fmt::format("__savegprlr_{}", i), savegpr.base, savegpr.size, Symbol_Function); auto& restfpr = functions.emplace_back(); restfpr.base = config.restFpr14Address + (i - 14) * 4; restfpr.size = (32 - i) * 4 + 4; - image.symbols.emplace(std::format("__restfpr_{}", i), restfpr.base, restfpr.size, Symbol_Function); + image.symbols.emplace(fmt::format("__restfpr_{}", i), restfpr.base, restfpr.size, Symbol_Function); auto& savefpr = functions.emplace_back(); savefpr.base = config.saveFpr14Address + (i - 14) * 4; savefpr.size = (32 - i) * 4 + 4; - image.symbols.emplace(std::format("__savefpr_{}", i), savefpr.base, savefpr.size, Symbol_Function); + image.symbols.emplace(fmt::format("__savefpr_{}", i), savefpr.base, savefpr.size, Symbol_Function); auto& restvmx = functions.emplace_back(); restvmx.base = config.restVmx14Address + (i - 14) * 8; restvmx.size = (32 - i) * 8 + 4; - image.symbols.emplace(std::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function); + image.symbols.emplace(fmt::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function); auto& savevmx = functions.emplace_back(); savevmx.base = config.saveVmx14Address + (i - 14) * 8; savevmx.size = (32 - i) * 8 + 4; - image.symbols.emplace(std::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function); + image.symbols.emplace(fmt::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function); } if (i >= 64) @@ -59,19 +59,19 @@ void Recompiler::Analyse() auto& restvmx = functions.emplace_back(); restvmx.base = config.restVmx64Address + (i - 64) * 8; restvmx.size = (128 - i) * 8 + 4; - image.symbols.emplace(std::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function); + image.symbols.emplace(fmt::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function); auto& savevmx = functions.emplace_back(); savevmx.base = config.saveVmx64Address + (i - 64) * 8; savevmx.size = (128 - i) * 8 + 4; - image.symbols.emplace(std::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function); + image.symbols.emplace(fmt::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function); } } for (auto& [address, size] : config.functions) { functions.emplace_back(address, size); - image.symbols.emplace(std::format("sub_{:X}", address), address, size, Symbol_Function); + image.symbols.emplace(fmt::format("sub_{:X}", address), address, size, Symbol_Function); } auto& pdata = *image.Find(".pdata"); @@ -80,8 +80,8 @@ void Recompiler::Analyse() for (size_t i = 0; i < count; i++) { auto fn = pf[i]; - fn.BeginAddress = std::byteswap(fn.BeginAddress); - fn.Data = std::byteswap(fn.Data); + fn.BeginAddress = ByteSwap(fn.BeginAddress); + fn.Data = ByteSwap(fn.Data); if (image.symbols.find(fn.BeginAddress) == image.symbols.end()) { @@ -89,7 +89,7 @@ void Recompiler::Analyse() f.base = fn.BeginAddress; f.size = fn.FunctionLength * 4; - image.symbols.emplace(std::format("sub_{:X}", f.base), f.base, f.size, Symbol_Function); + image.symbols.emplace(fmt::format("sub_{:X}", f.base), f.base, f.size, Symbol_Function); } } @@ -105,7 +105,7 @@ void Recompiler::Analyse() while (data < dataEnd) { - uint32_t insn = std::byteswap(*(uint32_t*)data); + uint32_t insn = ByteSwap(*(uint32_t*)data); if (PPC_OP(insn) == PPC_OP_B && PPC_BL(insn)) { size_t address = base + (data - section.data) + PPC_BI(insn); @@ -114,7 +114,7 @@ void Recompiler::Analyse() { auto data = section.data + address - section.base; auto& fn = functions.emplace_back(Function::Analyze(data, section.base + section.size - address, address)); - image.symbols.emplace(std::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function); + image.symbols.emplace(fmt::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function); } } data += 4; @@ -124,7 +124,7 @@ void Recompiler::Analyse() while (data < dataEnd) { - auto invalidInstr = config.invalidInstructions.find(std::byteswap(*(uint32_t*)data)); + auto invalidInstr = config.invalidInstructions.find(ByteSwap(*(uint32_t*)data)); if (invalidInstr != config.invalidInstructions.end()) { base += invalidInstr->second; @@ -143,7 +143,7 @@ void Recompiler::Analyse() else { auto& fn = functions.emplace_back(Function::Analyze(data, dataEnd - data, base)); - image.symbols.emplace(std::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function); + image.symbols.emplace(fmt::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function); base += fn.size; data += fn.size; @@ -172,9 +172,9 @@ bool Recompiler::Recompile( (config.nonVolatileRegistersAsLocalVariables && index >= 14)) { localVariables.r[index] = true; - return std::format("r{}", index); + return fmt::format("r{}", index); } - return std::format("ctx.r{}", index); + return fmt::format("ctx.r{}", index); }; auto f = [&](size_t index) @@ -183,9 +183,9 @@ bool Recompiler::Recompile( (config.nonVolatileRegistersAsLocalVariables && index >= 14)) { localVariables.f[index] = true; - return std::format("f{}", index); + return fmt::format("f{}", index); } - return std::format("ctx.f{}", index); + return fmt::format("ctx.f{}", index); }; auto v = [&](size_t index) @@ -194,9 +194,9 @@ bool Recompiler::Recompile( (config.nonVolatileRegistersAsLocalVariables && ((index >= 14 && index <= 31) || (index >= 64 && index <= 127)))) { localVariables.v[index] = true; - return std::format("v{}", index); + return fmt::format("v{}", index); } - return std::format("ctx.v{}", index); + return fmt::format("ctx.v{}", index); }; auto cr = [&](size_t index) @@ -204,9 +204,9 @@ bool Recompiler::Recompile( if (config.crRegistersAsLocalVariables) { localVariables.cr[index] = true; - return std::format("cr{}", index); + return fmt::format("cr{}", index); } - return std::format("ctx.cr{}", index); + return fmt::format("ctx.cr{}", index); }; auto ctr = [&]() @@ -287,7 +287,7 @@ bool Recompiler::Recompile( if (targetSymbol != image.symbols.end() && targetSymbol->address == address && targetSymbol->type == Symbol_Function) { - if (config.nonVolatileRegistersAsLocalVariables && (targetSymbol->name.starts_with("__rest") || targetSymbol->name.starts_with("__save"))) + if (config.nonVolatileRegistersAsLocalVariables && (targetSymbol->name.find("__rest") == 0 || targetSymbol->name.find("__save") == 0)) { // print nothing } @@ -513,7 +513,7 @@ bool Recompiler::Recompile( if (label < fn.base || label >= fn.base + fn.size) { println("\t\t// ERROR: 0x{:X}", label); - std::println("ERROR: Switch case at {:X} is trying to jump outside function: {:X}", base, label); + fmt::println("ERROR: Switch case at {:X} is trying to jump outside function: {:X}", base, label); println("\t\treturn;"); } else @@ -1897,7 +1897,7 @@ bool Recompiler::Recompile( { case 0: // D3D color if (insn.operands[3] != 1 || insn.operands[4] != 3) - std::println("Unexpected D3D color pack instruction at {:X}", base); + fmt::println("Unexpected D3D color pack instruction at {:X}", base); for (size_t i = 0; i < 4; i++) { @@ -2145,7 +2145,7 @@ bool Recompiler::Recompile( { int lastLine = out.find_last_of('\n', out.size() - 2); if (out.find("cr0", lastLine + 1) == std::string::npos && out.find("cr6", lastLine + 1) == std::string::npos) - std::println("{} at {:X} has RC bit enabled but no comparison was generated", insn.opcode->name, base); + fmt::println("{} at {:X} has RC bit enabled but no comparison was generated", insn.opcode->name, base); } #endif @@ -2163,7 +2163,7 @@ bool Recompiler::Recompile(const Function& fn) for (size_t addr = base; addr < end; addr += 4) { - const uint32_t instruction = std::byteswap(*(uint32_t*)((char*)data + addr - base)); + const uint32_t instruction = ByteSwap(*(uint32_t*)((char*)data + addr - base)); if (!PPC_BL(instruction)) { const size_t op = PPC_OP(instruction); @@ -2248,7 +2248,7 @@ bool Recompiler::Recompile(const Function& fn) } else { - name = std::format("sub_{}", fn.base); + name = fmt::format("sub_{}", fn.base); } println("__attribute__((alias(\"__imp__{}\"))) PPC_WEAK_FUNC({});", name, name); @@ -2268,7 +2268,7 @@ bool Recompiler::Recompile(const Function& fn) ppc_insn insn; while (base < end) { - if (labels.contains(base)) + if (labels.find(base) != labels.end()) { println("loc_{:X}:", base); @@ -2286,17 +2286,17 @@ bool Recompiler::Recompile(const Function& fn) println("\t// {}", insn.op_str); #if 1 if (*data != 0) - std::println("Unable to decode instruction {:X} at {:X}", *data, base); + fmt::println("Unable to decode instruction {:X} at {:X}", *data, base); #endif } else { if (insn.opcode->id == PPC_INST_BCTR && (*(data - 1) == 0x07008038 || *(data - 1) == 0x00000060) && switchTable == config.switchTables.end()) - std::println("Found a switch jump table at {:X} with no switch table entry present", base); + fmt::println("Found a switch jump table at {:X} with no switch table entry present", base); if (!Recompile(fn, base, insn, data, switchTable, localVariables, csrState)) { - std::println("Unrecognized instruction at 0x{:X}: {}", base, insn.opcode->name); + fmt::println("Unrecognized instruction at 0x{:X}: {}", base, insn.opcode->name); allRecompiled = false; } } @@ -2307,7 +2307,7 @@ bool Recompiler::Recompile(const Function& fn) #if 0 if (insn.opcode == nullptr || (insn.opcode->id != PPC_INST_B && insn.opcode->id != PPC_INST_BCTR && insn.opcode->id != PPC_INST_BLR)) - std::println("Function at {:X} ends prematurely with instruction {} at {:X}", fn.base, insn.opcode != nullptr ? insn.opcode->name : "INVALID", base - 4); + fmt::println("Function at {:X} ends prematurely with instruction {} at {:X}", fn.base, insn.opcode != nullptr ? insn.opcode->name : "INVALID", base - 4); #endif println("}}\n"); @@ -2441,7 +2441,7 @@ void Recompiler::Recompile() } if ((i % 2048) == 0 || (i == (functions.size() - 1))) - std::println("Recompiling functions... {}%", static_cast(i + 1) / functions.size() * 100.0f); + fmt::println("Recompiling functions... {}%", static_cast(i + 1) / functions.size() * 100.0f); Recompile(functions[i]); } @@ -2457,14 +2457,14 @@ void Recompiler::SaveCurrentOutData(const std::string_view& name) if (name.empty()) { - cppName = std::format("ppc_recomp.{}.cpp", cppFileIndex); + cppName = fmt::format("ppc_recomp.{}.cpp", cppFileIndex); ++cppFileIndex; } bool shouldWrite = true; // Check if an identical file already exists first to not trigger recompilation - std::string filePath = std::format("{}/{}/{}", config.directoryPath, config.outDirectoryPath, name.empty() ? cppName : name); + std::string filePath = fmt::format("{}/{}/{}", config.directoryPath, config.outDirectoryPath, name.empty() ? cppName : name); FILE* f = fopen(filePath.c_str(), "rb"); if (f) { diff --git a/PowerRecomp/recompiler.h b/PowerRecomp/recompiler.h index c7103cd..f014d96 100644 --- a/PowerRecomp/recompiler.h +++ b/PowerRecomp/recompiler.h @@ -38,15 +38,15 @@ struct Recompiler void LoadConfig(const std::string_view& configFilePath); template - void print(std::format_string fmt, Args&&... args) + void print(fmt::format_string fmt, Args&&... args) { - std::vformat_to(std::back_inserter(out), fmt.get(), std::make_format_args(args...)); + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); } template - void println(std::format_string fmt, Args&&... args) + void println(fmt::format_string fmt, Args&&... args) { - std::vformat_to(std::back_inserter(out), fmt.get(), std::make_format_args(args...)); + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); out += '\n'; } diff --git a/PowerRecomp/recompiler_config.cpp b/PowerRecomp/recompiler_config.cpp index 47a6aa2..2525d75 100644 --- a/PowerRecomp/recompiler_config.cpp +++ b/PowerRecomp/recompiler_config.cpp @@ -100,14 +100,14 @@ void RecompilerConfig::Load(const std::string_view& configFilePath) (midAsmHook.returnOnTrue && midAsmHook.jumpAddressOnTrue != NULL) || (midAsmHook.returnOnFalse && midAsmHook.jumpAddressOnFalse != NULL)) { - std::println("{}: can't return and jump at the same time", midAsmHook.name); + fmt::println("{}: can't return and jump at the same time", midAsmHook.name); } if ((midAsmHook.ret || midAsmHook.jumpAddress != NULL) && (midAsmHook.returnOnFalse != NULL || midAsmHook.returnOnTrue != NULL || midAsmHook.jumpAddressOnFalse != NULL || midAsmHook.jumpAddressOnTrue != NULL)) { - std::println("{}: can't mix direct and conditional return/jump", midAsmHook.name); + fmt::println("{}: can't mix direct and conditional return/jump", midAsmHook.name); } midAsmHooks.emplace(*table["address"].value(), std::move(midAsmHook)); diff --git a/PowerRecomp/test_recompiler.cpp b/PowerRecomp/test_recompiler.cpp index b70759f..c179907 100644 --- a/PowerRecomp/test_recompiler.cpp +++ b/PowerRecomp/test_recompiler.cpp @@ -22,7 +22,7 @@ void TestRecompiler::Analyse(const std::string_view& testName) } auto& fn = functions.emplace_back(Function::Analyze(data, dataEnd - data, base)); - image.symbols.emplace(std::format("{}_{:X}", testName, fn.base), fn.base, fn.size, Symbol_Function); + image.symbols.emplace(fmt::format("{}_{:X}", testName, fn.base), fn.base, fn.size, Symbol_Function); base += fn.size; data += fn.size; @@ -40,11 +40,11 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds { if (file.path().extension() == ".o") { - const auto exeFile = LoadFile(file.path().string().c_str()).value(); + const auto exeFile = LoadFile(file.path().string().c_str()); TestRecompiler recompiler; recompiler.config.outDirectoryPath = dstDirectoryPath; - recompiler.image = Image::ParseImage(exeFile.data(), exeFile.size()).value(); + recompiler.image = Image::ParseImage(exeFile.data(), exeFile.size()); auto stem = file.path().stem().string(); recompiler.Analyse(stem); @@ -61,7 +61,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds } else { - std::println("Function {:X} in {} has unimplemented instructions", fn.base, stem); + fmt::println("Function {:X} in {} has unimplemented instructions", fn.base, stem); } } stem += ".cpp"; @@ -73,7 +73,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds for (auto& [fn, addr] : functions) { - std::ifstream in(std::format("{}/{}.dis", srcDirectoryPath, fn)); + std::ifstream in(fmt::format("{}/{}.dis", srcDirectoryPath, fn)); if (in.is_open()) { std::string line; @@ -86,30 +86,30 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds size_t address = ~0; std::from_chars(&line[0], &line[spaceIndex], address, 16); address &= 0xFFFFF; - if (addr.contains(address)) - symbols.emplace(line.substr(spaceIndex + 2, bracketIndex - spaceIndex - 2), std::format("{}_{:X}", fn, address)); + if (addr.find(address) != addr.end()) + symbols.emplace(line.substr(spaceIndex + 2, bracketIndex - spaceIndex - 2), fmt::format("{}_{:X}", fn, address)); } } } else { - std::println("Unable to locate disassembly file for {}", fn); + fmt::println("Unable to locate disassembly file for {}", fn); } } - FILE* file = fopen(std::format("{}/main.cpp", dstDirectoryPath).c_str(), "w"); + FILE* file = fopen(fmt::format("{}/main.cpp", dstDirectoryPath).c_str(), "w"); std::string main; - std::println(file, "#define PPC_CONFIG_H_INCLUDED"); - std::println(file, "#include "); - std::println(file, "#include "); - std::println(file, "#include \n"); - std::println(file, "#define PPC_CHECK_VALUE_U(f, lhs, rhs) if (lhs != rhs) std::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{:X}}\", lhs)\n"); - std::println(file, "#define PPC_CHECK_VALUE_F(f, lhs, rhs) if (lhs != rhs) std::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{}}\", lhs)\n"); + fmt::println(file, "#define PPC_CONFIG_H_INCLUDED"); + fmt::println(file, "#include "); + fmt::println(file, "#include "); + fmt::println(file, "#include \n"); + fmt::println(file, "#define PPC_CHECK_VALUE_U(f, lhs, rhs) if (lhs != rhs) fmt::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{:X}}\", lhs)\n"); + fmt::println(file, "#define PPC_CHECK_VALUE_F(f, lhs, rhs) if (lhs != rhs) fmt::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{}}\", lhs)\n"); for (auto& [fn, addr] : functions) { - std::ifstream in(std::format("{}/../{}.s", srcDirectoryPath, fn)); + std::ifstream in(fmt::format("{}/../{}.s", srcDirectoryPath, fn)); if (in.is_open()) { std::string str; @@ -135,10 +135,10 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds auto symbol = symbols.find(name); if (symbol != symbols.end()) { - std::println(file, "PPC_FUNC({});\n", symbol->second); - std::println(file, "void {}(uint8_t* base) {{", name); - std::println(file, "\tPPCContext ctx{{}};"); - std::println(file, "\tctx.fpscr.loadFromHost();"); + fmt::println(file, "PPC_FUNC({});\n", symbol->second); + fmt::println(file, "void {}(uint8_t* base) {{", name); + fmt::println(file, "\tPPCContext ctx{{}};"); + fmt::println(file, "\tctx.fpscr.loadFromHost();"); while (getline() && !str.empty() && str[0] == '#') { @@ -158,14 +158,14 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds int commaIndex2 = str.find(',', commaIndex1 + 1); int closingBracketIndex = str.find(']', commaIndex2 + 1); - std::println(file, "\tctx.{}.u32[3] = 0x{};", reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1)); - std::println(file, "\tctx.{}.u32[2] = 0x{};", reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2)); - std::println(file, "\tctx.{}.u32[1] = 0x{};", reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2)); - std::println(file, "\tctx.{}.u32[0] = 0x{};", reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2)); + fmt::println(file, "\tctx.{}.u32[3] = 0x{};", reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1)); + fmt::println(file, "\tctx.{}.u32[2] = 0x{};", reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2)); + fmt::println(file, "\tctx.{}.u32[1] = 0x{};", reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2)); + fmt::println(file, "\tctx.{}.u32[0] = 0x{};", reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2)); } else { - std::println(file, "\tctx.{}.{}64 = {};", + fmt::println(file, "\tctx.{}.{}64 = {};", reg, str.find('.', secondSpaceIndex) != std::string::npos ? 'f' : 'u', str.substr(secondSpaceIndex + 1)); @@ -183,7 +183,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds { if (str[i] != ' ') { - std::println(file, "\tbase[0x{} + 0x{:X}] = 0x{}{};", address, j, str[i], str[i + 1]); + fmt::println(file, "\tbase[0x{} + 0x{:X}] = 0x{}{};", address, j, str[i], str[i + 1]); ++i; // the loop adds another ++j; } @@ -196,7 +196,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds while (getline() && (str.empty() || str[0] != '#')) ; - std::println(file, "\t{}(ctx, base);", symbol->second); + fmt::println(file, "\t{}(ctx, base);", symbol->second); do { @@ -218,14 +218,14 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds int commaIndex2 = str.find(',', commaIndex1 + 1); int closingBracketIndex = str.find(']', commaIndex2 + 1); - std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[3], 0x{});", name, reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1)); - std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[2], 0x{});", name, reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2)); - std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[1], 0x{});", name, reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2)); - std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[0], 0x{});", name, reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2)); + fmt::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[3], 0x{});", name, reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1)); + fmt::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[2], 0x{});", name, reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2)); + fmt::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[1], 0x{});", name, reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2)); + fmt::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[0], 0x{});", name, reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2)); } else { - std::println(file, "\tPPC_CHECK_VALUE_{}({}, ctx.{}.{}64, {});", + fmt::println(file, "\tPPC_CHECK_VALUE_{}({}, ctx.{}.{}64, {});", str.find('.', secondSpaceIndex) != std::string::npos ? 'F' : 'U', name, reg, @@ -245,7 +245,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds { if (str[i] != ' ') { - std::println(file, "\tPPC_CHECK_VALUE_U({}, base[0x{} + 0x{:X}], 0x{}{});", name, address, j, str[i], str[i + 1]); + fmt::println(file, "\tPPC_CHECK_VALUE_U({}, base[0x{} + 0x{:X}], 0x{}{});", name, address, j, str[i], str[i + 1]); ++i; // the loop adds another ++j; } @@ -255,13 +255,13 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds } } while (getline() && !str.empty() && str[0] == '#'); - std::println(file, "}}\n"); + fmt::println(file, "}}\n"); - std::format_to(std::back_inserter(main), "\t{}(base);\n", name); + fmt::format_to(std::back_inserter(main), "\t{}(base);\n", name); } else { - std::println("Found no symbol for {}", name); + fmt::println("Found no symbol for {}", name); } } } @@ -269,15 +269,15 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds } else { - std::println("Unable to locate source file for {}", fn); + fmt::println("Unable to locate source file for {}", fn); } } - std::println(file, "int main() {{"); - std::println(file, "\tuint8_t* base = reinterpret_cast(VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));"); + fmt::println(file, "int main() {{"); + fmt::println(file, "\tuint8_t* base = reinterpret_cast(VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));"); fwrite(main.data(), 1, main.size(), file); - std::println(file, "\treturn 0;"); - std::println(file, "}}"); + fmt::println(file, "\treturn 0;"); + fmt::println(file, "}}"); fclose(file); } diff --git a/PowerUtils/CMakeLists.txt b/PowerUtils/CMakeLists.txt index 57f9c7c..9757606 100644 --- a/PowerUtils/CMakeLists.txt +++ b/PowerUtils/CMakeLists.txt @@ -1,5 +1,5 @@ project("PowerUtils") -add_library(PowerUtils "disasm.h" "disasm.cpp" "file.h" "xex.cpp" "image.h" "image.cpp" "elf.h" "ppc_context.h" "symbol.h" "symbol_table.h" "section.h" "xdbf_wrapper.cpp") +add_library(PowerUtils "disasm.h" "disasm.cpp" "file.h" "xex.cpp" "image.h" "image.cpp" "elf.h" "ppc_context.h" "symbol.h" "symbol_table.h" "section.h" "xdbf_wrapper.cpp" "byteswap.h") target_include_directories(PowerUtils PUBLIC .) target_link_libraries(PowerUtils PUBLIC disasm) diff --git a/PowerUtils/byteswap.h b/PowerUtils/byteswap.h new file mode 100644 index 0000000..33e959f --- /dev/null +++ b/PowerUtils/byteswap.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +template +inline T ByteSwap(T value) +{ + if constexpr (sizeof(T) == 1) + return value; + else if constexpr (sizeof(T) == 2) + return static_cast(__builtin_bswap16(static_cast(value))); + else if constexpr (sizeof(T) == 4) + return static_cast(__builtin_bswap32(static_cast(value))); + else if constexpr (sizeof(T) == 8) + return static_cast(__builtin_bswap64(static_cast(value))); + + assert(false && "Unexpected byte size."); + return value; +} + +template +inline void ByteSwapInplace(T& value) +{ + value = ByteSwap(value); +} diff --git a/PowerUtils/file.h b/PowerUtils/file.h index 473086b..4b59822 100644 --- a/PowerUtils/file.h +++ b/PowerUtils/file.h @@ -1,14 +1,14 @@ #pragma once -#include + #include -inline static std::expected, int> LoadFile(const char* path) +inline std::vector LoadFile(const char* path) { std::vector data{}; auto* stream = fopen(path, "rb"); if (stream == nullptr) { - return std::unexpected(1); + return {}; } fseek(stream, 0, SEEK_END); diff --git a/PowerUtils/image.cpp b/PowerUtils/image.cpp index 6708c1a..dc93fd8 100644 --- a/PowerUtils/image.cpp +++ b/PowerUtils/image.cpp @@ -5,8 +5,8 @@ void Image::Map(const std::string_view& name, size_t base, uint32_t size, uint8_t flags, uint8_t* data) { - sections.emplace(std::string(name), this->base + base, - size, static_cast(flags), data); + sections.insert({ std::string(name), this->base + base, + size, static_cast(flags), data }); } const void* Image::Find(size_t address) const @@ -28,7 +28,7 @@ const Section* Image::Find(const std::string_view& name) const return nullptr; } -std::expected Image::ParseImage(const uint8_t* data, size_t size) +Image Image::ParseImage(const uint8_t* data, size_t size) { if (data[0] == ELFMAG0 && data[1] == ELFMAG1 && data[2] == ELFMAG2 && data[3] == ELFMAG3) { @@ -39,7 +39,7 @@ std::expected Image::ParseImage(const uint8_t* data, size_t size) return Xex2LoadImage(data); } - return std::unexpected(1); + return {}; } Image ElfLoadImage(const uint8_t* data, size_t size) @@ -50,27 +50,27 @@ Image ElfLoadImage(const uint8_t* data, size_t size) Image image{}; image.size = size; image.data = std::make_unique(size); - image.entry_point = std::byteswap(header->e_entry); + image.entry_point = ByteSwap(header->e_entry); memcpy(image.data.get(), data, size); - auto stringTableIndex = std::byteswap(header->e_shstrndx); + auto stringTableIndex = ByteSwap(header->e_shstrndx); - const auto numSections = std::byteswap(header->e_shnum); - const auto numpSections = std::byteswap(header->e_phnum); + const auto numSections = ByteSwap(header->e_shnum); + const auto numpSections = ByteSwap(header->e_phnum); - const auto* sections = (elf32_shdr*)(data + std::byteswap(header->e_shoff)); - const auto* psections = (elf32_phdr*)(data + std::byteswap(header->e_phoff)); + const auto* sections = (elf32_shdr*)(data + ByteSwap(header->e_shoff)); + const auto* psections = (elf32_phdr*)(data + ByteSwap(header->e_phoff)); for (size_t i = 0; i < numpSections; i++) { - if (psections[i].p_type == std::byteswap((Elf32_Word)PT_LOAD)) + if (psections[i].p_type == ByteSwap((Elf32_Word)PT_LOAD)) { - image.base = std::byteswap(psections[i].p_vaddr); + image.base = ByteSwap(psections[i].p_vaddr); break; } } - auto* stringTable = reinterpret_cast(data + std::byteswap(sections[stringTableIndex].sh_offset)); + auto* stringTable = reinterpret_cast(data + ByteSwap(sections[stringTableIndex].sh_offset)); for (size_t i = 0; i < numSections; i++) { @@ -82,16 +82,16 @@ Image ElfLoadImage(const uint8_t* data, size_t size) uint8_t flags{}; - if (section.sh_flags & std::byteswap(SHF_EXECINSTR)) + if (section.sh_flags & ByteSwap(SHF_EXECINSTR)) { flags |= SectionFlags_Code; } - auto* name = section.sh_name != 0 ? stringTable + std::byteswap(section.sh_name) : nullptr; - const auto rva = std::byteswap(section.sh_addr) - image.base; - const auto size = std::byteswap(section.sh_size); + auto* name = section.sh_name != 0 ? stringTable + ByteSwap(section.sh_name) : nullptr; + const auto rva = ByteSwap(section.sh_addr) - image.base; + const auto size = ByteSwap(section.sh_size); - image.Map(name, rva, size, flags, image.data.get() + std::byteswap(section.sh_offset)); + image.Map(name, rva, size, flags, image.data.get() + ByteSwap(section.sh_offset)); } return image; diff --git a/PowerUtils/image.h b/PowerUtils/image.h index 0c0da91..e443852 100644 --- a/PowerUtils/image.h +++ b/PowerUtils/image.h @@ -44,7 +44,7 @@ struct Image * \param size Size of data * \return Parsed image */ - static std::expected ParseImage(const uint8_t* data, size_t size); + static Image ParseImage(const uint8_t* data, size_t size); }; Image ElfLoadImage(const uint8_t* data, size_t size); diff --git a/PowerUtils/symbol.h b/PowerUtils/symbol.h index 161fd46..e9cae73 100644 --- a/PowerUtils/symbol.h +++ b/PowerUtils/symbol.h @@ -13,9 +13,18 @@ enum SymbolType struct Symbol { mutable std::string name{}; - uint32_t address{}; - uint32_t size{}; + size_t address{}; + size_t size{}; mutable SymbolType type{}; + + Symbol() + { + } + + Symbol(std::string name, size_t address, size_t size, SymbolType type) + : name(std::move(name)), address(address), size(size), type(type) + { + } }; struct SymbolComparer diff --git a/PowerUtils/xbox.h b/PowerUtils/xbox.h index e5c1656..10dabb4 100644 --- a/PowerUtils/xbox.h +++ b/PowerUtils/xbox.h @@ -3,7 +3,7 @@ #include #include #include - +#include "byteswap.h" #ifdef _WIN32 #include @@ -81,22 +81,22 @@ struct be { if constexpr (std::is_same_v) { - const uint64_t swapped = std::byteswap(*reinterpret_cast(&value)); + const uint64_t swapped = ByteSwap(*reinterpret_cast(&value)); return *reinterpret_cast(&swapped); } else if constexpr (std::is_same_v) { - const uint32_t swapped = std::byteswap(*reinterpret_cast(&value)); + const uint32_t swapped = ByteSwap(*reinterpret_cast(&value)); return *reinterpret_cast(&swapped); } else if constexpr (std::is_enum_v) { - const std::underlying_type_t swapped = std::byteswap(*reinterpret_cast*>(&value)); + const std::underlying_type_t swapped = ByteSwap(*reinterpret_cast*>(&value)); return *reinterpret_cast(&swapped); } else { - return std::byteswap(value); + return ByteSwap(value); } } diff --git a/PowerUtils/xex.cpp b/PowerUtils/xex.cpp index 209037b..ea8bc1a 100644 --- a/PowerUtils/xex.cpp +++ b/PowerUtils/xex.cpp @@ -126,7 +126,7 @@ Image Xex2LoadImage(const uint8_t* data) { auto originalThunk = (XEX_THUNK_DATA*)image.Find(descriptors[im].FirstThunk); auto originalData = originalThunk; - originalData->Data = std::byteswap(originalData->Data); + originalData->Data = ByteSwap(originalData->Data); if (originalData->OriginalData.Type != 0) { @@ -134,7 +134,7 @@ Image Xex2LoadImage(const uint8_t* data) auto name = names->find(originalData->OriginalData.Ordinal); if (name != names->end()) { - image.symbols.emplace(name->second, descriptors[im].FirstThunk, sizeof(thunk), Symbol_Function); + image.symbols.insert({ name->second, descriptors[im].FirstThunk, sizeof(thunk), Symbol_Function }); } memcpy(originalThunk, thunk, sizeof(thunk)); diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..db96992 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,12 @@ +{ + "builtin-baseline": "e63bd09dc0b7204467705c1c7c71d0e2a3f8860b", + "dependencies": [ + { + "name": "pkgconf", + "platform": "windows" + }, + "fmt", + "tomlplusplus", + "xxhash" + ] +}