[patch] Fix bfd_elf_bfd_from_remote_memory() loadbase
Jan Kratochvil
jan.kratochvil@redhat.com
Fri Aug 10 15:16:00 GMT 2007
Hi,
bfd_elf_bfd_from_remote_memory() is currently in use only for vDSOs where it
works fine. It fails for real memory-mapped ELF files, though.
On the other hand I do not need this fix as my build-id GDB patch no longer
uses bfd_elf_bfd_from_remote_memory() (as it was performance-ineffective).
My memory-mapped dummy test library has:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0005dc 0x0005dc R E 0x200000
LOAD 0x0005e0 0x00000000002005e0 0x00000000002005e0 0x0001e8 0x0001f8 RW 0x200000
which sets the LOADBASE variable by the current BFD CVS HEAD for both for the
first and for the second PT_LOAD segment by
if (loadbase == ehdr_vma)
loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
This command has no effect on the first PT_LOAD there (as P_VADDR is zero) and
so even the second PT_LOAD gets processed.
I believe a simple rule "just the first PT_LOAD segment" implemented in my
patch should be enough.
The current PF_R condition there targets ia64 vDSO which has:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0xa000000000000000 0xa000000000000000 0x000610 0x000610 R 0x10000
LOAD 0x000000 0xa000000000010000 0xa000000000010000 0x0009d0 0x0009d0 E 0x10000
so the (i_phdrs[i].p_flags & PF_R) condition picked the first one (the right
one). Still this condition is needed there as the memory needs to be readable.
Tested on x86_64 on GDB testsuite and on some IA64 vDSO GDB accesses with no
regressions.
Regards,
Jan
-------------- next part --------------
2007-08-10 Jan Kratochvil <jan.kratochvil@redhat.com>
* elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): LOADBASE is now
initialized only on the first PT_LOAD. New variable LOADBASE_SET.
Moved the IA-64 vDSO handling comments to the LOADBASE assignment.
--- bfd/elfcode.h 4 Aug 2007 16:31:00 -0000 1.85
+++ bfd/elfcode.h 10 Aug 2007 14:46:27 -0000
@@ -1635,6 +1635,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
int err;
unsigned int i;
bfd_vma loadbase;
+ bfd_boolean loadbase_set;
/* Read in the ELF header in external format. */
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
@@ -1711,12 +1712,11 @@ NAME(_bfd_elf,bfd_from_remote_memory)
contents_size = 0;
last_phdr = NULL;
loadbase = ehdr_vma;
+ loadbase_set = FALSE;
for (i = 0; i < i_ehdr.e_phnum; ++i)
{
elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
- /* IA-64 vDSO may have two mappings for one segment, where one mapping
- is executable only, and one is read only. We must not use the
- executable one. */
+ /* PF_R as we need to read the segment memory. */
if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R))
{
bfd_vma segment_end;
@@ -1725,8 +1725,18 @@ NAME(_bfd_elf,bfd_from_remote_memory)
if (segment_end > (bfd_vma) contents_size)
contents_size = segment_end;
- if ((i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
- loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
+ /* Only the first PT_LOAD segment indicates the file bias.
+ Next segments may have P_VADDR arbitrarily higher.
+ If the first segment has P_VADDR zero any next segment must not
+ confuse us, the first one sets LOADBASE certainly enough.
+ IA-64 vDSO may have two mappings for one segment, where the first
+ mapping is executable only, and the second one is read only.
+ We must use the first one. */
+ if (!loadbase_set && i_phdrs[i].p_offset == 0)
+ {
+ loadbase = ehdr_vma - i_phdrs[i].p_vaddr;
+ loadbase_set = TRUE;
+ }
last_phdr = &i_phdrs[i];
}
@@ -1764,9 +1774,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
}
for (i = 0; i < i_ehdr.e_phnum; ++i)
- /* IA-64 vDSO may have two mappings for one segment, where one mapping
- is executable only, and one is read only. We must not use the
- executable one. */
+ /* PF_R as we need to read the segment memory. */
if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R))
{
bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
More information about the Binutils
mailing list