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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ Compilers other than Clang have not been tested and are not recommended, includi

On Windows, you can use the clang-cl toolset and open the project in Visual Studio's CMake integration.

On Linux, you can build via the following commands after creating and entering the `build` directory:
```
cmake -S .. -B . -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang -DCMAKE_EXE_LINKER_FLAGS="-lstdc++"
cmake --build . --config Release
```

## Special Thanks

This project could not have been possible without the [Xenia](https://github.com/xenia-project/xenia) emulator, as many parts of the CPU code conversion process has been implemented by heavily referencing its PPC code translator. The project also uses code from [Xenia Canary](https://github.com/xenia-canary/xenia-canary) to patch XEX binaries.
This project could not have been possible without the [Xenia](https://github.com/xenia-project/xenia) emulator, as many parts of the CPU code conversion process has been implemented by heavily referencing its PPC code translator. The project also uses code from [Xenia Canary](https://github.com/xenia-canary/xenia-canary) to patch XEX binaries.
67 changes: 34 additions & 33 deletions XenonAnalyse/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ void ReadTable(Image& image, SwitchTable& table)
uint32_t pOffset;
ppc_insn insn;
auto* code = (uint32_t*)image.Find(table.base);
ppc::Disassemble(code, table.base, insn);
pOffset = insn.operands[1] << 16;
ppc::Disassemble(code, table.base, insn); // lis
pOffset = insn.operands[1] << 16; // Upper 16 bits

ppc::Disassemble(code + 1, table.base + 4, insn);
pOffset += insn.operands[2];
ppc::Disassemble(code + 2, table.base + 8, insn); // addi (skip rlwinm at +4)
pOffset += insn.operands[2]; // Lower 16 bits

if (table.type == SWITCH_ABSOLUTE)
{
Expand Down Expand Up @@ -213,51 +213,52 @@ int main(int argc, char** argv)
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)
{
data = (uint8_t*)SearchMask(data, pattern, count, dataEnd - data);

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)
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;
}
};
}
};

// adjusted for tag 2
uint32_t absoluteSwitch[] =
{
PPC_INST_LIS,
PPC_INST_RLWINM, // (slwi alias)
PPC_INST_ADDI,
PPC_INST_RLWINM,
PPC_INST_LWZX,
PPC_INST_MTCTR,
PPC_INST_BCTR,
PPC_INST_BCTR
};

uint32_t computedSwitch[] =
Expand Down
Loading