diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/config.host | 1 | ||||
-rw-r--r-- | libgcc/config/i386/heap-trampoline.c | 40 |
2 files changed, 38 insertions, 3 deletions
diff --git a/libgcc/config.host b/libgcc/config.host index 3e7d00f..59a42d3 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -774,6 +774,7 @@ i[34567]86-*-linux*) tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" tm_file="${tm_file} i386/elf-lib.h" md_unwind_header=i386/linux-unwind.h + tmake_file="${tmake_file} i386/t-heap-trampoline" ;; i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-kopensolaris*-gnu) extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" diff --git a/libgcc/config/i386/heap-trampoline.c b/libgcc/config/i386/heap-trampoline.c index 657b344..1df0aa0 100644 --- a/libgcc/config/i386/heap-trampoline.c +++ b/libgcc/config/i386/heap-trampoline.c @@ -29,12 +29,13 @@ void *allocate_trampoline_page (void); 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, @@ -54,6 +55,33 @@ union ix86_trampoline { } 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; @@ -145,8 +173,14 @@ __gcc_nested_func_ptr_created (void *chain, void *func, void *dst) 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. */ |