diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-06-13 01:13:26 +0000 |
---|---|---|
committer | Mark Mitchell <mark@codesourcery.com> | 1999-06-13 01:13:26 +0000 |
commit | 6b5bd373fb9597e34530f097bc1f35c375a2a12b (patch) | |
tree | c4adb1a8b0b2fb533fcbd652741333875f2c792c /bfd | |
parent | 197a7bfdcac1f79ca4a15612aa98ff7db58801f4 (diff) | |
download | gdb-6b5bd373fb9597e34530f097bc1f35c375a2a12b.zip gdb-6b5bd373fb9597e34530f097bc1f35c375a2a12b.tar.gz gdb-6b5bd373fb9597e34530f097bc1f35c375a2a12b.tar.bz2 |
* elflink.h (elf_link_read_relocs_from_section): New function,
split out from ...
(elf_link_read_relocs): Here. Use it for both relocation
sections.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elflink.h | 125 |
2 files changed, 91 insertions, 41 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d778609..0b79ccb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +1999-06-13 Mark Mitchell <mark@codesourcery.com> + + * elflink.h (elf_link_read_relocs_from_section): New function, + split out from ... + (elf_link_read_relocs): Here. Use it for both relocation + sections. + 1999-06-12 Mark Mitchell <mark@codesourcery.com> * elfcode.h (elf_slurp_reloc_table_from_section): Don't assume diff --git a/bfd/elflink.h b/bfd/elflink.h index 32bfab0..fcbacf8 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -52,6 +52,8 @@ static boolean elf_link_renumber_dynsyms PARAMS ((struct elf_link_hash_entry *, PTR)); static boolean elf_collect_hash_codes PARAMS ((struct elf_link_hash_entry *, PTR)); +static boolean elf_link_read_relocs_from_section + PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *)); /* Given an ELF BFD, add symbols to the global hash table as appropriate. */ @@ -1991,6 +1993,74 @@ elf_add_dynamic_entry (info, tag, val) } +/* Read and swap the relocs from the section indicated by SHDR. This + may be either a REL or a RELA section. The relocations are + translated into RELA relocations and stored in INTERNAL_RELOCS, + which should have already been allocated to contain enough space. + The EXTERNAL_RELOCS are a buffer where the external form of the + relocations should be stored. + + Returns false if something goes wrong. */ + +static boolean +elf_link_read_relocs_from_section (abfd, shdr, external_relocs, + internal_relocs) + bfd *abfd; + Elf_Internal_Shdr *shdr; + PTR external_relocs; + Elf_Internal_Rela *internal_relocs; +{ + /* If there aren't any relocations, that's OK. */ + if (!shdr) + return true; + + /* Position ourselves at the start of the section. */ + if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0) + return false; + + /* Read the relocations. */ + if (bfd_read (external_relocs, 1, shdr->sh_size, abfd) + != shdr->sh_size) + return false; + + /* Convert the external relocations to the internal format. */ + if (shdr->sh_entsize == sizeof (Elf_External_Rel)) + { + Elf_External_Rel *erel; + Elf_External_Rel *erelend; + Elf_Internal_Rela *irela; + + erel = (Elf_External_Rel *) external_relocs; + erelend = erel + shdr->sh_size / shdr->sh_entsize; + irela = internal_relocs; + for (; erel < erelend; erel++, irela++) + { + Elf_Internal_Rel irel; + + elf_swap_reloc_in (abfd, erel, &irel); + irela->r_offset = irel.r_offset; + irela->r_info = irel.r_info; + irela->r_addend = 0; + } + } + else + { + Elf_External_Rela *erela; + Elf_External_Rela *erelaend; + Elf_Internal_Rela *irela; + + BFD_ASSERT (shdr->sh_entsize == sizeof (Elf_External_Rela)); + + erela = (Elf_External_Rela *) external_relocs; + erelaend = erela + shdr->sh_size / shdr->sh_entsize; + irela = internal_relocs; + for (; erela < erelaend; erela++, irela++) + elf_swap_reloca_in (abfd, erela, irela); + } + + return true; +} + /* Read and swap the relocs for a section. They may have been cached. If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are not NULL, they are used as buffers to read into. They are known to be large @@ -2034,53 +2104,26 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs, if (external_relocs == NULL) { - alloc1 = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size); + size_t size = (size_t) rel_hdr->sh_size; + + if (elf_section_data (o)->rel_hdr2) + size += (size_t) elf_section_data (o)->rel_hdr2->sh_size; + alloc1 = (PTR) bfd_malloc (size); if (alloc1 == NULL) goto error_return; external_relocs = alloc1; } - if ((bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0) - || (bfd_read (external_relocs, 1, rel_hdr->sh_size, abfd) - != rel_hdr->sh_size)) + if (!elf_link_read_relocs_from_section (abfd, rel_hdr, + external_relocs, + internal_relocs)) + goto error_return; + if (!elf_link_read_relocs_from_section + (abfd, + elf_section_data (o)->rel_hdr2, + external_relocs + rel_hdr->sh_size, + internal_relocs + rel_hdr->sh_size / rel_hdr->sh_entsize)) goto error_return; - - /* Swap in the relocs. For convenience, we always produce an - Elf_Internal_Rela array; if the relocs are Rel, we set the addend - to 0. */ - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_External_Rel *erelend; - Elf_Internal_Rela *irela; - - erel = (Elf_External_Rel *) external_relocs; - erelend = erel + o->reloc_count; - irela = internal_relocs; - for (; erel < erelend; erel++, irela++) - { - Elf_Internal_Rel irel; - - elf_swap_reloc_in (abfd, erel, &irel); - irela->r_offset = irel.r_offset; - irela->r_info = irel.r_info; - irela->r_addend = 0; - } - } - else - { - Elf_External_Rela *erela; - Elf_External_Rela *erelaend; - Elf_Internal_Rela *irela; - - BFD_ASSERT (rel_hdr->sh_entsize == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) external_relocs; - erelaend = erela + o->reloc_count; - irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - elf_swap_reloca_in (abfd, erela, irela); - } /* Cache the results for next time, if we can. */ if (keep_memory) |