macro_rules! runtime_thunk {
($(
$(#[$meta:meta])*
fn $name:ident = $sym:literal via $target:ident {
prologue: [$($prologue:expr),* $(,)?],
branch: $branch:literal,
epilogue: [$($epilogue:expr),* $(,)?] $(,)?
}
)*) => {$(
/// The address this thunk dispatches to, filled in at run time.
#[unsafe(no_mangle)]
static mut $target: *const core::ffi::c_void = core::ptr::null();
core::arch::global_asm!(
".p2align 2",
concat!(".globl _", $sym),
concat!("_", $sym, ":"),
$($prologue,)*
concat!("adrp x16, _", stringify!($target), "@PAGE"),
concat!("add x16, x16, _", stringify!($target), "@PAGEOFF"),
"ldr x16, [x16]",
concat!($branch, " x16"),
$($epilogue,)*
);
unsafe extern "C" {
$(#[$meta])*
#[link_name = $sym]
fn $name();
}
)*};
}
pub(crate) use runtime_thunk;