diff options
author | DJ Delorie <dj@delorie.com> | 2011-05-23 19:50:38 +0000 |
---|---|---|
committer | DJ Delorie <dj@delorie.com> | 2011-05-23 19:50:38 +0000 |
commit | 24d38b419e61ac55f18e8801a272e527316d7a5d (patch) | |
tree | fd6d6ce65060bb598b19799fc37c7bb63714291c | |
parent | a1a99f5bbfb4fd8d6e43ed434c7fd555eec9255c (diff) | |
download | binutils-redhat-24d38b419e61ac55f18e8801a272e527316d7a5d.tar.gz |
* elf32-rx.c (rx_elf_object_p): When reading an RX object in, undo
the vma/lma swapping done in elf32_rx_modify_program_headers.
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf32-rx.c | 50 |
2 files changed, 55 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 910d8bc04b..64bdff6c93 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2011-05-23 DJ Delorie <dj@redhat.com> + + * elf32-rx.c (rx_elf_object_p): When reading an RX object in, undo + the vma/lma swapping done in elf32_rx_modify_program_headers. + 2011-05-15 Richard Sandiford <rdsandiford@googlemail.com> * elfxx-mips.c (_bfd_mips_elf_check_relocs): Record both local and diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c index d7e15a0e52..65f13b3caf 100644 --- a/bfd/elf32-rx.c +++ b/bfd/elf32-rx.c @@ -2947,8 +2947,58 @@ elf32_rx_machine (bfd * abfd) static bfd_boolean rx_elf_object_p (bfd * abfd) { + int i; + unsigned int u; + Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr; + int nphdrs = elf_elfheader (abfd)->e_phnum; + sec_ptr bsec; + bfd_default_set_arch_mach (abfd, bfd_arch_rx, elf32_rx_machine (abfd)); + + /* For each PHDR in the object, we must find some section that + corresponds (based on matching file offsets) and use its VMA + information to reconstruct the p_vaddr field we clobbered when we + wrote it out. */ + for (i=0; i<nphdrs; i++) + { + for (u=0; u<elf_tdata(abfd)->num_elf_sections; u++) + { + Elf_Internal_Shdr *sec = elf_tdata(abfd)->elf_sect_ptr[u]; + + if (phdr[i].p_offset <= (bfd_vma) sec->sh_offset + && (bfd_vma)sec->sh_offset <= phdr[i].p_offset + (phdr[i].p_filesz - 1)) + { + /* Found one! The difference between the two addresses, + plus the difference between the two file offsets, is + enough information to reconstruct the lma. */ + + /* Example where they aren't: + PHDR[1] = lma fffc0100 offset 00002010 size 00000100 + SEC[6] = vma 00000050 offset 00002050 size 00000040 + + The correct LMA for the section is fffc0140 + (2050-2010). + */ + + phdr[i].p_vaddr = sec->sh_addr + (sec->sh_offset - phdr[i].p_offset); + break; + } + } + + /* We must update the bfd sections as well, so we don't stop + with one match. */ + bsec = abfd->sections; + while (bsec) + { + if (phdr[i].p_vaddr <= bsec->lma + && bsec->vma <= phdr[i].p_vaddr + (phdr[i].p_filesz - 1)) + { + bsec->lma = phdr[i].p_paddr + (bsec->vma - phdr[i].p_vaddr); + } + bsec = bsec->next; + } + } + return TRUE; } |