This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] unify dynamic_symbol_p implementations


On Fri, Jul 18, 2003 at 11:21:06PM -0700, H. J. Lu wrote:
> That is not the problem. _bfd_elf_dynamic_symbol_p came from
> elfxx-ia64.c, which isn't symmetric with SYMBOL_REFERENCES_LOCAL.
> I don't know how we can get it both ways.

Yes, I see I agreed with Richard's patch too quickly..  The problem is
that SYMBOL_REFERENCES_LOCAL and SYMBOL_CALLS_LOCAL as used by ppc,
ppc64, x86, and x86_64 should only return true if we have a local
definition.  Causes failures in ld tests of visibility (hidden_undef).
I do like the idea of a predicate function though.

	* elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use..
	(_bfd_elf_symbol_refs_local_p): ..this.  Declare.
	* elflink.c (_bfd_elf_symbol_refs_local_p): New function.
	* elf32-i386.c (elf_i386_relocate_section): Remove h NULL test
	now done in _bfd_elf_symbol_refs_local_p.
	* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
	* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
	* elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.

One interesting place that this differs from (the inverse of) Richard's
function is in the treatment of weak and undefweak dynamic syms.  I
suspect I should allow a weak dynamic sym in an executable to be
overridden, even if we don't find a strong sym in a shared lib supplied
at link time.  Comments?

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.105
diff -u -p -r1.105 elf-bfd.h
--- bfd/elf-bfd.h	19 Jul 2003 04:12:22 -0000	1.105
+++ bfd/elf-bfd.h	20 Jul 2003 13:45:36 -0000
@@ -212,11 +212,11 @@ struct elf_link_hash_entry
    it's necessary for shared libs to also reference the .plt even
    though the symbol is really local to the shared lib.  */
 #define SYMBOL_REFERENCES_LOCAL(INFO, H) \
-  !_bfd_elf_dynamic_symbol_p (H, INFO, 1)
+  _bfd_elf_symbol_refs_local_p (H, INFO, 0)
 
 /* Will _calls_ to this symbol always call the version in this object?  */
 #define SYMBOL_CALLS_LOCAL(INFO, H) \
-  !_bfd_elf_dynamic_symbol_p (H, INFO, 0)
+  _bfd_elf_symbol_refs_local_p (H, INFO, 1)
 
 /* Records local symbols to be emitted in the dynamic symbol table.  */
 
@@ -1496,6 +1496,9 @@ extern bfd_boolean _bfd_elf_link_sec_mer
   PARAMS ((struct elf_link_hash_entry *, PTR));
 
 extern bfd_boolean _bfd_elf_dynamic_symbol_p
+  PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean));
+
+extern bfd_boolean _bfd_elf_symbol_refs_local_p
   PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean));
 
 extern const bfd_target *bfd_elf32_object_p
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.39
diff -u -p -r1.39 elflink.c
--- bfd/elflink.c	19 Jul 2003 06:41:42 -0000	1.39
+++ bfd/elflink.c	20 Jul 2003 13:45:46 -0000
@@ -2534,3 +2534,52 @@ _bfd_elf_dynamic_symbol_p (h, info, igno
      us that it remains local.  */
   return !binding_stays_local_p;
 }
+
+/* Return true if the symbol referred to by H should be considered
+   to resolve local to the current module, and false otherwise.  Differs
+   from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of
+   undefined symbols and weak symbols.  */
+
+bfd_boolean
+_bfd_elf_symbol_refs_local_p (h, info, local_protected)
+     struct elf_link_hash_entry *h;
+     struct bfd_link_info *info;
+     bfd_boolean local_protected;
+{
+  /* If it's a local sym, of course we resolve locally.  */
+  if (h == NULL)
+    return TRUE;
+
+  /* If we don't have a definition in a regular file, then we can't
+     resolve locally.  The sym is either undefined or dynamic.  */
+  if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+    return FALSE;
+
+  /* Forced local symbols resolve locally.  */
+  if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
+    return TRUE;
+
+  /* As do non-dynamic symbols.  */
+  if (h->dynindx == -1)
+    return TRUE;
+
+  /* At this point, we know the symbol is defined and dynamic.  In an
+     executable it must resolve locally, likewise when building symbolic
+     shared libraries.  */
+  if (info->executable || info->symbolic)
+    return TRUE;
+
+  /* Now deal with defined dynamic symbols in shared libraries.  Ones
+     with default visibility might not resolve locally.  */
+  if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+    return FALSE;
+
+  /* However, STV_HIDDEN or STV_INTERNAL ones must be local.  */
+  if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED)
+    return TRUE;
+
+  /* Function pointer equality tests may require that STV_PROTECTED
+     symbols be treated as dynamic symbols, even when we know that the
+     dynamic linker will resolve them locally.  */
+  return local_protected;
+}
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.107
diff -u -p -r1.107 elf32-i386.c
--- bfd/elf32-i386.c	4 Jul 2003 13:53:37 -0000	1.107
+++ bfd/elf32-i386.c	20 Jul 2003 13:45:37 -0000
@@ -2338,8 +2338,7 @@ elf_i386_relocate_section (bfd *output_b
 		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 		   || h->root.type != bfd_link_hash_undefweak)
 	       && (r_type != R_386_PC32
-		   || (h != NULL
-		       && !SYMBOL_CALLS_LOCAL (info, h))))
+		   || !SYMBOL_CALLS_LOCAL (info, h)))
 	      || (ELIMINATE_COPY_RELOCS
 		  && !info->shared
 		  && h != NULL
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.93
diff -u -p -r1.93 elf32-ppc.c
--- bfd/elf32-ppc.c	12 Jul 2003 11:16:46 -0000	1.93
+++ bfd/elf32-ppc.c	20 Jul 2003 13:45:39 -0000
@@ -5175,9 +5175,8 @@ ppc_elf_relocate_section (bfd *output_bf
 	case R_PPC_REL14_BRNTAKEN:
 	  /* If these relocations are not to a named symbol, they can be
 	     handled right here, no need to bother the dynamic linker.  */
-	  if (h == NULL
-	      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
-	      || SYMBOL_REFERENCES_LOCAL (info, h))
+	  if (SYMBOL_REFERENCES_LOCAL (info, h)
+	      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
 	    break;
 	  /* fall through */
 
@@ -5207,8 +5206,7 @@ ppc_elf_relocate_section (bfd *output_bf
 		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 		   || h->root.type != bfd_link_hash_undefweak)
 	       && (MUST_BE_DYN_RELOC (r_type)
-		   || (h != NULL
-		       && !SYMBOL_CALLS_LOCAL (info, h))))
+		   || !SYMBOL_CALLS_LOCAL (info, h)))
 	      || (ELIMINATE_COPY_RELOCS
 		  && !info->shared
 		  && (input_section->flags & SEC_ALLOC) != 0
@@ -5263,8 +5261,7 @@ ppc_elf_relocate_section (bfd *output_bf
 
 	      if (skip)
 		memset (&outrel, 0, sizeof outrel);
-	      else if (h != NULL
-		       && !SYMBOL_REFERENCES_LOCAL (info, h))
+	      else if (!SYMBOL_REFERENCES_LOCAL (info, h))
 		{
 		  unresolved_reloc = FALSE;
 		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.118
diff -u -p -r1.118 elf64-ppc.c
--- bfd/elf64-ppc.c	10 Jul 2003 00:37:26 -0000	1.118
+++ bfd/elf64-ppc.c	20 Jul 2003 13:45:43 -0000
@@ -8159,8 +8159,7 @@ ppc64_elf_relocate_section (bfd *output_
 		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 		   || h->root.type != bfd_link_hash_undefweak)
 	       && (MUST_BE_DYN_RELOC (r_type)
-		   || (h != NULL
-		       && !SYMBOL_CALLS_LOCAL (info, h))))
+		   || !SYMBOL_CALLS_LOCAL (info, h)))
 	      || (ELIMINATE_COPY_RELOCS
 		  && !info->shared
 		  && h != NULL
@@ -8206,8 +8205,7 @@ ppc64_elf_relocate_section (bfd *output_
 
 	      if (skip)
 		memset (&outrel, 0, sizeof outrel);
-	      else if (h != NULL
-		       && !SYMBOL_REFERENCES_LOCAL (info, h)
+	      else if (!SYMBOL_REFERENCES_LOCAL (info, h)
 		       && !is_opd
 		       && r_type != R_PPC64_TOC)
 		outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.63
diff -u -p -r1.63 elf64-x86-64.c
--- bfd/elf64-x86-64.c	4 Jul 2003 13:53:37 -0000	1.63
+++ bfd/elf64-x86-64.c	20 Jul 2003 13:45:45 -0000
@@ -2015,8 +2015,7 @@ elf64_x86_64_relocate_section (bfd *outp
 	       && ((r_type != R_X86_64_PC8
 		    && r_type != R_X86_64_PC16
 		    && r_type != R_X86_64_PC32)
-		   || (h != NULL
-		       && !SYMBOL_CALLS_LOCAL (info, h))))
+		   || !SYMBOL_CALLS_LOCAL (info, h)))
 	      || (ELIMINATE_COPY_RELOCS
 		  && !info->shared
 		  && h != NULL

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]