diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-08-28 19:14:49 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2016-06-23 09:48:52 -0700 |
commit | 7b0dbad23261aba50507025c59eacccb445d2ed7 (patch) | |
tree | d9d6edb3ed2c89e2cd6299b0e04c4b6d971131ef /gcc/configure.ac | |
parent | afa7ed877d72f2514673901cbd2c7779f8d4f880 (diff) | |
download | gcc-hjl/no-plt/got32x.tar.gz |
i386: Access external function via GOT slot for -fno-plthjl/no-plt/got32x
i386 psABI has been updated to clarify that R_386_GOT32X and R_386_GOT32
relocations can be used to access GOT without base register when PIC is
disabled:
https://groups.google.com/forum/#!topic/ia32-abi/awsRSvJOJfs
32-bit x86 assembler and linker from binutils 2.26.1 and 2.27 support
call/jmp *_start@GOT
cmpl $0, bar@GOT
for both normal and IFUNC functions. We check if 32-bit x86 assembler
and linker have the fix for:
https://sourceware.org/bugzilla/show_bug.cgi?id=20244
before accessing external function via GOT slot for -fno-plt in both PIC
and non-PIC modes.
PR target/66232
PR target/67400
* configure.ac (as_ix86_tls_ldm_opt): Renamed to ...
(as_ix86_gas_32_opt): This.
(ld_ix86_tls_ldm_opt): Renamed to ...
(ld_ix86_gld_32_opt): This.
(R_386_TLS_LDM reloc): Updated.
(R_386_GOT32X reloc): New assembler/linker check.
(HAVE_AS_IX86_GOT32X): New. Defined to 1 if 32-bit assembler and
linker support "jmp *_start@GOT" and "cmpl $0, bar@GOT". Otherise,
defined to 0.
* config.in: Regenerated.
* configure: Likewise.
* config/i386/i386.c (ix86_force_load_from_GOT_p): Return
true if HAVE_AS_IX86_GOT32X is 1 in 32-bit mode.
(ix86_legitimate_address_p): Allow UNSPEC_GOT for -fno-plt
if ix86_force_load_from_GOT_p returns true.
(ix86_print_operand_address_as): Also support UNSPEC_GOT if
ix86_force_load_from_GOT_p returns true.
(ix86_expand_move): Generate UNSPEC_GOT in 32-bit mode to load
the external function address via the GOT slot.
(ix86_nopic_noplt_attribute_p): Check both TARGET_64BIT and
HAVE_AS_IX86_GOT32X before returning false.
(ix86_output_call_insn): Generate "%!jmp/call\t*%p0@GOT" in
32-bit mode if ix86_nopic_noplt_attribute_p returns true.
gcc/testsuite/
PR target/66232
PR target/67400
* gcc.target/i386/pr66232-14.c: New file.
* gcc.target/i386/pr66232-15.c: Likewise.
* gcc.target/i386/pr66232-16.c: Likewise.
* gcc.target/i386/pr66232-17.c: Likewise.
* gcc.target/i386/pr67400-1.c: Don't disable for ia32. Scan for
ia32 if R_386_GOT32X relocation is supported.
* gcc.target/i386/pr67400-2.c: Likewise.
* gcc.target/i386/pr67400-3.c: Likewise.
* gcc.target/i386/pr67400-4.c: Likewise.
* gcc.target/i386/pr67400-6.c: Likewise.
* gcc.target/i386/pr67400-7.c: Likewise.
* lib/target-supports.exp (check_effective_target_got32x_reloc):
New.
Diffstat (limited to 'gcc/configure.ac')
-rw-r--r-- | gcc/configure.ac | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/gcc/configure.ac b/gcc/configure.ac index fabd48e5a25..b0f38d1e430 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4164,13 +4164,13 @@ tls_ld: # Enforce 32-bit output with gas and gld. if test x$gas = xyes; then - as_ix86_tls_ldm_opt="--32" + as_ix86_gas_32_opt="--32" fi if echo "$ld_ver" | grep GNU > /dev/null; then if $gcc_cv_ld -V 2>/dev/null | grep elf_i386_sol2 > /dev/null; then - ld_ix86_tls_ldm_opt="-melf_i386_sol2" + ld_ix86_gld_32_opt="-melf_i386_sol2" else - ld_ix86_tls_ldm_opt="-melf_i386" + ld_ix86_gld_32_opt="-melf_i386" fi fi conftest_s=' @@ -4186,10 +4186,10 @@ _start: value:' gcc_GAS_CHECK_FEATURE([R_386_TLS_LDM reloc], gcc_cv_as_ix86_tlsldm,, - [$as_ix86_tls_ldm_opt], + [$as_ix86_gas_32_opt], [$conftest_s], [if test x$gcc_cv_ld != x && test x$gcc_cv_objdump != x \ - && $gcc_cv_ld $ld_ix86_tls_ldm_opt -o conftest conftest.o $ld_tls_libs -lc > /dev/null 2>&1; then + && $gcc_cv_ld $ld_ix86_gld_32_opt -o conftest conftest.o $ld_tls_libs -lc > /dev/null 2>&1; then if $gcc_cv_objdump -d conftest 2>/dev/null | grep nop > /dev/null \ || dis conftest 2>/dev/null | grep nop > /dev/null; then gcc_cv_as_ix86_tlsldm=yes @@ -4200,6 +4200,35 @@ value:' [`if test $gcc_cv_as_ix86_tlsldm = yes; then echo 1; else echo 0; fi`], [Define to 1 if your assembler and linker support @tlsldm.]) + conftest_s=' + .data +bar: + .byte 1 + .text + .global _start +_start: + cmpl $0, bar@GOT + jmp *_start@GOT' + gcc_GAS_CHECK_FEATURE([R_386_GOT32X reloc], + gcc_cv_as_ix86_got32x,, + [$as_ix86_gas_32_opt], + [$conftest_s], + [if test x$gcc_cv_ld != x && test x$gcc_cv_objdump != x \ + && test x$gcc_cv_readelf != x \ + && $gcc_cv_readelf --relocs --wide conftest.o 2>&1 \ + | grep R_386_GOT32X > /dev/null 2>&1 \ + && $gcc_cv_ld $ld_ix86_gld_32_opt -o conftest conftest.o > /dev/null 2>&1; then + if $gcc_cv_objdump -dw conftest 2>&1 \ + | grep 0xffffff > /dev/null 2>&1; then + gcc_cv_as_ix86_got32x=no + else + gcc_cv_as_ix86_got32x=yes + fi + fi + rm -f conftest]) + AC_DEFINE_UNQUOTED(HAVE_AS_IX86_GOT32X, + [`if test x"$gcc_cv_as_ix86_got32x" = xyes; then echo 1; else echo 0; fi`], + [Define 0/1 if your assembler and linker support @GOT.]) ;; ia64*-*-*) |