Module Name:    src
Committed By:   christos
Date:           Tue Mar  8 03:58:08 UTC 2016

Modified Files:
        src/external/gpl3/gcc.old/dist/gcc: output.h varasm.c
        src/external/gpl3/gcc.old/dist/gcc/config/i386: i386.c

Log Message:
Fix copy relocations against protected symbols from:
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/external/gpl3/gcc.old/dist/gcc/output.h \
    src/external/gpl3/gcc.old/dist/gcc/varasm.c
cvs rdiff -u -r1.3 -r1.4 \
    src/external/gpl3/gcc.old/dist/gcc/config/i386/i386.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/gpl3/gcc.old/dist/gcc/output.h
diff -u src/external/gpl3/gcc.old/dist/gcc/output.h:1.3 src/external/gpl3/gcc.old/dist/gcc/output.h:1.4
--- src/external/gpl3/gcc.old/dist/gcc/output.h:1.3	Tue Sep 22 23:39:11 2015
+++ src/external/gpl3/gcc.old/dist/gcc/output.h	Mon Mar  7 22:58:08 2016
@@ -583,6 +583,7 @@ extern void default_asm_output_anchor (r
 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: src/external/gpl3/gcc.old/dist/gcc/varasm.c
diff -u src/external/gpl3/gcc.old/dist/gcc/varasm.c:1.3 src/external/gpl3/gcc.old/dist/gcc/varasm.c:1.4
--- src/external/gpl3/gcc.old/dist/gcc/varasm.c:1.3	Tue Sep 22 23:39:12 2015
+++ src/external/gpl3/gcc.old/dist/gcc/varasm.c	Mon Mar  7 22:58:08 2016
@@ -6620,95 +6620,106 @@ resolution_local_p (enum ld_plugin_symbo
 
 /* Assume ELF-ish defaults, since that's pretty much the most liberal
    wrt cross-module name binding.  */
-
-bool
-default_binds_local_p (const_tree exp)
+static bool
+default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate,
+			 bool extern_protected_data)
 {
-  return default_binds_local_p_1 (exp, flag_shlib);
-}
+  /* A non-decl is an entry in the constant pool.  */
+  if (!DECL_P (exp))
+    return true;
 
-bool
-default_binds_local_p_1 (const_tree exp, int shlib)
-{
-  bool local_p;
-  bool resolved_locally = false;
-  bool resolved_to_local_def = false;
+  /* Weakrefs may not bind locally, even though the weakref itself is always
+     static and therefore local.  Similarly, the resolver for ifunc functions
+     might resolve to a non-local function.
+     FIXME: We can resolve the weakref case more curefuly by looking at the
+     weakref alias.  */
+  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+	   || (TREE_CODE (exp) == FUNCTION_DECL
+	       && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
+    return false;
+
+  /* Static variables are always local.  */
+  if (! TREE_PUBLIC (exp))
+    return true;
 
-  /* With resolution file in hands, take look into resolutions.
+  /* With resolution file in hand, take look into resolutions.
      We can't just return true for resolved_locally symbols,
      because dynamic linking might overwrite symbols
      in shared libraries.  */
+  bool resolved_locally = false;
+  bool defined_locally = !DECL_EXTERNAL (exp);
   if (TREE_CODE (exp) == VAR_DECL && TREE_PUBLIC (exp)
       && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
     {
       struct varpool_node *vnode = varpool_get_node (exp);
-      if (vnode && resolution_local_p (vnode->symbol.resolution))
+      if (vnode && vnode->symbol.in_other_partition)
+	defined_locally = true;
+      if (vnode && resolution_to_local_definition_p (vnode->symbol.resolution))
+	defined_locally = resolved_locally = true;
+      else if (vnode && resolution_local_p (vnode->symbol.resolution))
 	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->symbol.resolution))
-	resolved_to_local_def = true;
-    }
-  else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
-    {
-      struct cgraph_node *node = cgraph_get_node (exp);
-      if (node
-	  && resolution_local_p (node->symbol.resolution))
-	resolved_locally = true;
-      if (node
-	  && resolution_to_local_definition_p (node->symbol.resolution))
-	resolved_to_local_def = true;
     }
+  if (defined_locally && weak_dominate && !shlib)
+    resolved_locally = true;
+
+  /* Undefined weak symbols are never defined locally.  */
+  if (DECL_WEAK (exp) && !defined_locally)
+    return false;
+
+  /* A symbol is local if the user has said explicitly that it will be,
+     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;
 
-  /* A non-decl is an entry in the constant pool.  */
-  if (!DECL_P (exp))
-    local_p = true;
-  /* Weakrefs may not bind locally, even though the weakref itself is always
-     static and therefore local.  Similarly, the resolver for ifunc functions
-     might resolve to a non-local function.
-     FIXME: We can resolve the weakref case more curefuly by looking at the
-     weakref alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
-	   || (TREE_CODE (exp) == FUNCTION_DECL
-	       && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
-    local_p = false;
-  /* Static variables are always local.  */
-  else if (! TREE_PUBLIC (exp))
-    local_p = true;
-  /* A variable is local if the user has said explicitly that it will
-     be.  */
-  else if ((DECL_VISIBILITY_SPECIFIED (exp)
-	    || resolved_to_local_def)
-	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
-  /* Variables defined outside this object might not be local.  */
-  else if (DECL_EXTERNAL (exp) && !resolved_locally)
-    local_p = false;
-  /* If defined in this object and visibility is not default, must be
-     local.  */
-  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
-  /* Default visibility weak data can be overridden by a strong symbol
-     in another module and so are not local.  */
-  else if (DECL_WEAK (exp)
-	   && !resolved_locally)
-    local_p = false;
   /* If PIC, then assume that any global name can be overridden by
      symbols resolved from other modules.  */
-  else if (shlib)
-    local_p = false;
+  if (shlib)
+    return false;
+
+  /* Variables defined outside this object might not be local.  */
+  if (DECL_EXTERNAL (exp) && !resolved_locally)
+    return false;
+
+  /* Non-dominant weak symbols are not defined locally.  */
+  if (DECL_WEAK (exp) && !resolved_locally)
+    return false;
+
   /* Uninitialized COMMON variable may be unified with symbols
      resolved from other modules.  */
-  else if (DECL_COMMON (exp)
-	   && !resolved_locally
-	   && (DECL_INITIAL (exp) == NULL
-	       || DECL_INITIAL (exp) == error_mark_node))
-    local_p = false;
+  if (DECL_COMMON (exp)
+      && !resolved_locally
+      && (DECL_INITIAL (exp) == NULL
+	  || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
+    return false;
+
   /* Otherwise we're left with initialized (or non-common) global data
      which is of necessity defined locally.  */
-  else
-    local_p = true;
+  return true;
+}
+
+bool
+default_binds_local_p (const_tree exp)
+{
+  return default_binds_local_p_3 (exp, flag_shlib != 0, true, false);
+}
+
+bool
+default_binds_local_p_1 (const_tree exp, int shlib)
+{
+  return default_binds_local_p_3 (exp, shlib != 0, false, false);
+}
 
-  return local_p;
+/* 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);
 }
 
 /* Return true when references to DECL must bind to current definition in

Index: src/external/gpl3/gcc.old/dist/gcc/config/i386/i386.c
diff -u src/external/gpl3/gcc.old/dist/gcc/config/i386/i386.c:1.3 src/external/gpl3/gcc.old/dist/gcc/config/i386/i386.c:1.4
--- src/external/gpl3/gcc.old/dist/gcc/config/i386/i386.c:1.3	Tue Sep 22 23:39:14 2015
+++ src/external/gpl3/gcc.old/dist/gcc/config/i386/i386.c	Mon Mar  7 22:58:08 2016
@@ -42532,6 +42532,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_
 #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

Reply via email to