This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[rx,head,2.21] fix lma/vma swap when reading executables in
- From: DJ Delorie <dj at redhat dot com>
- To: binutils at sourceware dot org
- Date: Mon, 23 May 2011 15:50:43 -0400
- Subject: [rx,head,2.21] fix lma/vma swap when reading executables in
Without this, it's impossible to "objcopy elf srec" as the addresses
in the srec are incorrect. Also affects gdb. Applied to both head
and 2.21 branch.
* 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.
Index: bfd/elf32-rx.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-rx.c,v
retrieving revision 1.10
diff -p -U5 -r1.10 elf32-rx.c
--- bfd/elf32-rx.c 17 May 2011 16:02:31 -0000 1.10
+++ bfd/elf32-rx.c 23 May 2011 19:48:06 -0000
@@ -2952,12 +2952,62 @@ 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;
}
#ifdef DEBUG