osom_lib_test_macros/
convert_to_fn.rs

1#[macro_export]
2#[doc(hidden)]
3macro_rules! _fn_signature {
4    ($abi:literal, fn() -> $ret:ty) => {
5        unsafe extern $abi fn() -> $ret
6    };
7    ($abi:literal, fn($arg_type:ty) -> $ret:ty) => {
8        unsafe extern $abi fn($arg_type) -> $ret
9    };
10    ($abi:literal, fn($arg_type:ty $(,$arg_type2:ty)*) -> $ret:ty) => {
11        unsafe extern $abi fn($arg_type $(,$arg_type2)*) -> $ret
12    };
13}
14
15/// Transforms pointerable into a function pointer.
16///
17/// # Arguments
18///
19/// * `abi` - The ABI of the function, e.g. `"sysv64"`.
20/// * `pointerable` - The pointerable to transform into a function pointer. This
21///   is any object that implements [`crate::traits::Pointerable`] trait.
22/// * `offset` - the offset in the instructions `u8` buffer to jump to, relative
23///   to the beginning of the buffer.
24/// * `tokens` - optional function signature, e.g. `fn(i32, bool) -> u8`.
25#[macro_export]
26macro_rules! convert_to_fn_with_offset {
27    ($abi:literal, $pointerable:expr, $offset:expr, $($tokens:tt)*) => {
28        $crate::hidden::call(|| {
29            unsafe {
30                type _FnSignature = $crate::_fn_signature!($abi, $($tokens)*);
31                let _ptr = $crate::traits::Pointerable::as_ptr(&($pointerable))
32                    .add(($offset) as usize);
33                return core::mem::transmute::<*mut u8, _FnSignature>(_ptr);
34            }
35        })
36    };
37    ($abi: literal, $pointerable:expr, $offset:expr) => {
38        $crate::convert_to_fn_with_offset!($abi, $pointerable, $offset, fn() -> i64)
39    };
40}
41
42/// Transforms pointerable into a function pointer.
43///
44/// # Arguments
45///
46/// * `abi` - The ABI of the function, e.g. `"sysv64"`.
47/// * `pointerable` - The pointerable to transform into a function pointer. This
48///   is any object that implements [`crate::traits::Pointerable`] trait.
49/// * `tokens` - optional function signature, e.g. `fn(i32, bool) -> u8`.
50#[macro_export]
51macro_rules! convert_to_fn {
52    ($abi:literal, $pointerable:expr, $($tokens:tt)*) => {
53        $crate::convert_to_fn_with_offset!($abi, $pointerable, 0, $($tokens)*)
54    };
55    ($abi:literal, $pointerable:expr) => {
56        $crate::convert_to_fn_with_offset!($abi, $pointerable, 0, fn() -> i64)
57    };
58}