This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: vdso handling
- From: Pedro Alves <palves at redhat dot com>
- To: "Metzger, Markus T" <markus dot t dot metzger at intel dot com>, Mark Wielaard <mjw at redhat dot com>, Cary Coutant <ccoutant at google dot com>, Doug Evans <dje at google dot com>, gdb-patches at sourceware dot org, binutils at sourceware dot org
- Date: Fri, 28 Mar 2014 13:37:52 +0000
- Subject: Re: vdso handling
- Authentication-results: sourceware.org; auth=none
- References: <20140313130322 dot GA3384 at bubble dot grove dot modra dot org> <5321C7C8 dot 6000707 at redhat dot com> <5321C8FA dot 40708 at gmail dot com> <5321CE1A dot 20509 at redhat dot com> <20140313235347 dot GD3384 at bubble dot grove dot modra dot org> <A78C989F6D9628469189715575E55B230AAB6B17 at IRSMSX103 dot ger dot corp dot intel dot com> <20140318230939 dot GA9145 at bubble dot grove dot modra dot org> <5329879C dot 6070805 at redhat dot com> <20140320013305 dot GA13347 at bubble dot grove dot modra dot org> <532C5F60 dot 80700 at redhat dot com> <20140328061321 dot GU18201 at bubble dot grove dot modra dot org>
On 03/28/2014 06:13 AM, Alan Modra wrote:
> On Fri, Mar 21, 2014 at 03:48:48PM +0000, Pedro Alves wrote:
>> I just tried pointing add-symbol-file-from-memory at an already
>> mapped DSO's elf header, but it doesn't work as is unfortunately:
>>
>> (gdb) info shared curses
>> 0x000000324d006d20 0x000000324d01df58 Yes /lib64/libncurses.so.5
>> (gdb) x /4b 0x000000324d000000
>> 0x324d000000: 127 69 76 70
>> (gdb) add-symbol-file-from-memory 0x000000324d000000
>> Failed to read a valid object file image from memory.
>>
>> I single stepped a little through
>> bfd_elf_bfd_from_remote_memory - something goes wrong with the
>> reading of the load segment contents, probably something wrong
>> with the address computations.
>
> readelf -a --wide on my x86_64 libncurses.so.5 shows
>
> [snip]
> Start of section headers: 132144 (bytes into file)
> [snip]
> [25] .shstrtab STRTAB 0000000000000000 02034c 0000de 00 0 0 1
> [snip]
> LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x01efe4 0x01efe4 R E 0x200000
> LOAD 0x01fd50 0x000000000021fd50 0x000000000021fd50 0x0005e4 0x000770 RW 0x200000
>
> So .shstrtab and the section headers might have been loaded by the
> second PT_LOAD header, *but* the second PT_LOAD has a bss area.
> Anything past 0x220334 will be cleared out by ld.so. No chance of
> getting at section headers then, and this will be true for most
> in-memory images.
Indeed.
> bfd_from_remote_memory should take note of p_memsz.. Hmm, and there
> are quite a few other issues there too, most notably that p_align
> on x86_64 these days tends to be *much* larger than the page size used
> by ld.so.
Hmm. Indeed. With current mainline, and with your patch as is,
the command still fails for me. In fact, it turns out
exactly related to p_align vs page size.
$ cat /proc/30669/maps | grep ncurses
324d000000-324d023000 r-xp 00000000 fd:01 315662 /usr/lib64/libncurses.so.5.9
324d023000-324d222000 ---p 00023000 fd:01 315662 /usr/lib64/libncurses.so.5.9
324d222000-324d223000 r--p 00022000 fd:01 315662 /usr/lib64/libncurses.so.5.9
324d223000-324d224000 rw-p 00023000 fd:01 315662 /usr/lib64/libncurses.so.5.9
So when trying to read the second PT_LOAD with p_vmaddr 324d222cf8
and p_vmaddr+p_filesz 324d2236b4, (the 3rd and 4th region above),
we'd end up reading from 324d200000 to 324d2236b4:
(top-gdb) p /x loadbase + vaddr
$5 = 0x324d200000
(top-gdb) p /x end
$6 = 0x236b4
(top-gdb) p /x loadbase + vaddr + end
$8 = 0x324d2236b4
which fails as it hits the (324d023000-324d222000) region,
which has no permissions.
This patch on top of yours makes things work for me:
---
bfd/elfcode.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 31f67a8..974c8b4 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -1622,6 +1622,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
bfd_vma shdr_end;
bfd_vma loadbase;
bfd_boolean loadbase_set;
+ bfd_vma page_size;
/* Read in the ELF header in external format. */
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
@@ -1693,6 +1694,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
}
i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
+ page_size = get_elf_backend_data (templ)->minpagesize;
high_offset = 0;
last_phdr = NULL;
loadbase = 0;
@@ -1753,7 +1755,6 @@ NAME(_bfd_elf,bfd_from_remote_memory)
high_offset = shdr_end;
else
{
- bfd_vma page_size = get_elf_backend_data (templ)->minpagesize;
bfd_vma segment_end = last_phdr->p_offset + last_phdr->p_filesz;
/* Assume we loaded full pages, allowing us to sometimes see
@@ -1781,15 +1782,14 @@ NAME(_bfd_elf,bfd_from_remote_memory)
if (i_phdrs[i].p_type == PT_LOAD)
{
bfd_vma start = i_phdrs[i].p_offset;
- bfd_vma end = start + i_phdrs[i].p_filesz;
bfd_vma vaddr = i_phdrs[i].p_vaddr;
+ bfd_vma end = start + i_phdrs[i].p_filesz;
- if (i_phdrs[i].p_align > 1)
- {
- start &= -i_phdrs[i].p_align;
- end = (end + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
- vaddr &= -i_phdrs[i].p_align;
- }
+ /* Assume we loaded full pages, allowing us to sometimes see
+ section headers. */
+ start &= -page_size;
+ vaddr &= -page_size;
+ end = (end + page_size - 1) & -page_size;
if (end > high_offset)
end = high_offset;
err = target_read_memory (loadbase + vaddr,
--
1.7.11.7
> Gah, I've been sucked into looking at this long enough that I may as
> well fix it. Does this look OK?
It does to me. Thanks!
--
Pedro Alves