@@ -15172,13 +15172,20 @@ darwin_local_data_pic (rtx disp)
bool
ix86_force_load_from_GOT_p (rtx x)
{
- return ((TARGET_64BIT || HAVE_AS_IX86_GOT32X)
- && !TARGET_PECOFF && !TARGET_MACHO
- && !flag_plt && !flag_pic
- && ix86_cmodel != CM_LARGE
- && GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_FUNCTION_P (x)
- && !SYMBOL_REF_LOCAL_P (x));
+ if ((TARGET_64BIT || HAVE_AS_IX86_GOT32X)
+ && !TARGET_PECOFF
+ && !flag_pic
+ && !TARGET_MACHO
+ && ix86_cmodel != CM_LARGE
+ && GET_CODE (x) == SYMBOL_REF
+ && !SYMBOL_REF_LOCAL_P (x))
+ {
+ if (SYMBOL_REF_FUNCTION_P (x))
+ return !flag_plt;
+ else
+ return !flag_copy_reloc;
+ }
+ return false;
}
/* Determine if a given RTX is a valid constant. We already know this
@@ -15439,6 +15446,7 @@ legitimate_pic_address_disp_p (rtx disp)
else if (!SYMBOL_REF_FAR_ADDR_P (op0)
&& (SYMBOL_REF_LOCAL_P (op0)
|| (HAVE_LD_PIE_COPYRELOC
+ && flag_copy_reloc
&& flag_pie
&& !SYMBOL_REF_WEAK (op0)
&& !SYMBOL_REF_FUNCTION_P (op0)))
@@ -897,3 +897,7 @@ Attempt to avoid generating instruction sequences containing ret bytes.
mgeneral-regs-only
Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
Generate code which uses only the general registers.
+
+mcopy-reloc
+Target Report Var(flag_copy_reloc) Init(1)
+Allow copy relocation when accessing external data.
@@ -1179,7 +1179,7 @@ See RS/6000 and PowerPC Options.
-msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol
-mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
-malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
--mmitigate-rop -mgeneral-regs-only}
+-mmitigate-rop -mgeneral-regs-only -mcopy-reloc}
@emph{x86 Windows Options}
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -24653,6 +24653,11 @@ Generate code that uses only the general-purpose registers. This
prevents the compiler from using floating-point, vector, mask and bound
registers.
+@item -mcopy-reloc
+@opindex mcopy-reloc
+Generate code that uses copy relocation in executable to access external
+data defined in shared object. It is enabled by default.
+
@end table
These @samp{-m} switches are supported in addition to the above
new file mode 100644
@@ -0,0 +1,15 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -mno-copy-reloc" } */
+
+extern int bar;
+
+int *
+foo (void)
+{
+ return &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\\(%rip\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)l\[ \t\]*\(\\\$|\)bar," { target { ia32 && got32x_reloc } } } } */
new file mode 100644
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -mno-copy-reloc" } */
+
+extern int bar;
+extern int *p;
+
+void
+foo (void)
+{
+ p = &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\\(%rip\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -mno-copy-reloc" } */
+
+static int bar;
+
+int *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { 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 } } } } */
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -mno-copy-reloc" } */
+
+extern int bar __attribute__ ((visibility ("hidden")));
+
+int *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { 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 } } } } */
new file mode 100644
@@ -0,0 +1,15 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -mno-copy-reloc" } */
+
+extern int bar;
+
+int
+foo (void)
+{
+ return 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\\(%rip\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "\(mov|lea\)l\[ \t\]*\(\\\$|\)bar," { target { ia32 && got32x_reloc } } } } */
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -mno-copy-reloc" } */
+
+extern int bar;
+
+int
+check (int *p)
+{
+ return p != &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 "cmp\(l|q\)\[ \t\]*\\\$bar," } } */
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -mno-copy-reloc" } */
+
+extern int bar[];
+
+int *
+foo (void)
+{
+ return &bar[1];
+}
+
+/* { 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\\+4," } } */
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie -mno-copy-reloc" } */
+
+extern int glob_a;
+
+int foo ()
+{
+ return glob_a;
+}
+
+/* { dg-final { scan-assembler "glob_a@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "glob_a@GOT\\(" { target { ia32 } } } } */
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie -mno-copy-reloc" } */
+
+extern int glob_a;
+
+int foo ()
+{
+ return glob_a;
+}
+
+/* { dg-final { scan-assembler "glob_a@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "glob_a@GOT\\(" { target { ia32 } } } } */