Message ID | 20240210171444.132-1-iain@sandoe.co.uk |
---|---|
State | New |
Headers | show |
Series | x86, libgcc: Implement ia32 basic heap trampoline [PR113855]. | expand |
On Sat, Feb 10, 2024 at 05:14:44PM +0000, Iain Sandoe wrote: > 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. LGTM. I bet it probably doesn't work properly for -mx32 (which defines __x86_64__), CCing H.J. on that, but that is a preexisting issue (and I don't have any experience with it; I guess one would either need to add 4 bytes of padding after the func_ptr so that those bits remain zeros as sizeof (void *) is 4, but presumably it would be better to just use movl (but into %r10) and maybe the jmpl instead of movabsq. Jakub
> On 10 Feb 2024, at 17:46, Jakub Jelinek <jakub@redhat.com> wrote: > > On Sat, Feb 10, 2024 at 05:14:44PM +0000, Iain Sandoe wrote: >> 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. > > LGTM. > > I bet it probably doesn't work properly for -mx32 (which defines > __x86_64__), CCing H.J. on that, but that is a preexisting issue > (and I don't have any experience with it; I guess one would either > need to add 4 bytes of padding after the func_ptr so that those > bits remain zeros as sizeof (void *) is 4, but presumably it would be > better to just use movl (but into %r10) and maybe the jmpl instead > of movabsq. It seems that ix86_trampoline_init flips codegen on TARGET_64BIT so perhaps if we make it __x86_64__ && __LP64__? I had also considered maybe forcing the alignment of the trampoline allocations to a cache line (or maybe at least half a cache line). These considerations are also something to add to the improvements we can make to generalize the handling. For now, assuming remaining testing does not throw up any new issues, I’ll apply this to make progress on the PR. thanks Iain > > Jakub >
On Sat, Feb 10, 2024 at 9:46 AM Jakub Jelinek <jakub@redhat.com> wrote: > > On Sat, Feb 10, 2024 at 05:14:44PM +0000, Iain Sandoe wrote: > > 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. > > LGTM. > > I bet it probably doesn't work properly for -mx32 (which defines > __x86_64__), CCing H.J. on that, but that is a preexisting issue > (and I don't have any experience with it; I guess one would either > need to add 4 bytes of padding after the func_ptr so that those > bits remain zeros as sizeof (void *) is 4, but presumably it would be > better to just use movl (but into %r10) and maybe the jmpl instead > of movabsq. > > Jakub > Are there any testcases to exercise this code on Linux?
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h index 8e64b4e9b5f..bf9c45d70bb 100644 --- a/gcc/config/i386/darwin.h +++ b/gcc/config/i386/darwin.h @@ -119,9 +119,10 @@ along with GCC; see the file COPYING3. If not see /* We default to x86_64 for single-arch builds, bi-arch overrides. */ #define DARWIN_ARCH_SPEC "x86_64" #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC +#endif + #undef DARWIN_HEAP_T_LIB #define DARWIN_HEAP_T_LIB " -lheapt_w " -#endif #undef SUBTARGET_EXTRA_SPECS #define SUBTARGET_EXTRA_SPECS \ diff --git a/gcc/config/i386/darwin32-biarch.h b/gcc/config/i386/darwin32-biarch.h index 2180f5a5352..051ad12b425 100644 --- a/gcc/config/i386/darwin32-biarch.h +++ b/gcc/config/i386/darwin32-biarch.h @@ -27,9 +27,6 @@ along with GCC; see the file COPYING3. If not see #undef DARWIN_SUBARCH_SPEC #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC -#undef DARWIN_HEAP_T_LIB -#define DARWIN_HEAP_T_LIB " %{m64:-lheapt_w}" - #undef SUBTARGET_EXTRA_SPECS #define SUBTARGET_EXTRA_SPECS \ DARWIN_EXTRA_SPECS \ diff --git a/gcc/config/i386/darwin64-biarch.h b/gcc/config/i386/darwin64-biarch.h index 620800749a8..85436791a6c 100644 --- a/gcc/config/i386/darwin64-biarch.h +++ b/gcc/config/i386/darwin64-biarch.h @@ -28,9 +28,6 @@ along with GCC; see the file COPYING3. If not see #undef DARWIN_SUBARCH_SPEC #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC -#undef DARWIN_HEAP_T_LIB -#define DARWIN_HEAP_T_LIB "%{!m32:-lheapt_w}" - #undef SUBTARGET_EXTRA_SPECS #define SUBTARGET_EXTRA_SPECS \ DARWIN_EXTRA_SPECS \ diff --git a/libgcc/config.host b/libgcc/config.host index 3e7d00f67aa..59a42d3a01f 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 657b344c10c..1df0aa06108 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. */