mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
LLVM: generate trampolines for "null" functions
Embed name into the trampoline for easier debugging. Only warn about it during the compilation phase.
This commit is contained in:
parent
aaaeb66cc8
commit
3567c43fb5
1 changed files with 58 additions and 7 deletions
|
@ -305,6 +305,49 @@ const bool jit_initialize = []() -> bool
|
||||||
return true;
|
return true;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
[[noreturn]] static void null(const char* name)
|
||||||
|
{
|
||||||
|
fmt::throw_exception("Null function: %s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static shared_mutex null_mtx;
|
||||||
|
|
||||||
|
static std::unordered_map<std::string, u64> null_funcs;
|
||||||
|
|
||||||
|
static u64 make_null_function(const std::string& name)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(null_mtx);
|
||||||
|
|
||||||
|
if (u64& func_ptr = null_funcs[name]) [[likely]]
|
||||||
|
{
|
||||||
|
// Already exists
|
||||||
|
return func_ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using namespace asmjit;
|
||||||
|
|
||||||
|
// Build a "null" function that contains its name
|
||||||
|
const auto func = build_function_asm<void (*)()>([&](X86Assembler& c, auto& args)
|
||||||
|
{
|
||||||
|
Label data = c.newLabel();
|
||||||
|
c.lea(args[0], x86::qword_ptr(data, 0));
|
||||||
|
c.jmp(imm_ptr(&null));
|
||||||
|
c.align(kAlignCode, 16);
|
||||||
|
c.bind(data);
|
||||||
|
|
||||||
|
// Copy function name bytes
|
||||||
|
for (char ch : name)
|
||||||
|
c.db(ch);
|
||||||
|
c.db(0);
|
||||||
|
c.align(kAlignData, 16);
|
||||||
|
});
|
||||||
|
|
||||||
|
func_ptr = reinterpret_cast<u64>(func);
|
||||||
|
return func_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Simple memory manager
|
// Simple memory manager
|
||||||
struct MemoryManager1 : llvm::RTDyldMemoryManager
|
struct MemoryManager1 : llvm::RTDyldMemoryManager
|
||||||
{
|
{
|
||||||
|
@ -327,19 +370,14 @@ struct MemoryManager1 : llvm::RTDyldMemoryManager
|
||||||
utils::memory_release(ptr, c_max_size * 2);
|
utils::memory_release(ptr, c_max_size * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] static void null()
|
|
||||||
{
|
|
||||||
fmt::throw_exception("Null function");
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm::JITSymbol findSymbol(const std::string& name) override
|
llvm::JITSymbol findSymbol(const std::string& name) override
|
||||||
{
|
{
|
||||||
u64 addr = RTDyldMemoryManager::getSymbolAddress(name);
|
u64 addr = RTDyldMemoryManager::getSymbolAddress(name);
|
||||||
|
|
||||||
if (!addr)
|
if (!addr)
|
||||||
{
|
{
|
||||||
jit_log.fatal("Function '%s' linked but not found.", name);
|
jit_log.error("Function '%s' linked but not found.", name);
|
||||||
addr = reinterpret_cast<uptr>(&null);
|
addr = make_null_function(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {addr, llvm::JITSymbolFlags::Exported};
|
return {addr, llvm::JITSymbolFlags::Exported};
|
||||||
|
@ -409,6 +447,19 @@ struct MemoryManager2 : llvm::RTDyldMemoryManager
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::JITSymbol findSymbol(const std::string& name) override
|
||||||
|
{
|
||||||
|
u64 addr = RTDyldMemoryManager::getSymbolAddress(name);
|
||||||
|
|
||||||
|
if (!addr)
|
||||||
|
{
|
||||||
|
jit_log.error("Function '%s' linked but not found.", name);
|
||||||
|
addr = make_null_function(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {addr, llvm::JITSymbolFlags::Exported};
|
||||||
|
}
|
||||||
|
|
||||||
u8* allocateCodeSection(uptr size, uint align, uint sec_id, llvm::StringRef sec_name) override
|
u8* allocateCodeSection(uptr size, uint align, uint sec_id, llvm::StringRef sec_name) override
|
||||||
{
|
{
|
||||||
return jit_runtime::alloc(size, align, true);
|
return jit_runtime::alloc(size, align, true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue