Add midasm hook patching.

This commit is contained in:
Skyth 2024-10-06 18:54:47 +03:00
parent 1f5d7c32e8
commit 516e23f1f7
3 changed files with 110 additions and 0 deletions

View File

@ -325,6 +325,51 @@ bool Recompiler::Recompile(
}
};
auto midAsmHook = config.midAsmHooks.find(base);
if (midAsmHook != config.midAsmHooks.end())
{
print("\t{}(", 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;
case 'x':
out += xer();
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 'v':
out += v(std::atoi(reg.c_str() + 1));
break;
}
}
println(");");
}
int id = insn.opcode->id;
// Handling instructions that don't disassemble correctly for some reason here
@ -2092,6 +2137,48 @@ bool Recompiler::Recompile(const Function& fn)
for (auto label : switchTable->second.labels)
labels.emplace(label);
}
auto midAsmHook = config.midAsmHooks.find(addr);
if (midAsmHook != config.midAsmHooks.end())
{
print("extern void {}(", midAsmHook->second.name);
for (auto& reg : midAsmHook->second.registers)
{
if (out.back() != '(')
out += ", ";
switch (reg[0])
{
case 'c':
if (reg == "ctr")
print("PPCRegister& ctr");
else
print("PPCCRRegister& {}", reg);
break;
case 'x':
print("PPCXERRegister& xer");
break;
case 'r':
print("PPCRegister& {}", reg);
break;
case 'f':
if (reg == "fpscr")
print("PPCFPSCRRegister& fpscr");
else
print("PPCRegister& {}", reg);
break;
case 'v':
print("PPCVRegister& {}", reg);
break;
}
}
println(");\n");
}
}
auto symbol = image.symbols.find(fn.base);

View File

@ -73,4 +73,20 @@ void RecompilerConfig::Load(const std::string_view& configFilePath)
}
}
}
if (auto midAsmHookArray = toml["midasm_hook"].as_array())
{
for (auto& entry : *midAsmHookArray)
{
auto& table = *entry.as_table();
RecompilerMidAsmHook midAsmHook;
midAsmHook.name = *table["name"].value<std::string>();
for (auto& reg : *table["registers"].as_array())
{
midAsmHook.registers.push_back(*reg.value<std::string>());
}
midAsmHooks.emplace(*table["address"].value<uint32_t>(), std::move(midAsmHook));
}
}
}

View File

@ -6,6 +6,12 @@ struct RecompilerSwitchTable
std::vector<uint32_t> labels;
};
struct RecompilerMidAsmHook
{
std::string name;
std::vector<std::string> registers;
};
struct RecompilerConfig
{
std::string directoryPath;
@ -33,6 +39,7 @@ struct RecompilerConfig
uint32_t setJmpAddress = 0;
std::unordered_map<uint32_t, uint32_t> functions;
std::unordered_map<uint32_t, uint32_t> invalidInstructions;
std::unordered_map<uint32_t, RecompilerMidAsmHook> midAsmHooks;
void Load(const std::string_view& configFilePath);
};