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.
This commit is contained in:
Iain Sandoe 2024-02-10 14:44:41 +00:00
parent 1e94648ab7
commit 5e39897ee2
5 changed files with 40 additions and 10 deletions

View File

@ -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. */ /* We default to x86_64 for single-arch builds, bi-arch overrides. */
#define DARWIN_ARCH_SPEC "x86_64" #define DARWIN_ARCH_SPEC "x86_64"
#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
#endif
#undef DARWIN_HEAP_T_LIB #undef DARWIN_HEAP_T_LIB
#define DARWIN_HEAP_T_LIB " -lheapt_w " #define DARWIN_HEAP_T_LIB " -lheapt_w "
#endif
#undef SUBTARGET_EXTRA_SPECS #undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \ #define SUBTARGET_EXTRA_SPECS \

View File

@ -27,9 +27,6 @@ along with GCC; see the file COPYING3. If not see
#undef DARWIN_SUBARCH_SPEC #undef DARWIN_SUBARCH_SPEC
#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_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 #undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \ #define SUBTARGET_EXTRA_SPECS \
DARWIN_EXTRA_SPECS \ DARWIN_EXTRA_SPECS \

View File

@ -28,9 +28,6 @@ along with GCC; see the file COPYING3. If not see
#undef DARWIN_SUBARCH_SPEC #undef DARWIN_SUBARCH_SPEC
#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_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 #undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \ #define SUBTARGET_EXTRA_SPECS \
DARWIN_EXTRA_SPECS \ DARWIN_EXTRA_SPECS \

View File

@ -774,6 +774,7 @@ i[34567]86-*-linux*)
tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules"
tm_file="${tm_file} i386/elf-lib.h" tm_file="${tm_file} i386/elf-lib.h"
md_unwind_header=i386/linux-unwind.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) i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-kopensolaris*-gnu)
extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"

View File

@ -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_created (void *chain, void *func, void *dst);
void __gcc_nested_func_ptr_deleted (void); void __gcc_nested_func_ptr_deleted (void);
#if __x86_64__
static const uint8_t trampoline_insns[] = { static const uint8_t trampoline_insns[] = {
/* movabs $<chain>,%r11 */ /* movabs $<func>,%r11 */
0x49, 0xbb, 0x49, 0xbb,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* movabs $<func>,%r10 */ /* movabs $<chain>,%r10 */
0x49, 0xba, 0x49, 0xba,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -54,6 +55,33 @@ union ix86_trampoline {
} fields; } 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
{ {
struct tramp_ctrl_data *prev; 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, memcpy (trampoline->insns, trampoline_insns,
sizeof(trampoline_insns)); sizeof(trampoline_insns));
trampoline->fields.func_ptr = func;
trampoline->fields.chain_ptr = chain; 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 #if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400
/* Re-enable write protection. */ /* Re-enable write protection. */