void __gcc_nested_func_ptr_created (void *chain, void *func, void *dst);
void __gcc_nested_func_ptr_deleted (void);
+#if __x86_64__
static const uint8_t trampoline_insns[] = {
- /* movabs $<chain>,%r11 */
+ /* movabs $<func>,%r11 */
0x49, 0xbb,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* movabs $<func>,%r10 */
+ /* movabs $<chain>,%r10 */
0x49, 0xba,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} fields;
};
+#elif __i386__
+
+static const uint8_t trampoline_insns[] = {
+ /* movl $<chain>,%ecx */
+ 0xb9,
+ 0x00, 0x00, 0x00, 0x00,
+
+ /* jmpl <func>-. */
+ 0xe9,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+union ix86_trampoline {
+ uint8_t insns[sizeof(trampoline_insns)];
+
+ struct __attribute__((packed)) fields {
+ uint8_t insn_0[1];
+ void *chain_ptr;
+ uint8_t insn_1[1];
+ uintptr_t func_offset;
+ } fields;
+};
+
+#else
+#error unsupported architecture/ABI
+#endif
+
struct tramp_ctrl_data
{
struct tramp_ctrl_data *prev;
memcpy (trampoline->insns, trampoline_insns,
sizeof(trampoline_insns));
- trampoline->fields.func_ptr = func;
trampoline->fields.chain_ptr = chain;
+#if __x86_64__
+ trampoline->fields.func_ptr = func;
+#elif __i386__
+ uintptr_t off_add = (uintptr_t) &trampoline->fields.func_offset;
+ off_add += 4;
+ trampoline->fields.func_offset = (uintptr_t)func - off_add;
+#endif
#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400
/* Re-enable write protection. */