53 lines
1.5 KiB
C
Raw Normal View History

2024-05-11 21:14:14 -04:00
#pragma once
2024-06-04 18:29:13 -04:00
#include "../common/common.h"
2024-05-11 21:14:14 -04:00
// Trampoline Function
2024-09-20 21:30:47 -04:00
extern "C" std::remove_pointer_t<trampoline_t> trampoline;
2024-05-11 21:14:14 -04:00
// Macro
2024-06-04 18:29:13 -04:00
typedef uint32_t handler_t(trampoline_writer_t writer, const unsigned char *args);
2024-05-11 21:14:14 -04:00
__attribute__((visibility("internal"))) void _add_handler(unsigned char id, handler_t *handler);
#define CALL(unique_id, name, ignored1, ignored2) \
static handler_t _run_##name; \
__attribute__((constructor)) static void _init_##name() { \
_add_handler(unique_id, _run_##name); \
} \
2024-06-04 18:29:13 -04:00
static uint32_t _run_##name(__attribute__((unused)) trampoline_writer_t writer, const unsigned char *raw_args) { \
__attribute__((unused)) TrampolineArguments args(raw_args); \
2024-10-15 13:38:22 -04:00
static constexpr typeof(name) *func = name;
2024-05-11 21:14:14 -04:00
2024-09-20 21:30:47 -04:00
// Arguments
2024-06-04 18:29:13 -04:00
struct TrampolineArguments {
2024-09-20 21:30:47 -04:00
explicit TrampolineArguments(const unsigned char *args) {
2024-06-04 18:29:13 -04:00
this->raw_args = args;
this->position = 0;
}
template <typename T>
T next() {
block_pointer(T);
T ret = *(const T *) raw_args;
raw_args += sizeof(T);
return ret;
}
template <typename T>
const T *next_arr(uint32_t *length = nullptr) {
block_pointer(T);
const uint32_t size = next<uint32_t>();
if (length != nullptr) {
*length = size / sizeof(T);
}
2024-07-10 23:15:58 -04:00
if (size == 0) {
return nullptr;
}
2024-06-04 18:29:13 -04:00
const T *ret = (const T *) raw_args;
raw_args += size;
return ret;
}
private:
const unsigned char *raw_args;
unsigned int position;
};