This is the mail archive of the binutils@sourceware.org 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]

ppc allocate_dynrelocs


Fixes a bug in the ppc allocate_dynrelocs function that resulted in
h->dynindx being set when it should not be.  This led to later
attempts to output dynamic relocs and assertion failures in
ppc_elf_relocate_section.  Triggered by glibc tls tests.

I've also made similar changes to the ppc64 code, and made the
condition under which we ELIMINATE_COPY_RELOCS the same as ppc32.
ppc32 lost the def_dynamic test 2008-02-26, and in fact it was this
change that requires we now test dynamic_sections_created before
processing dyn_relocs.

For comparison, the x86 code in allocate_dynrelocs looks like

  if (info->shared)
        ...
  else if (ELIMINATE_COPY_RELOCS)
    {
      if (!h->non_got_ref
	  && ((h->def_dynamic
	       && !h->def_regular)
	      || (htab->elf.dynamic_sections_created
		  && (h->root.type == bfd_link_hash_undefweak
		      || h->root.type == bfd_link_hash_undefined))))

You can rewrite the test inside ELIMINATE_COPY_RELOCS as

      if (!h->non_got_ref
	  && !h->def_regular
	  && (h->def_dynamic
	      || (htab->elf.dynamic_sections_created
		  && (h->root.type == bfd_link_hash_undefweak
		      || h->root.type == bfd_link_hash_undefined))))

since def_regular won't be set for undefined or undefweak.  Then
further factor to

      if (!h->non_got_ref
	  && !h->def_regular
	  && htab->elf.dynamic_sections_created
	  && (h->def_dynamic
	      || h->root.type == bfd_link_hash_undefweak
	      || h->root.type == bfd_link_hash_undefined))

since def_dynamic set means we've taken a definition from a dynamic
library and thus must have dynamic_sections_created.  Which I reckon
then simplifies down to

      if (!h->non_got_ref
	  && !h->def_regular
	  && htab->elf.dynamic_sections_created)

since !def_regular means we have either a defined dynamic symbol or
an undefined symbol.  Common symbols will have been converted to
def_regular by this stage (but only if dynamic_sections_created!)

Which arrives at the same logic as used in the ppc code.

	* elf32-ppc.c (allocate_dynrelocs): Ignore dyn_relocs when
	!dynamic_sections_created.  Don't make symbols with got
	references dynamic if !dynamic_sections_created.
	* elf64-ppc.c (allocate_dynrelocs): Likewise.  Alloc dynamic
	relocs on undefined symbols.
	(ppc64_elf_relocate_section): Allow dynamic relocs on
	undefined symbols.

Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.242
diff -u -p -r1.242 elf32-ppc.c
--- bfd/elf32-ppc.c	6 Aug 2008 07:29:31 -0000	1.242
+++ bfd/elf32-ppc.c	12 Aug 2008 12:29:21 -0000
@@ -4993,7 +4993,8 @@ allocate_dynrelocs (struct elf_link_hash
     {
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (eh->elf.dynindx == -1
-	  && !eh->elf.forced_local)
+	  && !eh->elf.forced_local
+	  && htab->elf.dynamic_sections_created)
 	{
 	  if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
 	    return FALSE;
@@ -5041,7 +5042,8 @@ allocate_dynrelocs (struct elf_link_hash
   else
     eh->elf.got.offset = (bfd_vma) -1;
 
-  if (eh->dyn_relocs == NULL)
+  if (eh->dyn_relocs == NULL
+      || !htab->elf.dynamic_sections_created)
     return TRUE;
 
   /* In the shared -Bsymbolic case, discard space allocated for
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.285
diff -u -p -r1.285 elf64-ppc.c
--- bfd/elf64-ppc.c	11 Aug 2008 14:38:40 -0000	1.285
+++ bfd/elf64-ppc.c	12 Aug 2008 12:29:31 -0000
@@ -7891,7 +7891,8 @@ allocate_dynrelocs (struct elf_link_hash
 	   Undefined weak syms won't yet be marked as dynamic,
 	   nor will all TLS symbols.  */
 	if (h->dynindx == -1
-	    && !h->forced_local)
+	    && !h->forced_local
+	    && htab->elf.dynamic_sections_created)
 	  {
 	    if (! bfd_elf_link_record_dynamic_symbol (info, h))
 	      return FALSE;
@@ -7925,7 +7926,8 @@ allocate_dynrelocs (struct elf_link_hash
     else
       gent->got.offset = (bfd_vma) -1;
 
-  if (eh->dyn_relocs == NULL)
+  if (eh->dyn_relocs == NULL
+      || !htab->elf.dynamic_sections_created)
     return TRUE;
 
   /* In the shared -Bsymbolic case, discard space allocated for
@@ -7982,7 +7984,6 @@ allocate_dynrelocs (struct elf_link_hash
 	 dynamic.  */
 
       if (!h->non_got_ref
-	  && h->def_dynamic
 	  && !h->def_regular)
 	{
 	  /* Make sure this symbol is output as a dynamic symbol.
@@ -11251,7 +11252,6 @@ ppc64_elf_relocate_section (bfd *output_
 		  && h != NULL
 		  && h->elf.dynindx != -1
 		  && !h->elf.non_got_ref
-		  && h->elf.def_dynamic
 		  && !h->elf.def_regular))
 	    {
 	      Elf_Internal_Rela outrel;

-- 
Alan Modra
Australia Development Lab, IBM


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