* [PATCH] i386: Access external function via GOT slot for -fno-plt
@ 2016-06-23 11:45 H.J. Lu
2016-06-23 12:34 ` Uros Bizjak
0 siblings, 1 reply; 5+ messages in thread
From: H.J. Lu @ 2016-06-23 11:45 UTC (permalink / raw)
To: gcc-patches; +Cc: Uros Bizjak
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.
Tested on i686 and x86-64. OK for trunk?
H.J.
----
PR target/66232
PR target/67400
* configure.ac (HAVE_LD_IX86_GOT32X_RELOC): New. Defined to 1
if 32-bit assembler and linker support "jmp *_start@GOT" and
"movl $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_LD_IX86_GOT32X_RELOC 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 HAVE_LD_IX86_GOT32X_RELOC
== 0 before returning false in 32-bit mode.
(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 and 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.
---
gcc/config.in | 9 +++++-
gcc/config/i386/i386.c | 35 ++++++++++++++++----
gcc/configure | 50 +++++++++++++++++++++++++++++
gcc/configure.ac | 42 ++++++++++++++++++++++++
gcc/testsuite/gcc.target/i386/pr66232-14.c | 13 ++++++++
gcc/testsuite/gcc.target/i386/pr66232-15.c | 14 ++++++++
gcc/testsuite/gcc.target/i386/pr66232-16.c | 13 ++++++++
gcc/testsuite/gcc.target/i386/pr66232-17.c | 13 ++++++++
gcc/testsuite/gcc.target/i386/pr67400-1.c | 8 +++--
gcc/testsuite/gcc.target/i386/pr67400-2.c | 8 +++--
gcc/testsuite/gcc.target/i386/pr67400-3.c | 3 +-
gcc/testsuite/gcc.target/i386/pr67400-4.c | 5 +--
gcc/testsuite/gcc.target/i386/pr67400-6.c | 8 +++--
gcc/testsuite/gcc.target/i386/pr67400-7.c | 6 ++--
gcc/testsuite/lib/target-supports.exp | 51 ++++++++++++++++++++++++++++++
15 files changed, 256 insertions(+), 22 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-14.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-15.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-16.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-17.c
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9c7b015..a2dcf36 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -15125,7 +15125,8 @@ darwin_local_data_pic (rtx disp)
bool
ix86_force_load_from_GOT_p (rtx x)
{
- return (TARGET_64BIT && !TARGET_PECOFF && !TARGET_MACHO
+ return ((TARGET_64BIT || HAVE_LD_IX86_GOT32X_RELOC)
+ && !TARGET_PECOFF && !TARGET_MACHO
&& !flag_plt && !flag_pic
&& ix86_cmodel != CM_LARGE
&& GET_CODE (x) == SYMBOL_REF
@@ -15606,6 +15607,14 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
used. While ABI specify also 32bit relocations, we don't produce
them at all and use IP relative instead. */
case UNSPEC_GOT:
+ gcc_assert (flag_pic
+ || ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)));
+ if (!TARGET_64BIT)
+ goto is_legitimate_pic;
+
+ /* 64bit address unspec. */
+ return false;
+
case UNSPEC_GOTOFF:
gcc_assert (flag_pic);
if (!TARGET_64BIT)
@@ -18194,7 +18203,8 @@ ix86_print_operand_address_as (FILE *file, rtx addr,
/* Load the external function address via the GOT slot to avoid PLT. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
- && XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
+ && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
+ || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
&& ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
output_pic_addr_const (file, disp, 0);
else if (flag_pic)
@@ -19449,7 +19459,9 @@ ix86_expand_move (machine_mode mode, rtx operands[])
{
/* Load the external function address via GOT slot to avoid PLT. */
op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op1),
- UNSPEC_GOTPCREL);
+ (TARGET_64BIT
+ ? UNSPEC_GOTPCREL
+ : UNSPEC_GOT));
op1 = gen_rtx_CONST (Pmode, op1);
op1 = gen_const_mem (Pmode, op1);
set_mem_alias_set (op1, ix86_GOT_alias_set ());
@@ -28027,7 +28039,8 @@ static bool
ix86_nopic_noplt_attribute_p (rtx call_op)
{
if (flag_pic || ix86_cmodel == CM_LARGE
- || !TARGET_64BIT || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
+ || (!TARGET_64BIT && HAVE_LD_IX86_GOT32X_RELOC == 0)
+ || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
|| SYMBOL_REF_LOCAL_P (call_op))
return false;
@@ -28055,7 +28068,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
if (direct_p)
{
if (ix86_nopic_noplt_attribute_p (call_op))
- xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ {
+ if (TARGET_64BIT)
+ xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ else
+ xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
+ }
else
xasm = "%!jmp\t%P0";
}
@@ -28103,7 +28121,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
if (direct_p)
{
if (ix86_nopic_noplt_attribute_p (call_op))
- xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ {
+ if (TARGET_64BIT)
+ xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ else
+ xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
+ }
else
xasm = "%!call\t%P0";
}
diff --git a/gcc/configure.ac b/gcc/configure.ac
index fabd48e..2506957 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4200,6 +4200,48 @@ 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.])
+ AC_CACHE_CHECK([linker for R_386_GOT32X relocation],
+ [gcc_cv_ld_ix86_got32x_reloc],
+ [gcc_cv_ld_ix86_got32x_reloc=no
+ if test x$gcc_cv_as != x -a x$gcc_cv_ld != x \
+ -a x$gcc_cv_objdump != x -a x$gcc_cv_readelf != x; then
+ # Enforce 32-bit output with gas and gld.
+ if test x$gas = xyes; then
+ as_ix86_got32x_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_got32x_opt="-melf_i386_sol2"
+ else
+ ld_ix86_got32x_opt="-melf_i386"
+ fi
+ fi
+ cat > conftest.s <<EOF
+ .data
+bar:
+ .byte 1
+ .text
+ .global _start
+_start:
+ movl \$0, bar@GOT
+ jmp *_start@GOT
+EOF
+ if $gcc_cv_as $as_ix86_got32x_opt -o conftest.o conftest.s > /dev/null 2>&1 \
+ && $gcc_cv_readelf --relocs --wide conftest.o 2>&1 \
+ | grep R_386_GOT32X > /dev/null 2>&1 \
+ && $gcc_cv_ld $ld_ix86_got32x_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_ld_ix86_got32x_reloc=no
+ else
+ gcc_cv_ld_ix86_got32x_reloc=yes
+ fi
+ fi
+ fi
+ rm -f conftest conftest.s conftest.o])
+ AC_DEFINE_UNQUOTED(HAVE_LD_IX86_GOT32X_RELOC,
+ [`if test x"$gcc_cv_ld_ix86_got32x_reloc" = xyes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if Define if your linker supports R_386_GOT32X relocation.])
;;
ia64*-*-*)
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-14.c b/gcc/testsuite/gcc.target/i386/pr66232-14.c
new file mode 100644
index 0000000..804e5a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-14.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern void bar (void);
+
+void
+foo (void)
+{
+ bar ();
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-15.c b/gcc/testsuite/gcc.target/i386/pr66232-15.c
new file mode 100644
index 0000000..3d2f6da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-15.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern void bar (void);
+
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-16.c b/gcc/testsuite/gcc.target/i386/pr66232-16.c
new file mode 100644
index 0000000..d67f1a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-16.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern int bar (void);
+
+int
+foo (void)
+{
+ return bar ();
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-17.c b/gcc/testsuite/gcc.target/i386/pr66232-17.c
new file mode 100644
index 0000000..bf6f375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-17.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern int bar (void);
+
+int
+foo (void)
+{
+ return bar () + 1;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-1.c b/gcc/testsuite/gcc.target/i386/pr67400-1.c
index 18b3790..8af6650 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void);
@@ -9,5 +9,7 @@ foo (void)
return &bar;
}
-/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," } } */
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)l\[ \t\]*\(\\\$|\)bar," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-2.c b/gcc/testsuite/gcc.target/i386/pr67400-2.c
index 8f61c3f..23dd4bf 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-2.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void);
@@ -10,5 +10,7 @@ foo (void)
p = &bar;
}
-/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-3.c b/gcc/testsuite/gcc.target/i386/pr67400-3.c
index 40d3521..649c980 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-3.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-3.c
@@ -13,4 +13,5 @@ foo (void)
}
/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-4.c b/gcc/testsuite/gcc.target/i386/pr67400-4.c
index a329bbf..5f6883d 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-4.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-4.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void) __attribute__ ((visibility ("hidden")));
@@ -10,4 +10,5 @@ foo (void)
}
/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-6.c b/gcc/testsuite/gcc.target/i386/pr67400-6.c
index bb766cd..652add4 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-6.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-6.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern int bar (void);
@@ -9,5 +9,7 @@ check (void *p)
return p != &bar;
}
-/* { dg-final { scan-assembler "cmp\(l|q\)\[ \t\]*.*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler "cmp\(l|q\)\[ \t\]*.*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-7.c b/gcc/testsuite/gcc.target/i386/pr67400-7.c
index 32ae85f..900e87a 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-7.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-7.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void);
@@ -9,5 +9,5 @@ foo (void)
return &bar+1;
}
-/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," } } */
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 1b1d03a..0b9b507 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6975,6 +6975,57 @@ proc check_effective_target_pie_copyreloc { } {
return $pie_copyreloc_available_saved
}
+# Return 1 if the x86 target supports R_386_GOT32X relocation, 0
+# otherwise. Cache the result.
+
+proc check_effective_target_got32x_reloc { } {
+ global got32x_reloc_available_saved
+ global tool
+ global GCC_UNDER_TEST
+
+ if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+ return 0
+ }
+
+ # Need auto-host.h to check linker support.
+ if { ![file exists ../../auto-host.h ] } {
+ return 0
+ }
+
+ if [info exists got32x_reloc_available_saved] {
+ verbose "check_effective_target_got32x_reloc returning saved $got32x_reloc_available_saved" 2
+ } else {
+ # Include the current process ID in the file names to prevent
+ # conflicts with invocations for multiple testsuites.
+
+ set src got32x[pid].c
+ set obj got32x[pid].o
+
+ set f [open $src "w"]
+ puts $f "#include \"../../auto-host.h\""
+ puts $f "#if HAVE_LD_IX86_GOT32X_RELOC == 0"
+ puts $f "# error Assembler does not support R_386_GOT32X."
+ puts $f "#endif"
+ close $f
+
+ verbose "check_effective_target_got32x_reloc compiling testfile $src" 2
+ set lines [${tool}_target_compile $src $obj object ""]
+
+ file delete $src
+ file delete $obj
+
+ if [string match "" $lines] then {
+ verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
+ set got32x_reloc_available_saved 1
+ } else {
+ verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
+ set got32x_reloc_available_saved 0
+ }
+ }
+
+ return $got32x_reloc_available_saved
+}
+
# Return 1 if the target uses comdat groups.
proc check_effective_target_comdat_group {} {
--
2.5.5
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] i386: Access external function via GOT slot for -fno-plt
2016-06-23 11:45 [PATCH] i386: Access external function via GOT slot for -fno-plt H.J. Lu
@ 2016-06-23 12:34 ` Uros Bizjak
2016-06-23 16:08 ` H.J. Lu
0 siblings, 1 reply; 5+ messages in thread
From: Uros Bizjak @ 2016-06-23 12:34 UTC (permalink / raw)
To: H.J. Lu; +Cc: gcc-patches
On Thu, Jun 23, 2016 at 1:45 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> 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.
>
> Tested on i686 and x86-64. OK for trunk?
>
>
> H.J.
> ----
> PR target/66232
> PR target/67400
> * configure.ac (HAVE_LD_IX86_GOT32X_RELOC): New. Defined to 1
> if 32-bit assembler and linker support "jmp *_start@GOT" and
> "movl $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_LD_IX86_GOT32X_RELOC 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 HAVE_LD_IX86_GOT32X_RELOC
> == 0 before returning false in 32-bit mode.
> (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 and 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.
> ---
> gcc/config.in | 9 +++++-
> gcc/config/i386/i386.c | 35 ++++++++++++++++----
> gcc/configure | 50 +++++++++++++++++++++++++++++
> gcc/configure.ac | 42 ++++++++++++++++++++++++
> gcc/testsuite/gcc.target/i386/pr66232-14.c | 13 ++++++++
> gcc/testsuite/gcc.target/i386/pr66232-15.c | 14 ++++++++
> gcc/testsuite/gcc.target/i386/pr66232-16.c | 13 ++++++++
> gcc/testsuite/gcc.target/i386/pr66232-17.c | 13 ++++++++
> gcc/testsuite/gcc.target/i386/pr67400-1.c | 8 +++--
> gcc/testsuite/gcc.target/i386/pr67400-2.c | 8 +++--
> gcc/testsuite/gcc.target/i386/pr67400-3.c | 3 +-
> gcc/testsuite/gcc.target/i386/pr67400-4.c | 5 +--
> gcc/testsuite/gcc.target/i386/pr67400-6.c | 8 +++--
> gcc/testsuite/gcc.target/i386/pr67400-7.c | 6 ++--
> gcc/testsuite/lib/target-supports.exp | 51 ++++++++++++++++++++++++++++++
> 15 files changed, 256 insertions(+), 22 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-14.c
> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-15.c
> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-16.c
> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-17.c
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 9c7b015..a2dcf36 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -15125,7 +15125,8 @@ darwin_local_data_pic (rtx disp)
> bool
> ix86_force_load_from_GOT_p (rtx x)
> {
> - return (TARGET_64BIT && !TARGET_PECOFF && !TARGET_MACHO
> + return ((TARGET_64BIT || HAVE_LD_IX86_GOT32X_RELOC)
> + && !TARGET_PECOFF && !TARGET_MACHO
> && !flag_plt && !flag_pic
> && ix86_cmodel != CM_LARGE
> && GET_CODE (x) == SYMBOL_REF
> @@ -15606,6 +15607,14 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
> used. While ABI specify also 32bit relocations, we don't produce
> them at all and use IP relative instead. */
> case UNSPEC_GOT:
> + gcc_assert (flag_pic
> + || ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)));
> + if (!TARGET_64BIT)
> + goto is_legitimate_pic;
> +
> + /* 64bit address unspec. */
> + return false;
The above should read like:
case UNSPEC_GOT:
if (!TARGET_64BIT
&& ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
goto is_legitimate_pic;
/* FALLTHRU */
case UNSPEC_GOTOFF:
gcc_assert (flag_pic);
if (!TARGET_64BIT)
goto is_legitimate_pic;
Please also update the comment above.
> case UNSPEC_GOTOFF:
> gcc_assert (flag_pic);
> if (!TARGET_64BIT)
> @@ -18194,7 +18203,8 @@ ix86_print_operand_address_as (FILE *file, rtx addr,
> /* Load the external function address via the GOT slot to avoid PLT. */
> else if (GET_CODE (disp) == CONST
> && GET_CODE (XEXP (disp, 0)) == UNSPEC
> - && XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
> + && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
> + || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
> && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
> output_pic_addr_const (file, disp, 0);
> else if (flag_pic)
> @@ -19449,7 +19459,9 @@ ix86_expand_move (machine_mode mode, rtx operands[])
> {
> /* Load the external function address via GOT slot to avoid PLT. */
> op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op1),
> - UNSPEC_GOTPCREL);
> + (TARGET_64BIT
> + ? UNSPEC_GOTPCREL
> + : UNSPEC_GOT));
> op1 = gen_rtx_CONST (Pmode, op1);
> op1 = gen_const_mem (Pmode, op1);
> set_mem_alias_set (op1, ix86_GOT_alias_set ());
> @@ -28027,7 +28039,8 @@ static bool
> ix86_nopic_noplt_attribute_p (rtx call_op)
> {
> if (flag_pic || ix86_cmodel == CM_LARGE
> - || !TARGET_64BIT || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
> + || (!TARGET_64BIT && HAVE_LD_IX86_GOT32X_RELOC == 0)
|| !(TARGET_64BIT || HAVE_LD_IX86_GOT32X_RELOC)
> + || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
> || SYMBOL_REF_LOCAL_P (call_op))
> return false;
>
> @@ -28055,7 +28068,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
> if (direct_p)
> {
> if (ix86_nopic_noplt_attribute_p (call_op))
> - xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
> + {
> + if (TARGET_64BIT)
> + xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
> + else
> + xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
> + }
> else
> xasm = "%!jmp\t%P0";
> }
> @@ -28103,7 +28121,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
> if (direct_p)
> {
> if (ix86_nopic_noplt_attribute_p (call_op))
> - xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
> + {
> + if (TARGET_64BIT)
> + xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
> + else
> + xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
> + }
> else
> xasm = "%!call\t%P0";
> }
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index fabd48e..2506957 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -4200,6 +4200,48 @@ 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.])
>
> + AC_CACHE_CHECK([linker for R_386_GOT32X relocation],
> + [gcc_cv_ld_ix86_got32x_reloc],
> + [gcc_cv_ld_ix86_got32x_reloc=no
> + if test x$gcc_cv_as != x -a x$gcc_cv_ld != x \
> + -a x$gcc_cv_objdump != x -a x$gcc_cv_readelf != x; then
> + # Enforce 32-bit output with gas and gld.
> + if test x$gas = xyes; then
> + as_ix86_got32x_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_got32x_opt="-melf_i386_sol2"
> + else
> + ld_ix86_got32x_opt="-melf_i386"
> + fi
> + fi
> + cat > conftest.s <<EOF
> + .data
> +bar:
> + .byte 1
> + .text
> + .global _start
> +_start:
> + movl \$0, bar@GOT
> + jmp *_start@GOT
> +EOF
> + if $gcc_cv_as $as_ix86_got32x_opt -o conftest.o conftest.s > /dev/null 2>&1 \
> + && $gcc_cv_readelf --relocs --wide conftest.o 2>&1 \
> + | grep R_386_GOT32X > /dev/null 2>&1 \
> + && $gcc_cv_ld $ld_ix86_got32x_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_ld_ix86_got32x_reloc=no
> + else
> + gcc_cv_ld_ix86_got32x_reloc=yes
> + fi
> + fi
> + fi
> + rm -f conftest conftest.s conftest.o])
> + AC_DEFINE_UNQUOTED(HAVE_LD_IX86_GOT32X_RELOC,
> + [`if test x"$gcc_cv_ld_ix86_got32x_reloc" = xyes; then echo 1; else echo 0; fi`],
> + [Define 0/1 if Define if your linker supports R_386_GOT32X relocation.])
THe configure script already determined how to enforce 32bit output
with gas and gld, please rename and reuse as_ix86_tls_ldm_opt and
ld_ix86_tls_ldm_opt from the above check. Then define conftest_s and
call gcc_GAS_CHECK_FEATURE, as is the case with R_386_TLS_LDM reloc
check.
Also, please name this variable in a similar way, HAVE_AS_IX86_GOT32X.
Please repost v2 patch.
Uros.
> ;;
>
> ia64*-*-*)
> diff --git a/gcc/testsuite/gcc.target/i386/pr66232-14.c b/gcc/testsuite/gcc.target/i386/pr66232-14.c
> new file mode 100644
> index 0000000..804e5a5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr66232-14.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fno-pic -fno-plt" } */
> +
> +extern void bar (void);
> +
> +void
> +foo (void)
> +{
> + bar ();
> +}
> +
> +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr66232-15.c b/gcc/testsuite/gcc.target/i386/pr66232-15.c
> new file mode 100644
> index 0000000..3d2f6da
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr66232-15.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fno-pic -fno-plt" } */
> +
> +extern void bar (void);
> +
> +int
> +foo (void)
> +{
> + bar ();
> + return 0;
> +}
> +
> +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr66232-16.c b/gcc/testsuite/gcc.target/i386/pr66232-16.c
> new file mode 100644
> index 0000000..d67f1a5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr66232-16.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fno-pic -fno-plt" } */
> +
> +extern int bar (void);
> +
> +int
> +foo (void)
> +{
> + return bar ();
> +}
> +
> +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr66232-17.c b/gcc/testsuite/gcc.target/i386/pr66232-17.c
> new file mode 100644
> index 0000000..bf6f375
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr66232-17.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fno-pic -fno-plt" } */
> +
> +extern int bar (void);
> +
> +int
> +foo (void)
> +{
> + return bar () + 1;
> +}
> +
> +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr67400-1.c b/gcc/testsuite/gcc.target/i386/pr67400-1.c
> index 18b3790..8af6650 100644
> --- a/gcc/testsuite/gcc.target/i386/pr67400-1.c
> +++ b/gcc/testsuite/gcc.target/i386/pr67400-1.c
> @@ -1,4 +1,4 @@
> -/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
> +/* { dg-do compile { target *-*-linux* } } */
> /* { dg-options "-O2 -fno-pic -fno-plt" } */
>
> extern void bar (void);
> @@ -9,5 +9,7 @@ foo (void)
> return &bar;
> }
>
> -/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
> -/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," } } */
> +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
> +/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "\(mov|lea\)l\[ \t\]*\(\\\$|\)bar," { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr67400-2.c b/gcc/testsuite/gcc.target/i386/pr67400-2.c
> index 8f61c3f..23dd4bf 100644
> --- a/gcc/testsuite/gcc.target/i386/pr67400-2.c
> +++ b/gcc/testsuite/gcc.target/i386/pr67400-2.c
> @@ -1,4 +1,4 @@
> -/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
> +/* { dg-do compile { target *-*-linux* } } */
> /* { dg-options "-O2 -fno-pic -fno-plt" } */
>
> extern void bar (void);
> @@ -10,5 +10,7 @@ foo (void)
> p = &bar;
> }
>
> -/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
> -/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," } } */
> +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
> +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr67400-3.c b/gcc/testsuite/gcc.target/i386/pr67400-3.c
> index 40d3521..649c980 100644
> --- a/gcc/testsuite/gcc.target/i386/pr67400-3.c
> +++ b/gcc/testsuite/gcc.target/i386/pr67400-3.c
> @@ -13,4 +13,5 @@ foo (void)
> }
>
> /* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
> -/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
> +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr67400-4.c b/gcc/testsuite/gcc.target/i386/pr67400-4.c
> index a329bbf..5f6883d 100644
> --- a/gcc/testsuite/gcc.target/i386/pr67400-4.c
> +++ b/gcc/testsuite/gcc.target/i386/pr67400-4.c
> @@ -1,4 +1,4 @@
> -/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
> +/* { dg-do compile { target *-*-linux* } } */
> /* { dg-options "-O2 -fno-pic -fno-plt" } */
>
> extern void bar (void) __attribute__ ((visibility ("hidden")));
> @@ -10,4 +10,5 @@ foo (void)
> }
>
> /* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
> -/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
> +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr67400-6.c b/gcc/testsuite/gcc.target/i386/pr67400-6.c
> index bb766cd..652add4 100644
> --- a/gcc/testsuite/gcc.target/i386/pr67400-6.c
> +++ b/gcc/testsuite/gcc.target/i386/pr67400-6.c
> @@ -1,4 +1,4 @@
> -/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
> +/* { dg-do compile { target *-*-linux* } } */
> /* { dg-options "-O2 -fno-pic -fno-plt" } */
>
> extern int bar (void);
> @@ -9,5 +9,7 @@ check (void *p)
> return p != &bar;
> }
>
> -/* { dg-final { scan-assembler "cmp\(l|q\)\[ \t\]*.*bar@GOTPCREL" } } */
> -/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," } } */
> +/* { dg-final { scan-assembler "cmp\(l|q\)\[ \t\]*.*bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
> +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr67400-7.c b/gcc/testsuite/gcc.target/i386/pr67400-7.c
> index 32ae85f..900e87a 100644
> --- a/gcc/testsuite/gcc.target/i386/pr67400-7.c
> +++ b/gcc/testsuite/gcc.target/i386/pr67400-7.c
> @@ -1,4 +1,4 @@
> -/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
> +/* { dg-do compile { target *-*-linux* } } */
> /* { dg-options "-O2 -fno-pic -fno-plt" } */
>
> extern void bar (void);
> @@ -9,5 +9,5 @@ foo (void)
> return &bar+1;
> }
>
> -/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
> -/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," } } */
> +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," { target { ! ia32 } } } } */
> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
> index 1b1d03a..0b9b507 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -6975,6 +6975,57 @@ proc check_effective_target_pie_copyreloc { } {
> return $pie_copyreloc_available_saved
> }
>
> +# Return 1 if the x86 target supports R_386_GOT32X relocation, 0
> +# otherwise. Cache the result.
> +
> +proc check_effective_target_got32x_reloc { } {
> + global got32x_reloc_available_saved
> + global tool
> + global GCC_UNDER_TEST
> +
> + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
> + return 0
> + }
> +
> + # Need auto-host.h to check linker support.
> + if { ![file exists ../../auto-host.h ] } {
> + return 0
> + }
> +
> + if [info exists got32x_reloc_available_saved] {
> + verbose "check_effective_target_got32x_reloc returning saved $got32x_reloc_available_saved" 2
> + } else {
> + # Include the current process ID in the file names to prevent
> + # conflicts with invocations for multiple testsuites.
> +
> + set src got32x[pid].c
> + set obj got32x[pid].o
> +
> + set f [open $src "w"]
> + puts $f "#include \"../../auto-host.h\""
> + puts $f "#if HAVE_LD_IX86_GOT32X_RELOC == 0"
> + puts $f "# error Assembler does not support R_386_GOT32X."
> + puts $f "#endif"
> + close $f
> +
> + verbose "check_effective_target_got32x_reloc compiling testfile $src" 2
> + set lines [${tool}_target_compile $src $obj object ""]
> +
> + file delete $src
> + file delete $obj
> +
> + if [string match "" $lines] then {
> + verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
> + set got32x_reloc_available_saved 1
> + } else {
> + verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
> + set got32x_reloc_available_saved 0
> + }
> + }
> +
> + return $got32x_reloc_available_saved
> +}
> +
> # Return 1 if the target uses comdat groups.
>
> proc check_effective_target_comdat_group {} {
> --
> 2.5.5
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] i386: Access external function via GOT slot for -fno-plt
2016-06-23 12:34 ` Uros Bizjak
@ 2016-06-23 16:08 ` H.J. Lu
2016-06-23 16:23 ` Uros Bizjak
0 siblings, 1 reply; 5+ messages in thread
From: H.J. Lu @ 2016-06-23 16:08 UTC (permalink / raw)
To: Uros Bizjak; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 10967 bytes --]
On Thu, Jun 23, 2016 at 5:33 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Thu, Jun 23, 2016 at 1:45 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>> 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.
>>
>> Tested on i686 and x86-64. OK for trunk?
>>
>>
>> H.J.
>> ----
>> PR target/66232
>> PR target/67400
>> * configure.ac (HAVE_LD_IX86_GOT32X_RELOC): New. Defined to 1
>> if 32-bit assembler and linker support "jmp *_start@GOT" and
>> "movl $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_LD_IX86_GOT32X_RELOC 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 HAVE_LD_IX86_GOT32X_RELOC
>> == 0 before returning false in 32-bit mode.
>> (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 and 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.
>> ---
>> gcc/config.in | 9 +++++-
>> gcc/config/i386/i386.c | 35 ++++++++++++++++----
>> gcc/configure | 50 +++++++++++++++++++++++++++++
>> gcc/configure.ac | 42 ++++++++++++++++++++++++
>> gcc/testsuite/gcc.target/i386/pr66232-14.c | 13 ++++++++
>> gcc/testsuite/gcc.target/i386/pr66232-15.c | 14 ++++++++
>> gcc/testsuite/gcc.target/i386/pr66232-16.c | 13 ++++++++
>> gcc/testsuite/gcc.target/i386/pr66232-17.c | 13 ++++++++
>> gcc/testsuite/gcc.target/i386/pr67400-1.c | 8 +++--
>> gcc/testsuite/gcc.target/i386/pr67400-2.c | 8 +++--
>> gcc/testsuite/gcc.target/i386/pr67400-3.c | 3 +-
>> gcc/testsuite/gcc.target/i386/pr67400-4.c | 5 +--
>> gcc/testsuite/gcc.target/i386/pr67400-6.c | 8 +++--
>> gcc/testsuite/gcc.target/i386/pr67400-7.c | 6 ++--
>> gcc/testsuite/lib/target-supports.exp | 51 ++++++++++++++++++++++++++++++
>> 15 files changed, 256 insertions(+), 22 deletions(-)
>> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-14.c
>> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-15.c
>> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-16.c
>> create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-17.c
>>
>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>> index 9c7b015..a2dcf36 100644
>> --- a/gcc/config/i386/i386.c
>> +++ b/gcc/config/i386/i386.c
>> @@ -15125,7 +15125,8 @@ darwin_local_data_pic (rtx disp)
>> bool
>> ix86_force_load_from_GOT_p (rtx x)
>> {
>> - return (TARGET_64BIT && !TARGET_PECOFF && !TARGET_MACHO
>> + return ((TARGET_64BIT || HAVE_LD_IX86_GOT32X_RELOC)
>> + && !TARGET_PECOFF && !TARGET_MACHO
>> && !flag_plt && !flag_pic
>> && ix86_cmodel != CM_LARGE
>> && GET_CODE (x) == SYMBOL_REF
>> @@ -15606,6 +15607,14 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
>> used. While ABI specify also 32bit relocations, we don't produce
>> them at all and use IP relative instead. */
>> case UNSPEC_GOT:
>> + gcc_assert (flag_pic
>> + || ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)));
>> + if (!TARGET_64BIT)
>> + goto is_legitimate_pic;
>> +
>> + /* 64bit address unspec. */
>> + return false;
>
> The above should read like:
>
> case UNSPEC_GOT:
> if (!TARGET_64BIT
> && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
> goto is_legitimate_pic;
> /* FALLTHRU */
> case UNSPEC_GOTOFF:
> gcc_assert (flag_pic);
> if (!TARGET_64BIT)
> goto is_legitimate_pic;
>
> Please also update the comment above.
>
>> case UNSPEC_GOTOFF:
>> gcc_assert (flag_pic);
>> if (!TARGET_64BIT)
>> @@ -18194,7 +18203,8 @@ ix86_print_operand_address_as (FILE *file, rtx addr,
>> /* Load the external function address via the GOT slot to avoid PLT. */
>> else if (GET_CODE (disp) == CONST
>> && GET_CODE (XEXP (disp, 0)) == UNSPEC
>> - && XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
>> + && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
>> + || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
>> && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
>> output_pic_addr_const (file, disp, 0);
>> else if (flag_pic)
>> @@ -19449,7 +19459,9 @@ ix86_expand_move (machine_mode mode, rtx operands[])
>> {
>> /* Load the external function address via GOT slot to avoid PLT. */
>> op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op1),
>> - UNSPEC_GOTPCREL);
>> + (TARGET_64BIT
>> + ? UNSPEC_GOTPCREL
>> + : UNSPEC_GOT));
>> op1 = gen_rtx_CONST (Pmode, op1);
>> op1 = gen_const_mem (Pmode, op1);
>> set_mem_alias_set (op1, ix86_GOT_alias_set ());
>> @@ -28027,7 +28039,8 @@ static bool
>> ix86_nopic_noplt_attribute_p (rtx call_op)
>> {
>> if (flag_pic || ix86_cmodel == CM_LARGE
>> - || !TARGET_64BIT || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
>> + || (!TARGET_64BIT && HAVE_LD_IX86_GOT32X_RELOC == 0)
>
> || !(TARGET_64BIT || HAVE_LD_IX86_GOT32X_RELOC)
>
>> + || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
>> || SYMBOL_REF_LOCAL_P (call_op))
>> return false;
>>
>> @@ -28055,7 +28068,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
>> if (direct_p)
>> {
>> if (ix86_nopic_noplt_attribute_p (call_op))
>> - xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
>> + {
>> + if (TARGET_64BIT)
>> + xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
>> + else
>> + xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
>> + }
>> else
>> xasm = "%!jmp\t%P0";
>> }
>> @@ -28103,7 +28121,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
>> if (direct_p)
>> {
>> if (ix86_nopic_noplt_attribute_p (call_op))
>> - xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
>> + {
>> + if (TARGET_64BIT)
>> + xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
>> + else
>> + xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
>> + }
>> else
>> xasm = "%!call\t%P0";
>> }
>> diff --git a/gcc/configure.ac b/gcc/configure.ac
>> index fabd48e..2506957 100644
>> --- a/gcc/configure.ac
>> +++ b/gcc/configure.ac
>> @@ -4200,6 +4200,48 @@ 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.])
>>
>> + AC_CACHE_CHECK([linker for R_386_GOT32X relocation],
>> + [gcc_cv_ld_ix86_got32x_reloc],
>> + [gcc_cv_ld_ix86_got32x_reloc=no
>> + if test x$gcc_cv_as != x -a x$gcc_cv_ld != x \
>> + -a x$gcc_cv_objdump != x -a x$gcc_cv_readelf != x; then
>> + # Enforce 32-bit output with gas and gld.
>> + if test x$gas = xyes; then
>> + as_ix86_got32x_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_got32x_opt="-melf_i386_sol2"
>> + else
>> + ld_ix86_got32x_opt="-melf_i386"
>> + fi
>> + fi
>> + cat > conftest.s <<EOF
>> + .data
>> +bar:
>> + .byte 1
>> + .text
>> + .global _start
>> +_start:
>> + movl \$0, bar@GOT
>> + jmp *_start@GOT
>> +EOF
>> + if $gcc_cv_as $as_ix86_got32x_opt -o conftest.o conftest.s > /dev/null 2>&1 \
>> + && $gcc_cv_readelf --relocs --wide conftest.o 2>&1 \
>> + | grep R_386_GOT32X > /dev/null 2>&1 \
>> + && $gcc_cv_ld $ld_ix86_got32x_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_ld_ix86_got32x_reloc=no
>> + else
>> + gcc_cv_ld_ix86_got32x_reloc=yes
>> + fi
>> + fi
>> + fi
>> + rm -f conftest conftest.s conftest.o])
>> + AC_DEFINE_UNQUOTED(HAVE_LD_IX86_GOT32X_RELOC,
>> + [`if test x"$gcc_cv_ld_ix86_got32x_reloc" = xyes; then echo 1; else echo 0; fi`],
>> + [Define 0/1 if Define if your linker supports R_386_GOT32X relocation.])
>
> THe configure script already determined how to enforce 32bit output
> with gas and gld, please rename and reuse as_ix86_tls_ldm_opt and
> ld_ix86_tls_ldm_opt from the above check. Then define conftest_s and
> call gcc_GAS_CHECK_FEATURE, as is the case with R_386_TLS_LDM reloc
> check.
>
> Also, please name this variable in a similar way, HAVE_AS_IX86_GOT32X.
>
> Please repost v2 patch.
>
Here is the updated patch. OK for trunk?
Thanks.
--
H.J.
[-- Attachment #2: 0001-i386-Access-external-function-via-GOT-slot-for-fno-p.patch --]
[-- Type: text/x-patch, Size: 20294 bytes --]
From 10a37b1c3681a5d9432f98541fca76206b798b59 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 28 Aug 2015 19:14:49 -0700
Subject: [PATCH] i386: Access external function via GOT slot for -fno-plt
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_opt): This.
(ld_ix86_tls_ldm_opt): Renamed to ...
(ld_ix86_gld_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.
---
gcc/config.in | 9 ++++-
gcc/config/i386/i386.c | 51 ++++++++++++++++--------
gcc/configure | 62 +++++++++++++++++++++++++++---
gcc/configure.ac | 39 ++++++++++++++++---
gcc/testsuite/gcc.target/i386/pr66232-14.c | 13 +++++++
gcc/testsuite/gcc.target/i386/pr66232-15.c | 14 +++++++
gcc/testsuite/gcc.target/i386/pr66232-16.c | 13 +++++++
gcc/testsuite/gcc.target/i386/pr66232-17.c | 13 +++++++
gcc/testsuite/gcc.target/i386/pr67400-1.c | 8 ++--
gcc/testsuite/gcc.target/i386/pr67400-2.c | 8 ++--
gcc/testsuite/gcc.target/i386/pr67400-3.c | 3 +-
gcc/testsuite/gcc.target/i386/pr67400-4.c | 5 ++-
gcc/testsuite/gcc.target/i386/pr67400-6.c | 8 ++--
gcc/testsuite/gcc.target/i386/pr67400-7.c | 6 +--
gcc/testsuite/lib/target-supports.exp | 51 ++++++++++++++++++++++++
15 files changed, 262 insertions(+), 41 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-14.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-15.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-16.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-17.c
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9c7b015..f7944f9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -15125,7 +15125,8 @@ darwin_local_data_pic (rtx disp)
bool
ix86_force_load_from_GOT_p (rtx x)
{
- return (TARGET_64BIT && !TARGET_PECOFF && !TARGET_MACHO
+ return ((TARGET_64BIT || HAVE_AS_IX86_GOT32X)
+ && !TARGET_PECOFF && !TARGET_MACHO
&& !flag_plt && !flag_pic
&& ix86_cmodel != CM_LARGE
&& GET_CODE (x) == SYMBOL_REF
@@ -15602,10 +15603,16 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
&& XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
switch (XINT (XEXP (disp, 0), 1))
{
- /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit when
- used. While ABI specify also 32bit relocations, we don't produce
- them at all and use IP relative instead. */
+ /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit
+ when used. While ABI specify also 32bit relocations, we
+ don't produce them at all and use IP relative instead.
+ Allow GOT in 32bit mode for both PIC and non-PIC if symbol
+ should be loaded via GOT. */
case UNSPEC_GOT:
+ if (!TARGET_64BIT
+ && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
+ goto is_legitimate_pic;
+ /* FALLTHRU */
case UNSPEC_GOTOFF:
gcc_assert (flag_pic);
if (!TARGET_64BIT)
@@ -18194,7 +18201,8 @@ ix86_print_operand_address_as (FILE *file, rtx addr,
/* Load the external function address via the GOT slot to avoid PLT. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
- && XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
+ && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
+ || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
&& ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
output_pic_addr_const (file, disp, 0);
else if (flag_pic)
@@ -19449,7 +19457,9 @@ ix86_expand_move (machine_mode mode, rtx operands[])
{
/* Load the external function address via GOT slot to avoid PLT. */
op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op1),
- UNSPEC_GOTPCREL);
+ (TARGET_64BIT
+ ? UNSPEC_GOTPCREL
+ : UNSPEC_GOT));
op1 = gen_rtx_CONST (Pmode, op1);
op1 = gen_const_mem (Pmode, op1);
set_mem_alias_set (op1, ix86_GOT_alias_set ());
@@ -28016,18 +28026,19 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
return call;
}
-/* Return true if the function being called was marked with attribute "noplt"
- or using -fno-plt and we are compiling for non-PIC and x86_64. We need to
- handle the non-PIC case in the backend because there is no easy interface
- for the front-end to force non-PLT calls to use the GOT. This is currently
- used only with 64-bit ELF targets to call the function marked "noplt"
- indirectly. */
+/* Return true if the function being called was marked with attribute
+ "noplt" or using -fno-plt and we are compiling for non-PIC. We need
+ to handle the non-PIC case in the backend because there is no easy
+ interface for the front-end to force non-PLT calls to use the GOT.
+ This is currently used only with 64-bit or 32-bit GOT32X ELF targets
+ to call the function marked "noplt" indirectly. */
static bool
ix86_nopic_noplt_attribute_p (rtx call_op)
{
if (flag_pic || ix86_cmodel == CM_LARGE
- || !TARGET_64BIT || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
+ || !(TARGET_64BIT || HAVE_AS_IX86_GOT32X)
+ || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
|| SYMBOL_REF_LOCAL_P (call_op))
return false;
@@ -28055,7 +28066,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
if (direct_p)
{
if (ix86_nopic_noplt_attribute_p (call_op))
- xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ {
+ if (TARGET_64BIT)
+ xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ else
+ xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
+ }
else
xasm = "%!jmp\t%P0";
}
@@ -28103,7 +28119,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
if (direct_p)
{
if (ix86_nopic_noplt_attribute_p (call_op))
- xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ {
+ if (TARGET_64BIT)
+ xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
+ else
+ xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
+ }
else
xasm = "%!call\t%P0";
}
diff --git a/gcc/configure.ac b/gcc/configure.ac
index fabd48e..db3c603 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_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_opt="-melf_i386_sol2"
else
- ld_ix86_tls_ldm_opt="-melf_i386"
+ ld_ix86_gld_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_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_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_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_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*-*-*)
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-14.c b/gcc/testsuite/gcc.target/i386/pr66232-14.c
new file mode 100644
index 0000000..804e5a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-14.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern void bar (void);
+
+void
+foo (void)
+{
+ bar ();
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-15.c b/gcc/testsuite/gcc.target/i386/pr66232-15.c
new file mode 100644
index 0000000..3d2f6da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-15.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern void bar (void);
+
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-16.c b/gcc/testsuite/gcc.target/i386/pr66232-16.c
new file mode 100644
index 0000000..d67f1a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-16.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern int bar (void);
+
+int
+foo (void)
+{
+ return bar ();
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr66232-17.c b/gcc/testsuite/gcc.target/i386/pr66232-17.c
new file mode 100644
index 0000000..bf6f375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66232-17.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern int bar (void);
+
+int
+foo (void)
+{
+ return bar () + 1;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-1.c b/gcc/testsuite/gcc.target/i386/pr67400-1.c
index 18b3790..8af6650 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void);
@@ -9,5 +9,7 @@ foo (void)
return &bar;
}
-/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," } } */
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)l\[ \t\]*\(\\\$|\)bar," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-2.c b/gcc/testsuite/gcc.target/i386/pr67400-2.c
index 8f61c3f..23dd4bf 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-2.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void);
@@ -10,5 +10,7 @@ foo (void)
p = &bar;
}
-/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-3.c b/gcc/testsuite/gcc.target/i386/pr67400-3.c
index 40d3521..649c980 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-3.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-3.c
@@ -13,4 +13,5 @@ foo (void)
}
/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-4.c b/gcc/testsuite/gcc.target/i386/pr67400-4.c
index a329bbf..5f6883d 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-4.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-4.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void) __attribute__ ((visibility ("hidden")));
@@ -10,4 +10,5 @@ foo (void)
}
/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-6.c b/gcc/testsuite/gcc.target/i386/pr67400-6.c
index bb766cd..652add4 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-6.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-6.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern int bar (void);
@@ -9,5 +9,7 @@ check (void *p)
return p != &bar;
}
-/* { dg-final { scan-assembler "cmp\(l|q\)\[ \t\]*.*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler "cmp\(l|q\)\[ \t\]*.*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-7.c b/gcc/testsuite/gcc.target/i386/pr67400-7.c
index 32ae85f..900e87a 100644
--- a/gcc/testsuite/gcc.target/i386/pr67400-7.c
+++ b/gcc/testsuite/gcc.target/i386/pr67400-7.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-O2 -fno-pic -fno-plt" } */
extern void bar (void);
@@ -9,5 +9,5 @@ foo (void)
return &bar+1;
}
-/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" } } */
-/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," } } */
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)\(l|q\)\[ \t\]*\(\\\$|\)bar," { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 1b1d03a..51042b5 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6975,6 +6975,57 @@ proc check_effective_target_pie_copyreloc { } {
return $pie_copyreloc_available_saved
}
+# Return 1 if the x86 target supports R_386_GOT32X relocation, 0
+# otherwise. Cache the result.
+
+proc check_effective_target_got32x_reloc { } {
+ global got32x_reloc_available_saved
+ global tool
+ global GCC_UNDER_TEST
+
+ if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+ return 0
+ }
+
+ # Need auto-host.h to check linker support.
+ if { ![file exists ../../auto-host.h ] } {
+ return 0
+ }
+
+ if [info exists got32x_reloc_available_saved] {
+ verbose "check_effective_target_got32x_reloc returning saved $got32x_reloc_available_saved" 2
+ } else {
+ # Include the current process ID in the file names to prevent
+ # conflicts with invocations for multiple testsuites.
+
+ set src got32x[pid].c
+ set obj got32x[pid].o
+
+ set f [open $src "w"]
+ puts $f "#include \"../../auto-host.h\""
+ puts $f "#if HAVE_AS_IX86_GOT32X == 0"
+ puts $f "# error Assembler does not support R_386_GOT32X."
+ puts $f "#endif"
+ close $f
+
+ verbose "check_effective_target_got32x_reloc compiling testfile $src" 2
+ set lines [${tool}_target_compile $src $obj object ""]
+
+ file delete $src
+ file delete $obj
+
+ if [string match "" $lines] then {
+ verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
+ set got32x_reloc_available_saved 1
+ } else {
+ verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
+ set got32x_reloc_available_saved 0
+ }
+ }
+
+ return $got32x_reloc_available_saved
+}
+
# Return 1 if the target uses comdat groups.
proc check_effective_target_comdat_group {} {
--
2.5.5
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] i386: Access external function via GOT slot for -fno-plt
2016-06-23 16:08 ` H.J. Lu
@ 2016-06-23 16:23 ` Uros Bizjak
2016-06-23 16:32 ` H.J. Lu
0 siblings, 1 reply; 5+ messages in thread
From: Uros Bizjak @ 2016-06-23 16:23 UTC (permalink / raw)
To: H.J. Lu; +Cc: gcc-patches
On Thu, Jun 23, 2016 at 6:08 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> Here is the updated patch. OK for trunk?
>
> PR target/66232
> PR target/67400
> * configure.ac (as_ix86_tls_ldm_opt): Renamed to ...
> (as_ix86_gas_opt): This.
> (ld_ix86_tls_ldm_opt): Renamed to ...
> (ld_ix86_gld_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.
OK with a nit below.
Thanks,
Uros.
--- 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_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_opt="-melf_i386_sol2"
else
- ld_ix86_tls_ldm_opt="-melf_i386"
+ ld_ix86_gld_opt="-melf_i386"
fi
fi
conftest_s='
I'd like to suggest better names, perhaps as_ix86_gas_32_opt and
ld_ix86_gld_32_opt to mark that they are intended for 32bit targets.
But it is up to you, we can also live with above names.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] i386: Access external function via GOT slot for -fno-plt
2016-06-23 16:23 ` Uros Bizjak
@ 2016-06-23 16:32 ` H.J. Lu
0 siblings, 0 replies; 5+ messages in thread
From: H.J. Lu @ 2016-06-23 16:32 UTC (permalink / raw)
To: Uros Bizjak; +Cc: gcc-patches
On Thu, Jun 23, 2016 at 9:23 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Thu, Jun 23, 2016 at 6:08 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>
>> Here is the updated patch. OK for trunk?
>>
>> PR target/66232
>> PR target/67400
>> * configure.ac (as_ix86_tls_ldm_opt): Renamed to ...
>> (as_ix86_gas_opt): This.
>> (ld_ix86_tls_ldm_opt): Renamed to ...
>> (ld_ix86_gld_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.
>
> OK with a nit below.
>
> Thanks,
> Uros.
>
> --- 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_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_opt="-melf_i386_sol2"
> else
> - ld_ix86_tls_ldm_opt="-melf_i386"
> + ld_ix86_gld_opt="-melf_i386"
> fi
> fi
> conftest_s='
>
> I'd like to suggest better names, perhaps as_ix86_gas_32_opt and
> ld_ix86_gld_32_opt to mark that they are intended for 32bit targets.
> But it is up to you, we can also live with above names.
I checked it with the name change suggested above.
Thanks.
--
H.J.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-06-23 16:32 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-23 11:45 [PATCH] i386: Access external function via GOT slot for -fno-plt H.J. Lu
2016-06-23 12:34 ` Uros Bizjak
2016-06-23 16:08 ` H.J. Lu
2016-06-23 16:23 ` Uros Bizjak
2016-06-23 16:32 ` H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).