Re: [patch] solib-svr4.c - allow reading linkmap info from core without executable

Aleksandar Ristovski
2009-06-19T16:03:50Z

Pedro Alves wrote:
> On Friday 19 June 2009 15:42:04, Mark Kettenis wrote:
>>> From: Aleksandar Ristovski <aristovski@qnx.com>
>>> Date: Fri, 19 Jun 2009 10:16:26 -0400
>>>
>>> Pedro Alves wrote:
>>>> I was thinking on pushing the elf check a bit down instead,
>>>> like the below. However, having now tested this, I see that
>>>> this doesn't work in most of the cores I have here (x86_64-linux).
>>>> In most cases I see, the segment that would contain the program
>>>> headers, as indicated by auxv info, isn't included in the
>>>> core...
>>>>
>>>> (objdump -h)
>>>> Idx Name Size VMA LMA File off Algn
>>>> :
>>>> 6 load1 00000000 0000000000400000 0000000000000000 000008f8 2**0
>>>> ALLOC, READONLY, CODE
>>>> :
>>>>
>> I'm somewhat amazed that the Linux kernel doesn't dump the auxv stuff.
>> Without the auxv data, debugging core dumps of PIE executables will be
>> impossible.
>>
>> Perhaps the kernel does include the information in the does, but bfd
>> doesn't have the necessary code to turn it into an .auxv section?
>
> Nope, let me explain a bit better: the auxv data is there, but the
> program headers aren't.
>
> Idx Name Size VMA LMA File off Algn
> 0 note0 00000538 0000000000000000 0000000000000000 000003c0 2**0
> CONTENTS, READONLY
> 1 .reg/30270 000000d8 0000000000000000 0000000000000000 000004e0 2**2
> CONTENTS
> 2 .reg 000000d8 0000000000000000 0000000000000000 000004e0 2**2
> CONTENTS
> 3 .reg2/30270 00000200 0000000000000000 0000000000000000 000005d4 2**2
> CONTENTS
> 4 .reg2 00000200 0000000000000000 0000000000000000 000005d4 2**2
> CONTENTS
> 5 .auxv 00000110 0000000000000000 0000000000000000 000007e8 2**3
> CONTENTS
> 6 load1 00000000 0000000000400000 0000000000000000 000008f8 2**0
> ^^^^^^^^
> ALLOC, READONLY, CODE
> ^^^^^^^^^^^^^^^^^^^^^
> 7 load2 00001000 0000000000600000 0000000000000000 000008f8 2**0
> CONTENTS, ALLOC, LOAD
> :
>
> In this case, AT_PHDR points at 0x400040, but the data is just not there
> in the core, because it is read-only data, and the kernel decided it
> isn't worth to dump it (gdb's gcore does the same):
>
>> cat /proc/18439/maps
> 00400000-00401000 r-xp 00000000 08:07 2819992 /home/pedro/gdb/mainline/build/gdb/testsuite/gdb.base/annota1
> ^^^^
> 00600000-00601000 rw-p 00000000 08:07 2819992 /home/pedro/gdb/mainline/build/gdb/testsuite/gdb.base/annota1
>
> Aleksandar, did you try the version of the patch I posted?
>

Yes, it works:

$ ./gdb --nx --core testsuite/gdb.base/bigcore.corefile
GNU gdb (GDB) 6.8.50.20090619-cvs
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and
redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type
"show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(no debugging symbols found)
Core was generated by
`/space/src/gdbcvs2/qnx/srcclean/linux-native/gdb/testsuite/gdb.base/bigcore'.
Program terminated with signal 6, Aborted.
#0 0x08048b8f in ?? ()
(gdb) info shared
From To Syms Read Shared Object Library
0x4cb3e470 0x4cb58844 No /lib/libm.so.6
0x4ca18dd0 0x4cafe490 No /lib/libc.so.6
0x4c9e5880 0x4c9fa8ef No /lib/ld-linux.so.2
(gdb) q

With:
$ cvs-diff gdb/solib-svr4.c
Index: gdb/solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.100
diff -u -p -r1.100 solib-svr4.c
--- gdb/solib-svr4.c 22 May 2009 23:49:13 -0000 1.100
+++ gdb/solib-svr4.c 19 Jun 2009 15:34:40 -0000
@@ -266,7 +266,7 @@ IGNORE_FIRST_LINK_MAP_ENTRY (struct so_l

/* Assume that everything is a library if the dynamic
loader was loaded
late by a static executable. */
- if (bfd_get_section_by_name (exec_bfd, ".dynamic") == NULL)
+ if (exec_bfd && bfd_get_section_by_name (exec_bfd,
".dynamic") == NULL)
return 0;

return extract_typed_address (so->lm_info->lm +
lmo->l_prev_offset,
@@ -600,9 +600,13 @@ scan_dyntag (int dyntag, bfd *abfd, CORE

if (abfd == NULL)
return 0;
+
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ return 0;
+
arch_size = bfd_get_arch_size (abfd);
if (arch_size == -1)
- return 0;
+ return 0;

/* Find the start address of the .dynamic section. */
sect = bfd_get_section_by_name (abfd, ".dynamic");
@@ -825,11 +829,7 @@ locate_base (struct svr4_info *info)
though if we don't have some link map offsets to work
with. */

if (info->debug_base == 0 && svr4_have_link_map_offsets ())
- {
- if (exec_bfd != NULL
- && bfd_get_flavour (exec_bfd) ==
bfd_target_elf_flavour)
- info->debug_base = elf_locate_base ();
- }
+ info->debug_base = elf_locate_base ();
return info->debug_base;
}

--
Aleksandar Ristovski
QNX Software Systems