mirror of
https://github.com/sal063/AC6_recomp
synced 2026-08-25 00:05:52 -04:00
82 lines
2.8 KiB
C++
82 lines
2.8 KiB
C++
/**
|
|
* ReXGlue runtime - AC6 Recompilation project
|
|
* Copyright (c) 2026 Tom Clay. All rights reserved.
|
|
*/
|
|
|
|
#include <rex/logging.h>
|
|
#include <rex/ppc/function.h>
|
|
#include <rex/system/kernel_module.h>
|
|
#include <rex/system/function_dispatcher.h>
|
|
#include <rex/system/kernel_state.h>
|
|
#include <rex/thread/mutex.h>
|
|
|
|
namespace rex::system {
|
|
|
|
KernelModule::KernelModule(KernelState* kernel_state, const std::string_view path)
|
|
: XModule(kernel_state, ModuleType::kKernelModule) {
|
|
export_resolver_ = kernel_state->export_resolver();
|
|
|
|
path_ = path;
|
|
name_ = rex::string::utf8_find_base_name_from_guest_path(path);
|
|
|
|
// Persist this object through reloads.
|
|
host_object_ = true;
|
|
|
|
OnLoad();
|
|
}
|
|
|
|
KernelModule::~KernelModule() {}
|
|
|
|
uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
|
// Look up the export in the resolver
|
|
auto export_entry = export_resolver_->GetExportByOrdinal(name_, ordinal);
|
|
if (!export_entry) {
|
|
REXSYS_DEBUG("GetProcAddressByOrdinal: ordinal {:04X} not found in {}", ordinal, name_);
|
|
return 0;
|
|
}
|
|
|
|
if (export_entry->type == rex::runtime::Export::Type::kVariable) {
|
|
// Variables have guest addresses we can return directly
|
|
REXSYS_DEBUG("GetProcAddressByOrdinal: {} ({:04X}) -> variable at {:08X}", export_entry->name,
|
|
ordinal, export_entry->variable_ptr);
|
|
return export_entry->variable_ptr;
|
|
}
|
|
|
|
// Check thunk cache first (already allocated)
|
|
auto thunk_it = thunk_cache_.find(ordinal);
|
|
if (thunk_it != thunk_cache_.end()) {
|
|
REXSYS_DEBUG("GetProcAddressByOrdinal: {} ({:04X}) in {} -> cached thunk {:08X}",
|
|
export_entry->name, ordinal, name_, thunk_it->second);
|
|
return thunk_it->second;
|
|
}
|
|
|
|
// Look up native implementation by name from the auto-registry
|
|
std::string imp_name = std::string("__imp__") + export_entry->name;
|
|
REXSYS_DEBUG("GetProcAddressByOrdinal: searching registry for '{}'", imp_name);
|
|
PPCFunc* func = rex::FindPPCFuncByName(imp_name.c_str());
|
|
if (func) {
|
|
auto* dispatcher = kernel_state_->function_dispatcher();
|
|
uint32_t thunk_addr = dispatcher->AllocateThunk(func);
|
|
if (thunk_addr) {
|
|
thunk_cache_[ordinal] = thunk_addr;
|
|
REXSYS_INFO("GetProcAddressByOrdinal: {} ({:04X}) in {} -> thunk at {:08X}",
|
|
export_entry->name, ordinal, name_, thunk_addr);
|
|
return thunk_addr;
|
|
}
|
|
}
|
|
|
|
// No native implementation available
|
|
REXSYS_WARN("GetProcAddressByOrdinal: function {} ({:04X}) in {} - no native implementation",
|
|
export_entry->name, ordinal, name_);
|
|
return 0;
|
|
}
|
|
|
|
uint32_t KernelModule::GetProcAddressByName(const std::string_view name) {
|
|
// TODO: Does this even work for kernel modules?
|
|
(void)name;
|
|
REXSYS_ERROR("KernelModule::GetProcAddressByName not implemented");
|
|
return 0;
|
|
}
|
|
|
|
} // namespace rex::system
|