Add default_binds_local_p_2 and use it for x86
authorH.J. Lu <hongjiu.lu@intel.com>
Fri, 27 Mar 2015 18:11:00 +0000 (18:11 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Fri, 27 Mar 2015 18:11:00 +0000 (11:11 -0700)
Protected data symbol means that it can't be pre-emptied.  It doesn't mean
its address won't be external.  This is true for pointer to protected
function.  With copy relocation, address of protected data defined in the
shared library may also be external.  We only know that for sure at
run-time.  TARGET_BINDS_LOCAL_P should return false on protected data
symbol.

gcc/

PR target/65248
* output.h (default_binds_local_p_2): New.
* varasm.c (default_binds_local_p_2): Renamed to ...
(default_binds_local_p_3): This.  Don't return true on protected
data symbol if protected data may be external.
(default_binds_local_p): Use default_binds_local_p_3.
(default_binds_local_p_1): Likewise.
(default_binds_local_p_2): New.
* config/i386/i386.c (TARGET_BINDS_LOCAL_P): Set to
default_binds_local_p_2 if TARGET_MACHO is undefined.

gcc/testsuite/

PR target/65248
* gcc.target/i386/pr65248-1.c: New file.
* gcc.target/i386/pr65248-2.c: Likewise.
* gcc.target/i386/pr65248-3.c: Likewise.
* gcc.target/i386/pr65248-4.c: Likewise.

From-SVN: r221742

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/output.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr65248-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65248-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65248-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65248-4.c [new file with mode: 0644]
gcc/varasm.c

index 0fb06d645b81eadd1ff6d5c3559a4c85109a3eb3..d8221f371d9181018e5899c13f29187ee49f9f76 100644 (file)
@@ -1,3 +1,16 @@
+2015-03-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/65248
+       * output.h (default_binds_local_p_2): New.
+       * varasm.c (default_binds_local_p_2): Renamed to ...
+       (default_binds_local_p_3): This.  Don't return true on protected
+       data symbol if protected data may be external.
+       (default_binds_local_p): Use default_binds_local_p_3.
+       (default_binds_local_p_1): Likewise.
+       (default_binds_local_p_2): New.
+       * config/i386/i386.c (TARGET_BINDS_LOCAL_P): Set to
+       default_binds_local_p_2 if TARGET_MACHO is undefined.
+
 2015-03-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/65593
index 862bda529b8f6a8611ff3b1979baf39bab585909..744642c7e36ae4ae3230c3cee240c096cadcdbf2 100644 (file)
@@ -51900,6 +51900,9 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts)
 #if TARGET_MACHO
 #undef TARGET_BINDS_LOCAL_P
 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
+#else
+#undef TARGET_BINDS_LOCAL_P
+#define TARGET_BINDS_LOCAL_P default_binds_local_p_2
 #endif
 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
 #undef TARGET_BINDS_LOCAL_P
index 217d979e5deee32b107e16eaa96500b7fceb1d52..53e47d03b3a6f99d767717e0b29ccf0436e6889c 100644 (file)
@@ -586,6 +586,7 @@ extern void default_asm_output_anchor (rtx);
 extern bool default_use_anchors_for_symbol_p (const_rtx);
 extern bool default_binds_local_p (const_tree);
 extern bool default_binds_local_p_1 (const_tree, int);
+extern bool default_binds_local_p_2 (const_tree);
 extern void default_globalize_label (FILE *, const char *);
 extern void default_globalize_decl_name (FILE *, tree);
 extern void default_emit_unwind_label (FILE *, tree, int, int);
index 4fb0e221e831db5b07a16f3dee182c02878a5444..de043af08ed91dc6864d6d6d2db5cacfdb45e6cb 100644 (file)
@@ -1,3 +1,11 @@
+2015-03-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/65248
+       * gcc.target/i386/pr65248-1.c: New file.
+       * gcc.target/i386/pr65248-2.c: Likewise.
+       * gcc.target/i386/pr65248-3.c: Likewise.
+       * gcc.target/i386/pr65248-4.c: Likewise.
+
 2015-03-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/65593
diff --git a/gcc/testsuite/gcc.target/i386/pr65248-1.c b/gcc/testsuite/gcc.target/i386/pr65248-1.c
new file mode 100644 (file)
index 0000000..735adde
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+__attribute__((visibility("protected")))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "xxx\\(%rip\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTOFF" { target ia32 } } } */
+/* { dg-final { scan-assembler "xxx@GOT\\(" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr65248-2.c b/gcc/testsuite/gcc.target/i386/pr65248-2.c
new file mode 100644 (file)
index 0000000..af264f3
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak, visibility("protected")))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "xxx\\(%rip\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTOFF" { target ia32 } } } */
+/* { dg-final { scan-assembler "xxx@GOT\\(" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr65248-3.c b/gcc/testsuite/gcc.target/i386/pr65248-3.c
new file mode 100644 (file)
index 0000000..e7a05ea
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+__attribute__((visibility("protected")))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "xxx\\(%rip\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTOFF" { target ia32 } } } */
+/* { dg-final { scan-assembler "xxx@GOT\\(" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr65248-4.c b/gcc/testsuite/gcc.target/i386/pr65248-4.c
new file mode 100644 (file)
index 0000000..db818fc
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak, visibility("protected")))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "xxx\\(%rip\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTOFF" { target ia32 } } } */
+/* { dg-final { scan-assembler "xxx@GOT\\(" { target ia32 } } } */
index 752dccf935dfe06a9e1308731de081c5366ec4b7..537a64d347a4639f289db324dbe07ce5dc90eaad 100644 (file)
@@ -6809,7 +6809,8 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution)
 }
 
 static bool
-default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
+default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate,
+                        bool extern_protected_data)
 {
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
@@ -6855,6 +6856,9 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
      or if we have a definition for the symbol.  We cannot infer visibility
      for undefined symbols.  */
   if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT
+      && (TREE_CODE (exp) == FUNCTION_DECL
+         || !extern_protected_data
+         || DECL_VISIBILITY (exp) != VISIBILITY_PROTECTED)
       && (DECL_VISIBILITY_SPECIFIED (exp) || defined_locally))
     return true;
 
@@ -6890,13 +6894,21 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
 bool
 default_binds_local_p (const_tree exp)
 {
-  return default_binds_local_p_2 (exp, flag_shlib != 0, true);
+  return default_binds_local_p_3 (exp, flag_shlib != 0, true, false);
+}
+
+/* Similar to default_binds_local_p, but protected data may be
+   external.  */
+bool
+default_binds_local_p_2 (const_tree exp)
+{
+  return default_binds_local_p_3 (exp, flag_shlib != 0, true, true);
 }
 
 bool
 default_binds_local_p_1 (const_tree exp, int shlib)
 {
-  return default_binds_local_p_2 (exp, shlib != 0, false);
+  return default_binds_local_p_3 (exp, shlib != 0, false, false);
 }
 
 /* Return true when references to DECL must bind to current definition in