This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
PATCH for elf_slurp_reloc_table to handle multiple relocsections
- To: binutils@sourceware.cygnus.com
- Subject: PATCH for elf_slurp_reloc_table to handle multiple relocsections
- From: Mark Mitchell <mark@codesourcery.com>
- Date: Wed, 02 Jun 1999 16:37:26 -0700
- Organization: CodeSourcery, LLC
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