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]

[PATCH] MIPS/ld: Calculate DT_RELSZ correctly.


As outlined in this thread:

http://sourceware.org/ml/binutils/2005-05/msg00624.html

The 2.16 ld cannot correctly link the libgcj component of gcc 4.0.0.

The problem is that DT_RELSZ was being calculated before all of the relocations had been added to the dynamic relocations section. This resulted in a value of DT_RELSZ that was too small. The result was that the runtime loader did not do all the relocations that were needed.


2005-05-23 David Daney <ddaney@avtrex.com>


        * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections):  Move
        calculation of DT_RELSZ to occur after all dynamic relocations
        are created.


Tested on the CVS HEAD mipsel-linux cross running on i686-pc-linux-gnu with make -k check showing regressions.


O.K. to commit? Should this go on the 2.16 branch as well?

David Daney
? bfd/doc/bfd.info
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.139
diff -c -p -r1.139 elfxx-mips.c
*** bfd/elfxx-mips.c	23 May 2005 17:44:54 -0000	1.139
--- bfd/elfxx-mips.c	23 May 2005 21:29:41 -0000
*************** _bfd_mips_elf_finish_dynamic_sections (b
*** 7674,7691 ****
  	      dyn.d_un.d_ptr = s->vma;
  	      break;
  
- 	    case DT_RELSZ:
- 	      /* Reduce DT_RELSZ to account for any relocations we
- 		 decided not to make.  This is for the n64 irix rld,
- 		 which doesn't seem to apply any relocations if there
- 		 are trailing null entries.  */
- 	      s = mips_elf_rel_dyn_section (dynobj, FALSE);
- 	      dyn.d_un.d_val = (s->reloc_count
- 				* (ABI_64_P (output_bfd)
- 				   ? sizeof (Elf64_Mips_External_Rel)
- 				   : sizeof (Elf32_External_Rel)));
- 	      break;
- 
  	    default:
  	      swap_out_p = FALSE;
  	      break;
--- 7674,7679 ----
*************** _bfd_mips_elf_finish_dynamic_sections (b
*** 7747,7752 ****
--- 7735,7789 ----
  	}
      }
  
+   /* The generation of dynamic relocations for the non-primary gots
+      adds more dynamic relocations.  We cannot count them until
+      here.  */
+ 
+   if (elf_hash_table (info)->dynamic_sections_created)
+     {
+       bfd_byte *b;
+       bfd_boolean swap_out_p;
+ 
+       BFD_ASSERT (sdyn != NULL);
+ 
+       for (b = sdyn->contents;
+ 	   b < sdyn->contents + sdyn->size;
+ 	   b += MIPS_ELF_DYN_SIZE (dynobj))
+ 	{
+ 	  Elf_Internal_Dyn dyn;
+ 	  asection *s;
+ 
+ 	  /* Read in the current dynamic entry.  */
+ 	  (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
+ 
+ 	  /* Assume that we're going to modify it and write it out.  */
+ 	  swap_out_p = TRUE;
+ 
+ 	  switch (dyn.d_tag)
+ 	    {
+ 	    case DT_RELSZ:
+ 	      /* Reduce DT_RELSZ to account for any relocations we
+ 		 decided not to make.  This is for the n64 irix rld,
+ 		 which doesn't seem to apply any relocations if there
+ 		 are trailing null entries.  */
+ 	      s = mips_elf_rel_dyn_section (dynobj, FALSE);
+ 	      dyn.d_un.d_val = (s->reloc_count
+ 				* (ABI_64_P (output_bfd)
+ 				   ? sizeof (Elf64_Mips_External_Rel)
+ 				   : sizeof (Elf32_External_Rel)));
+ 	      break;
+ 
+ 	    default:
+ 	      swap_out_p = FALSE;
+ 	      break;
+ 	    }
+ 
+ 	  if (swap_out_p)
+ 	    (*get_elf_backend_data (dynobj)->s->swap_dyn_out)
+ 	      (dynobj, &dyn, b);
+ 	}
+     }
+ 
    {
      asection *s;
      Elf32_compact_rel cpt;

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