diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..901036ca --- /dev/null +++ b/.clang-format @@ -0,0 +1,17 @@ +BasedOnStyle: LLVM +UseTab: Never +IndentWidth: 4 +Language: Cpp +DerivePointerAlignment: false +PointerAlignment: Left +BreakBeforeBraces: Allman +LineEnding: LF +ColumnLimit: 0 +IndentCaseLabels: false +InsertNewlineAtEOF: true +Cpp11BracedListStyle: false +SpaceBeforeCpp11BracedList: true +AlignAfterOpenBracket: DontAlign +ContinuationIndentWidth: 4 +AllowAllArgumentsOnNextLine: false +SpaceAfterTemplateKeyword: false diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 00000000..41a866a8 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,25 @@ +name: Clang Format +on: + push: + paths-ignore: + - "**/*.md" + - '**/*.txt' + - 'thirdparty/*' + pull_request: + paths-ignore: + - "**/*.md" + - '**/*.txt' + - 'thirdparty/*' + workflow_dispatch: +jobs: + clang-format: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run clang-format + uses: jidicula/clang-format-action@v4.14.0 + with: + exclude-regex: (thirdparty) + clang-format-version: 19 diff --git a/XenonAnalyse/function.cpp b/XenonAnalyse/function.cpp index 34add408..e02d3665 100644 --- a/XenonAnalyse/function.cpp +++ b/XenonAnalyse/function.cpp @@ -1,10 +1,10 @@ #include "function.h" -#include -#include -#include #include -#include +#include #include +#include +#include +#include size_t Function::SearchBlock(size_t address) const { @@ -40,7 +40,7 @@ size_t Function::SearchBlock(size_t address) const Function Function::Analyze(const void* code, size_t size, size_t base) { - Function fn{ base, 0 }; + Function fn { base, 0 }; if (*((uint32_t*)code + 1) == 0x04000048) // shifted ptr tail call { @@ -55,14 +55,16 @@ Function Function::Analyze(const void* code, size_t size, size_t base) const auto* data = (uint32_t*)code; const auto* dataStart = data; const auto* dataEnd = (uint32_t*)((uint8_t*)code + size); - std::vector blockStack{}; + std::vector blockStack {}; blockStack.reserve(32); blockStack.emplace_back(); - #define RESTORE_DATA() if (!blockStack.empty()) data = (dataStart + ((blocks[blockStack.back()].base + blocks[blockStack.back()].size) / sizeof(*data))) - 1; // continue adds one +#define RESTORE_DATA() \ + if (!blockStack.empty()) \ + data = (dataStart + ((blocks[blockStack.back()].base + blocks[blockStack.back()].size) / sizeof(*data))) - 1; // continue adds one // TODO: Branch fallthrough - for (; data <= dataEnd ; ++data) + for (; data <= dataEnd; ++data) { const size_t addr = base + ((data - dataStart) * sizeof(*data)); if (blockStack.empty()) @@ -82,7 +84,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base) ppc::Disassemble(data, addr, insn); // Sanity check - assert(addr == base + curBlock.base + curBlock.size); + assert(addr == base + curBlock.base + curBlock.size); if (curBlock.projectedSize != -1 && curBlock.size >= curBlock.projectedSize) // fallthrough { blockStack.pop_back(); @@ -172,7 +174,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base) blocks.emplace_back(branchBase, 0, sizeProjection); blockStack.emplace_back(blocks.size() - 1); - + DEBUG(blocks.back().parent = blockBase); RESTORE_DATA(); continue; @@ -214,9 +216,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base) if (blocks.size() > 1) { std::sort(blocks.begin(), blocks.end(), [](const Block& a, const Block& b) - { - return a.base < b.base; - }); + { return a.base < b.base; }); size_t discontinuity = -1; for (size_t i = 0; i < blocks.size() - 1; i++) diff --git a/XenonAnalyse/function.h b/XenonAnalyse/function.h index 7df1c6ae..2249a95f 100644 --- a/XenonAnalyse/function.h +++ b/XenonAnalyse/function.h @@ -13,29 +13,29 @@ struct Function { struct Block { - size_t base{}; - size_t size{}; - size_t projectedSize{ static_cast(-1) }; // scratch - DEBUG(size_t parent{}); + size_t base {}; + size_t size {}; + size_t projectedSize { static_cast(-1) }; // scratch + DEBUG(size_t parent {}); - Block() + Block() { } Block(size_t base, size_t size) - : base(base), size(size) + : base(base), size(size) { } - Block(size_t base, size_t size, size_t projectedSize) + 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{}; + size_t base {}; + size_t size {}; + std::vector blocks {}; Function() { @@ -45,7 +45,7 @@ struct Function : 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/XenonAnalyse/main.cpp b/XenonAnalyse/main.cpp index d08371ef..cac60ae8 100644 --- a/XenonAnalyse/main.cpp +++ b/XenonAnalyse/main.cpp @@ -1,11 +1,11 @@ +#include "function.h" #include -#include -#include #include +#include +#include #include +#include #include -#include -#include "function.h" #define SWITCH_ABSOLUTE 0 #define SWITCH_COMPUTED 1 @@ -14,11 +14,11 @@ struct SwitchTable { - std::vector labels{}; - size_t base{}; - size_t defaultLabel{}; - uint32_t r{}; - uint32_t type{}; + std::vector labels {}; + size_t base {}; + size_t defaultLabel {}; + uint32_t r {}; + uint32_t type {}; }; void ReadTable(Image& image, SwitchTable& table) @@ -104,7 +104,7 @@ void ReadTable(Image& image, SwitchTable& table) void ScanTable(const uint32_t* code, size_t base, SwitchTable& table) { ppc_insn insn; - uint32_t cr{ (uint32_t)-1 }; + uint32_t cr { (uint32_t)-1 }; for (int i = 0; i < 32; i++) { ppc::Disassemble(&code[-i], base - (4 * i), insn); @@ -193,65 +193,64 @@ int main(int argc, char** argv) auto image = Image::ParseImage(file.data(), file.size()); auto printTable = [&](const SwitchTable& table) + { + println("[[switch]]"); + println("base = 0x{:X}", table.base); + println("r = {}", table.r); + println("default = 0x{:X}", table.defaultLabel); + println("labels = ["); + for (const auto& label : table.labels) { - println("[[switch]]"); - println("base = 0x{:X}", table.base); - println("r = {}", table.r); - println("default = 0x{:X}", table.defaultLabel); - println("labels = ["); - for (const auto& label : table.labels) - { - println(" 0x{:X},", label); - } + println(" 0x{:X},", label); + } - println("]"); - println(""); - }; + println("]"); + println(""); + }; - std::vector switches{}; + std::vector switches {}; println("# Generated by XenonAnalyse"); auto scanPattern = [&](uint32_t* pattern, size_t count, size_t type) + { + for (const auto& section : image.sections) { - for (const auto& section : image.sections) + if (!(section.flags & SectionFlags_Code)) { - if (!(section.flags & SectionFlags_Code)) - { - continue; - } + continue; + } - size_t base = section.base; - uint8_t* data = section.data; - uint8_t* dataStart = section.data; - uint8_t* dataEnd = section.data + section.size; - while (data < dataEnd && data != nullptr) + size_t base = section.base; + uint8_t* data = section.data; + uint8_t* dataStart = section.data; + uint8_t* dataEnd = section.data + section.size; + while (data < dataEnd && data != nullptr) + { + data = (uint8_t*)SearchMask(data, pattern, count, dataEnd - data); + + if (data != nullptr) { - data = (uint8_t*)SearchMask(data, pattern, count, dataEnd - data); + SwitchTable table {}; + table.type = type; + ScanTable((uint32_t*)data, base + (data - dataStart), table); - if (data != nullptr) + // fmt::println("{:X} ; jmptable - {}", base + (data - dataStart), table.labels.size()); + if (table.base != 0) { - SwitchTable table{}; - table.type = type; - ScanTable((uint32_t*)data, base + (data - dataStart), table); - - // fmt::println("{:X} ; jmptable - {}", base + (data - dataStart), table.labels.size()); - if (table.base != 0) - { - ReadTable(image, table); - printTable(table); - switches.emplace_back(std::move(table)); - } - - data += 4; + ReadTable(image, table); + printTable(table); + switches.emplace_back(std::move(table)); } - continue; + + data += 4; } + continue; } - }; + } + }; - uint32_t absoluteSwitch[] = - { + uint32_t absoluteSwitch[] = { PPC_INST_LIS, PPC_INST_ADDI, PPC_INST_RLWINM, @@ -260,8 +259,7 @@ int main(int argc, char** argv) PPC_INST_BCTR, }; - uint32_t computedSwitch[] = - { + uint32_t computedSwitch[] = { PPC_INST_LIS, PPC_INST_ADDI, PPC_INST_LBZX, @@ -272,8 +270,7 @@ int main(int argc, char** argv) PPC_INST_MTCTR, }; - uint32_t offsetSwitch[] = - { + uint32_t offsetSwitch[] = { PPC_INST_LIS, PPC_INST_ADDI, PPC_INST_LBZX, @@ -283,8 +280,7 @@ int main(int argc, char** argv) PPC_INST_MTCTR, }; - uint32_t wordOffsetSwitch[] = - { + uint32_t wordOffsetSwitch[] = { PPC_INST_LIS, PPC_INST_ADDI, PPC_INST_RLWINM, diff --git a/XenonRecomp/main.cpp b/XenonRecomp/main.cpp index 12c6d8ca..157b7f2e 100644 --- a/XenonRecomp/main.cpp +++ b/XenonRecomp/main.cpp @@ -11,12 +11,12 @@ int main(int argc, char* argv[]) } #endif - const char* path = - #ifdef XENON_RECOMP_CONFIG_FILE_PATH + const char* path = +#ifdef XENON_RECOMP_CONFIG_FILE_PATH XENON_RECOMP_CONFIG_FILE_PATH - #else +#else argv[1] - #endif +#endif ; if (std::filesystem::is_regular_file(path)) diff --git a/XenonRecomp/pch.h b/XenonRecomp/pch.h index 02e53d91..682a7907 100644 --- a/XenonRecomp/pch.h +++ b/XenonRecomp/pch.h @@ -2,11 +2,12 @@ #include #include -#include #include +#include #include #include #include +#include #include #include #include @@ -14,6 +15,5 @@ #include #include #include -#include -#include #include +#include diff --git a/XenonRecomp/recompiler.cpp b/XenonRecomp/recompiler.cpp index 53747975..bee06668 100644 --- a/XenonRecomp/recompiler.cpp +++ b/XenonRecomp/recompiler.cpp @@ -1,5 +1,5 @@ -#include "pch.h" #include "recompiler.h" +#include "pch.h" #include static uint64_t ComputeMask(uint32_t mstart, uint32_t mstop) @@ -104,7 +104,7 @@ void Recompiler::Analyse() auto& restgpr = functions.emplace_back(); restgpr.base = config.restGpr14Address + (i - 14) * 4; restgpr.size = (32 - i) * 4 + 12; - image.symbols.emplace(Symbol{ fmt::format("__restgprlr_{}", i), restgpr.base, restgpr.size, Symbol_Function }); + image.symbols.emplace(Symbol { fmt::format("__restgprlr_{}", i), restgpr.base, restgpr.size, Symbol_Function }); } if (config.saveGpr14Address != 0) @@ -251,7 +251,8 @@ void Recompiler::Analyse() } } - std::sort(functions.begin(), functions.end(), [](auto& lhs, auto& rhs) { return lhs.base < rhs.base; }); + std::sort(functions.begin(), functions.end(), [](auto& lhs, auto& rhs) + { return lhs.base < rhs.base; }); } bool Recompiler::Recompile( @@ -267,251 +268,251 @@ bool Recompiler::Recompile( // TODO: we could cache these formats in an array auto r = [&](size_t index) + { + if ((config.nonArgumentRegistersAsLocalVariables && (index == 0 || index == 2 || index == 11 || index == 12)) || + (config.nonVolatileRegistersAsLocalVariables && index >= 14)) { - if ((config.nonArgumentRegistersAsLocalVariables && (index == 0 || index == 2 || index == 11 || index == 12)) || - (config.nonVolatileRegistersAsLocalVariables && index >= 14)) - { - localVariables.r[index] = true; - return fmt::format("r{}", index); - } - return fmt::format("ctx.r{}", index); - }; + localVariables.r[index] = true; + return fmt::format("r{}", index); + } + return fmt::format("ctx.r{}", index); + }; auto f = [&](size_t index) + { + if ((config.nonArgumentRegistersAsLocalVariables && index == 0) || + (config.nonVolatileRegistersAsLocalVariables && index >= 14)) { - if ((config.nonArgumentRegistersAsLocalVariables && index == 0) || - (config.nonVolatileRegistersAsLocalVariables && index >= 14)) - { - localVariables.f[index] = true; - return fmt::format("f{}", index); - } - return fmt::format("ctx.f{}", index); - }; + localVariables.f[index] = true; + return fmt::format("f{}", index); + } + return fmt::format("ctx.f{}", index); + }; auto v = [&](size_t index) + { + if ((config.nonArgumentRegistersAsLocalVariables && (index >= 32 && index <= 63)) || + (config.nonVolatileRegistersAsLocalVariables && ((index >= 14 && index <= 31) || (index >= 64 && index <= 127)))) { - if ((config.nonArgumentRegistersAsLocalVariables && (index >= 32 && index <= 63)) || - (config.nonVolatileRegistersAsLocalVariables && ((index >= 14 && index <= 31) || (index >= 64 && index <= 127)))) - { - localVariables.v[index] = true; - return fmt::format("v{}", index); - } - return fmt::format("ctx.v{}", index); - }; + localVariables.v[index] = true; + return fmt::format("v{}", index); + } + return fmt::format("ctx.v{}", index); + }; auto cr = [&](size_t index) + { + if (config.crRegistersAsLocalVariables) { - if (config.crRegistersAsLocalVariables) - { - localVariables.cr[index] = true; - return fmt::format("cr{}", index); - } - return fmt::format("ctx.cr{}", index); - }; + localVariables.cr[index] = true; + return fmt::format("cr{}", index); + } + return fmt::format("ctx.cr{}", index); + }; auto ctr = [&]() + { + if (config.ctrAsLocalVariable) { - if (config.ctrAsLocalVariable) - { - localVariables.ctr = true; - return "ctr"; - } - return "ctx.ctr"; - }; + localVariables.ctr = true; + return "ctr"; + } + return "ctx.ctr"; + }; auto xer = [&]() + { + if (config.xerAsLocalVariable) { - if (config.xerAsLocalVariable) - { - localVariables.xer = true; - return "xer"; - } - return "ctx.xer"; - }; + localVariables.xer = true; + return "xer"; + } + return "ctx.xer"; + }; auto reserved = [&]() + { + if (config.reservedRegisterAsLocalVariable) { - if (config.reservedRegisterAsLocalVariable) - { - localVariables.reserved = true; - return "reserved"; - } - return "ctx.reserved"; - }; + localVariables.reserved = true; + return "reserved"; + } + return "ctx.reserved"; + }; auto temp = [&]() - { - localVariables.temp = true; - return "temp"; - }; + { + localVariables.temp = true; + return "temp"; + }; auto vTemp = [&]() - { - localVariables.vTemp = true; - return "vTemp"; - }; + { + localVariables.vTemp = true; + return "vTemp"; + }; auto env = [&]() - { - localVariables.env = true; - return "env"; - }; + { + localVariables.env = true; + return "env"; + }; auto ea = [&]() - { - localVariables.ea = true; - return "ea"; - }; + { + localVariables.ea = true; + return "ea"; + }; // TODO (Sajid): Check for out of bounds access auto mmioStore = [&]() -> bool - { - return *(data + 1) == c_eieio; - }; + { + return *(data + 1) == c_eieio; + }; auto printFunctionCall = [&](uint32_t address) + { + if (address == config.longJmpAddress) { - if (address == config.longJmpAddress) - { - println("\tlongjmp(*reinterpret_cast(base + {}.u32), {}.s32);", r(3), r(4)); - } - else if (address == config.setJmpAddress) - { - println("\t{} = ctx;", env()); - println("\t{}.s64 = setjmp(*reinterpret_cast(base + {}.u32));", r(3), r(3)); - println("\tif ({}.s64 != 0) ctx = {};", r(3), env()); - } - else - { - auto targetSymbol = image.symbols.find(address); + println("\tlongjmp(*reinterpret_cast(base + {}.u32), {}.s32);", r(3), r(4)); + } + else if (address == config.setJmpAddress) + { + println("\t{} = ctx;", env()); + println("\t{}.s64 = setjmp(*reinterpret_cast(base + {}.u32));", r(3), r(3)); + println("\tif ({}.s64 != 0) ctx = {};", r(3), env()); + } + else + { + auto targetSymbol = image.symbols.find(address); - if (targetSymbol != image.symbols.end() && targetSymbol->address == address && targetSymbol->type == Symbol_Function) + if (targetSymbol != image.symbols.end() && targetSymbol->address == address && targetSymbol->type == Symbol_Function) + { + if (config.nonVolatileRegistersAsLocalVariables && (targetSymbol->name.find("__rest") == 0 || targetSymbol->name.find("__save") == 0)) { - if (config.nonVolatileRegistersAsLocalVariables && (targetSymbol->name.find("__rest") == 0 || targetSymbol->name.find("__save") == 0)) - { - // print nothing - } - else - { - println("\t{}(ctx, base);", targetSymbol->name); - } + // print nothing } else { - println("\t// ERROR {:X}", address); + println("\t{}(ctx, base);", targetSymbol->name); } } - }; - - auto printConditionalBranch = [&](bool not_, const std::string_view& cond) - { - if (insn.operands[1] < fn.base || insn.operands[1] >= fn.base + fn.size) - { - println("\tif ({}{}.{}) {{", not_ ? "!" : "", cr(insn.operands[0]), cond); - print("\t"); - printFunctionCall(insn.operands[1]); - println("\t\treturn;"); - println("\t}}"); - } else { - println("\tif ({}{}.{}) goto loc_{:X};", not_ ? "!" : "", cr(insn.operands[0]), cond, insn.operands[1]); + println("\t// ERROR {:X}", address); } - }; + } + }; + + auto printConditionalBranch = [&](bool not_, const std::string_view& cond) + { + if (insn.operands[1] < fn.base || insn.operands[1] >= fn.base + fn.size) + { + println("\tif ({}{}.{}) {{", not_ ? "!" : "", cr(insn.operands[0]), cond); + print("\t"); + printFunctionCall(insn.operands[1]); + println("\t\treturn;"); + println("\t}}"); + } + else + { + println("\tif ({}{}.{}) goto loc_{:X};", not_ ? "!" : "", cr(insn.operands[0]), cond, insn.operands[1]); + } + }; auto printSetFlushMode = [&](bool enable) + { + auto newState = enable ? CSRState::VMX : CSRState::FPU; + if (csrState != newState) { - auto newState = enable ? CSRState::VMX : CSRState::FPU; - if (csrState != newState) - { - auto prefix = enable ? "enable" : "disable"; - auto suffix = csrState != CSRState::Unknown ? "Unconditional" : ""; - println("\tctx.fpscr.{}FlushMode{}();", prefix, suffix); + auto prefix = enable ? "enable" : "disable"; + auto suffix = csrState != CSRState::Unknown ? "Unconditional" : ""; + println("\tctx.fpscr.{}FlushMode{}();", prefix, suffix); - csrState = newState; - } - }; + csrState = newState; + } + }; auto midAsmHook = config.midAsmHooks.find(base); auto printMidAsmHook = [&]() - { - bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue || - midAsmHook->second.jumpAddressOnFalse != NULL || midAsmHook->second.jumpAddressOnTrue != NULL; + { + bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue || + midAsmHook->second.jumpAddressOnFalse != NULL || midAsmHook->second.jumpAddressOnTrue != NULL; - print("\t"); - if (returnsBool) - print("if ("); + print("\t"); + if (returnsBool) + print("if ("); - print("{}(", midAsmHook->second.name); - for (auto& reg : midAsmHook->second.registers) - { - if (out.back() != '(') - out += ", "; + print("{}(", midAsmHook->second.name); + for (auto& reg : midAsmHook->second.registers) + { + if (out.back() != '(') + out += ", "; - switch (reg[0]) - { - case 'c': - if (reg == "ctr") - out += ctr(); - else - out += cr(std::atoi(reg.c_str() + 2)); - break; + switch (reg[0]) + { + case 'c': + if (reg == "ctr") + out += ctr(); + else + out += cr(std::atoi(reg.c_str() + 2)); + break; - case 'x': - out += xer(); - break; + case 'x': + out += xer(); + break; - case 'r': - if (reg == "reserved") - out += reserved(); - else - out += r(std::atoi(reg.c_str() + 1)); - break; + case 'r': + if (reg == "reserved") + out += reserved(); + else + out += r(std::atoi(reg.c_str() + 1)); + break; - case 'f': - if (reg == "fpscr") - out += "ctx.fpscr"; - else - out += f(std::atoi(reg.c_str() + 1)); - break; + case 'f': + if (reg == "fpscr") + out += "ctx.fpscr"; + else + out += f(std::atoi(reg.c_str() + 1)); + break; - case 'v': - out += v(std::atoi(reg.c_str() + 1)); - break; - } + case 'v': + out += v(std::atoi(reg.c_str() + 1)); + break; } + } - if (returnsBool) - { - println(")) {{"); + if (returnsBool) + { + println(")) {{"); - if (midAsmHook->second.returnOnTrue) - println("\t\treturn;"); - else if (midAsmHook->second.jumpAddressOnTrue != NULL) - println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue); + if (midAsmHook->second.returnOnTrue) + println("\t\treturn;"); + else if (midAsmHook->second.jumpAddressOnTrue != NULL) + println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue); - println("\t}}"); + println("\t}}"); - println("\telse {{"); + println("\telse {{"); - if (midAsmHook->second.returnOnFalse) - println("\t\treturn;"); - else if (midAsmHook->second.jumpAddressOnFalse != NULL) - println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse); + if (midAsmHook->second.returnOnFalse) + println("\t\treturn;"); + else if (midAsmHook->second.jumpAddressOnFalse != NULL) + println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse); - println("\t}}"); - } - else - { - println(");"); + println("\t}}"); + } + else + { + println(");"); - if (midAsmHook->second.ret) - println("\treturn;"); - else if (midAsmHook->second.jumpAddress != NULL) - println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress); - } - }; + if (midAsmHook->second.ret) + println("\treturn;"); + else if (midAsmHook->second.jumpAddress != NULL) + println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress); + } + }; if (midAsmHook != config.midAsmHooks.end() && !midAsmHook->second.afterInstruction) printMidAsmHook(); @@ -519,8 +520,10 @@ bool Recompiler::Recompile( int id = insn.opcode->id; // Handling instructions that don't disassemble correctly for some reason here - if (id == PPC_INST_VUPKHSB128 && insn.operands[2] == 0x60) id = PPC_INST_VUPKHSH128; - else if (id == PPC_INST_VUPKLSB128 && insn.operands[2] == 0x60) id = PPC_INST_VUPKLSH128; + if (id == PPC_INST_VUPKHSB128 && insn.operands[2] == 0x60) + id = PPC_INST_VUPKHSH128; + else if (id == PPC_INST_VUPKLSB128 && insn.operands[2] == 0x60) + id = PPC_INST_VUPKLSH128; switch (id) { @@ -2255,7 +2258,7 @@ bool Recompiler::Recompile( if (midAsmHook != config.midAsmHooks.end() && midAsmHook->second.afterInstruction) printMidAsmHook(); - + return true; } @@ -2339,9 +2342,9 @@ bool Recompiler::Recompile(const Function& fn) println(");\n"); if (midAsmHook->second.jumpAddress != NULL) - labels.emplace(midAsmHook->second.jumpAddress); + labels.emplace(midAsmHook->second.jumpAddress); if (midAsmHook->second.jumpAddressOnTrue != NULL) - labels.emplace(midAsmHook->second.jumpAddressOnTrue); + labels.emplace(midAsmHook->second.jumpAddressOnTrue); if (midAsmHook->second.jumpAddressOnFalse != NULL) labels.emplace(midAsmHook->second.jumpAddressOnFalse); } @@ -2430,7 +2433,7 @@ bool Recompiler::Recompile(const Function& fn) std::swap(out, tempString); if (localVariables.ctr) - println("\tPPCRegister ctr{{}};"); + println("\tPPCRegister ctr{{}};"); if (localVariables.xer) println("\tPPCXERRegister xer{{}};"); if (localVariables.reserved) @@ -2461,11 +2464,11 @@ bool Recompiler::Recompile(const Function& fn) } if (localVariables.env) - println("\tPPCContext env{{}};"); - + println("\tPPCContext env{{}};"); + if (localVariables.temp) - println("\tPPCRegister temp{{}};"); - + println("\tPPCRegister temp{{}};"); + if (localVariables.vTemp) println("\tPPCVRegister vTemp{{}};"); @@ -2488,19 +2491,19 @@ void Recompiler::Recompile(const std::filesystem::path& headerFilePath) println("#define PPC_CONFIG_H_INCLUDED\n"); if (config.skipLr) - println("#define PPC_CONFIG_SKIP_LR"); + println("#define PPC_CONFIG_SKIP_LR"); if (config.ctrAsLocalVariable) - println("#define PPC_CONFIG_CTR_AS_LOCAL"); + println("#define PPC_CONFIG_CTR_AS_LOCAL"); if (config.xerAsLocalVariable) - println("#define PPC_CONFIG_XER_AS_LOCAL"); + println("#define PPC_CONFIG_XER_AS_LOCAL"); if (config.reservedRegisterAsLocalVariable) - println("#define PPC_CONFIG_RESERVED_AS_LOCAL"); + println("#define PPC_CONFIG_RESERVED_AS_LOCAL"); if (config.skipMsr) - println("#define PPC_CONFIG_SKIP_MSR"); + println("#define PPC_CONFIG_SKIP_MSR"); if (config.crRegistersAsLocalVariables) - println("#define PPC_CONFIG_CR_AS_LOCAL"); + println("#define PPC_CONFIG_CR_AS_LOCAL"); if (config.nonArgumentRegistersAsLocalVariables) - println("#define PPC_CONFIG_NON_ARGUMENT_AS_LOCAL"); + println("#define PPC_CONFIG_NON_ARGUMENT_AS_LOCAL"); if (config.nonVolatileRegistersAsLocalVariables) println("#define PPC_CONFIG_NON_VOLATILE_AS_LOCAL"); @@ -2508,7 +2511,7 @@ void Recompiler::Recompile(const std::filesystem::path& headerFilePath) println("#define PPC_IMAGE_BASE 0x{:X}ull", image.base); println("#define PPC_IMAGE_SIZE 0x{:X}ull", image.size); - + // Extract the address of the minimum code segment to store the function table at. size_t codeMin = ~0; size_t codeMax = 0; @@ -2543,7 +2546,7 @@ void Recompiler::Recompile(const std::filesystem::path& headerFilePath) println("#pragma once"); println("#include \"ppc_config.h\"\n"); - + std::ifstream stream(headerFilePath); if (stream.good()) { diff --git a/XenonRecomp/recompiler.h b/XenonRecomp/recompiler.h index 8242db53..2ed69823 100644 --- a/XenonRecomp/recompiler.h +++ b/XenonRecomp/recompiler.h @@ -5,17 +5,17 @@ struct RecompilerLocalVariables { - bool ctr{}; - bool xer{}; - bool reserved{}; - bool cr[8]{}; - bool r[32]{}; - bool f[32]{}; - bool v[128]{}; - bool env{}; - bool temp{}; - bool vTemp{}; - bool ea{}; + bool ctr {}; + bool xer {}; + bool reserved {}; + bool cr[8] {}; + bool r[32] {}; + bool f[32] {}; + bool v[128] {}; + bool env {}; + bool temp {}; + bool vTemp {}; + bool ea {}; }; enum class CSRState diff --git a/XenonRecomp/recompiler_config.cpp b/XenonRecomp/recompiler_config.cpp index 81330a47..f24306d0 100644 --- a/XenonRecomp/recompiler_config.cpp +++ b/XenonRecomp/recompiler_config.cpp @@ -5,7 +5,7 @@ void RecompilerConfig::Load(const std::string_view& configFilePath) directoryPath = configFilePath.substr(0, configFilePath.find_last_of("\\/") + 1); toml::table toml = toml::parse_file(configFilePath) #if !TOML_EXCEPTIONS - .table() + .table() #endif ; @@ -38,14 +38,22 @@ void RecompilerConfig::Load(const std::string_view& configFilePath) longJmpAddress = main["longjmp_address"].value_or(0u); setJmpAddress = main["setjmp_address"].value_or(0u); - if (restGpr14Address == 0) fmt::println("ERROR: __restgprlr_14 address is unspecified"); - if (saveGpr14Address == 0) fmt::println("ERROR: __savegprlr_14 address is unspecified"); - if (restFpr14Address == 0) fmt::println("ERROR: __restfpr_14 address is unspecified"); - if (saveFpr14Address == 0) fmt::println("ERROR: __savefpr_14 address is unspecified"); - if (restVmx14Address == 0) fmt::println("ERROR: __restvmx_14 address is unspecified"); - if (saveVmx14Address == 0) fmt::println("ERROR: __savevmx_14 address is unspecified"); - if (restVmx64Address == 0) fmt::println("ERROR: __restvmx_64 address is unspecified"); - if (saveVmx64Address == 0) fmt::println("ERROR: __savevmx_64 address is unspecified"); + if (restGpr14Address == 0) + fmt::println("ERROR: __restgprlr_14 address is unspecified"); + if (saveGpr14Address == 0) + fmt::println("ERROR: __savegprlr_14 address is unspecified"); + if (restFpr14Address == 0) + fmt::println("ERROR: __restfpr_14 address is unspecified"); + if (saveFpr14Address == 0) + fmt::println("ERROR: __savefpr_14 address is unspecified"); + if (restVmx14Address == 0) + fmt::println("ERROR: __restvmx_14 address is unspecified"); + if (saveVmx14Address == 0) + fmt::println("ERROR: __savevmx_14 address is unspecified"); + if (restVmx64Address == 0) + fmt::println("ERROR: __restvmx_64 address is unspecified"); + if (saveVmx64Address == 0) + fmt::println("ERROR: __savevmx_64 address is unspecified"); if (auto functionsArray = main["functions"].as_array()) { @@ -73,7 +81,7 @@ void RecompilerConfig::Load(const std::string_view& configFilePath) { toml::table switchToml = toml::parse_file(directoryPath + switchTableFilePath) #if !TOML_EXCEPTIONS - .table() + .table() #endif ; if (auto switchArray = switchToml["switch"].as_array()) diff --git a/XenonRecomp/test_recompiler.cpp b/XenonRecomp/test_recompiler.cpp index f4fcdfef..125ec317 100644 --- a/XenonRecomp/test_recompiler.cpp +++ b/XenonRecomp/test_recompiler.cpp @@ -23,13 +23,14 @@ void TestRecompiler::Analyse(const std::string_view& testName) auto& fn = functions.emplace_back(Function::Analyze(data, dataEnd - data, base)); image.symbols.emplace(fmt::format("{}_{:X}", testName, fn.base), fn.base, fn.size, Symbol_Function); - + base += fn.size; data += fn.size; } } - std::sort(functions.begin(), functions.end(), [](auto& lhs, auto& rhs) { return lhs.base < rhs.base; }); + std::sort(functions.begin(), functions.end(), [](auto& lhs, auto& rhs) + { return lhs.base < rhs.base; }); } void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* dstDirectoryPath) @@ -118,15 +119,15 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds { std::string str; auto getline = [&]() + { + if (std::getline(in, str)) { - if (std::getline(in, str)) - { - str.erase(str.find_last_not_of(' ') + 1); - str.erase(0, str.find_first_not_of(' ')); - return true; - } - return false; - }; + str.erase(str.find_last_not_of(' ') + 1); + str.erase(0, str.find_first_not_of(' ')); + return true; + } + return false; + }; while (getline()) { diff --git a/XenonRecomp/test_recompiler.h b/XenonRecomp/test_recompiler.h index 2ef368c2..dc9527ff 100644 --- a/XenonRecomp/test_recompiler.h +++ b/XenonRecomp/test_recompiler.h @@ -5,6 +5,6 @@ struct TestRecompiler : Recompiler { void Analyse(const std::string_view& testName); void Reset(); - + static void RecompileTests(const char* srcDirectoryPath, const char* dstDirectoryPath); }; diff --git a/XenonUtils/byteswap.h b/XenonUtils/byteswap.h index 33e959fc..e2d9ec9e 100644 --- a/XenonUtils/byteswap.h +++ b/XenonUtils/byteswap.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include diff --git a/XenonUtils/disasm.cpp b/XenonUtils/disasm.cpp index 4610b9be..54b772f7 100644 --- a/XenonUtils/disasm.cpp +++ b/XenonUtils/disasm.cpp @@ -1,6 +1,6 @@ #include "disasm.h" -thread_local ppc::DisassemblerEngine ppc::gBigEndianDisassembler{ BFD_ENDIAN_BIG, "cell 64"}; +thread_local ppc::DisassemblerEngine ppc::gBigEndianDisassembler { BFD_ENDIAN_BIG, "cell 64" }; ppc::DisassemblerEngine::DisassemblerEngine(bfd_endian endian, const char* options) { diff --git a/XenonUtils/disasm.h b/XenonUtils/disasm.h index 195bc857..fb1095f0 100644 --- a/XenonUtils/disasm.h +++ b/XenonUtils/disasm.h @@ -4,32 +4,32 @@ namespace ppc { - struct DisassemblerEngine - { - disassemble_info info{}; - DisassemblerEngine(const DisassemblerEngine&) = default; - DisassemblerEngine& operator=(const DisassemblerEngine&) = delete; - - DisassemblerEngine(bfd_endian endian, const char* options); - ~DisassemblerEngine() = default; +struct DisassemblerEngine +{ + disassemble_info info {}; + DisassemblerEngine(const DisassemblerEngine&) = default; + DisassemblerEngine& operator=(const DisassemblerEngine&) = delete; - /** - * \return Numbers of bytes decoded - */ - int Disassemble(const void* code, size_t size, uint64_t base, ppc_insn& out); - }; + DisassemblerEngine(bfd_endian endian, const char* options); + ~DisassemblerEngine() = default; - thread_local extern DisassemblerEngine gBigEndianDisassembler; + /** + * \return Numbers of bytes decoded + */ + int Disassemble(const void* code, size_t size, uint64_t base, ppc_insn& out); +}; - static int Disassemble(const void* code, size_t size, uint64_t base, ppc_insn& out) - { - return gBigEndianDisassembler.Disassemble(code, size, base, out); - } +thread_local extern DisassemblerEngine gBigEndianDisassembler; - static int Disassemble(const void* code, uint64_t base, ppc_insn& out) - { - return Disassemble(code, 4, base, out); - } +static int Disassemble(const void* code, size_t size, uint64_t base, ppc_insn& out) +{ + return gBigEndianDisassembler.Disassemble(code, size, base, out); +} - static int Disassemble(const void* code, uint64_t base, ppc_insn* out, size_t nOut); +static int Disassemble(const void* code, uint64_t base, ppc_insn& out) +{ + return Disassemble(code, 4, base, out); } + +static int Disassemble(const void* code, uint64_t base, ppc_insn* out, size_t nOut); +} // namespace ppc diff --git a/XenonUtils/elf.h b/XenonUtils/elf.h index 72922670..d41eec0b 100644 --- a/XenonUtils/elf.h +++ b/XenonUtils/elf.h @@ -12,43 +12,42 @@ typedef unsigned long long __u64; typedef signed long long __s64; /* 32-bit ELF base types. */ -typedef __u32 Elf32_Addr; -typedef __u16 Elf32_Half; -typedef __u32 Elf32_Off; -typedef __s32 Elf32_Sword; -typedef __u32 Elf32_Word; +typedef __u32 Elf32_Addr; +typedef __u16 Elf32_Half; +typedef __u32 Elf32_Off; +typedef __s32 Elf32_Sword; +typedef __u32 Elf32_Word; /* 64-bit ELF base types. */ -typedef __u64 Elf64_Addr; -typedef __u16 Elf64_Half; -typedef __s16 Elf64_SHalf; -typedef __u64 Elf64_Off; -typedef __s32 Elf64_Sword; -typedef __u32 Elf64_Word; -typedef __u64 Elf64_Xword; -typedef __s64 Elf64_Sxword; +typedef __u64 Elf64_Addr; +typedef __u16 Elf64_Half; +typedef __s16 Elf64_SHalf; +typedef __u64 Elf64_Off; +typedef __s32 Elf64_Sword; +typedef __u32 Elf64_Word; +typedef __u64 Elf64_Xword; +typedef __s64 Elf64_Sxword; /* These constants are for the segment types stored in the image headers */ -#define PT_NULL 0 -#define PT_LOAD 1 +#define PT_NULL 0 +#define PT_LOAD 1 #define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_TLS 7 /* Thread local storage segment */ -#define PT_LOOS 0x60000000 /* OS-specific */ -#define PT_HIOS 0x6fffffff /* OS-specific */ -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff -#define PT_GNU_EH_FRAME (PT_LOOS + 0x474e550) -#define PT_GNU_STACK (PT_LOOS + 0x474e551) -#define PT_GNU_RELRO (PT_LOOS + 0x474e552) -#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553) - +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 /* Thread local storage segment */ +#define PT_LOOS 0x60000000 /* OS-specific */ +#define PT_HIOS 0x6fffffff /* OS-specific */ +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff +#define PT_GNU_EH_FRAME (PT_LOOS + 0x474e550) +#define PT_GNU_STACK (PT_LOOS + 0x474e551) +#define PT_GNU_RELRO (PT_LOOS + 0x474e552) +#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553) /* ARM MTE memory tag segment type */ -#define PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 0x2) +#define PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 0x2) /* * Extended Numbering @@ -72,91 +71,95 @@ typedef __s64 Elf64_Sxword; */ #define PN_XNUM 0xffff - /* These constants define the different elf file types */ -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 +/* These constants define the different elf file types */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 #define ET_LOPROC 0xff00 #define ET_HIPROC 0xffff /* This is the info that is needed to parse the dynamic section of the file */ -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_ENCODING 32 -#define OLD_DT_LOOS 0x60000000 -#define DT_LOOS 0x6000000d -#define DT_HIOS 0x6ffff000 -#define DT_VALRNGLO 0x6ffffd00 -#define DT_VALRNGHI 0x6ffffdff -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_ADDRRNGHI 0x6ffffeff -#define DT_VERSYM 0x6ffffff0 -#define DT_RELACOUNT 0x6ffffff9 -#define DT_RELCOUNT 0x6ffffffa -#define DT_FLAGS_1 0x6ffffffb -#define DT_VERDEF 0x6ffffffc -#define DT_VERDEFNUM 0x6ffffffd -#define DT_VERNEED 0x6ffffffe -#define DT_VERNEEDNUM 0x6fffffff -#define OLD_DT_HIOS 0x6fffffff -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_ENCODING 32 +#define OLD_DT_LOOS 0x60000000 +#define DT_LOOS 0x6000000d +#define DT_HIOS 0x6ffff000 +#define DT_VALRNGLO 0x6ffffd00 +#define DT_VALRNGHI 0x6ffffdff +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_VERSYM 0x6ffffff0 +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa +#define DT_FLAGS_1 0x6ffffffb +#define DT_VERDEF 0x6ffffffc +#define DT_VERDEFNUM 0x6ffffffd +#define DT_VERNEED 0x6ffffffe +#define DT_VERNEEDNUM 0x6fffffff +#define OLD_DT_HIOS 0x6fffffff +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff /* This info is needed when parsing the symbol table */ -#define STB_LOCAL 0 +#define STB_LOCAL 0 #define STB_GLOBAL 1 -#define STB_WEAK 2 +#define STB_WEAK 2 -#define STT_NOTYPE 0 -#define STT_OBJECT 1 -#define STT_FUNC 2 +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 #define STT_SECTION 3 -#define STT_FILE 4 -#define STT_COMMON 5 -#define STT_TLS 6 - -#define ELF_ST_BIND(x) ((x) >> 4) -#define ELF_ST_TYPE(x) ((x) & 0xf) -#define ELF32_ST_BIND(x) ELF_ST_BIND(x) -#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x) -#define ELF64_ST_BIND(x) ELF_ST_BIND(x) -#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x) - -typedef struct { +#define STT_FILE 4 +#define STT_COMMON 5 +#define STT_TLS 6 + +#define ELF_ST_BIND(x) ((x) >> 4) +#define ELF_ST_TYPE(x) ((x) & 0xf) +#define ELF32_ST_BIND(x) ELF_ST_BIND(x) +#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x) +#define ELF64_ST_BIND(x) ELF_ST_BIND(x) +#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x) + +typedef struct +{ Elf32_Sword d_tag; - union { - Elf32_Sword d_val; - Elf32_Addr d_ptr; + union + { + Elf32_Sword d_val; + Elf32_Addr d_ptr; } d_un; } Elf32_Dyn; -typedef struct { - Elf64_Sxword d_tag; /* entry tag value */ - union { +typedef struct +{ + Elf64_Sxword d_tag; /* entry tag value */ + union + { Elf64_Xword d_val; Elf64_Addr d_ptr; } d_un; @@ -166,77 +169,84 @@ typedef struct { #define ELF32_R_SYM(x) ((x) >> 8) #define ELF32_R_TYPE(x) ((x) & 0xff) -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -typedef struct elf32_rel { - Elf32_Addr r_offset; - Elf32_Word r_info; +typedef struct elf32_rel +{ + Elf32_Addr r_offset; + Elf32_Word r_info; } Elf32_Rel; -typedef struct elf64_rel { - Elf64_Addr r_offset; /* Location at which to apply the action */ - Elf64_Xword r_info; /* index and type of relocation */ +typedef struct elf64_rel +{ + Elf64_Addr r_offset; /* Location at which to apply the action */ + Elf64_Xword r_info; /* index and type of relocation */ } Elf64_Rel; -typedef struct elf32_rela { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; +typedef struct elf32_rela +{ + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; } Elf32_Rela; -typedef struct elf64_rela { - Elf64_Addr r_offset; /* Location at which to apply the action */ - Elf64_Xword r_info; /* index and type of relocation */ - Elf64_Sxword r_addend; /* Constant addend used to compute value */ +typedef struct elf64_rela +{ + Elf64_Addr r_offset; /* Location at which to apply the action */ + Elf64_Xword r_info; /* index and type of relocation */ + Elf64_Sxword r_addend; /* Constant addend used to compute value */ } Elf64_Rela; -typedef struct elf32_sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; +typedef struct elf32_sym +{ + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; } Elf32_Sym; -typedef struct elf64_sym { - Elf64_Word st_name; /* Symbol name, index in string tbl */ - unsigned char st_info; /* Type and binding attributes */ - unsigned char st_other; /* No defined meaning, 0 */ - Elf64_Half st_shndx; /* Associated section index */ - Elf64_Addr st_value; /* Value of the symbol */ - Elf64_Xword st_size; /* Associated symbol size */ +typedef struct elf64_sym +{ + Elf64_Word st_name; /* Symbol name, index in string tbl */ + unsigned char st_info; /* Type and binding attributes */ + unsigned char st_other; /* No defined meaning, 0 */ + Elf64_Half st_shndx; /* Associated section index */ + Elf64_Addr st_value; /* Value of the symbol */ + Elf64_Xword st_size; /* Associated symbol size */ } Elf64_Sym; - -#define EI_NIDENT 16 - -typedef struct elf32_hdr { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; /* Entry point */ - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; +#define EI_NIDENT 16 + +typedef struct elf32_hdr +{ + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; /* Entry point */ + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; } Elf32_Ehdr; -typedef struct elf64_hdr { - unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ +typedef struct elf64_hdr +{ + unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; - Elf64_Addr e_entry; /* Entry point virtual address */ - Elf64_Off e_phoff; /* Program header table file offset */ - Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; @@ -248,127 +258,131 @@ typedef struct elf64_hdr { /* These constants define the permissions on sections in the program header, p_flags. */ -#define PF_R 0x4 -#define PF_W 0x2 -#define PF_X 0x1 - -typedef struct elf32_phdr { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; +#define PF_R 0x4 +#define PF_W 0x2 +#define PF_X 0x1 + +typedef struct elf32_phdr +{ + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; } Elf32_Phdr; -typedef struct elf64_phdr { +typedef struct elf64_phdr +{ Elf64_Word p_type; Elf64_Word p_flags; - Elf64_Off p_offset; /* Segment file offset */ - Elf64_Addr p_vaddr; /* Segment virtual address */ - Elf64_Addr p_paddr; /* Segment physical address */ - Elf64_Xword p_filesz; /* Segment size in file */ - Elf64_Xword p_memsz; /* Segment size in memory */ - Elf64_Xword p_align; /* Segment alignment, file & memory */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment, file & memory */ } Elf64_Phdr; /* sh_type */ -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_NUM 12 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_NUM 12 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff /* sh_flags */ -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_RELA_LIVEPATCH 0x00100000 -#define SHF_RO_AFTER_INIT 0x00200000 -#define SHF_MASKPROC 0xf0000000 +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_RELA_LIVEPATCH 0x00100000 +#define SHF_RO_AFTER_INIT 0x00200000 +#define SHF_MASKPROC 0xf0000000 /* special section indexes */ -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_LIVEPATCH 0xff20 -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - -typedef struct elf32_shdr { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_LIVEPATCH 0xff20 +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +typedef struct elf32_shdr +{ + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; } Elf32_Shdr; -typedef struct elf64_shdr { - Elf64_Word sh_name; /* Section name, index in string tbl */ - Elf64_Word sh_type; /* Type of section */ - Elf64_Xword sh_flags; /* Miscellaneous section attributes */ - Elf64_Addr sh_addr; /* Section virtual addr at execution */ - Elf64_Off sh_offset; /* Section file offset */ - Elf64_Xword sh_size; /* Size of section in bytes */ - Elf64_Word sh_link; /* Index of another section */ - Elf64_Word sh_info; /* Additional section information */ - Elf64_Xword sh_addralign; /* Section alignment */ - Elf64_Xword sh_entsize; /* Entry size if section holds table */ +typedef struct elf64_shdr +{ + Elf64_Word sh_name; /* Section name, index in string tbl */ + Elf64_Word sh_type; /* Type of section */ + Elf64_Xword sh_flags; /* Miscellaneous section attributes */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Size of section in bytes */ + Elf64_Word sh_link; /* Index of another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ } Elf64_Shdr; -#define EI_MAG0 0 /* e_ident[] indexes */ -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_OSABI 7 -#define EI_PAD 8 - -#define ELFMAG0 0x7f /* EI_MAG */ -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define ELFCLASSNONE 0 /* EI_CLASS */ -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFCLASSNUM 3 - -#define ELFDATANONE 0 /* e_ident[EI_DATA] */ -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 - -#define EV_NONE 0 /* e_version, EI_VERSION */ -#define EV_CURRENT 1 -#define EV_NUM 2 - -#define ELFOSABI_NONE 0 -#define ELFOSABI_LINUX 3 +#define EI_MAG0 0 /* e_ident[] indexes */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_PAD 8 + +#define ELFMAG0 0x7f /* EI_MAG */ +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define ELFCLASSNONE 0 /* EI_CLASS */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 /* e_version, EI_VERSION */ +#define EV_CURRENT 1 +#define EV_NUM 2 + +#define ELFOSABI_NONE 0 +#define ELFOSABI_LINUX 3 #ifndef ELF_OSABI #define ELF_OSABI ELFOSABI_NONE @@ -381,108 +395,110 @@ typedef struct elf64_shdr { * The note name for these types is "LINUX", except NT_PRFPREG that is named * "CORE". */ -#define NT_PRSTATUS 1 -#define NT_PRFPREG 2 -#define NT_PRPSINFO 3 -#define NT_TASKSTRUCT 4 -#define NT_AUXV 6 - /* - * Note to userspace developers: size of NT_SIGINFO note may increase - * in the future to accomodate more fields, don't assume it is fixed! - */ -#define NT_SIGINFO 0x53494749 -#define NT_FILE 0x46494c45 -#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ -#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -#define NT_PPC_TAR 0x103 /* Target Address Register */ -#define NT_PPC_PPR 0x104 /* Program Priority Register */ -#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */ -#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */ -#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */ -#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */ -#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */ -#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */ -#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */ -#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */ -#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address Register */ -#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority Register */ -#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control Register */ -#define NT_PPC_PKEY 0x110 /* Memory Protection Keys registers */ -#define NT_PPC_DEXCR 0x111 /* PowerPC DEXCR registers */ -#define NT_PPC_HASHKEYR 0x112 /* PowerPC HASHKEYR register */ -#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ - /* Old binutils treats 0x203 as a CET state */ -#define NT_X86_SHSTK 0x204 /* x86 SHSTK state */ -#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ -#define NT_S390_TIMER 0x301 /* s390 timer register */ -#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ -#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ -#define NT_S390_CTRS 0x304 /* s390 control registers */ -#define NT_S390_PREFIX 0x305 /* s390 prefix register */ -#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ -#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ -#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */ -#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 upper half */ -#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */ -#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */ -#define NT_S390_GS_BC 0x30c /* s390 guarded storage broadcast control block */ -#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation */ -#define NT_S390_PV_CPU_DATA 0x30e /* s390 protvirt cpu dump data */ -#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ -#define NT_ARM_TLS 0x401 /* ARM TLS register */ -#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ -#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ -#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ -#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension registers */ -#define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication code masks */ -#define NT_ARM_PACA_KEYS 0x407 /* ARM pointer authentication address keys */ -#define NT_ARM_PACG_KEYS 0x408 /* ARM pointer authentication generic key */ -#define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* arm64 tagged address control (prctl()) */ -#define NT_ARM_PAC_ENABLED_KEYS 0x40a /* arm64 ptr auth enabled keys (prctl()) */ -#define NT_ARM_SSVE 0x40b /* ARM Streaming SVE registers */ -#define NT_ARM_ZA 0x40c /* ARM SME ZA registers */ -#define NT_ARM_ZT 0x40d /* ARM SME ZT registers */ -#define NT_ARM_FPMR 0x40e /* ARM floating point mode register */ -#define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */ -#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */ -#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */ -#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode */ -#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers */ -#define NT_RISCV_CSR 0x900 /* RISC-V Control and Status Registers */ -#define NT_RISCV_VECTOR 0x901 /* RISC-V vector registers */ -#define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers */ -#define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and status registers */ -#define NT_LOONGARCH_LSX 0xa02 /* LoongArch Loongson SIMD Extension registers */ -#define NT_LOONGARCH_LASX 0xa03 /* LoongArch Loongson Advanced SIMD Extension registers */ -#define NT_LOONGARCH_LBT 0xa04 /* LoongArch Loongson Binary Translation registers */ -#define NT_LOONGARCH_HW_BREAK 0xa05 /* LoongArch hardware breakpoint registers */ -#define NT_LOONGARCH_HW_WATCH 0xa06 /* LoongArch hardware watchpoint registers */ +#define NT_PRSTATUS 1 +#define NT_PRFPREG 2 +#define NT_PRPSINFO 3 +#define NT_TASKSTRUCT 4 +#define NT_AUXV 6 +/* + * Note to userspace developers: size of NT_SIGINFO note may increase + * in the future to accomodate more fields, don't assume it is fixed! + */ +#define NT_SIGINFO 0x53494749 +#define NT_FILE 0x46494c45 +#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ +#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ +#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ +#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +#define NT_PPC_TAR 0x103 /* Target Address Register */ +#define NT_PPC_PPR 0x104 /* Program Priority Register */ +#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */ +#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */ +#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */ +#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */ +#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */ +#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */ +#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */ +#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */ +#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address Register */ +#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority Register */ +#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control Register */ +#define NT_PPC_PKEY 0x110 /* Memory Protection Keys registers */ +#define NT_PPC_DEXCR 0x111 /* PowerPC DEXCR registers */ +#define NT_PPC_HASHKEYR 0x112 /* PowerPC HASHKEYR register */ +#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ +#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ +#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ + /* Old binutils treats 0x203 as a CET state */ +#define NT_X86_SHSTK 0x204 /* x86 SHSTK state */ +#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ +#define NT_S390_TIMER 0x301 /* s390 timer register */ +#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ +#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ +#define NT_S390_CTRS 0x304 /* s390 control registers */ +#define NT_S390_PREFIX 0x305 /* s390 prefix register */ +#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ +#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ +#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */ +#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 upper half */ +#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */ +#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */ +#define NT_S390_GS_BC 0x30c /* s390 guarded storage broadcast control block */ +#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation */ +#define NT_S390_PV_CPU_DATA 0x30e /* s390 protvirt cpu dump data */ +#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ +#define NT_ARM_TLS 0x401 /* ARM TLS register */ +#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ +#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ +#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ +#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension registers */ +#define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication code masks */ +#define NT_ARM_PACA_KEYS 0x407 /* ARM pointer authentication address keys */ +#define NT_ARM_PACG_KEYS 0x408 /* ARM pointer authentication generic key */ +#define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* arm64 tagged address control (prctl()) */ +#define NT_ARM_PAC_ENABLED_KEYS 0x40a /* arm64 ptr auth enabled keys (prctl()) */ +#define NT_ARM_SSVE 0x40b /* ARM Streaming SVE registers */ +#define NT_ARM_ZA 0x40c /* ARM SME ZA registers */ +#define NT_ARM_ZT 0x40d /* ARM SME ZT registers */ +#define NT_ARM_FPMR 0x40e /* ARM floating point mode register */ +#define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */ +#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */ +#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */ +#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode */ +#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers */ +#define NT_RISCV_CSR 0x900 /* RISC-V Control and Status Registers */ +#define NT_RISCV_VECTOR 0x901 /* RISC-V vector registers */ +#define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers */ +#define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and status registers */ +#define NT_LOONGARCH_LSX 0xa02 /* LoongArch Loongson SIMD Extension registers */ +#define NT_LOONGARCH_LASX 0xa03 /* LoongArch Loongson Advanced SIMD Extension registers */ +#define NT_LOONGARCH_LBT 0xa04 /* LoongArch Loongson Binary Translation registers */ +#define NT_LOONGARCH_HW_BREAK 0xa05 /* LoongArch hardware breakpoint registers */ +#define NT_LOONGARCH_HW_WATCH 0xa06 /* LoongArch hardware watchpoint registers */ /* Note types with note name "GNU" */ -#define NT_GNU_PROPERTY_TYPE_0 5 +#define NT_GNU_PROPERTY_TYPE_0 5 /* Note header in a PT_NOTE section */ -typedef struct elf32_note { - Elf32_Word n_namesz; /* Name size */ - Elf32_Word n_descsz; /* Content size */ - Elf32_Word n_type; /* Content type */ +typedef struct elf32_note +{ + Elf32_Word n_namesz; /* Name size */ + Elf32_Word n_descsz; /* Content size */ + Elf32_Word n_type; /* Content type */ } Elf32_Nhdr; /* Note header in a PT_NOTE section */ -typedef struct elf64_note { - Elf64_Word n_namesz; /* Name size */ - Elf64_Word n_descsz; /* Content size */ - Elf64_Word n_type; /* Content type */ +typedef struct elf64_note +{ + Elf64_Word n_namesz; /* Name size */ + Elf64_Word n_descsz; /* Content size */ + Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; /* .note.gnu.property types for EM_AARCH64: */ -#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 /* Bits for GNU_PROPERTY_AARCH64_FEATURE_1_BTI */ -#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) -#endif /* _UAPI_LINUX_ELF_H */ \ No newline at end of file +#endif /* _UAPI_LINUX_ELF_H */ diff --git a/XenonUtils/file.h b/XenonUtils/file.h index 8d0f2ae4..0fefc4cf 100644 --- a/XenonUtils/file.h +++ b/XenonUtils/file.h @@ -18,7 +18,7 @@ inline std::vector LoadFile(const std::filesystem::path& path) std::vector data; data.resize(size); - stream.read((char *)(data.data()), size); + stream.read((char*)(data.data()), size); if (stream.bad()) { return {}; diff --git a/XenonUtils/image.cpp b/XenonUtils/image.cpp index 39afe920..9ce43723 100644 --- a/XenonUtils/image.cpp +++ b/XenonUtils/image.cpp @@ -48,7 +48,7 @@ Image ElfLoadImage(const uint8_t* data, size_t size) const auto* header = (elf32_hdr*)data; assert(header->e_ident[EI_DATA] == 2); - Image image{}; + Image image {}; image.size = size; image.data = std::make_unique(size); image.entry_point = ByteSwap(header->e_entry); @@ -81,7 +81,7 @@ Image ElfLoadImage(const uint8_t* data, size_t size) continue; } - uint8_t flags{}; + uint8_t flags {}; if (section.sh_flags & ByteSwap(SHF_EXECINSTR)) { diff --git a/XenonUtils/image.h b/XenonUtils/image.h index be611195..af2c48e7 100644 --- a/XenonUtils/image.h +++ b/XenonUtils/image.h @@ -1,19 +1,19 @@ #pragma once +#include "symbol_table.h" #include -#include -#include #include -#include "symbol_table.h" +#include +#include struct Image { - std::unique_ptr data{}; - size_t base{}; - uint32_t size{}; + std::unique_ptr data {}; + size_t base {}; + uint32_t size {}; - size_t entry_point{}; - std::set sections{}; - SymbolTable symbols{}; + size_t entry_point {}; + std::set sections {}; + SymbolTable symbols {}; /** * \brief Map data to image by RVA diff --git a/XenonUtils/memory_mapped_file.cpp b/XenonUtils/memory_mapped_file.cpp index ba3c5d8a..a315525a 100644 --- a/XenonUtils/memory_mapped_file.cpp +++ b/XenonUtils/memory_mapped_file.cpp @@ -1,10 +1,10 @@ #include "memory_mapped_file.h" #if !defined(_WIN32) -# include -# include -# include -# include +#include +#include +#include +#include #endif MemoryMappedFile::MemoryMappedFile() @@ -12,7 +12,7 @@ MemoryMappedFile::MemoryMappedFile() // Default constructor. } -MemoryMappedFile::MemoryMappedFile(const std::filesystem::path &path) +MemoryMappedFile::MemoryMappedFile(const std::filesystem::path& path) { open(path); } @@ -22,7 +22,7 @@ MemoryMappedFile::~MemoryMappedFile() close(); } -MemoryMappedFile::MemoryMappedFile(MemoryMappedFile &&other) +MemoryMappedFile::MemoryMappedFile(MemoryMappedFile&& other) { #if defined(_WIN32) fileHandle = other.fileHandle; @@ -45,7 +45,7 @@ MemoryMappedFile::MemoryMappedFile(MemoryMappedFile &&other) #endif } -bool MemoryMappedFile::open(const std::filesystem::path &path) +bool MemoryMappedFile::open(const std::filesystem::path& path) { #if defined(_WIN32) fileHandle = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); @@ -154,9 +154,9 @@ bool MemoryMappedFile::isOpen() const #endif } -uint8_t *MemoryMappedFile::data() const +uint8_t* MemoryMappedFile::data() const { - return reinterpret_cast(fileView); + return reinterpret_cast(fileView); } size_t MemoryMappedFile::size() const diff --git a/XenonUtils/memory_mapped_file.h b/XenonUtils/memory_mapped_file.h index a3de88b2..611de3c5 100644 --- a/XenonUtils/memory_mapped_file.h +++ b/XenonUtils/memory_mapped_file.h @@ -3,12 +3,13 @@ #include #if defined(_WIN32) -# include +#include #else -# include +#include #endif -struct MemoryMappedFile { +struct MemoryMappedFile +{ #if defined(_WIN32) HANDLE fileHandle = nullptr; HANDLE fileMappingHandle = nullptr; @@ -16,17 +17,17 @@ struct MemoryMappedFile { LARGE_INTEGER fileSize = {}; #else int fileHandle = -1; - void *fileView = MAP_FAILED; + void* fileView = MAP_FAILED; off_t fileSize = 0; #endif MemoryMappedFile(); - MemoryMappedFile(const std::filesystem::path &path); - MemoryMappedFile(MemoryMappedFile &&other); + MemoryMappedFile(const std::filesystem::path& path); + MemoryMappedFile(MemoryMappedFile&& other); ~MemoryMappedFile(); - bool open(const std::filesystem::path &path); + bool open(const std::filesystem::path& path); void close(); bool isOpen() const; - uint8_t *data() const; + uint8_t* data() const; size_t size() const; }; diff --git a/XenonUtils/ppc_context.h b/XenonUtils/ppc_context.h index 0ed3fcf5..ad212e3a 100644 --- a/XenonUtils/ppc_context.h +++ b/XenonUtils/ppc_context.h @@ -17,8 +17,8 @@ #ifdef _WIN32 #include #else -#include #include +#include #endif #define PPC_JOIN(x, y) x##y @@ -27,7 +27,7 @@ #define PPC_FUNC(x) void x(PPCContext& __restrict ctx, uint8_t* base) #define PPC_FUNC_IMPL(x) extern "C" PPC_FUNC(x) #define PPC_EXTERN_FUNC(x) extern PPC_FUNC(x) -#define PPC_WEAK_FUNC(x) __attribute__((weak,noinline)) PPC_FUNC(x) +#define PPC_WEAK_FUNC(x) __attribute__((weak, noinline)) PPC_FUNC(x) #define PPC_FUNC_PROLOGUE() __builtin_assume(((size_t)base & 0x1F) == 0) @@ -49,10 +49,10 @@ // TODO: Implement. // These are currently unused. However, MMIO loads could possibly be handled statically with some profiling and a fallback. -// The fallback would be a runtime exception handler which will intercept reads from MMIO regions +// The fallback would be a runtime exception handler which will intercept reads from MMIO regions // and log the PC for compiling to static code later. #ifndef PPC_MM_LOAD_U8 -#define PPC_MM_LOAD_U8(x) PPC_LOAD_U8 (x) +#define PPC_MM_LOAD_U8(x) PPC_LOAD_U8(x) #endif #ifndef PPC_MM_LOAD_U16 @@ -86,19 +86,19 @@ // MMIO Store handling is completely reliant on being preeceded by eieio. // TODO: Verify if that's always the case. #ifndef PPC_MM_STORE_U8 -#define PPC_MM_STORE_U8(x, y) PPC_STORE_U8 (x, y) +#define PPC_MM_STORE_U8(x, y) PPC_STORE_U8(x, y) #endif #ifndef PPC_MM_STORE_U16 -#define PPC_MM_STORE_U16(x, y) PPC_STORE_U16(x, y) +#define PPC_MM_STORE_U16(x, y) PPC_STORE_U16(x, y) #endif #ifndef PPC_MM_STORE_U32 -#define PPC_MM_STORE_U32(x, y) PPC_STORE_U32(x, y) +#define PPC_MM_STORE_U32(x, y) PPC_STORE_U32(x, y) #endif #ifndef PPC_MM_STORE_U64 -#define PPC_MM_STORE_U64(x, y) PPC_STORE_U64(x, y) +#define PPC_MM_STORE_U64(x, y) PPC_STORE_U64(x, y) #endif #ifndef PPC_CALL_FUNC @@ -229,7 +229,7 @@ struct PPCFPSCRRegister csr = _mm_getcsr(); return HostToGuest[(csr & _MM_ROUND_MASK) >> 13]; } - + inline void storeFromGuest(uint32_t value) noexcept { csr &= ~_MM_ROUND_MASK; @@ -513,6 +513,8 @@ struct PPCContext #endif }; +// clang-format off + inline uint8_t VectorMaskL[] = { 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, @@ -593,7 +595,9 @@ inline uint8_t VectorShiftTableR[] = 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; -inline __m128i _mm_adds_epu32(__m128i a, __m128i b) +// clang-format on + +inline __m128i _mm_adds_epu32(__m128i a, __m128i b) { return _mm_add_epi32(a, _mm_min_epu32(_mm_xor_si128(a, _mm_cmpeq_epi32(a, a)), b)); } diff --git a/XenonUtils/section.h b/XenonUtils/section.h index f245cd61..1e392de5 100644 --- a/XenonUtils/section.h +++ b/XenonUtils/section.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include enum SectionFlags : uint8_t { @@ -11,11 +11,11 @@ enum SectionFlags : uint8_t struct Section { - std::string name{}; - size_t base{}; - uint32_t size{}; - SectionFlags flags{}; - uint8_t* data{}; + std::string name {}; + size_t base {}; + uint32_t size {}; + SectionFlags flags {}; + uint8_t* data {}; bool operator<(size_t address) const { diff --git a/XenonUtils/symbol.h b/XenonUtils/symbol.h index e9cae73a..0e8dd53e 100644 --- a/XenonUtils/symbol.h +++ b/XenonUtils/symbol.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include enum SymbolType { @@ -12,10 +12,10 @@ enum SymbolType struct Symbol { - mutable std::string name{}; - size_t address{}; - size_t size{}; - mutable SymbolType type{}; + mutable std::string name {}; + size_t address {}; + size_t size {}; + mutable SymbolType type {}; Symbol() { diff --git a/XenonUtils/symbol_table.h b/XenonUtils/symbol_table.h index ca3ab700..08781489 100644 --- a/XenonUtils/symbol_table.h +++ b/XenonUtils/symbol_table.h @@ -4,7 +4,7 @@ class SymbolTable : public std::multiset { -public: + public: const_iterator find(size_t address) const { auto [beginIt, endIt] = equal_range(address); @@ -13,7 +13,7 @@ class SymbolTable : public std::multiset return end(); } - size_t closest{ address - beginIt->address }; + size_t closest { address - beginIt->address }; auto match = end(); for (auto it = beginIt; it != endIt; ++it) { @@ -41,7 +41,7 @@ class SymbolTable : public std::multiset return end(); } - size_t closest{ address - beginIt->address }; + size_t closest { address - beginIt->address }; auto match = end(); for (auto it = beginIt; it != endIt; ++it) { diff --git a/XenonUtils/xbox.h b/XenonUtils/xbox.h index 0361b0f4..4de0f0a4 100644 --- a/XenonUtils/xbox.h +++ b/XenonUtils/xbox.h @@ -1,12 +1,12 @@ #pragma once -#include -#include +#include "byteswap.h" #include +#include #include -#include "byteswap.h" +#include #ifdef _WIN32 - #include +#include #endif // real win32 handles will never use the upper bits unless something goes really wrong @@ -15,7 +15,7 @@ #define HOST_HANDLE(HANDLE) ((HANDLE) & ~0x80000000) // Return true to free the associated memory -typedef bool(*TypeDestructor_t)(void*); +typedef bool (*TypeDestructor_t)(void*); template bool DestroyObject(void* obj) @@ -71,13 +71,13 @@ struct be return byteswap(value); } - be& operator| (T value) + be& operator|(T value) { set(get() | value); return *this; } - be& operator& (T value) + be& operator&(T value) { set(get() & value); return *this; @@ -119,7 +119,7 @@ struct xpointer return reinterpret_cast(MmGetHostAddress(ptr)); } - operator T* () const + operator T*() const { return get(); } @@ -144,7 +144,7 @@ typedef struct _IMAGE_CE_RUNTIME_FUNCTION { uint32_t BeginAddress; - union + union { uint32_t Data; struct @@ -196,7 +196,7 @@ typedef struct _XDISPATCHER_HEADER be SignalState; XLIST_ENTRY WaitListHead; -} XDISPATCHER_HEADER, * XPDISPATCHER_HEADER; +} XDISPATCHER_HEADER, *XPDISPATCHER_HEADER; // These variables are never accessed in guest code, we can safely use them in little endian typedef struct _XRTL_CRITICAL_SECTION @@ -207,7 +207,8 @@ typedef struct _XRTL_CRITICAL_SECTION uint32_t OwningThread; } XRTL_CRITICAL_SECTION; -typedef struct _XANSI_STRING { +typedef struct _XANSI_STRING +{ be Length; be MaximumLength; xpointer Buffer; @@ -224,14 +225,16 @@ typedef XDISPATCHER_HEADER XKEVENT; typedef struct _XIO_STATUS_BLOCK { - union { + union + { be Status; be Pointer; }; be Information; } XIO_STATUS_BLOCK; -typedef struct _XOVERLAPPED { +typedef struct _XOVERLAPPED +{ be Internal; be InternalHigh; be Offset; @@ -240,7 +243,8 @@ typedef struct _XOVERLAPPED { } XOVERLAPPED; // this name is so dumb -typedef struct _XXOVERLAPPED { +typedef struct _XXOVERLAPPED +{ union { struct @@ -265,7 +269,8 @@ typedef struct _XXOVERLAPPED { static_assert(sizeof(_XXOVERLAPPED) == 0x1C); // https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-memorystatus -typedef struct _XMEMORYSTATUS { +typedef struct _XMEMORYSTATUS +{ be dwLength; be dwMemoryLoad; be dwTotalPhys; @@ -274,7 +279,7 @@ typedef struct _XMEMORYSTATUS { be dwAvailPageFile; be dwTotalVirtual; be dwAvailVirtual; -} XMEMORYSTATUS, * XLPMEMORYSTATUS; +} XMEMORYSTATUS, *XLPMEMORYSTATUS; typedef struct _XVIDEO_MODE { @@ -296,7 +301,8 @@ typedef struct _XKSEMAPHORE be Limit; } XKSEMAPHORE; -typedef struct _XUSER_SIGNIN_INFO { +typedef struct _XUSER_SIGNIN_INFO +{ be xuid; be dwField08; be SigninState; @@ -315,19 +321,19 @@ typedef struct _XTIME_FIELDS be Second; be Milliseconds; be Weekday; -} XTIME_FIELDS, * PXTIME_FIELDS; +} XTIME_FIELDS, *PXTIME_FIELDS; // Content types #define XCONTENTTYPE_SAVEDATA 1 -#define XCONTENTTYPE_DLC 2 +#define XCONTENTTYPE_DLC 2 #define XCONTENTTYPE_RESERVED 3 -#define XCONTENT_NEW 1 +#define XCONTENT_NEW 1 #define XCONTENT_EXISTING 2 #define XCONTENT_MAX_DISPLAYNAME 128 -#define XCONTENT_MAX_FILENAME 42 -#define XCONTENTDEVICE_MAX_NAME 27 +#define XCONTENT_MAX_FILENAME 42 +#define XCONTENTDEVICE_MAX_NAME 27 typedef struct _XCONTENT_DATA { @@ -335,15 +341,14 @@ typedef struct _XCONTENT_DATA be dwContentType; be szDisplayName[XCONTENT_MAX_DISPLAYNAME]; char szFileName[XCONTENT_MAX_FILENAME]; -} XCONTENT_DATA, * PXCONTENT_DATA; +} XCONTENT_DATA, *PXCONTENT_DATA; typedef struct _XHOSTCONTENT_DATA : _XCONTENT_DATA { // This is a host exclusive type so we don't care what goes on - std::string szRoot{}; + std::string szRoot {}; } XHOSTCONTENT_DATA, *PXHOSTCONTENT_DATA; - #define XCONTENTDEVICETYPE_HDD 1 #define XCONTENTDEVICETYPE_MU 2 @@ -358,52 +363,52 @@ typedef struct _XDEVICE_DATA // Direct reflection of XInput structures -#define XAMINPUT_DEVTYPE_GAMEPAD 0x01 -#define XAMINPUT_DEVSUBTYPE_GAMEPAD 0x01 - -#define XAMINPUT_GAMEPAD_DPAD_UP 0x0001 -#define XAMINPUT_GAMEPAD_DPAD_DOWN 0x0002 -#define XAMINPUT_GAMEPAD_DPAD_LEFT 0x0004 -#define XAMINPUT_GAMEPAD_DPAD_RIGHT 0x0008 -#define XAMINPUT_GAMEPAD_START 0x0010 -#define XAMINPUT_GAMEPAD_BACK 0x0020 -#define XAMINPUT_GAMEPAD_LEFT_THUMB 0x0040 -#define XAMINPUT_GAMEPAD_RIGHT_THUMB 0x0080 -#define XAMINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 -#define XAMINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 -#define XAMINPUT_GAMEPAD_A 0x1000 -#define XAMINPUT_GAMEPAD_B 0x2000 -#define XAMINPUT_GAMEPAD_X 0x4000 -#define XAMINPUT_GAMEPAD_Y 0x8000 +#define XAMINPUT_DEVTYPE_GAMEPAD 0x01 +#define XAMINPUT_DEVSUBTYPE_GAMEPAD 0x01 + +#define XAMINPUT_GAMEPAD_DPAD_UP 0x0001 +#define XAMINPUT_GAMEPAD_DPAD_DOWN 0x0002 +#define XAMINPUT_GAMEPAD_DPAD_LEFT 0x0004 +#define XAMINPUT_GAMEPAD_DPAD_RIGHT 0x0008 +#define XAMINPUT_GAMEPAD_START 0x0010 +#define XAMINPUT_GAMEPAD_BACK 0x0020 +#define XAMINPUT_GAMEPAD_LEFT_THUMB 0x0040 +#define XAMINPUT_GAMEPAD_RIGHT_THUMB 0x0080 +#define XAMINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 +#define XAMINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 +#define XAMINPUT_GAMEPAD_A 0x1000 +#define XAMINPUT_GAMEPAD_B 0x2000 +#define XAMINPUT_GAMEPAD_X 0x4000 +#define XAMINPUT_GAMEPAD_Y 0x8000 typedef struct _XAMINPUT_GAMEPAD { - uint16_t wButtons; - uint8_t bLeftTrigger; - uint8_t bRightTrigger; - int16_t sThumbLX; - int16_t sThumbLY; - int16_t sThumbRX; - int16_t sThumbRY; + uint16_t wButtons; + uint8_t bLeftTrigger; + uint8_t bRightTrigger; + int16_t sThumbLX; + int16_t sThumbLY; + int16_t sThumbRX; + int16_t sThumbRY; } XAMINPUT_GAMEPAD, *PXAMINPUT_GAMEPAD; typedef struct _XAMINPUT_VIBRATION { - uint16_t wLeftMotorSpeed; - uint16_t wRightMotorSpeed; -} XAMINPUT_VIBRATION, * PXAMINPUT_VIBRATION; + uint16_t wLeftMotorSpeed; + uint16_t wRightMotorSpeed; +} XAMINPUT_VIBRATION, *PXAMINPUT_VIBRATION; typedef struct _XAMINPUT_CAPABILITIES { - uint8_t Type; - uint8_t SubType; - uint16_t Flags; - XAMINPUT_GAMEPAD Gamepad; - XAMINPUT_VIBRATION Vibration; -} XAMINPUT_CAPABILITIES, * PXAMINPUT_CAPABILITIES; + uint8_t Type; + uint8_t SubType; + uint16_t Flags; + XAMINPUT_GAMEPAD Gamepad; + XAMINPUT_VIBRATION Vibration; +} XAMINPUT_CAPABILITIES, *PXAMINPUT_CAPABILITIES; typedef struct _XAMINPUT_STATE { - uint32_t dwPacketNumber; - XAMINPUT_GAMEPAD Gamepad; -} XAMINPUT_STATE, * PXAMINPUT_STATE; + uint32_t dwPacketNumber; + XAMINPUT_GAMEPAD Gamepad; +} XAMINPUT_STATE, *PXAMINPUT_STATE; diff --git a/XenonUtils/xdbf_wrapper.cpp b/XenonUtils/xdbf_wrapper.cpp index 9f6b2cd9..7d73f58d 100644 --- a/XenonUtils/xdbf_wrapper.cpp +++ b/XenonUtils/xdbf_wrapper.cpp @@ -36,7 +36,7 @@ XDBFBlock XDBFWrapper::GetResource(EXDBFNamespace ns, uint64_t id) const if (entry.NamespaceID == ns && entry.ResourceID == id) { - XDBFBlock block{}; + XDBFBlock block {}; block.pBuffer = pContent + entry.Offset; block.BufferSize = entry.Length; return block; @@ -89,7 +89,7 @@ std::vector XDBFWrapper::GetAchievements(EXDBFLanguage language) co seek += sizeof(XACHEntry); - Achievement achievement{}; + Achievement achievement {}; achievement.ID = entry->AchievementID; achievement.Name = GetString(language, entry->NameID); achievement.UnlockedDesc = GetString(language, entry->UnlockedDescID); @@ -112,7 +112,7 @@ std::vector XDBFWrapper::GetAchievements(EXDBFLanguage language) co Achievement XDBFWrapper::GetAchievement(EXDBFLanguage language, uint16_t id) const { - Achievement result{}; + Achievement result {}; auto achievementsBlock = GetResource(XDBF_SPA_NAMESPACE_METADATA, 0x58414348); diff --git a/XenonUtils/xdbf_wrapper.h b/XenonUtils/xdbf_wrapper.h index c92540af..d2981838 100644 --- a/XenonUtils/xdbf_wrapper.h +++ b/XenonUtils/xdbf_wrapper.h @@ -1,7 +1,7 @@ #pragma once -#include #include "xdbf.h" +#include struct Achievement { @@ -27,7 +27,7 @@ struct XDBFBlock class XDBFWrapper { -public: + public: const uint8_t* pBuffer; size_t BufferSize; diff --git a/XenonUtils/xex.cpp b/XenonUtils/xex.cpp index d1972c0a..07af99c4 100644 --- a/XenonUtils/xex.cpp +++ b/XenonUtils/xex.cpp @@ -1,125 +1,130 @@ #include "xex.h" #include "image.h" +#include #include #include -#include #include -#include +#include #define STRINGIFY(X) #X #define XE_EXPORT(MODULE, ORDINAL, NAME, TYPE) { (ORDINAL), "__imp__" STRINGIFY(NAME) } #ifndef _WIN32 -typedef struct _IMAGE_DOS_HEADER { - uint16_t e_magic; - uint16_t e_cblp; - uint16_t e_cp; - uint16_t e_crlc; - uint16_t e_cparhdr; - uint16_t e_minalloc; - uint16_t e_maxalloc; - uint16_t e_ss; - uint16_t e_sp; - uint16_t e_csum; - uint16_t e_ip; - uint16_t e_cs; - uint16_t e_lfarlc; - uint16_t e_ovno; - uint16_t e_res[4]; - uint16_t e_oemid; - uint16_t e_oeminfo; - uint16_t e_res2[10]; - uint32_t e_lfanew; -} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER; - -typedef struct _IMAGE_FILE_HEADER { - uint16_t Machine; - uint16_t NumberOfSections; - uint32_t TimeDateStamp; - uint32_t PointerToSymbolTable; - uint32_t NumberOfSymbols; - uint16_t SizeOfOptionalHeader; - uint16_t Characteristics; -} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER; - -typedef struct _IMAGE_DATA_DIRECTORY { - uint32_t VirtualAddress; - uint32_t Size; -} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY; - -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 - -typedef struct _IMAGE_OPTIONAL_HEADER { - uint16_t Magic; - uint8_t MajorLinkerVersion; - uint8_t MinorLinkerVersion; - uint32_t SizeOfCode; - uint32_t SizeOfInitializedData; - uint32_t SizeOfUninitializedData; - uint32_t AddressOfEntryPoint; - uint32_t BaseOfCode; - uint32_t BaseOfData; - uint32_t ImageBase; - uint32_t SectionAlignment; - uint32_t FileAlignment; - uint16_t MajorOperatingSystemVersion; - uint16_t MinorOperatingSystemVersion; - uint16_t MajorImageVersion; - uint16_t MinorImageVersion; - uint16_t MajorSubsystemVersion; - uint16_t MinorSubsystemVersion; - uint32_t Win32VersionValue; - uint32_t SizeOfImage; - uint32_t SizeOfHeaders; - uint32_t CheckSum; - uint16_t Subsystem; - uint16_t DllCharacteristics; - uint32_t SizeOfStackReserve; - uint32_t SizeOfStackCommit; - uint32_t SizeOfHeapReserve; - uint32_t SizeOfHeapCommit; - uint32_t LoaderFlags; - uint32_t NumberOfRvaAndSizes; +typedef struct _IMAGE_DOS_HEADER +{ + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + uint32_t e_lfanew; +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_FILE_HEADER +{ + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY +{ + uint32_t VirtualAddress; + uint32_t Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef struct _IMAGE_OPTIONAL_HEADER +{ + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint32_t BaseOfData; + uint32_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint32_t SizeOfStackReserve; + uint32_t SizeOfStackCommit; + uint32_t SizeOfHeapReserve; + uint32_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} IMAGE_OPTIONAL_HEADER32, * PIMAGE_OPTIONAL_HEADER32; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; -typedef struct _IMAGE_NT_HEADERS { +typedef struct _IMAGE_NT_HEADERS +{ uint32_t Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; -} IMAGE_NT_HEADERS32, * PIMAGE_NT_HEADERS32; +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; -#define IMAGE_SIZEOF_SHORT_NAME 8 +#define IMAGE_SIZEOF_SHORT_NAME 8 -typedef struct _IMAGE_SECTION_HEADER { - uint8_t Name[IMAGE_SIZEOF_SHORT_NAME]; - union { - uint32_t PhysicalAddress; - uint32_t VirtualSize; +typedef struct _IMAGE_SECTION_HEADER +{ + uint8_t Name[IMAGE_SIZEOF_SHORT_NAME]; + union + { + uint32_t PhysicalAddress; + uint32_t VirtualSize; } Misc; - uint32_t VirtualAddress; - uint32_t SizeOfRawData; - uint32_t PointerToRawData; - uint32_t PointerToRelocations; - uint32_t PointerToLinenumbers; - uint16_t NumberOfRelocations; - uint16_t NumberOfLinenumbers; - uint32_t Characteristics; -} IMAGE_SECTION_HEADER, * PIMAGE_SECTION_HEADER; - -#define IMAGE_SCN_CNT_CODE 0x00000020 + uint32_t VirtualAddress; + uint32_t SizeOfRawData; + uint32_t PointerToRawData; + uint32_t PointerToRelocations; + uint32_t PointerToLinenumbers; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SCN_CNT_CODE 0x00000020 #endif -std::unordered_map XamExports = -{ - #include "xbox/xam_table.inc" +std::unordered_map XamExports = { +#include "xbox/xam_table.inc" }; -std::unordered_map XboxKernelExports = -{ - #include "xbox/xboxkrnl_table.inc" +std::unordered_map XboxKernelExports = { +#include "xbox/xboxkrnl_table.inc" }; Image Xex2LoadImage(const uint8_t* data, size_t dataSize) @@ -128,8 +133,8 @@ Image Xex2LoadImage(const uint8_t* data, size_t dataSize) auto* security = reinterpret_cast(data + header->securityOffset); const auto* fileFormatInfo = reinterpret_cast(getOptHeaderPtr(data, XEX_HEADER_FILE_FORMAT_INFO)); - Image image{}; - std::unique_ptr result{}; + Image image {}; + std::unique_ptr result {}; size_t imageSize = security->imageSize; // Decompress image @@ -210,14 +215,14 @@ Image Xex2LoadImage(const uint8_t* data, size_t dataSize) for (size_t i = 0; i < numSections; i++) { const auto& section = sections[i]; - uint8_t flags{}; + uint8_t flags {}; if (section.Characteristics & IMAGE_SCN_CNT_CODE) { flags |= SectionFlags_Code; } - image.Map(reinterpret_cast(section.Name), section.VirtualAddress, + image.Map(reinterpret_cast(section.Name), section.VirtualAddress, section.Misc.VirtualSize, flags, image.data.get() + section.VirtualAddress); } diff --git a/XenonUtils/xex.h b/XenonUtils/xex.h index 9ab831eb..ed3ec90b 100644 --- a/XenonUtils/xex.h +++ b/XenonUtils/xex.h @@ -1,6 +1,6 @@ #pragma once -#include #include "xbox.h" +#include inline constexpr uint8_t Xex2RetailKey[16] = { 0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3, 0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91 }; inline constexpr uint8_t AESBlankIV[16] = {}; @@ -193,7 +193,7 @@ struct Xex2ImportHeader be numImports; }; -struct Xex2ImportLibrary +struct Xex2ImportLibrary { be size; char nextImportDigest[0x14]; @@ -204,12 +204,12 @@ struct Xex2ImportLibrary be numberOfImports; }; -struct Xex2ImportDescriptor +struct Xex2ImportDescriptor { be firstThunk; // VA XEX_THUNK_DATA }; -struct Xex2ThunkData +struct Xex2ThunkData { union { diff --git a/XenonUtils/xex_patcher.cpp b/XenonUtils/xex_patcher.cpp index 18aacdaa..f123a294 100644 --- a/XenonUtils/xex_patcher.cpp +++ b/XenonUtils/xex_patcher.cpp @@ -17,22 +17,22 @@ #include #include +#include #include #include #include -#include #include "memory_mapped_file.h" struct mspack_memory_file { mspack_system sys; - void *buffer; + void* buffer; size_t bufferSize; size_t offset; }; -static mspack_memory_file *mspack_memory_open(mspack_system *sys, void *buffer, size_t bufferSize) +static mspack_memory_file* mspack_memory_open(mspack_system* sys, void* buffer, size_t bufferSize) { assert(bufferSize < INT_MAX); @@ -41,7 +41,7 @@ static mspack_memory_file *mspack_memory_open(mspack_system *sys, void *buffer, return nullptr; } - mspack_memory_file *memoryFile = (mspack_memory_file *)(std::calloc(1, sizeof(mspack_memory_file))); + mspack_memory_file* memoryFile = (mspack_memory_file*)(std::calloc(1, sizeof(mspack_memory_file))); if (memoryFile == nullptr) { return memoryFile; @@ -53,49 +53,49 @@ static mspack_memory_file *mspack_memory_open(mspack_system *sys, void *buffer, return memoryFile; } -static void mspack_memory_close(mspack_memory_file *file) +static void mspack_memory_close(mspack_memory_file* file) { std::free(file); } -static int mspack_memory_read(mspack_file *file, void *buffer, int chars) +static int mspack_memory_read(mspack_file* file, void* buffer, int chars) { - mspack_memory_file *memoryFile = (mspack_memory_file *)(file); + mspack_memory_file* memoryFile = (mspack_memory_file*)(file); const size_t remaining = memoryFile->bufferSize - memoryFile->offset; const size_t total = std::min(size_t(chars), remaining); - std::memcpy(buffer, (uint8_t *)(memoryFile->buffer) + memoryFile->offset, total); + std::memcpy(buffer, (uint8_t*)(memoryFile->buffer) + memoryFile->offset, total); memoryFile->offset += total; return int(total); } -static int mspack_memory_write(mspack_file *file, void *buffer, int chars) +static int mspack_memory_write(mspack_file* file, void* buffer, int chars) { - mspack_memory_file *memoryFile = (mspack_memory_file *)(file); + mspack_memory_file* memoryFile = (mspack_memory_file*)(file); const size_t remaining = memoryFile->bufferSize - memoryFile->offset; const size_t total = std::min(size_t(chars), remaining); - std::memcpy((uint8_t *)(memoryFile->buffer) + memoryFile->offset, buffer, total); + std::memcpy((uint8_t*)(memoryFile->buffer) + memoryFile->offset, buffer, total); memoryFile->offset += total; return int(total); } -static void *mspack_memory_alloc(mspack_system *sys, size_t chars) +static void* mspack_memory_alloc(mspack_system* sys, size_t chars) { return std::calloc(chars, 1); } -static void mspack_memory_free(void *ptr) +static void mspack_memory_free(void* ptr) { std::free(ptr); } -static void mspack_memory_copy(void *src, void *dest, size_t chars) +static void mspack_memory_copy(void* src, void* dest, size_t chars) { std::memcpy(dest, src, chars); } -static mspack_system *mspack_memory_sys_create() +static mspack_system* mspack_memory_sys_create() { - auto sys = (mspack_system *)(std::calloc(1, sizeof(mspack_system))); + auto sys = (mspack_system*)(std::calloc(1, sizeof(mspack_system))); if (!sys) { return nullptr; @@ -109,31 +109,31 @@ static mspack_system *mspack_memory_sys_create() return sys; } -static void mspack_memory_sys_destroy(struct mspack_system *sys) +static void mspack_memory_sys_destroy(struct mspack_system* sys) { free(sys); } #if defined(_WIN32) -inline bool bitScanForward(uint32_t v, uint32_t *outFirstSetIndex) +inline bool bitScanForward(uint32_t v, uint32_t* outFirstSetIndex) { - return _BitScanForward((unsigned long *)(outFirstSetIndex), v) != 0; + return _BitScanForward((unsigned long*)(outFirstSetIndex), v) != 0; } -inline bool bitScanForward(uint64_t v, uint32_t *outFirstSetIndex) +inline bool bitScanForward(uint64_t v, uint32_t* outFirstSetIndex) { - return _BitScanForward64((unsigned long *)(outFirstSetIndex), v) != 0; + return _BitScanForward64((unsigned long*)(outFirstSetIndex), v) != 0; } #else -inline bool bitScanForward(uint32_t v, uint32_t *outFirstSetIndex) +inline bool bitScanForward(uint32_t v, uint32_t* outFirstSetIndex) { int i = ffs(v); *outFirstSetIndex = i - 1; return i != 0; } -inline bool bitScanForward(uint64_t v, uint32_t *outFirstSetIndex) +inline bool bitScanForward(uint64_t v, uint32_t* outFirstSetIndex) { int i = __builtin_ffsll(v); *outFirstSetIndex = i - 1; @@ -141,20 +141,23 @@ inline bool bitScanForward(uint64_t v, uint32_t *outFirstSetIndex) } #endif -static int lzxDecompress(const void *lzxData, size_t lzxLength, void *dst, size_t dstLength, uint32_t windowSize, void *windowData, size_t windowDataLength) +static int lzxDecompress(const void* lzxData, size_t lzxLength, void* dst, size_t dstLength, uint32_t windowSize, void* windowData, size_t windowDataLength) { int resultCode = 1; uint32_t windowBits; - if (!bitScanForward(windowSize, &windowBits)) { + if (!bitScanForward(windowSize, &windowBits)) + { return resultCode; } - mspack_system *sys = mspack_memory_sys_create(); - mspack_memory_file *lzxSrc = mspack_memory_open(sys, (void *)(lzxData), lzxLength); - mspack_memory_file *lzxDst = mspack_memory_open(sys, dst, dstLength); - lzxd_stream *lzxd = lzxd_init(sys, (mspack_file *)(lzxSrc), (mspack_file *)(lzxDst), windowBits, 0, 0x8000, dstLength, 0); - if (lzxd != nullptr) { - if (windowData != nullptr) { + mspack_system* sys = mspack_memory_sys_create(); + mspack_memory_file* lzxSrc = mspack_memory_open(sys, (void*)(lzxData), lzxLength); + mspack_memory_file* lzxDst = mspack_memory_open(sys, dst, dstLength); + lzxd_stream* lzxd = lzxd_init(sys, (mspack_file*)(lzxSrc), (mspack_file*)(lzxDst), windowBits, 0, 0x8000, dstLength, 0); + if (lzxd != nullptr) + { + if (windowData != nullptr) + { size_t paddingLength = windowSize - windowDataLength; std::memset(&lzxd->window[0], 0, paddingLength); std::memcpy(&lzxd->window[paddingLength], windowData, windowDataLength); @@ -165,28 +168,31 @@ static int lzxDecompress(const void *lzxData, size_t lzxLength, void *dst, size_ lzxd_free(lzxd); } - if (lzxSrc) { + if (lzxSrc) + { mspack_memory_close(lzxSrc); } - if (lzxDst) { + if (lzxDst) + { mspack_memory_close(lzxDst); } - if (sys) { + if (sys) + { mspack_memory_sys_destroy(sys); } return resultCode; } -static int lzxDeltaApplyPatch(const Xex2DeltaPatch *deltaPatch, uint32_t patchLength, uint32_t windowSize, uint8_t *dstData) +static int lzxDeltaApplyPatch(const Xex2DeltaPatch* deltaPatch, uint32_t patchLength, uint32_t windowSize, uint8_t* dstData) { - const void *patchEnd = (const uint8_t *)(deltaPatch) + patchLength; - const Xex2DeltaPatch *curPatch = deltaPatch; + const void* patchEnd = (const uint8_t*)(deltaPatch) + patchLength; + const Xex2DeltaPatch* curPatch = deltaPatch; while (patchEnd > curPatch) { - int patchSize = -4; + int patchSize = -4; if (curPatch->compressedLength == 0 && curPatch->uncompressedLength == 0 && curPatch->newAddress == 0 && curPatch->oldAddress == 0) { // End of patch. @@ -216,23 +222,23 @@ static int lzxDeltaApplyPatch(const Xex2DeltaPatch *deltaPatch, uint32_t patchLe } curPatch++; - curPatch = (const Xex2DeltaPatch *)((const uint8_t *)(curPatch) + patchSize); + curPatch = (const Xex2DeltaPatch*)((const uint8_t*)(curPatch) + patchSize); } return 0; } -XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSize, const uint8_t* patchBytes, size_t patchBytesSize, std::vector &outBytes, bool skipData) +XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSize, const uint8_t* patchBytes, size_t patchBytesSize, std::vector& outBytes, bool skipData) { // Validate headers. static const char Xex2Magic[] = "XEX2"; - const Xex2Header *xexHeader = (const Xex2Header *)(xexBytes); + const Xex2Header* xexHeader = (const Xex2Header*)(xexBytes); if (memcmp(xexBytes, Xex2Magic, 4) != 0) { return Result::XexFileInvalid; } - const Xex2Header *patchHeader = (const Xex2Header *)(patchBytes); + const Xex2Header* patchHeader = (const Xex2Header*)(patchBytes); if (memcmp(patchBytes, Xex2Magic, 4) != 0) { return Result::PatchFileInvalid; @@ -244,13 +250,13 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz } // Validate patch. - const Xex2OptDeltaPatchDescriptor *patchDescriptor = (const Xex2OptDeltaPatchDescriptor *)(getOptHeaderPtr(patchBytes, XEX_HEADER_DELTA_PATCH_DESCRIPTOR)); + const Xex2OptDeltaPatchDescriptor* patchDescriptor = (const Xex2OptDeltaPatchDescriptor*)(getOptHeaderPtr(patchBytes, XEX_HEADER_DELTA_PATCH_DESCRIPTOR)); if (patchDescriptor == nullptr) { return Result::PatchFileInvalid; } - - const Xex2OptFileFormatInfo *patchFileFormatInfo = (const Xex2OptFileFormatInfo *)(getOptHeaderPtr(patchBytes, XEX_HEADER_FILE_FORMAT_INFO)); + + const Xex2OptFileFormatInfo* patchFileFormatInfo = (const Xex2OptFileFormatInfo*)(getOptHeaderPtr(patchBytes, XEX_HEADER_FILE_FORMAT_INFO)); if (patchFileFormatInfo == nullptr) { return Result::PatchFileInvalid; @@ -295,7 +301,7 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz memset(outBytes.data(), 0, newXexHeaderSize); memcpy(outBytes.data(), xexBytes, headerTargetSize); - Xex2Header *newXexHeader = (Xex2Header *)(outBytes.data()); + Xex2Header* newXexHeader = (Xex2Header*)(outBytes.data()); if (patchDescriptor->deltaHeadersSourceOffset > 0) { memcpy(&outBytes[patchDescriptor->deltaHeadersTargetOffset], &outBytes[patchDescriptor->deltaHeadersSourceOffset], patchDescriptor->deltaHeadersSourceSize); @@ -309,20 +315,20 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz // Make the header the specified size by the patch. outBytes.resize(headerTargetSize); - newXexHeader = (Xex2Header *)(outBytes.data()); + newXexHeader = (Xex2Header*)(outBytes.data()); // Copy the rest of the data. - const Xex2SecurityInfo *newSecurityInfo = (const Xex2SecurityInfo *)(&outBytes[newXexHeader->securityOffset]); + const Xex2SecurityInfo* newSecurityInfo = (const Xex2SecurityInfo*)(&outBytes[newXexHeader->securityOffset]); outBytes.resize(outBytes.size() + newSecurityInfo->imageSize); memset(&outBytes[headerTargetSize], 0, outBytes.size() - headerTargetSize); memcpy(&outBytes[headerTargetSize], &xexBytes[xexHeader->headerSize], xexBytesSize - xexHeader->headerSize); - newXexHeader = (Xex2Header *)(outBytes.data()); - newSecurityInfo = (const Xex2SecurityInfo *)(&outBytes[newXexHeader->securityOffset]); - + newXexHeader = (Xex2Header*)(outBytes.data()); + newSecurityInfo = (const Xex2SecurityInfo*)(&outBytes[newXexHeader->securityOffset]); + // Decrypt the keys and validate that the patch is compatible with the base file. constexpr uint32_t KeySize = 16; - const Xex2SecurityInfo *originalSecurityInfo = (const Xex2SecurityInfo *)(&xexBytes[xexHeader->securityOffset]); - const Xex2SecurityInfo *patchSecurityInfo = (const Xex2SecurityInfo *)(&patchBytes[patchHeader->securityOffset]); + const Xex2SecurityInfo* originalSecurityInfo = (const Xex2SecurityInfo*)(&xexBytes[xexHeader->securityOffset]); + const Xex2SecurityInfo* patchSecurityInfo = (const Xex2SecurityInfo*)(&patchBytes[patchHeader->securityOffset]); uint8_t decryptedOriginalKey[KeySize]; uint8_t decryptedNewKey[KeySize]; uint8_t decryptedPatchKey[KeySize]; @@ -356,9 +362,9 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz { return Result::Success; } - + // Decrypt base XEX if necessary. - const Xex2OptFileFormatInfo *fileFormatInfo = (const Xex2OptFileFormatInfo *)(getOptHeaderPtr(xexBytes, XEX_HEADER_FILE_FORMAT_INFO)); + const Xex2OptFileFormatInfo* fileFormatInfo = (const Xex2OptFileFormatInfo*)(getOptHeaderPtr(xexBytes, XEX_HEADER_FILE_FORMAT_INFO)); if (fileFormatInfo == nullptr) { return Result::XexFileInvalid; @@ -377,11 +383,12 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz // Decompress base XEX if necessary. if (fileFormatInfo->compressionType == XEX_COMPRESSION_BASIC) { - const Xex2FileBasicCompressionBlock *blocks = &((const Xex2FileBasicCompressionInfo*)(fileFormatInfo + 1))->firstBlock; + const Xex2FileBasicCompressionBlock* blocks = &((const Xex2FileBasicCompressionInfo*)(fileFormatInfo + 1))->firstBlock; int32_t numBlocks = (fileFormatInfo->infoSize / sizeof(Xex2FileBasicCompressionBlock)) - 1; int32_t baseCompressedSize = 0; int32_t baseImageSize = 0; - for (int32_t i = 0; i < numBlocks; i++) { + for (int32_t i = 0; i < numBlocks; i++) + { baseCompressedSize += blocks[i].dataSize; baseImageSize += blocks[i].dataSize + blocks[i].zeroSize; } @@ -390,10 +397,10 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz { return Result::XexFileInvalid; } - + // Reverse iteration allows to perform this decompression in place. - uint8_t *srcDataCursor = outBytes.data() + headerTargetSize + baseCompressedSize; - uint8_t *outDataCursor = outBytes.data() + headerTargetSize + baseImageSize; + uint8_t* srcDataCursor = outBytes.data() + headerTargetSize + baseCompressedSize; + uint8_t* outDataCursor = outBytes.data() + headerTargetSize + baseImageSize; for (int32_t i = numBlocks - 1; i >= 0; i--) { outDataCursor -= blocks[i].zeroSize; @@ -412,12 +419,12 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz return Result::XexFileInvalid; } - Xex2OptFileFormatInfo *newFileFormatInfo = (Xex2OptFileFormatInfo *)(getOptHeaderPtr(outBytes.data(), XEX_HEADER_FILE_FORMAT_INFO)); + Xex2OptFileFormatInfo* newFileFormatInfo = (Xex2OptFileFormatInfo*)(getOptHeaderPtr(outBytes.data(), XEX_HEADER_FILE_FORMAT_INFO)); if (newFileFormatInfo == nullptr) { return Result::PatchFailed; } - + // Update the header to indicate no encryption or compression is used. newFileFormatInfo->encryptionType = XEX_ENCRYPTION_NONE; newFileFormatInfo->compressionType = XEX_COMPRESSION_NONE; @@ -437,8 +444,8 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz return Result::PatchFileInvalid; } - const Xex2CompressedBlockInfo *currentBlock = &((const Xex2FileNormalCompressionInfo*)(patchFileFormatInfo + 1))->firstBlock; - uint8_t *outExe = &outBytes[newXexHeader->headerSize]; + const Xex2CompressedBlockInfo* currentBlock = &((const Xex2FileNormalCompressionInfo*)(patchFileFormatInfo + 1))->firstBlock; + uint8_t* outExe = &outBytes[newXexHeader->headerSize]; if (patchDescriptor->deltaImageSourceOffset > 0) { memcpy(&outExe[patchDescriptor->deltaImageTargetOffset], &outExe[patchDescriptor->deltaImageSourceOffset], patchDescriptor->deltaImageSourceSize); @@ -447,10 +454,10 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz static const uint32_t DigestSize = 20; uint8_t sha1Digest[DigestSize]; sha1::SHA1 sha1Context; - uint8_t *patchDataCursor = patchData.data(); + uint8_t* patchDataCursor = patchData.data(); while (currentBlock->blockSize > 0) { - const Xex2CompressedBlockInfo *nextBlock = (const Xex2CompressedBlockInfo *)(patchDataCursor); + const Xex2CompressedBlockInfo* nextBlock = (const Xex2CompressedBlockInfo*)(patchDataCursor); // Hash and validate the block. sha1Context.reset(); @@ -465,7 +472,7 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz // Apply the block's patch data. uint32_t blockDataSize = currentBlock->blockSize - 24; - if (lzxDeltaApplyPatch((const Xex2DeltaPatch *)(patchDataCursor), blockDataSize, ((const Xex2FileNormalCompressionInfo*)(patchFileFormatInfo + 1))->windowSize, outExe) != 0) + if (lzxDeltaApplyPatch((const Xex2DeltaPatch*)(patchDataCursor), blockDataSize, ((const Xex2FileNormalCompressionInfo*)(patchFileFormatInfo + 1))->windowSize, outExe) != 0) { return Result::PatchFailed; } @@ -477,7 +484,7 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz return Result::Success; } -XexPatcher::Result XexPatcher::apply(const std::filesystem::path &baseXexPath, const std::filesystem::path &patchXexPath, const std::filesystem::path &newXexPath) +XexPatcher::Result XexPatcher::apply(const std::filesystem::path& baseXexPath, const std::filesystem::path& patchXexPath, const std::filesystem::path& newXexPath) { MemoryMappedFile baseXexFile(baseXexPath); MemoryMappedFile patchFile(patchXexPath); @@ -499,7 +506,7 @@ XexPatcher::Result XexPatcher::apply(const std::filesystem::path &baseXexPath, c return Result::FileOpenFailed; } - newXexFile.write((const char *)(newXexBytes.data()), newXexBytes.size()); + newXexFile.write((const char*)(newXexBytes.data()), newXexBytes.size()); newXexFile.close(); if (newXexFile.bad()) diff --git a/XenonUtils/xex_patcher.h b/XenonUtils/xex_patcher.h index b8c57289..ba1c591b 100644 --- a/XenonUtils/xex_patcher.h +++ b/XenonUtils/xex_patcher.h @@ -18,7 +18,8 @@ struct XexPatcher { - enum class Result { + enum class Result + { Success, FileOpenFailed, FileWriteFailed, @@ -30,6 +31,6 @@ struct XexPatcher PatchUnsupported }; - static Result apply(const uint8_t* xexBytes, size_t xexBytesSize, const uint8_t* patchBytes, size_t patchBytesSize, std::vector &outBytes, bool skipData); - static Result apply(const std::filesystem::path &baseXexPath, const std::filesystem::path &patchXexPath, const std::filesystem::path &newXexPath); + static Result apply(const uint8_t* xexBytes, size_t xexBytesSize, const uint8_t* patchBytes, size_t patchBytesSize, std::vector& outBytes, bool skipData); + static Result apply(const std::filesystem::path& baseXexPath, const std::filesystem::path& patchXexPath, const std::filesystem::path& newXexPath); };