Implement CALL_FUNC

This commit is contained in:
Nekotekina 2017-10-01 04:40:11 +03:00
parent d296e6021d
commit 144f6809bf
3 changed files with 76 additions and 13 deletions

View file

@ -124,7 +124,8 @@ struct ppu_linkage_info
{
struct info
{
bool hle = false;
ppu_static_function* static_func = nullptr;
ppu_static_variable* static_var = nullptr;
u32 export_addr = 0;
std::set<u32> imports;
std::set<u32> frefss;
@ -315,8 +316,9 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
{
auto& flink = linkage.functions[function.first];
flink.hle = true;
flink.static_func = &function.second;
flink.export_addr = ppu_function_manager::addr + 8 * function.second.index;
function.second.export_addr = &flink.export_addr;
}
}
@ -364,8 +366,9 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
{
auto& vlink = linkage.variables[variable.first];
vlink.hle = true;
vlink.export_addr = variable.second.var->addr();
vlink.static_var = &variable.second;
vlink.export_addr = variable.second.addr;
variable.second.export_addr = &vlink.export_addr;
}
}
}
@ -518,7 +521,12 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
// Function linkage info
auto& flink = mlink.functions[fnid];
if (flink.export_addr && !flink.hle)
if (flink.static_func && flink.export_addr == ppu_function_manager::addr + 8 * flink.static_func->index)
{
flink.export_addr = 0;
}
if (flink.export_addr)
{
LOG_ERROR(LOADER, "Already linked function '%s' in module '%s'", ppu_get_function_name(module_name, fnid), module_name);
}
@ -552,7 +560,6 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
{
// Set exported function
flink.export_addr = faddr;
flink.hle = false;
// Fix imports
for (const u32 addr : flink.imports)
@ -582,7 +589,12 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
// Variable linkage info
auto& vlink = mlink.variables[vnid];
if (vlink.export_addr && !vlink.hle)
if (vlink.static_var && vlink.export_addr == vlink.static_var->addr)
{
vlink.export_addr = 0;
}
if (vlink.export_addr)
{
LOG_ERROR(LOADER, "Already linked variable '%s' in module '%s'", ppu_get_variable_name(module_name, vnid), module_name);
}
@ -590,7 +602,6 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
{
// Set exported variable
vlink.export_addr = vaddr;
vlink.hle = false;
// Fix imports
for (const auto vref : vlink.imports)
@ -954,6 +965,23 @@ void ppu_unload_prx(const lv2_prx& prx)
pinfo->imports.erase(imp.first);
}
//for (auto& exp : prx.exports)
//{
// auto pinfo = static_cast<ppu_linkage_info::module::info*>(exp.second);
// if (pinfo->static_func)
// {
// pinfo->export_addr = ppu_function_manager::addr + 8 * pinfo->static_func->index;
// }
// else if (pinfo->static_var)
// {
// pinfo->export_addr = pinfo->static_var->addr;
// }
// else
// {
// pinfo->export_addr = 0;
// }
//}
for (auto& seg : prx.segs)
{
vm::dealloc(seg.addr, vm::main);