Check for the validity of save/restore function addresses. (#42)

This commit is contained in:
Skyth (Asilkan) 2025-03-04 18:44:24 +03:00 committed by GitHub
parent 2991a3b698
commit 3ee19542c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 32 deletions

View File

@ -98,51 +98,75 @@ void Recompiler::Analyse()
for (size_t i = 14; i < 128; i++) for (size_t i = 14; i < 128; i++)
{ {
if (i < 32) if (i < 32)
{
if (config.restGpr14Address != 0)
{ {
auto& restgpr = functions.emplace_back(); auto& restgpr = functions.emplace_back();
restgpr.base = config.restGpr14Address + (i - 14) * 4; restgpr.base = config.restGpr14Address + (i - 14) * 4;
restgpr.size = (32 - i) * 4 + 12; 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)
{
auto& savegpr = functions.emplace_back(); auto& savegpr = functions.emplace_back();
savegpr.base = config.saveGpr14Address + (i - 14) * 4; savegpr.base = config.saveGpr14Address + (i - 14) * 4;
savegpr.size = (32 - i) * 4 + 8; savegpr.size = (32 - i) * 4 + 8;
image.symbols.emplace(fmt::format("__savegprlr_{}", i), savegpr.base, savegpr.size, Symbol_Function); image.symbols.emplace(fmt::format("__savegprlr_{}", i), savegpr.base, savegpr.size, Symbol_Function);
}
if (config.restFpr14Address != 0)
{
auto& restfpr = functions.emplace_back(); auto& restfpr = functions.emplace_back();
restfpr.base = config.restFpr14Address + (i - 14) * 4; restfpr.base = config.restFpr14Address + (i - 14) * 4;
restfpr.size = (32 - i) * 4 + 4; restfpr.size = (32 - i) * 4 + 4;
image.symbols.emplace(fmt::format("__restfpr_{}", i), restfpr.base, restfpr.size, Symbol_Function); image.symbols.emplace(fmt::format("__restfpr_{}", i), restfpr.base, restfpr.size, Symbol_Function);
}
if (config.saveFpr14Address != 0)
{
auto& savefpr = functions.emplace_back(); auto& savefpr = functions.emplace_back();
savefpr.base = config.saveFpr14Address + (i - 14) * 4; savefpr.base = config.saveFpr14Address + (i - 14) * 4;
savefpr.size = (32 - i) * 4 + 4; savefpr.size = (32 - i) * 4 + 4;
image.symbols.emplace(fmt::format("__savefpr_{}", i), savefpr.base, savefpr.size, Symbol_Function); image.symbols.emplace(fmt::format("__savefpr_{}", i), savefpr.base, savefpr.size, Symbol_Function);
}
if (config.restVmx14Address != 0)
{
auto& restvmx = functions.emplace_back(); auto& restvmx = functions.emplace_back();
restvmx.base = config.restVmx14Address + (i - 14) * 8; restvmx.base = config.restVmx14Address + (i - 14) * 8;
restvmx.size = (32 - i) * 8 + 4; restvmx.size = (32 - i) * 8 + 4;
image.symbols.emplace(fmt::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function); image.symbols.emplace(fmt::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function);
}
if (config.saveVmx14Address != 0)
{
auto& savevmx = functions.emplace_back(); auto& savevmx = functions.emplace_back();
savevmx.base = config.saveVmx14Address + (i - 14) * 8; savevmx.base = config.saveVmx14Address + (i - 14) * 8;
savevmx.size = (32 - i) * 8 + 4; savevmx.size = (32 - i) * 8 + 4;
image.symbols.emplace(fmt::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function); image.symbols.emplace(fmt::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function);
} }
}
if (i >= 64) if (i >= 64)
{
if (config.restVmx64Address != 0)
{ {
auto& restvmx = functions.emplace_back(); auto& restvmx = functions.emplace_back();
restvmx.base = config.restVmx64Address + (i - 64) * 8; restvmx.base = config.restVmx64Address + (i - 64) * 8;
restvmx.size = (128 - i) * 8 + 4; restvmx.size = (128 - i) * 8 + 4;
image.symbols.emplace(fmt::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function); image.symbols.emplace(fmt::format("__restvmx_{}", i), restvmx.base, restvmx.size, Symbol_Function);
}
if (config.saveVmx64Address != 0)
{
auto& savevmx = functions.emplace_back(); auto& savevmx = functions.emplace_back();
savevmx.base = config.saveVmx64Address + (i - 64) * 8; savevmx.base = config.saveVmx64Address + (i - 64) * 8;
savevmx.size = (128 - i) * 8 + 4; savevmx.size = (128 - i) * 8 + 4;
image.symbols.emplace(fmt::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function); image.symbols.emplace(fmt::format("__savevmx_{}", i), savevmx.base, savevmx.size, Symbol_Function);
} }
} }
}
for (auto& [address, size] : config.functions) for (auto& [address, size] : config.functions)
{ {

View File

@ -38,6 +38,15 @@ void RecompilerConfig::Load(const std::string_view& configFilePath)
longJmpAddress = main["longjmp_address"].value_or(0u); longJmpAddress = main["longjmp_address"].value_or(0u);
setJmpAddress = main["setjmp_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 (auto functionsArray = main["functions"].as_array()) if (auto functionsArray = main["functions"].as_array())
{ {
for (auto& func : *functionsArray) for (auto& func : *functionsArray)