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: PATCH: Fix the weak undefined symbols with non-default visibility


I think I may have OK'd HJ's patch a little too quickly.  At least
on powerpc, the change to elf_fix_symbol_flags to hide undef weak
syms with non-default visibility meant that the backend tried to
output .got relocs against a dynamic sym index of -1.  Other backends
may behave similarly, but at least this should show up when running
the ld testsuite (if the tests aren't xfailed for some reason!).
Also, dynamic relocs weren't being counted correctly in
allocate_dynrelocs.

This patch tidies the x86 and x86-64 code, and makes powerpc treat
undef weaks similarly to x86.

	* elf32-i386.c (allocate_dynrelocs): For undef weak syms with
	non-default visibility, a) don't make them dynamic, b) discard
	space for dynamic relocs.
	* elf64-x86-64.c (allocate_dynrelocs): Likewise.

	* elf32-ppc.c (allocate_dynrelocs): For undef weak syms with
	non-default visibility, a) don't allocate plt entries, b) don't
	allocate .got relocs, c) discard dyn rel space,
	(ppc_elf_relocate_section): d) don't generate .got relocs, e)
	don't generate dynamic relocs.
	* elf64-ppc.c (allocate_dynrelocs): As above.
	(ppc64_elf_relocate_section): As above.

Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.99
diff -u -p -r1.99 elf32-i386.c
--- bfd/elf32-i386.c	5 May 2003 05:46:52 -0000	1.99
+++ bfd/elf32-i386.c	5 May 2003 12:33:39 -0000
@@ -1558,7 +1558,9 @@ allocate_dynrelocs (h, inf)
   htab = elf_i386_hash_table (info);
 
   if (htab->elf.dynamic_sections_created
-      && h->plt.refcount > 0)
+      && h->plt.refcount > 0
+      && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+	  || h->root.type != bfd_link_hash_undefweak))
     {
       /* Make sure this symbol is output as a dynamic symbol.
 	 Undefined weak syms won't yet be marked as dynamic.  */
@@ -1569,10 +1571,8 @@ allocate_dynrelocs (h, inf)
 	    return FALSE;
 	}
 
-      if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-	   || h->root.type != bfd_link_hash_undefweak)
-	  && (info->shared
-	      || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)))
+      if (info->shared
+	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
 	{
 	  asection *s = htab->splt;
 
@@ -1695,6 +1695,12 @@ allocate_dynrelocs (h, inf)
 		pp = &p->next;
 	    }
 	}
+
+      /* Also discard relocs on undefined weak syms with non-default
+	 visibility.  */
+      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+	  && h->root.type == bfd_link_hash_undefweak)
+	eh->dyn_relocs = NULL;
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.58
diff -u -p -r1.58 elf64-x86-64.c
--- bfd/elf64-x86-64.c	5 May 2003 08:50:43 -0000	1.58
+++ bfd/elf64-x86-64.c	5 May 2003 12:33:41 -0000
@@ -1385,7 +1385,9 @@ allocate_dynrelocs (h, inf)
   htab = elf64_x86_64_hash_table (info);
 
   if (htab->elf.dynamic_sections_created
-      && h->plt.refcount > 0)
+      && h->plt.refcount > 0
+      && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+	  || h->root.type != bfd_link_hash_undefweak))
     {
       /* Make sure this symbol is output as a dynamic symbol.
 	 Undefined weak syms won't yet be marked as dynamic.  */
@@ -1396,9 +1398,7 @@ allocate_dynrelocs (h, inf)
 	    return FALSE;
 	}
 
-      if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-	   || h->root.type != bfd_link_hash_undefweak)
-	  && WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
+      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
 	{
 	  asection *s = htab->splt;
 
@@ -1516,6 +1516,12 @@ allocate_dynrelocs (h, inf)
 		pp = &p->next;
 	    }
 	}
+
+      /* Also discard relocs on undefined weak syms with non-default
+	 visibility.  */
+      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+	  && h->root.type == bfd_link_hash_undefweak)
+	eh->dyn_relocs = NULL;
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.76
diff -u -p -r1.76 elf32-ppc.c
--- bfd/elf32-ppc.c	1 May 2003 10:22:46 -0000	1.76
+++ bfd/elf32-ppc.c	5 May 2003 12:33:44 -0000
@@ -2694,7 +2694,9 @@ allocate_dynrelocs (h, inf)
 
   htab = ppc_elf_hash_table (info);
   if (htab->elf.dynamic_sections_created
-      && h->plt.refcount > 0)
+      && h->plt.refcount > 0
+      && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+	  || h->root.type != bfd_link_hash_undefweak))
     {
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (h->dynindx == -1
@@ -2789,8 +2791,10 @@ allocate_dynrelocs (h, inf)
 	  else
 	    htab->got->_raw_size += 4;
 	  dyn = htab->elf.dynamic_sections_created;
-	  if (info->shared
-	      || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
+	  if ((info->shared
+	       || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
+	      && (ELF_ST_VISIBILITY (eh->elf.other) == STV_DEFAULT
+		  || eh->elf.root.type != bfd_link_hash_undefweak))
 	    {
 	      /* All the entries we allocated need relocs.  */
 	      htab->relgot->_raw_size
@@ -2831,6 +2835,12 @@ allocate_dynrelocs (h, inf)
 		pp = &p->next;
 	    }
 	}
+
+      /* Also discard relocs on undefined weak syms with non-default
+	 visibility.  */
+      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+	  && h->root.type == bfd_link_hash_undefweak)
+	eh->dyn_relocs = NULL;
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
@@ -4793,7 +4803,10 @@ ppc_elf_relocate_section (output_bfd, in
 		      }
 
 		    /* Generate relocs for the dynamic linker.  */
-		    if (info->shared || indx != 0)
+		    if ((info->shared || indx != 0)
+			&& (h == NULL
+			    || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+			    || h->root.type != bfd_link_hash_undefweak))
 		      {
 			outrel.r_offset = (htab->got->output_section->vma
 					   + htab->got->output_offset
@@ -4995,6 +5008,9 @@ ppc_elf_relocate_section (output_bfd, in
 	  /* Fall thru.  */
 
 	  if ((info->shared
+	       && (h == NULL
+		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+		   || h->root.type != bfd_link_hash_undefweak)
 	       && (MUST_BE_DYN_RELOC (r_type)
 		   || (h != NULL
 		       && h->dynindx != -1
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.93
diff -u -p -r1.93 elf64-ppc.c
--- bfd/elf64-ppc.c	1 May 2003 10:22:46 -0000	1.93
+++ bfd/elf64-ppc.c	5 May 2003 12:33:52 -0000
@@ -5497,7 +5497,9 @@ allocate_dynrelocs (h, inf)
 
   if (htab->elf.dynamic_sections_created
       && h->dynindx != -1
-      && WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+      && WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)
+      && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+	  || h->root.type != bfd_link_hash_undefweak))
     {
       struct plt_entry *pent;
       bfd_boolean doneone = FALSE;
@@ -5597,8 +5599,10 @@ allocate_dynrelocs (h, inf)
 	s->_raw_size
 	  += (gent->tls_type & eh->tls_mask & (TLS_GD | TLS_LD)) ? 16 : 8;
 	dyn = htab->elf.dynamic_sections_created;
-	if (info->shared
-	    || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+	if ((info->shared
+	     || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+	    && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+		|| h->root.type != bfd_link_hash_undefweak))
 	  htab->srelgot->_raw_size
 	    += (gent->tls_type & eh->tls_mask & TLS_GD
 		? 2 * sizeof (Elf64_External_Rela)
@@ -5634,6 +5638,12 @@ allocate_dynrelocs (h, inf)
 		pp = &p->next;
 	    }
 	}
+
+      /* Also discard relocs on undefined weak syms with non-default
+	 visibility.  */
+      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+	  && h->root.type == bfd_link_hash_undefweak)
+	eh->dyn_relocs = NULL;
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
@@ -7640,7 +7650,10 @@ ppc64_elf_relocate_section (output_bfd, 
 		   the case of TLSLD where we'll use one entry per
 		   module.  */
 		*offp = off | 1;
-		if (info->shared || indx != 0)
+		if ((info->shared || indx != 0)
+		    && (h == NULL
+			|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+			|| h->root.type != bfd_link_hash_undefweak))
 		  {
 		    outrel.r_offset = (htab->sgot->output_section->vma
 				       + htab->sgot->output_offset
@@ -7864,6 +7877,9 @@ ppc64_elf_relocate_section (output_bfd, 
 	    break;
 
 	  if ((info->shared
+	       && (h == NULL
+		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+		   || h->root.type != bfd_link_hash_undefweak)
 	       && (MUST_BE_DYN_RELOC (r_type)
 		   || (h != NULL
 		       && h->dynindx != -1

-- 
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]