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

PATCH for elf_slurp_reloc_table to handle multiple relocsections



This patch allows elf_slurp_reloc_table to work correctly even when a
single section has two sections providing relocations against it.
This happens on Irix 6, where there can be both REL and RELA
relocations against the same section.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-06-02  Mark Mitchell  <Mark Mitchell <mark@codesourcery.com>>

	* elfcode.h (elf_slurp_reloc_table_from_section): New function,
	split out from ...
	(elf_slurp_reloc_table): Here.  Use it to handle the case where a
	single section has two associated relocation sections.
	
Index: elfcode.h
===================================================================
RCS file: /usr/local/Repository/binutils/bfd/elfcode.h,v
retrieving revision 1.1.1.1.2.1
diff -c -p -r1.1.1.1.2.1 elfcode.h
*** elfcode.h	1999/06/02 03:28:46	1.1.1.1.2.1
--- elfcode.h	1999/06/02 23:20:57
*************** static void elf_swap_shdr_out
*** 162,167 ****
--- 162,170 ----
  
  #define section_from_elf_index bfd_section_from_elf_index
  
+ static boolean elf_slurp_reloc_table_from_section 
+   PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type,
+ 	   arelent *, asymbol **, boolean));
  static boolean elf_slurp_reloc_table
    PARAMS ((bfd *, asection *, asymbol **, boolean));
  
*************** error_return:
*** 1195,1244 ****
    return -1;
  }
  
! /* Read in and swap the external relocs.  */
  
  static boolean
! elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
       bfd *abfd;
       asection *asect;
       asymbol **symbols;
       boolean dynamic;
  {
    struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
-   struct bfd_elf_section_data * const d = elf_section_data (asect);
-   Elf_Internal_Shdr *rel_hdr;
-   bfd_size_type reloc_count;
    PTR allocated = NULL;
    bfd_byte *native_relocs;
-   arelent *relents;
    arelent *relent;
    unsigned int i;
    int entsize;
  
-   if (asect->relocation != NULL)
-     return true;
- 
-   if (! dynamic)
-     {
-       if ((asect->flags & SEC_RELOC) == 0
- 	  || asect->reloc_count == 0)
- 	return true;
- 
-       rel_hdr = &d->rel_hdr;
-       reloc_count = asect->reloc_count;
- 
-       BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
- 		  && reloc_count == rel_hdr->sh_size / rel_hdr->sh_entsize);
-     }
-   else
-     {
-       if (asect->_raw_size == 0)
- 	return true;
- 
-       rel_hdr = &d->this_hdr;
-       reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
-     }
- 
    allocated = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
    if (allocated == NULL)
      goto error_return;
--- 1198,1224 ----
    return -1;
  }
  
! /* Read  relocations for ASECT from REL_HDR.  There are RELOC_COUNT of 
!    them.  */
  
  static boolean
! elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count,
! 				    relents, symbols, dynamic)
       bfd *abfd;
       asection *asect;
+      Elf_Internal_Shdr *rel_hdr;
+      bfd_size_type reloc_count;
+      arelent *relents;
       asymbol **symbols;
       boolean dynamic;
  {
    struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
    PTR allocated = NULL;
    bfd_byte *native_relocs;
    arelent *relent;
    unsigned int i;
    int entsize;
  
    allocated = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
    if (allocated == NULL)
      goto error_return;
*************** elf_slurp_reloc_table (abfd, asect, symb
*** 1250,1259 ****
  
    native_relocs = (bfd_byte *) allocated;
  
-   relents = (arelent *) bfd_alloc (abfd, reloc_count * sizeof (arelent));
-   if (relents == NULL)
-     goto error_return;
- 
    entsize = rel_hdr->sh_entsize;
    BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
  	      || entsize == sizeof (Elf_External_Rela));
--- 1230,1235 ----
*************** elf_slurp_reloc_table (abfd, asect, symb
*** 1308,1315 ****
  	(*ebd->elf_info_to_howto_rel) (abfd, relent, &rel);
      }
  
-   asect->relocation = relents;
- 
    if (allocated != NULL)
      free (allocated);
  
--- 1284,1289 ----
*************** elf_slurp_reloc_table (abfd, asect, symb
*** 1319,1324 ****
--- 1293,1368 ----
    if (allocated != NULL)
      free (allocated);
    return false;
+ }
+ 
+ /* Read in and swap the external relocs.  */
+ 
+ static boolean
+ elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
+      bfd *abfd;
+      asection *asect;
+      asymbol **symbols;
+      boolean dynamic;
+ {
+   struct bfd_elf_section_data * const d = elf_section_data (asect);
+   Elf_Internal_Shdr *rel_hdr;
+   Elf_Internal_Shdr *rel_hdr2;
+   bfd_size_type reloc_count;
+   bfd_size_type reloc_count2;
+   arelent *relents;
+ 
+   if (asect->relocation != NULL)
+     return true;
+ 
+   if (! dynamic)
+     {
+       if ((asect->flags & SEC_RELOC) == 0
+ 	  || asect->reloc_count == 0)
+ 	return true;
+ 
+       rel_hdr = &d->rel_hdr;
+       reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
+       rel_hdr2 = d->rel_hdr2;
+       reloc_count2 = (rel_hdr2 
+ 		      ? (rel_hdr2->sh_size / rel_hdr2->sh_entsize)
+ 		      : 0);
+ 
+       BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
+       BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
+ 		  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
+ 
+     }
+   else
+     {
+       if (asect->_raw_size == 0)
+ 	return true;
+ 
+       rel_hdr = &d->this_hdr;
+       reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
+       rel_hdr2 = NULL;
+     }
+ 
+   relents = (arelent *) bfd_alloc (abfd, 
+ 				   asect->reloc_count * sizeof (arelent));
+   if (relents == NULL)
+     return false;
+ 
+   if (!elf_slurp_reloc_table_from_section (abfd, asect,
+ 					   rel_hdr, reloc_count,
+ 					   relents,
+ 					   symbols, dynamic))
+     return false;
+   
+   if (rel_hdr2 
+       && !elf_slurp_reloc_table_from_section (abfd, asect,
+ 					      rel_hdr2, reloc_count2,
+ 					      relents + reloc_count,
+ 					      symbols, dynamic))
+     return false;
+ 
+   
+   asect->relocation = relents;
+   return true;
  }
  
  #ifdef DEBUG

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