Merge pull request #3225 from neobrain/fix_32bit_funcptrs

Thunks: Fix function pointer support on 32-bit
This commit is contained in:
Ryan Houdek authored and GitHub committed 2023-10-25 07:07:18 -07:00
commit 39c5ab1c81
3 files changed
+23 -17

No files matched your search

@@ -393,7 +393,7 @@ void Dispatcher::EmitDispatcher() {
LoadConstant(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r0, CTX->X86CodeGen.CallbackReturn);
ldr(ARMEmitter::XReg::x2, STATE_PTR(CpuStateFrame, State.gregs[X86State::REG_RSP]));
sub(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r2, ARMEmitter::Reg::r2, 16);
sub(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r2, ARMEmitter::Reg::r2, CTX->Config.Is64BitMode ? 16 : 12);
str(ARMEmitter::XReg::x2, STATE_PTR(CpuStateFrame, State.gregs[X86State::REG_RSP]));
// Store the trampoline to the guest stack
@@ -171,8 +171,14 @@ namespace FEXCore {
Set arg0/1 to arg regs, use CTX::HandleCallback to handle the callback
*/
static void CallCallback(void *callback, void *arg0, void* arg1) {
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0;
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1;
auto CTX = static_cast<Context::ContextImpl*>(Thread->CTX);
if (CTX->Config.Is64BitMode) {
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0;
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1;
} else {
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RCX] = (uintptr_t)arg0;
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDX] = (uintptr_t)arg1;
}
Thread->CTX->HandleCallback(Thread, (uintptr_t)callback);
}
@@ -220,7 +226,7 @@ namespace FEXCore {
emit->_StoreRegister(emit->_Constant(Entrypoint), false, offsetof(Core::CPUState, gregs[X86State::REG_R11]), IR::GPRClass, IR::GPRFixedClass, GPRSize);
}
else {
emit->_StoreRegister(emit->_Constant(Entrypoint), false, offsetof(Core::CPUState, mm[0][0]), IR::GPRClass, IR::GPRFixedClass, GPRSize);
emit->_StoreContext(GPRSize, IR::FPRClass, emit->_VCastFromGPR(8, 8, emit->_Constant(Entrypoint)), offsetof(Core::CPUState, mm[0][0]));
}
emit->_ExitFunction(emit->_Constant(GuestThunkEntrypoint));
}, CTX->ThunkHandler.get(), (void*)args->target_addr);
+13 -13
View File
@@ -10,7 +10,7 @@
#ifdef __clang__
#define THUNK_ABI __fastcall
#else
#define THUNK_ABI [[gnu::fastcall]]
#define THUNK_ABI __attribute__((fastcall))
#endif
#endif
@@ -75,8 +75,8 @@ MAKE_THUNK(fex, allocate_host_trampoline_for_guest_function, "0x9b, 0xb2, 0xf4,
inline void LinkAddressToFunction(uintptr_t addr, uintptr_t target) {
struct args_t {
uintptr_t original_callee;
uintptr_t target_addr; // Function to call when branching to replaced_addr
uint64_t original_callee;
uint64_t target_addr; // Function to call when branching to replaced_addr
};
args_t args = { addr, target };
fexthunks_fex_link_address_to_function(&args);
@@ -126,14 +126,14 @@ inline Result CallHostFunction(Args... args) {
// Use mm0 to pass in host_addr (chosen to avoid conflicts with vectorcall).
// Note this register overlaps the x87 st(0) register (used to return float values),
// so applications that expect this register to be preserved could run into problems.
register uintptr_t host_addr asm ("mm0");
asm volatile("" : "=r" (host_addr));
uintptr_t host_addr; \
asm volatile("movd %%mm0, %0" : "=r" (host_addr));
#endif
#else
uintptr_t host_addr = 0;
#endif
PackedArguments<Result, Args..., uintptr_t> packed_args = {
PackedArguments<Result, Args..., uint64_t> packed_args = {
args...,
host_addr
// Return value not explicitly initialized since an initializer would fail to compile for the void case
@@ -162,20 +162,20 @@ inline void MakeHostFunctionGuestCallable(THUNK_ABI Result (*host_func)(Args...)
}
template<typename Target>
inline Target *AllocateHostTrampolineForGuestFunction(void (*GuestUnpacker)(uintptr_t, void*), Target *GuestTarget) {
inline Target* AllocateHostTrampolineForGuestFunction(void THUNK_ABI (*GuestUnpacker)(uintptr_t, void*), Target *GuestTarget) {
if (!GuestTarget) {
return nullptr;
return 0;
}
struct {
uintptr_t GuestUnpacker;
uintptr_t GuestTarget;
uintptr_t rv;
uint64_t GuestUnpacker;
uint64_t GuestTarget;
uint64_t rv;
} argsrv = { (uintptr_t)GuestUnpacker, (uintptr_t)GuestTarget };
fexthunks_fex_allocate_host_trampoline_for_guest_function((void*)&argsrv);
return (Target *)argsrv.rv;
return (Target*)argsrv.rv;
}
template<typename F>
@@ -183,7 +183,7 @@ struct CallbackUnpack;
template<typename Result, typename... Args>
struct CallbackUnpack<Result(Args...)> {
static void Unpack(uintptr_t cb, void* argsv) {
static void THUNK_ABI Unpack(uintptr_t cb, void* argsv) {
using fn_t = Result(Args...);
auto callback = reinterpret_cast<fn_t*>(cb);
auto args = reinterpret_cast<PackedArguments<Result, Args...>*>(argsv);