diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2024-02-10 14:44:41 +0000 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2024-02-12 15:03:12 +0000 |
commit | 5e39897ee2c73938fa940c4792d987608aeeebcd (patch) | |
tree | 0eb96f27c53c6cfbdd7a7838e222562c03b9cd0e /libgcc | |
parent | 1e94648ab7b370c5867e146c7f59603e2e6ba2e6 (diff) | |
download | gcc-5e39897ee2c73938fa940c4792d987608aeeebcd.zip gcc-5e39897ee2c73938fa940c4792d987608aeeebcd.tar.gz gcc-5e39897ee2c73938fa940c4792d987608aeeebcd.tar.bz2 |
x86, libgcc: Implement ia32 basic heap trampoline [PR113855].
The initial heap trampoline implementation was targeting 64b
platforms. As the PR demonstrates this creates an issue where it
is expected that the same symbols are exported for 32 and 64b.
Rather than conditionalize the exports and code-gen on x86_64,
this patch provides a basic implementation of the IA32 trampoline.
This also avoids potential user confusion, when a 32b target has
64b multilibs, and vice versa; which is the case for Darwin.
PR target/113855
gcc/ChangeLog:
* config/i386/darwin.h (DARWIN_HEAP_T_LIB): Moved to be
available to all sub-targets.
* config/i386/darwin32-biarch.h (DARWIN_HEAP_T_LIB): Delete.
* config/i386/darwin64-biarch.h (DARWIN_HEAP_T_LIB): Delete.
libgcc/ChangeLog:
* config.host: Add trampoline support to x?86-linux.
* config/i386/heap-trampoline.c (trampoline_insns): Provide
a variant for IA32.
(union ix86_trampoline): Likewise.
(__gcc_nested_func_ptr_created): Implement a basic trampoline
for IA32.
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. */ |