* vdso handling @ 2014-03-10 13:05 Metzger, Markus T 2014-03-12 7:17 ` Alan Modra 0 siblings, 1 reply; 41+ messages in thread From: Metzger, Markus T @ 2014-03-10 13:05 UTC (permalink / raw) To: gdb, binutils Hello, My name is Markus. I work for Intel on GDB in the area of hardware-supported execution recording. I noticed that the BFD created for the VDSO (system-provided in-memory DSO) does not contain any BFD sections. Is this intentional? Or has there just been no need for them? If it just hasn't been done, yet, how would I best approach this? Here's the problem I am trying to solve with this. May as well be that I'm on the wrong track... When using the btrace record target, GDB only allows access to read-only memory during replay. The btrace record target does not trace data so read-write memory corresponds to the end of the trace, not the current replay position. The implementation uses the same check that is also used for 'trust-readonly-sections", i.e. section = target_section_by_addr (ops, offset); if (section != NULL) { /* Check if the section we found is readonly. */ if ((bfd_get_section_flags (section->the_bfd_section->owner, section->the_bfd_section) & SEC_READONLY) != 0) For the vdso, there is no target section, so the check fails. This prevents GDB from disassembling vdso instructions during replay. The vdso is processed in symbol_file_add_from_memory at gdb/symfile-mem.c:84. It calls bfd_from_remote_memory to create a BFD for the vdso and then processes it. If there were BFD sections, the following small patch should add the respective target sections to GDB. diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c index e3230de..cf4da38 100644 --- a/gdb/symfile-mem.c +++ b/gdb/symfile-mem.c @@ -91,6 +91,7 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name, struct section_addr_info *sai; unsigned int i; struct cleanup *cleanup; + struct target_section *sections, *sections_end, *tsec; if (bfd_get_flavour (templ) != bfd_target_elf_flavour) error (_("add-symbol-file-from-memory not supported for this target")); @@ -113,6 +114,22 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name, error (_("Got object file from memory but can't read symbols: %s."), bfd_errmsg (bfd_get_error ())); + /* Add target sections for this bfd. */ + sections = NULL; + sections_end = NULL; + if (build_section_table (nbfd, §ions, §ions_end)) + error (_("Failed to build section table")); + + /* Adjust the target section addresses by the load address. */ + for (tsec = sections; tsec != sections_end; ++tsec) + { + tsec->addr += loadbase; + tsec->endaddr += loadbase; + } + + add_target_sections (&nbfd, sections, sections_end); + xfree (sections); + sai = alloc_section_addr_info (bfd_count_sections (nbfd)); make_cleanup (xfree, sai); i = 0; This should allow me to pass the above read-only section check and allow GDB to disassemble vdso instructions. thanks, markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-10 13:05 vdso handling Metzger, Markus T @ 2014-03-12 7:17 ` Alan Modra 2014-03-12 11:31 ` Mike Frysinger 2014-03-12 17:34 ` Doug Evans 0 siblings, 2 replies; 41+ messages in thread From: Alan Modra @ 2014-03-12 7:17 UTC (permalink / raw) To: Metzger, Markus T; +Cc: gdb, binutils On Mon, Mar 10, 2014 at 01:04:33PM +0000, Metzger, Markus T wrote: > I noticed that the BFD created for the VDSO (system-provided in-memory > DSO) does not contain any BFD sections. Is this intentional? Or has > there just been no need for them? [snip] > The vdso is processed in symbol_file_add_from_memory at > gdb/symfile-mem.c:84. It calls bfd_from_remote_memory to create a BFD > for the vdso and then processes it. The underlying cause is that you're trying to debug an ELF binary that only contains the execution view. The linking view (of which the sections are a part) is not loaded, so bfd_from_remote_memory does not have this information. See elfcode.h bfd_from_remote_memory. You can see similar breakage of gdb and binutils if you zap e_shoff, e_shnum, and e_shstrndx of your favourite hello world program. I suppose one way to provide something that gdb and other tools expect would be to treat the vdso like a core file, and create fake sections corresponding to the program headers. I'm not really keen on the idea though, since I know that will open up a can of worms. Can't you point gdb at a file image for the vdso? -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-12 7:17 ` Alan Modra @ 2014-03-12 11:31 ` Mike Frysinger 2014-03-12 17:34 ` Doug Evans 1 sibling, 0 replies; 41+ messages in thread From: Mike Frysinger @ 2014-03-12 11:31 UTC (permalink / raw) To: gdb; +Cc: Alan Modra, Metzger, Markus T, binutils [-- Attachment #1: Type: text/plain, Size: 1409 bytes --] On Wed 12 Mar 2014 17:47:02 Alan Modra wrote: > On Mon, Mar 10, 2014 at 01:04:33PM +0000, Metzger, Markus T wrote: > > I noticed that the BFD created for the VDSO (system-provided in-memory > > DSO) does not contain any BFD sections. Is this intentional? Or has > > there just been no need for them? > > [snip] > > > The vdso is processed in symbol_file_add_from_memory at > > gdb/symfile-mem.c:84. It calls bfd_from_remote_memory to create a BFD > > for the vdso and then processes it. > > The underlying cause is that you're trying to debug an ELF binary that > only contains the execution view. The linking view (of which the > sections are a part) is not loaded, so bfd_from_remote_memory does not > have this information. See elfcode.h bfd_from_remote_memory. > > You can see similar breakage of gdb and binutils if you zap e_shoff, > e_shnum, and e_shstrndx of your favourite hello world program. > > I suppose one way to provide something that gdb and other tools expect > would be to treat the vdso like a core file, and create fake sections > corresponding to the program headers. I'm not really keen on the idea > though, since I know that will open up a can of worms. > > Can't you point gdb at a file image for the vdso? i don't think distros generally ship it ? the kernel doesn't install it by default (e.g. into /lib/modules/$(uname -r)/vdso/). -mike [-- Attachment #2: This is a digitally signed message part. --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-12 7:17 ` Alan Modra 2014-03-12 11:31 ` Mike Frysinger @ 2014-03-12 17:34 ` Doug Evans 2014-03-12 20:23 ` Cary Coutant 1 sibling, 1 reply; 41+ messages in thread From: Doug Evans @ 2014-03-12 17:34 UTC (permalink / raw) To: Metzger, Markus T, gdb, binutils On Wed, Mar 12, 2014 at 12:17 AM, Alan Modra <amodra@gmail.com> wrote: > On Mon, Mar 10, 2014 at 01:04:33PM +0000, Metzger, Markus T wrote: >> I noticed that the BFD created for the VDSO (system-provided in-memory >> DSO) does not contain any BFD sections. Is this intentional? Or has >> there just been no need for them? > [snip] >> The vdso is processed in symbol_file_add_from_memory at >> gdb/symfile-mem.c:84. It calls bfd_from_remote_memory to create a BFD >> for the vdso and then processes it. > > The underlying cause is that you're trying to debug an ELF binary that > only contains the execution view. The linking view (of which the > sections are a part) is not loaded, so bfd_from_remote_memory does not > have this information. See elfcode.h bfd_from_remote_memory. > > You can see similar breakage of gdb and binutils if you zap e_shoff, > e_shnum, and e_shstrndx of your favourite hello world program. > > I suppose one way to provide something that gdb and other tools expect > would be to treat the vdso like a core file, and create fake sections > corresponding to the program headers. I'm not really keen on the idea > though, since I know that will open up a can of worms. I think a case can be made that gdb should be able to use the "execution view" of the program here. As for how to achieve that ... "Discuss." :-) ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-12 17:34 ` Doug Evans @ 2014-03-12 20:23 ` Cary Coutant 2014-03-13 1:01 ` Alan Modra 0 siblings, 1 reply; 41+ messages in thread From: Cary Coutant @ 2014-03-12 20:23 UTC (permalink / raw) To: Doug Evans; +Cc: Metzger, Markus T, gdb, binutils > I think a case can be made that gdb should be able to use the > "execution view" of the program here. > As for how to achieve that ... "Discuss." :-) Add a PT_DEBUG program header entry? The PT_DEBUG segment would need to have a small header that allows the debugger to find .debug_abbrev, .debug_info, etc. (i.e., a mini section table). Or, just add individual program header entries for each of the standard debug sections: PT_DEBUG_ABBREV, PT_DEBUG_INFO, etc. -cary ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-12 20:23 ` Cary Coutant @ 2014-03-13 1:01 ` Alan Modra 2014-03-13 8:25 ` Metzger, Markus T 2014-03-13 9:52 ` Mark Wielaard 0 siblings, 2 replies; 41+ messages in thread From: Alan Modra @ 2014-03-13 1:01 UTC (permalink / raw) To: Cary Coutant; +Cc: Doug Evans, Metzger, Markus T, gdb, binutils On Wed, Mar 12, 2014 at 01:22:58PM -0700, Cary Coutant wrote: > > I think a case can be made that gdb should be able to use the > > "execution view" of the program here. > > As for how to achieve that ... "Discuss." :-) > > Add a PT_DEBUG program header entry? The PT_DEBUG segment would need > to have a small header that allows the debugger to find .debug_abbrev, > .debug_info, etc. (i.e., a mini section table). Or, just add > individual program header entries for each of the standard debug > sections: PT_DEBUG_ABBREV, PT_DEBUG_INFO, etc. Debug sections are not normally loaded. For that reason I don't think it makes any sense to specify program headers for them. It wouldn't help in the vdso case anyway, since the problem there is that you only have the loaded part of the original ELF file. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-03-13 1:01 ` Alan Modra @ 2014-03-13 8:25 ` Metzger, Markus T 2014-03-13 9:48 ` Metzger, Markus T 2014-03-13 10:07 ` Pedro Alves 2014-03-13 9:52 ` Mark Wielaard 1 sibling, 2 replies; 41+ messages in thread From: Metzger, Markus T @ 2014-03-13 8:25 UTC (permalink / raw) To: Alan Modra, Cary Coutant; +Cc: Doug Evans, gdb, binutils > -----Original Message----- > From: Alan Modra [mailto:amodra@gmail.com] > Sent: Thursday, March 13, 2014 2:02 AM > To: Cary Coutant > Cc: Doug Evans; Metzger, Markus T; gdb@sourceware.org; > binutils@sourceware.org > Subject: Re: vdso handling > > On Wed, Mar 12, 2014 at 01:22:58PM -0700, Cary Coutant wrote: > > > I think a case can be made that gdb should be able to use the > > > "execution view" of the program here. > > > As for how to achieve that ... "Discuss." :-) > > > > Add a PT_DEBUG program header entry? The PT_DEBUG segment would > need > > to have a small header that allows the debugger to find .debug_abbrev, > > .debug_info, etc. (i.e., a mini section table). Or, just add > > individual program header entries for each of the standard debug > > sections: PT_DEBUG_ABBREV, PT_DEBUG_INFO, etc. > > Debug sections are not normally loaded. For that reason I don't think > it makes any sense to specify program headers for them. It wouldn't > help in the vdso case anyway, since the problem there is that you only > have the loaded part of the original ELF file. The vdso contains a section table, as well. When I hack bfd_from_remote_memory to create BFD sections from them similar to what elf_object_p does, I get the target sections that I wanted in GDB. The patch is rather big, though, and duplicating a lot of elf_object_p's code. I have not tried generating fake sections from segments, yet. Regards, Markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-03-13 8:25 ` Metzger, Markus T @ 2014-03-13 9:48 ` Metzger, Markus T 2014-03-13 10:07 ` Pedro Alves 1 sibling, 0 replies; 41+ messages in thread From: Metzger, Markus T @ 2014-03-13 9:48 UTC (permalink / raw) To: Alan Modra, Cary Coutant; +Cc: Doug Evans, gdb, binutils > -----Original Message----- > From: Metzger, Markus T > Sent: Thursday, March 13, 2014 9:24 AM > > On Wed, Mar 12, 2014 at 01:22:58PM -0700, Cary Coutant wrote: > > > > I think a case can be made that gdb should be able to use the > > > > "execution view" of the program here. > > > > As for how to achieve that ... "Discuss." :-) > > > > > > Add a PT_DEBUG program header entry? The PT_DEBUG segment would > > need > > > to have a small header that allows the debugger to find .debug_abbrev, > > > .debug_info, etc. (i.e., a mini section table). Or, just add > > > individual program header entries for each of the standard debug > > > sections: PT_DEBUG_ABBREV, PT_DEBUG_INFO, etc. > > > > Debug sections are not normally loaded. For that reason I don't think > > it makes any sense to specify program headers for them. It wouldn't > > help in the vdso case anyway, since the problem there is that you only > > have the loaded part of the original ELF file. > > The vdso contains a section table, as well. When I hack > bfd_from_remote_memory to create BFD sections from them similar > to what elf_object_p does, I get the target sections that I wanted in GDB. > The patch is rather big, though, and duplicating a lot of elf_object_p's code. > > I have not tried generating fake sections from segments, yet. This turned out to be rather simple. Is this the right direction to go? Should I maybe restrict this to PT_LOAD segments? diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 20101be..22aae2a 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1771,7 +1771,6 @@ NAME(_bfd_elf,bfd_from_remote_memory) return NULL; } } - free (x_phdrs); /* If the segments visible in memory didn't include the section headers, then clear them from the file header. */ @@ -1791,6 +1790,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); if (bim == NULL) { + free (x_phdrs); free (contents); bfd_set_error (bfd_error_no_memory); return NULL; @@ -1799,6 +1799,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) if (nbfd == NULL) { free (bim); + free (x_phdrs); free (contents); bfd_set_error (bfd_error_no_memory); return NULL; @@ -1815,6 +1816,12 @@ NAME(_bfd_elf,bfd_from_remote_memory) nbfd->mtime = time (NULL); nbfd->mtime_set = TRUE; + /* Add fake sections for program headers. We ignore errors. */ + for (i = 0; i < i_ehdr.e_phnum; ++i) + (void) bfd_section_from_phdr (nbfd, &i_phdrs[i], i); + + free (x_phdrs); + if (loadbasep) *loadbasep = loadbase; return nbfd; regards, markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 8:25 ` Metzger, Markus T 2014-03-13 9:48 ` Metzger, Markus T @ 2014-03-13 10:07 ` Pedro Alves 2014-03-13 10:46 ` Pedro Alves 2014-03-13 13:13 ` Alan Modra 1 sibling, 2 replies; 41+ messages in thread From: Pedro Alves @ 2014-03-13 10:07 UTC (permalink / raw) To: Metzger, Markus T; +Cc: Alan Modra, Cary Coutant, Doug Evans, gdb, binutils On 03/13/2014 08:23 AM, Metzger, Markus T wrote: >> -----Original Message----- >> From: Alan Modra [mailto:amodra@gmail.com] >> Sent: Thursday, March 13, 2014 2:02 AM >> To: Cary Coutant >> Cc: Doug Evans; Metzger, Markus T; gdb@sourceware.org; >> binutils@sourceware.org >> Subject: Re: vdso handling >> >> On Wed, Mar 12, 2014 at 01:22:58PM -0700, Cary Coutant wrote: >>>> I think a case can be made that gdb should be able to use the >>>> "execution view" of the program here. >>>> As for how to achieve that ... "Discuss." :-) >>> >>> Add a PT_DEBUG program header entry? The PT_DEBUG segment would >> need >>> to have a small header that allows the debugger to find .debug_abbrev, >>> .debug_info, etc. (i.e., a mini section table). Or, just add >>> individual program header entries for each of the standard debug >>> sections: PT_DEBUG_ABBREV, PT_DEBUG_INFO, etc. >> >> Debug sections are not normally loaded. For that reason I don't think >> it makes any sense to specify program headers for them. It wouldn't >> help in the vdso case anyway, since the problem there is that you only >> have the loaded part of the original ELF file. > > The vdso contains a section table, as well. When I hack > bfd_from_remote_memory to create BFD sections from them similar > to what elf_object_p does, I get the target sections that I wanted in GDB. I got curious. Indeed: $ gdb --quiet /bin/ls Reading symbols from /usr/bin/ls...(no debugging symbols found)...done. (gdb) catch syscall Catchpoint 1 (any syscall) (gdb) r Starting program: /usr/bin/ls Catchpoint 1 (call to syscall brk), 0x000000323d0163fa in __brk (addr=addr@entry=0x0) at ../sysdeps/unix/sysv/linux/x86_64/brk.c:32 32 __curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr); (gdb) shell cat /proc/23042/maps|grep vdso 7ffff7ffd000-7ffff7fff000 r-xp 00000000 00:00 0 [vdso] (gdb) dump memory /tmp/vdso.so 0x7ffff7ffd000 0x7ffff7fff000 (gdb) q $ objdump -h /tmp/vdso.so /tmp/vdso.so: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .hash 00000040 ffffffffff700120 ffffffffff700120 00000120 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .dynsym 00000108 ffffffffff700160 ffffffffff700160 00000160 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .dynstr 0000005e ffffffffff700268 ffffffffff700268 00000268 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .gnu.version 00000016 ffffffffff7002c6 ffffffffff7002c6 000002c6 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .gnu.version_d 00000038 ffffffffff7002e0 ffffffffff7002e0 000002e0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .note 0000003c ffffffffff700318 ffffffffff700318 00000318 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .eh_frame_hdr 0000003c ffffffffff700354 ffffffffff700354 00000354 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .eh_frame 00000138 ffffffffff700390 ffffffffff700390 00000390 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .dynamic 000000f0 ffffffffff7004c8 ffffffffff7004c8 000004c8 2**3 CONTENTS, ALLOC, LOAD, DATA 9 .rodata 00000020 ffffffffff7005b8 ffffffffff7005b8 000005b8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 10 __bug_table 0000000c ffffffffff7005d8 ffffffffff7005d8 000005d8 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 11 .discard 00000006 ffffffffff7005e4 ffffffffff7005e4 000005e4 2**0 CONTENTS, ALLOC, LOAD, DATA 12 .altinstructions 00000048 ffffffffff7005ea ffffffffff7005ea 000005ea 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 13 .altinstr_replacement 00000012 ffffffffff700632 ffffffffff700632 00000632 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 14 .text 0000069d ffffffffff700700 ffffffffff700700 00000700 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 15 .comment 0000002c 0000000000000000 0000000000000000 00000d9d 2**0 CONTENTS, READONLY > The patch is rather big, though, and duplicating a lot of elf_object_p's code. Why's that? Why doesn't the memory-backed bfd paths take the same paths as a file-backed bfd internally in bfd? It sounds to me that this should be doable without duplication. -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 10:07 ` Pedro Alves @ 2014-03-13 10:46 ` Pedro Alves 2014-06-01 23:45 ` Samuel Bronson 2014-03-13 13:13 ` Alan Modra 1 sibling, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-13 10:46 UTC (permalink / raw) To: Metzger, Markus T; +Cc: Alan Modra, Cary Coutant, Doug Evans, gdb, binutils On 03/13/2014 10:07 AM, Pedro Alves wrote: > Why's that? Why doesn't the memory-backed bfd paths take the same paths as > a file-backed bfd internally in bfd? It sounds to me that this should be > doable without duplication. BTW, I meant that for vDSO's only. The vsyscall page is not an elf, and therefore bfd still needs to be passed a template elf. For the latter, GDB would indeed need to work with the segments. Do we still care for vsyscall kernels? But for the former, bfd should just be able to read the whole DSO as a plain elf. Some glibc versions even include the vdso in the DSO list (*), and GDB should be able to tell that that DSO is the vDSO (by matching addresses), and load it completely from memory, still using a memory backed bfd, but _without_ a template. So with that in mind, bfd should be able to read the vdso as a bfd from memory using the same paths as a file-backed bfd, except, well, the bfd's backing store is in memory rather than in a file. (*) note how linux-vdso.so.1 is listed by ldd, even if "info shared" in gdb doesn't show it, on some systems. -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 10:46 ` Pedro Alves @ 2014-06-01 23:45 ` Samuel Bronson 2014-06-06 12:45 ` Pedro Alves 0 siblings, 1 reply; 41+ messages in thread From: Samuel Bronson @ 2014-06-01 23:45 UTC (permalink / raw) To: binutils; +Cc: gdb Pedro Alves <palves@redhat.com> writes: > On 03/13/2014 10:07 AM, Pedro Alves wrote: >> Why's that? Why doesn't the memory-backed bfd paths take the same paths as >> a file-backed bfd internally in bfd? It sounds to me that this should be >> doable without duplication. > > BTW, I meant that for vDSO's only. The vsyscall page is not an elf, > and therefore bfd still needs to be passed a template elf. For the > latter, GDB would indeed need to work with the segments. Do we still > care for vsyscall kernels? But for the former, bfd should just be > able to read the whole DSO as a plain elf. > > Some glibc versions even include the vdso in the DSO list (*), and GDB > should be able to tell that that DSO is the vDSO (by matching addresses), and ^^^^^^^^^^^^^^^^^^^^^ Hmm, why don't we already do that? It's bound to be easier than meeting the conditions to get glibc to stop falsely cliaming that the vDSO comes from a file <https://sourceware.org/bugzilla/show_bug.cgi?id=13097#c5>. That'd be enough to take two bugs off of <http://bugs.debian.org/gdb> right there. > load it completely from memory, still using a memory backed bfd, but _without_ > a template. So with that in mind, bfd should be able to read the vdso > as a bfd from memory using the same paths as a file-backed bfd, except, > well, the bfd's backing store is in memory rather than in a file. > > (*) note how linux-vdso.so.1 is listed by ldd, even if "info shared" in gdb > doesn't show it, on some systems. What versions don't list the vdso under some name or other? (Mine calls it linux-gate.so.1 for some reason.) -- Hi! I'm a .signature virus! Copy me into your ~/.signature to help me spread! ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-06-01 23:45 ` Samuel Bronson @ 2014-06-06 12:45 ` Pedro Alves 0 siblings, 0 replies; 41+ messages in thread From: Pedro Alves @ 2014-06-06 12:45 UTC (permalink / raw) To: Samuel Bronson, gdb; +Cc: binutils On 06/01/2014 09:31 PM, Samuel Bronson wrote: > Pedro Alves <palves@redhat.com> writes: >> Some glibc versions even include the vdso in the DSO list (*), and GDB >> should be able to tell that that DSO is the vDSO (by matching addresses), and > ^^^^^^^^^^^^^^^^^^^^^ > Hmm, why don't we already do that? It's bound to be easier than meeting > the conditions to get glibc to stop falsely cliaming that the vDSO comes > from a file <https://sourceware.org/bugzilla/show_bug.cgi?id=13097#c5>. Dunno. Because nobody has done it? I suppose that's what Ulrich meant in <https://sourceware.org/bugzilla/show_bug.cgi?id=13097#c1>. >> (*) note how linux-vdso.so.1 is listed by ldd, even if "info shared" in gdb >> doesn't show it, on some systems. > > What versions don't list the vdso under some name or other? (Mine calls > it linux-gate.so.1 for some reason.) I don't know versions numbers, but all before the glibc commit mentioned in <https://sourceware.org/bugzilla/show_bug.cgi?id=13097#c1> I guess, and also, see the rest of the discussion there, indicating that Fedora carries a reversion of the offending patch. -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 10:07 ` Pedro Alves 2014-03-13 10:46 ` Pedro Alves @ 2014-03-13 13:13 ` Alan Modra 1 sibling, 0 replies; 41+ messages in thread From: Alan Modra @ 2014-03-13 13:13 UTC (permalink / raw) To: Pedro Alves; +Cc: Metzger, Markus T, Cary Coutant, Doug Evans, gdb, binutils On Thu, Mar 13, 2014 at 10:07:10AM +0000, Pedro Alves wrote: > Why doesn't the memory-backed bfd paths take the same paths as > a file-backed bfd internally in bfd? I think they do. In symfile-mem.c:symbol_file_add_from_memory nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase, target_read_memory_bfd); .. if (!bfd_check_format (nbfd, bfd_object)) That bfd_check_format is where elf_object_p is called. *If* bfd_from_remote_memory picked up the sections headers, you'll get a normal bfd with sections.. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 1:01 ` Alan Modra 2014-03-13 8:25 ` Metzger, Markus T @ 2014-03-13 9:52 ` Mark Wielaard 2014-03-13 13:03 ` Alan Modra 1 sibling, 1 reply; 41+ messages in thread From: Mark Wielaard @ 2014-03-13 9:52 UTC (permalink / raw) To: Alan Modra; +Cc: Cary Coutant, Doug Evans, Metzger, Markus T, gdb, binutils On Thu, 2014-03-13 at 11:31 +1030, Alan Modra wrote: > It wouldn't > help in the vdso case anyway, since the problem there is that you only > have the loaded part of the original ELF file. Note that the vdso is often special, compared to other ELF dsos, because the loaded part is just the complete ELF image in memory. Since they are very simple they will just have one PT_LOAD at offset zero and if the image is smaller than the page size then the whole file is just simply mapped into memory completely. So by fetching the vdso ELF image from remote memory you should be able to get the section headers and the not-allocated sections too. Cheers, Mark ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 9:52 ` Mark Wielaard @ 2014-03-13 13:03 ` Alan Modra 2014-03-13 14:38 ` Mark Wielaard 2014-03-13 14:59 ` Pedro Alves 0 siblings, 2 replies; 41+ messages in thread From: Alan Modra @ 2014-03-13 13:03 UTC (permalink / raw) To: Mark Wielaard; +Cc: Cary Coutant, Doug Evans, Metzger, Markus T, gdb, binutils On Thu, Mar 13, 2014 at 10:52:16AM +0100, Mark Wielaard wrote: > On Thu, 2014-03-13 at 11:31 +1030, Alan Modra wrote: > > It wouldn't > > help in the vdso case anyway, since the problem there is that you only > > have the loaded part of the original ELF file. > > Note that the vdso is often special, compared to other ELF dsos, because > the loaded part is just the complete ELF image in memory. Since they are > very simple they will just have one PT_LOAD at offset zero and if the > image is smaller than the page size then the whole file is just simply > mapped into memory completely. So by fetching the vdso ELF image from > remote memory you should be able to get the section headers and the > not-allocated sections too. Yes, but if the vdso does not fit in a page (which incidentally is inferred by program header p_align), then you may lose the section headers. I was assuming this was the case. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 13:03 ` Alan Modra @ 2014-03-13 14:38 ` Mark Wielaard 2014-03-13 14:59 ` Pedro Alves 1 sibling, 0 replies; 41+ messages in thread From: Mark Wielaard @ 2014-03-13 14:38 UTC (permalink / raw) To: Alan Modra; +Cc: Cary Coutant, Doug Evans, Metzger, Markus T, gdb, binutils On Thu, 2014-03-13 at 23:33 +1030, Alan Modra wrote: > On Thu, Mar 13, 2014 at 10:52:16AM +0100, Mark Wielaard wrote: > > On Thu, 2014-03-13 at 11:31 +1030, Alan Modra wrote: > > > It wouldn't > > > help in the vdso case anyway, since the problem there is that you only > > > have the loaded part of the original ELF file. > > > > Note that the vdso is often special, compared to other ELF dsos, because > > the loaded part is just the complete ELF image in memory. Since they are > > very simple they will just have one PT_LOAD at offset zero and if the > > image is smaller than the page size then the whole file is just simply > > mapped into memory completely. So by fetching the vdso ELF image from > > remote memory you should be able to get the section headers and the > > not-allocated sections too. > > Yes, but if the vdso does not fit in a page (which incidentally is > inferred by program header p_align), then you may lose the section > headers. I was assuming this was the case. Yes, you are right. Almost everything else is bigger than a page and has multiple PT_LOAD segments. In which case determining whether the full shdrs were mapped in from the file is much trickier. And might have to rely on only the phdrs. We recently went through this for elfutils, which also contains an elf_from_remote_memory implementation (if someone needs inspiration). Currently that implementation just uses the phdrs and so needs some heuristics using the program header fields to know what part of the file was mapped where. But if you have access to the actual /proc/PID/maps ranges you might be able to do something more accurate, or at least be able to cross check that the program headers view is really how the ELF image is actually laid out (*). Cheers, Mark (*) Don't make the mistake we made to think p_align is what segments are actually aligned to, the dynamic loader on GNU/Linux just uses the actual page size of the architecture to align the mappings: https://lists.fedorahosted.org/pipermail/elfutils-devel/2014-March/003859.html ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 13:03 ` Alan Modra 2014-03-13 14:38 ` Mark Wielaard @ 2014-03-13 14:59 ` Pedro Alves 2014-03-13 15:04 ` Pedro Alves 1 sibling, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-13 14:59 UTC (permalink / raw) To: Mark Wielaard, Cary Coutant, Doug Evans, Metzger, Markus T, gdb, binutils On 03/13/2014 01:03 PM, Alan Modra wrote: > On Thu, Mar 13, 2014 at 10:52:16AM +0100, Mark Wielaard wrote: >> On Thu, 2014-03-13 at 11:31 +1030, Alan Modra wrote: >>> It wouldn't >>> help in the vdso case anyway, since the problem there is that you only >>> have the loaded part of the original ELF file. >> >> Note that the vdso is often special, compared to other ELF dsos, because >> the loaded part is just the complete ELF image in memory. Since they are >> very simple they will just have one PT_LOAD at offset zero and if the >> image is smaller than the page size then the whole file is just simply >> mapped into memory completely. So by fetching the vdso ELF image from >> remote memory you should be able to get the section headers and the >> not-allocated sections too. > > Yes, but if the vdso does not fit in a page (which incidentally is > inferred by program header p_align), then you may lose the section > headers. I was assuming this was the case. Hmm. How so? On x86 (arch/x86/vdso/vdso.S), the kernel just does: .globl vdso_start, vdso_end .align PAGE_SIZE vdso_start: .incbin "arch/x86/vdso/vdso.so" vdso_end: .align PAGE_SIZE /* extra data here leaks to userspace. */ And then arch/x86/vdso/vma.c has: static int __init init_vdso(void) { int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE; int i; patch_vdso64(vdso_start, vdso_end - vdso_start); vdso_size = npages << PAGE_SHIFT; for (i = 0; i < npages; i++) vdso_pages[i] = virt_to_page(vdso_start + i*PAGE_SIZE); #ifdef CONFIG_X86_X32_ABI patch_vdsox32(vdsox32_start, vdsox32_end - vdsox32_start); npages = (vdsox32_end - vdsox32_start + PAGE_SIZE - 1) / PAGE_SIZE; vdsox32_size = npages << PAGE_SHIFT; for (i = 0; i < npages; i++) vdsox32_pages[i] = virt_to_page(vdsox32_start + i*PAGE_SIZE); #endif return 0; } And patch_vdso64 _relies_ on sections being present at runtime: static void __init patch_vdso64(void *vdso, size_t len) { Elf64_Ehdr *hdr = vdso; Elf64_Shdr *sechdrs, *alt_sec = 0; char *secstrings; void *alt_data; int i; BUG_ON(len < sizeof(Elf64_Ehdr)); BUG_ON(memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0); sechdrs = (void *)hdr + hdr->e_shoff; secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (i = 1; i < hdr->e_shnum; i++) { Elf64_Shdr *shdr = &sechdrs[i]; if (!strcmp(secstrings + shdr->sh_name, ".altinstructions")) { alt_sec = shdr; goto found; } } /* If we get here, it's probably a bug. */ pr_warning("patch_vdso64: .altinstructions not found\n"); return; /* nothing to patch */ found: alt_data = (void *)hdr + alt_sec->sh_offset; apply_alternatives(alt_data, alt_data + alt_sec->sh_size); } On e.g., arch/powerpc/kernel/vdso.c, I see even a lot more code looking at the sections of the vdso. -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 14:59 ` Pedro Alves @ 2014-03-13 15:04 ` Pedro Alves 2014-03-13 15:26 ` Pedro Alves 0 siblings, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-13 15:04 UTC (permalink / raw) Cc: Mark Wielaard, Cary Coutant, Doug Evans, Metzger, Markus T, gdb, binutils On 03/13/2014 02:59 PM, Pedro Alves wrote: > Hmm. How so? On x86 (arch/x86/vdso/vdso.S), the kernel just does: Hmm, guess I should really be looking at where the vdso is actually mapped to a process's address space... (no idea where that is). -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 15:04 ` Pedro Alves @ 2014-03-13 15:26 ` Pedro Alves 2014-03-13 23:53 ` Alan Modra 0 siblings, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-13 15:26 UTC (permalink / raw) To: Mark Wielaard, Cary Coutant, Doug Evans, Metzger, Markus T, gdb, binutils On 03/13/2014 03:04 PM, Pedro Alves wrote: > On 03/13/2014 02:59 PM, Pedro Alves wrote: > >> Hmm. How so? On x86 (arch/x86/vdso/vdso.S), the kernel just does: > > Hmm, guess I should really be looking at where the vdso is > actually mapped to a process's address space... (no idea where > that is). > I think I found it in the same file (arch/x86/vdso/vma.c): int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { return setup_additional_pages(bprm, uses_interp, vdso_pages, vdso_size); } vdso_size comes from: static int __init init_vdso(void) { int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE; int i; patch_vdso64(vdso_start, vdso_end - vdso_start); vdso_size = npages << PAGE_SHIFT; So it seems like the whole vdso should be always mapped in. I didn't look at the whole mode compat mess, but if it behaves differently, it'd sound like a kernel bug to me. -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-13 15:26 ` Pedro Alves @ 2014-03-13 23:53 ` Alan Modra 2014-03-18 15:14 ` Metzger, Markus T 0 siblings, 1 reply; 41+ messages in thread From: Alan Modra @ 2014-03-13 23:53 UTC (permalink / raw) To: Pedro Alves Cc: Mark Wielaard, Cary Coutant, Doug Evans, Metzger, Markus T, gdb, binutils On Thu, Mar 13, 2014 at 03:26:18PM +0000, Pedro Alves wrote: > So it seems like the whole vdso should be always mapped in. OK, so I think Markus should be looking at why bfd_from_remote_memory decides to exclude the section headers. ie. why the following code is being executed /* If the segments visible in memory didn't include the section headers, then clear them from the file header. */ if ((bfd_vma) contents_size < (i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize)) { memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx); } It may be that we can tweak the heuristic. One thing I noticed is that the following /* Trim the last segment so we don't bother with zeros in the last page that are off the end of the file. However, if the extra bit in that page includes the section headers, keep them. */ will trim off .symtab which might otherwise be available. GNU ld places .symtab after the section headers. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-03-13 23:53 ` Alan Modra @ 2014-03-18 15:14 ` Metzger, Markus T 2014-03-18 23:10 ` Alan Modra 0 siblings, 1 reply; 41+ messages in thread From: Metzger, Markus T @ 2014-03-18 15:14 UTC (permalink / raw) To: Alan Modra, Pedro Alves Cc: Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils > -----Original Message----- > From: Alan Modra [mailto:amodra@gmail.com] > Sent: Friday, March 14, 2014 12:54 AM > OK, so I think Markus should be looking at why bfd_from_remote_memory > decides to exclude the section headers. ie. why the following code > is being executed > > /* If the segments visible in memory didn't include the section headers, > then clear them from the file header. */ > if ((bfd_vma) contents_size < (i_ehdr.e_shoff > + i_ehdr.e_shnum * i_ehdr.e_shentsize)) > { > memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); > memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); > memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx); > } > > It may be that we can tweak the heuristic. One thing I noticed is > that the following > > /* Trim the last segment so we don't bother with zeros in the last page > that are off the end of the file. However, if the extra bit in that > page includes the section headers, keep them. */ > > will trim off .symtab which might otherwise be available. GNU ld places > .symtab after the section headers. Something like this? diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 20101be..601d7ea 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1616,7 +1616,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) bfd_byte *contents; int err; unsigned int i; - bfd_vma loadbase; + bfd_vma loadbase, shdr_begin, shdr_end; bfd_boolean loadbase_set; /* Read in the ELF header in external format. */ @@ -1728,20 +1728,16 @@ NAME(_bfd_elf,bfd_from_remote_memory) } /* Trim the last segment so we don't bother with zeros in the last page - that are off the end of the file. However, if the extra bit in that - page includes the section headers, keep them. */ - if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz - && (bfd_vma) contents_size >= (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - { - contents_size = last_phdr->p_offset + last_phdr->p_filesz; - if ((bfd_vma) contents_size < (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; - } - else + that are off the end of the file. */ + if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz) contents_size = last_phdr->p_offset + last_phdr->p_filesz; + /* Keep the section headers. */ + shdr_begin = i_ehdr.e_shoff; + shdr_end = shdr_begin + i_ehdr.e_shnum * i_ehdr.e_shentsize; + if (shdr_end > (bfd_vma) contents_size) + contents_size = shdr_end; + /* Now we know the size of the whole image we want read in. */ contents = (bfd_byte *) bfd_zmalloc (contents_size); if (contents == NULL) @@ -1773,18 +1769,19 @@ NAME(_bfd_elf,bfd_from_remote_memory) } free (x_phdrs); - /* If the segments visible in memory didn't include the section headers, - then clear them from the file header. */ - if ((bfd_vma) contents_size < (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - { - memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); - memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); - memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx); - } + /* Copy the section headers. */ + err = target_read_memory (ehdr_vma + shdr_begin, + contents + shdr_begin, shdr_end - shdr_begin); + if (err) + { + free (contents); + bfd_set_error (bfd_error_system_call); + errno = err; + return NULL; + } /* This will normally have been in the first PT_LOAD segment. But it - conceivably could be missing, and we might have just changed it. */ + conceivably could be missing. */ memcpy (contents, &x_ehdr, sizeof x_ehdr); /* Now we have a memory image of the ELF file contents. Make a BFD. */ Would it be OK to send this patch as part of a GDB patch series with binutils-patches and you CC'ed? Or do you want a separate patch only to binutils-patches? This patch alone runs without new fails in the gdb and binutils suite on x86-64 Fedora 19. For the latter I ran "make check" from $build/binutils, where $build is my build directory from I which I called configure. In combination with my other GDB changes, it shows regressions in gdb.base/break-interp.exp. I'll send the patch once I fixed them. thanks, Markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-18 15:14 ` Metzger, Markus T @ 2014-03-18 23:10 ` Alan Modra 2014-03-19 8:11 ` Metzger, Markus T ` (2 more replies) 0 siblings, 3 replies; 41+ messages in thread From: Alan Modra @ 2014-03-18 23:10 UTC (permalink / raw) To: Metzger, Markus T Cc: Pedro Alves, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils On Tue, Mar 18, 2014 at 03:09:58PM +0000, Metzger, Markus T wrote: > diff --git a/bfd/elfcode.h b/bfd/elfcode.h > index 20101be..601d7ea 100644 > --- a/bfd/elfcode.h > +++ b/bfd/elfcode.h > @@ -1616,7 +1616,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) > bfd_byte *contents; > int err; > unsigned int i; > - bfd_vma loadbase; > + bfd_vma loadbase, shdr_begin, shdr_end; > bfd_boolean loadbase_set; > > /* Read in the ELF header in external format. */ > @@ -1728,20 +1728,16 @@ NAME(_bfd_elf,bfd_from_remote_memory) > } > > /* Trim the last segment so we don't bother with zeros in the last page > - that are off the end of the file. However, if the extra bit in that > - page includes the section headers, keep them. */ > - if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz > - && (bfd_vma) contents_size >= (i_ehdr.e_shoff > - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) > - { > - contents_size = last_phdr->p_offset + last_phdr->p_filesz; > - if ((bfd_vma) contents_size < (i_ehdr.e_shoff > - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) > - contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; > - } > - else > + that are off the end of the file. */ > + if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz) > contents_size = last_phdr->p_offset + last_phdr->p_filesz; > > + /* Keep the section headers. */ > + shdr_begin = i_ehdr.e_shoff; > + shdr_end = shdr_begin + i_ehdr.e_shnum * i_ehdr.e_shentsize; > + if (shdr_end > (bfd_vma) contents_size) > + contents_size = shdr_end; > + I don't think this is a good idea. If/when bfd_from_remote_memory is used for something other than the linux kernel vdso, we can't assume the section headers are loaded. The original code made the assumption that the highest address loaded from a PT_LOAD header was rounded up to a page, and that the page size could be inferred from p_align. Here: segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; if (segment_end > (bfd_vma) contents_size) contents_size = segment_end; Now, p_align is generally set from the page size if using GNU ld, but I'm wondering if your vdso somehow doesn't have that property. Can you show us your vdso readelf -e output? If p_align isn't set to a page, then the change in heuristic I envision is to make use of elf_backend_data maxpagesize to figure out which parts of the image might be loaded. If that isn't enough then perhaps we should add another parameter to bfd_from_remote_memory to allow its caller to specify the end of the image. > Would it be OK to send this patch as part of a GDB patch series with > binutils-patches and you CC'ed? Or do you want a separate patch > only to binutils-patches? I don't mind either way. This part of bfd belongs to gdb, so gdb maintainers really have the final say on patch approval. I'm just someone who happened to become interested in the problem.. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-03-18 23:10 ` Alan Modra @ 2014-03-19 8:11 ` Metzger, Markus T 2014-03-19 8:31 ` Metzger, Markus T 2014-03-19 12:03 ` Pedro Alves 2 siblings, 0 replies; 41+ messages in thread From: Metzger, Markus T @ 2014-03-19 8:11 UTC (permalink / raw) To: Alan Modra Cc: Pedro Alves, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils > -----Original Message----- > From: Alan Modra [mailto:amodra@gmail.com] > Sent: Wednesday, March 19, 2014 12:10 AM > Now, p_align is generally set from the page size if using GNU ld, but > I'm wondering if your vdso somehow doesn't have that property. Can > you show us your vdso readelf -e output? ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0xffffffffff700700 Start of program headers: 64 (bytes into file) Start of section headers: 4320 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 4 Size of section headers: 64 (bytes) Number of section headers: 18 Section header string table index: 17 Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .hash HASH ffffffffff700120 000120 000040 04 A 2 0 8 [ 2] .dynsym DYNSYM ffffffffff700160 000160 000108 18 A 3 2 8 [ 3] .dynstr STRTAB ffffffffff700268 000268 00005e 00 A 0 0 1 [ 4] .gnu.version VERSYM ffffffffff7002c6 0002c6 000016 02 A 2 0 2 [ 5] .gnu.version_d VERDEF ffffffffff7002e0 0002e0 000038 00 A 3 2 8 [ 6] .note NOTE ffffffffff700318 000318 00003c 00 A 0 0 4 [ 7] .eh_frame_hdr PROGBITS ffffffffff700354 000354 00002c 00 A 0 0 4 [ 8] .eh_frame PROGBITS ffffffffff700380 000380 0000e8 00 A 0 0 8 [ 9] .dynamic DYNAMIC ffffffffff700468 000468 0000f0 10 WA 3 0 8 [10] .rodata PROGBITS ffffffffff700558 000558 000020 01 AMS 0 0 8 [11] __bug_table PROGBITS ffffffffff700578 000578 000018 00 A 0 0 1 [12] .discard PROGBITS ffffffffff700590 000590 000012 00 WA 0 0 1 [13] .altinstructions PROGBITS ffffffffff7005a2 0005a2 0000d8 00 A 0 0 1 [14] .altinstr_replacement PROGBITS ffffffffff70067a 00067a 000036 00 AX 0 0 1 [15] .text PROGBITS ffffffffff700700 000700 0008fd 00 AX 0 0 16 [16] .comment PROGBITS 0000000000000000 000ffd 00002c 01 MS 0 0 1 [17] .shstrtab STRTAB 0000000000000000 001029 0000b7 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0xffffffffff700000 0xffffffffff700000 0x000ffd 0x000ffd R E 0x1000 DYNAMIC 0x000468 0xffffffffff700468 0xffffffffff700468 0x0000f0 0x0000f0 R 0x8 NOTE 0x000318 0xffffffffff700318 0xffffffffff700318 0x00003c 0x00003c R 0x4 GNU_EH_FRAME 0x000354 0xffffffffff700354 0xffffffffff700354 0x00002c 0x00002c R 0x4 Section to Segment mapping: Segment Sections... 00 .hash .dynsym .dynstr .gnu.version .gnu.version_d .note .eh_frame_hdr .eh_frame .dynamic .rodata __bug_table .discard .altinstructions .altinstr_replacement .text 01 .dynamic 02 .note 03 .eh_frame_hdr Regards, Markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-03-18 23:10 ` Alan Modra 2014-03-19 8:11 ` Metzger, Markus T @ 2014-03-19 8:31 ` Metzger, Markus T 2014-03-19 12:04 ` Pedro Alves 2014-03-20 2:00 ` Alan Modra 2014-03-19 12:03 ` Pedro Alves 2 siblings, 2 replies; 41+ messages in thread From: Metzger, Markus T @ 2014-03-19 8:31 UTC (permalink / raw) To: Alan Modra, Pedro Alves Cc: Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils > -----Original Message----- > From: Alan Modra [mailto:amodra@gmail.com] > Sent: Wednesday, March 19, 2014 12:10 AM > > + /* Keep the section headers. */ > > + shdr_begin = i_ehdr.e_shoff; > > + shdr_end = shdr_begin + i_ehdr.e_shnum * i_ehdr.e_shentsize; > > + if (shdr_end > (bfd_vma) contents_size) > > + contents_size = shdr_end; > > + > > I don't think this is a good idea. If/when bfd_from_remote_memory is > used for something other than the linux kernel vdso, we can't assume > the section headers are loaded. Shouldn't the ehdr indicate that there are no sections in this case? > The original code made the assumption > that the highest address loaded from a PT_LOAD header was rounded up > to a page, and that the page size could be inferred from p_align. > Here: > segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz > + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; > if (segment_end > (bfd_vma) contents_size) > contents_size = segment_end; > > Now, p_align is generally set from the page size if using GNU ld, but > I'm wondering if your vdso somehow doesn't have that property. Can > you show us your vdso readelf -e output? If p_align isn't set to a > page, then the change in heuristic I envision is to make use of > elf_backend_data maxpagesize to figure out which parts of the image > might be loaded. If that isn't enough then perhaps we should add > another parameter to bfd_from_remote_memory to allow its caller to > specify the end of the image. I'm not sure the caller knows. GDB gets the base address from AUXV's AT_SYSINFO_EHDR. If we can't trust the image to contain everything that the ELF header describes, would it be safer to generate fake sections based on the program header? We already assume that the program header is contained in the image. Regards, Markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-19 8:31 ` Metzger, Markus T @ 2014-03-19 12:04 ` Pedro Alves 2014-03-20 2:00 ` Alan Modra 1 sibling, 0 replies; 41+ messages in thread From: Pedro Alves @ 2014-03-19 12:04 UTC (permalink / raw) To: Metzger, Markus T Cc: Alan Modra, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils On 03/19/2014 08:29 AM, Metzger, Markus T wrote: > If we can't trust the image to contain everything that the ELF header > describes, would it be safer to generate fake sections based on the > program header? We already assume that the program header is > contained in the image. Please let's try to make this work before giving up and going in that direction. -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-19 8:31 ` Metzger, Markus T 2014-03-19 12:04 ` Pedro Alves @ 2014-03-20 2:00 ` Alan Modra 2014-03-21 15:55 ` Pedro Alves 1 sibling, 1 reply; 41+ messages in thread From: Alan Modra @ 2014-03-20 2:00 UTC (permalink / raw) To: Metzger, Markus T Cc: Pedro Alves, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils On Wed, Mar 19, 2014 at 08:29:47AM +0000, Metzger, Markus T wrote: > Shouldn't the ehdr indicate that there are no sections in this case? Nope. See my other email to Pedro. > If we can't trust the image to contain everything that the ELF header > describes, would it be safer to generate fake sections based on the > program header? We already assume that the program header is > contained in the image. Yes, you're correct that it is wrong to assume program headers are loaded. Even worse, the in-memory image doesn't even need to contain the ELF file header. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-20 2:00 ` Alan Modra @ 2014-03-21 15:55 ` Pedro Alves 2014-03-26 9:32 ` Metzger, Markus T 0 siblings, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-21 15:55 UTC (permalink / raw) To: Metzger, Markus T, Pedro Alves, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils On 03/20/2014 01:59 AM, Alan Modra wrote: > On Wed, Mar 19, 2014 at 08:29:47AM +0000, Metzger, Markus T wrote: >> Shouldn't the ehdr indicate that there are no sections in this case? > > Nope. See my other email to Pedro. > >> If we can't trust the image to contain everything that the ELF header >> describes, would it be safer to generate fake sections based on the >> program header? We already assume that the program header is >> contained in the image. > > Yes, you're correct that it is wrong to assume program headers are > loaded. Even worse, the in-memory image doesn't even need to contain > the ELF file header. Yeah, and I was just assuming it didn't, hence my "just trust the headers" push before. I'm now thinking that we'll need pseudo-sections from program headers anyway, so I'd suggest going in that direction, leaving the add-symbol-file-from-memory command's intention generic, and leave revisiting how gdb retrieves the vdso itself off of memory for another day. -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-03-21 15:55 ` Pedro Alves @ 2014-03-26 9:32 ` Metzger, Markus T 0 siblings, 0 replies; 41+ messages in thread From: Metzger, Markus T @ 2014-03-26 9:32 UTC (permalink / raw) To: Pedro Alves, Alan Modra Cc: Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils > -----Original Message----- > From: Pedro Alves [mailto:palves@redhat.com] > Sent: Friday, March 21, 2014 4:55 PM > >> If we can't trust the image to contain everything that the ELF header > >> describes, would it be safer to generate fake sections based on the > >> program header? We already assume that the program header is > >> contained in the image. > > > > Yes, you're correct that it is wrong to assume program headers are > > loaded. Even worse, the in-memory image doesn't even need to contain > > the ELF file header. > > Yeah, and I was just assuming it didn't, hence my "just trust the > headers" push before. > > I'm now thinking that we'll need pseudo-sections from program > headers anyway, so I'd suggest going in that direction, leaving > the add-symbol-file-from-memory command's intention generic, > and leave revisiting how gdb retrieves the vdso itself off of > memory for another day. That would be something like the patch in one of the previous emails in this thread: https://sourceware.org/ml/gdb/2014-03/msg00028.html, wouldn't it? Alan, would you be OK with this, as well? Thanks, Markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-18 23:10 ` Alan Modra 2014-03-19 8:11 ` Metzger, Markus T 2014-03-19 8:31 ` Metzger, Markus T @ 2014-03-19 12:03 ` Pedro Alves 2014-03-20 1:33 ` Alan Modra 2 siblings, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-19 12:03 UTC (permalink / raw) To: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils On 03/18/2014 11:09 PM, Alan Modra wrote: > I don't think this is a good idea. If/when bfd_from_remote_memory is > used for something other than the linux kernel vdso, we can't assume > the section headers are loaded. I wonder what use cases are these though. It'd be odd to me to load the elf headers, but not all that the headers point at. Sounds like we should just make that a requirement? I looked at the history of this whole code, and here's what I found. Roland originally added this bfd function for reading the Linux vsyscall dso, in 8d6337fe: https://sourceware.org/ml/binutils/2003-05/msg00542.html As far as I can judge from http://lwn.net/Articles/30258/ , and from looking at the early days of the vsyscall dso in the Linux tree, it looks like the vsyscall dso was always included complete in memory (e.g., at v2.6.12-rc2, the initial git import): ... /* 32bit VDSOs mapped into user space. */ asm(".section \".init.data\",\"aw\"\n" "syscall32_syscall:\n" ".incbin \"arch/x86_64/ia32/vsyscall-syscall.so\"\n" "syscall32_syscall_end:\n" "syscall32_sysenter:\n" ".incbin \"arch/x86_64/ia32/vsyscall-sysenter.so\"\n" "syscall32_sysenter_end:\n" ".previous"); ... # The DSO images are built using a special linker script quiet_cmd_syscall = SYSCALL $@ cmd_syscall = $(CC) -m32 -nostdlib -shared -s \ -Wl,-soname=linux-gate.so.1 -o $@ \ -Wl,-T,$(filter-out FORCE,$^) ... I found no sign of strip or of any special elf munging. GDB only uses bfd_elf_bfd_from_remote_memory for the vdso, and for "add-symbol-file-from-memory". Roland himself added the "add-symbol-file-from-memory" command (5417f6dc) to GDB too, at: https://www.sourceware.org/ml/gdb-patches/2003-10/msg00045.html "This command may not really be worth having, but it serves to exercise the underlying function symbol_file_add_from_memory. That function does the work of reading symbols and unwind info from the Linux vsyscall DSO." -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-19 12:03 ` Pedro Alves @ 2014-03-20 1:33 ` Alan Modra 2014-03-21 8:10 ` Metzger, Markus T 2014-03-21 15:48 ` Pedro Alves 0 siblings, 2 replies; 41+ messages in thread From: Alan Modra @ 2014-03-20 1:33 UTC (permalink / raw) To: Pedro Alves Cc: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils On Wed, Mar 19, 2014 at 12:03:40PM +0000, Pedro Alves wrote: > On 03/18/2014 11:09 PM, Alan Modra wrote: > > I don't think this is a good idea. If/when bfd_from_remote_memory is > > used for something other than the linux kernel vdso, we can't assume > > the section headers are loaded. > > I wonder what use cases are these though. It'd be odd to me to > load the elf headers, but not all that the headers point at. Well, no, the section headers are part of the linking view. The ELF file header points at their *file offset*. Thinking it odd that they are not loaded is exactly the same as thinking it odd that .comment is not loaded! > Sounds like we should just make that a requirement? You indeed could make that a requirement, but it'd mean that object files loaded by glibc ld.so would not satisfy the requirement. Taking Markus' vdso as an example, the PT_LOAD header covers file offsets from 0 to 0xffd and page size is 0x1000. If ld.so were loading a similar image, it would just load in 0 to 0xfff (assuming ld.so's dl_pagesize is also 0x1000). The section headers are at file offset 0x10e0 so would miss being loaded. Nor should they be loaded, since they are completely extraneous to executing the image it would be foolish to waste another page to load them. > "This command may not really be worth having, but it serves to exercise the > underlying function symbol_file_add_from_memory. That function does the > work of reading symbols and unwind info from the Linux vsyscall DSO." Heh, OK, so don't let my comments about more general uses of bfd_from_remote_memory get in your way of fixing this problem. Hmm, if you only want to read vdsos then bfd_from_remote_memory is way overengineered. In fact, I think it could disappear entirely. If you can find the extent of the vdso in gdb, then all of the ELF version of bfd_from_remote_memory prior to allocating the bim is unnecessary, because all that code really does is find the extent. So the tail of bfd_from_remote_memory moves to bfd/opncls.c as (totally untested): bfd_boolean bfd_openr_bim (bfd *templ, void *contents, size_t contents_size) { struct bfd_in_memory *bim; bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); if (bim == NULL) return NULL; nbfd = _bfd_new_bfd (); if (nbfd == NULL) { free (bim); return NULL; } nbfd->filename = "<in-memory>"; if (templ != NULL) nbfd->xvec = templ->xvec; bim->size = contents_size; bim->buffer = (bfd_byte *) contents; nbfd->iostream = bim; nbfd->flags = BFD_IN_MEMORY; nbfd->iovec = &_bfd_memory_iovec; nbfd->origin = 0; nbfd->direction = read_direction; nbfd->mtime = time (NULL); nbfd->mtime_set = TRUE; return nbfd; } gdb is then responsible for filling in "contents" and determining "contents_size", which presumably can be done in the same way as you did in https://sourceware.org/ml/binutils/2014-03/msg00130.html The loadbase calculation also moves to gdb, which shouldn't be too hard. Note that "templ" above is optional, which allows you to get rid of /* FIXME: cagney/2004-05-06: Should not require an existing BFD when trying to create a run-time BFD of the VSYSCALL -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-03-20 1:33 ` Alan Modra @ 2014-03-21 8:10 ` Metzger, Markus T 2014-03-21 15:48 ` Pedro Alves 1 sibling, 0 replies; 41+ messages in thread From: Metzger, Markus T @ 2014-03-21 8:10 UTC (permalink / raw) To: Alan Modra, Pedro Alves Cc: Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils > -----Original Message----- > From: Alan Modra [mailto:amodra@gmail.com] > Sent: Thursday, March 20, 2014 2:33 AM > On Wed, Mar 19, 2014 at 12:03:40PM +0000, Pedro Alves wrote: > > On 03/18/2014 11:09 PM, Alan Modra wrote: > > > I don't think this is a good idea. If/when bfd_from_remote_memory is > > > used for something other than the linux kernel vdso, we can't assume > > > the section headers are loaded. > > > > I wonder what use cases are these though. It'd be odd to me to > > load the elf headers, but not all that the headers point at. > > Well, no, the section headers are part of the linking view. The ELF > file header points at their *file offset*. Thinking it odd that they > are not loaded is exactly the same as thinking it odd that .comment is > not loaded! > > > Sounds like we should just make that a requirement? > > You indeed could make that a requirement, but it'd mean that object > files loaded by glibc ld.so would not satisfy the requirement. > > Taking Markus' vdso as an example, the PT_LOAD header covers file > offsets from 0 to 0xffd and page size is 0x1000. If ld.so were > loading a similar image, it would just load in 0 to 0xfff (assuming > ld.so's dl_pagesize is also 0x1000). The section headers are at file > offset 0x10e0 so would miss being loaded. Nor should they be loaded, > since they are completely extraneous to executing the image it would > be foolish to waste another page to load them. > > > "This command may not really be worth having, but it serves to exercise > the > > underlying function symbol_file_add_from_memory. That function does > the > > work of reading symbols and unwind info from the Linux vsyscall DSO." > > Heh, OK, so don't let my comments about more general uses of > bfd_from_remote_memory get in your way of fixing this problem. > > Hmm, if you only want to read vdsos then bfd_from_remote_memory is way > overengineered. In fact, I think it could disappear entirely. > If you can find the extent of the vdso in gdb, then all of the ELF > version of bfd_from_remote_memory prior to allocating the bim is > unnecessary, because all that code really does is find the extent. > So the tail of bfd_from_remote_memory moves to bfd/opncls.c as > (totally untested): > > bfd_boolean > bfd_openr_bim (bfd *templ, void *contents, size_t contents_size) > { > struct bfd_in_memory *bim; > > bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct > bfd_in_memory)); > if (bim == NULL) > return NULL; > > nbfd = _bfd_new_bfd (); > if (nbfd == NULL) > { > free (bim); > return NULL; > } > nbfd->filename = "<in-memory>"; > if (templ != NULL) > nbfd->xvec = templ->xvec; > bim->size = contents_size; > bim->buffer = (bfd_byte *) contents; > nbfd->iostream = bim; > nbfd->flags = BFD_IN_MEMORY; > nbfd->iovec = &_bfd_memory_iovec; > nbfd->origin = 0; > nbfd->direction = read_direction; > nbfd->mtime = time (NULL); > nbfd->mtime_set = TRUE; > return nbfd; > } > > gdb is then responsible for filling in "contents" and determining > "contents_size", which presumably can be done in the same way as > you did in https://sourceware.org/ml/binutils/2014-03/msg00130.html > The loadbase calculation also moves to gdb, which shouldn't be too > hard. Note that "templ" above is optional, which allows you to get > rid of > /* FIXME: cagney/2004-05-06: Should not require an existing > BFD when trying to create a run-time BFD of the VSYSCALL I was waiting for Pedro to reply but he didn't. This would move the ELF processing itself into GDB. That sounds a bit odd to me but it seems GDB already does a fair amount of ELF reading. Pedro, are you OK with this? Will you accept a patch that goes into the direction that Alan described above? Thanks, Markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-20 1:33 ` Alan Modra 2014-03-21 8:10 ` Metzger, Markus T @ 2014-03-21 15:48 ` Pedro Alves 2014-03-28 6:13 ` Alan Modra 1 sibling, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-21 15:48 UTC (permalink / raw) To: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb, binutils On 03/20/2014 01:33 AM, Alan Modra wrote: > On Wed, Mar 19, 2014 at 12:03:40PM +0000, Pedro Alves wrote: >> On 03/18/2014 11:09 PM, Alan Modra wrote: >>> I don't think this is a good idea. If/when bfd_from_remote_memory is >>> used for something other than the linux kernel vdso, we can't assume >>> the section headers are loaded. >> >> I wonder what use cases are these though. It'd be odd to me to >> load the elf headers, but not all that the headers point at. > > Well, no, the section headers are part of the linking view. The ELF > file header points at their *file offset*. Thinking it odd that they > are not loaded is exactly the same as thinking it odd that .comment is > not loaded! :-) Sorry, I get that, but I was somehow assuming the elf header wasn't itself covered by a PT_LOAD. Rookie mistake... >> Sounds like we should just make that a requirement? > > You indeed could make that a requirement, but it'd mean that object > files loaded by glibc ld.so would not satisfy the requirement. Indeed. So this mechanism could be further extended in future to be able to read DSOs out of memory, and be able to retrieve the dynamic symbol table, etc., which would allow getting at unwind info for already-deleted libraries. I guess that's what the elfutils folks had been talking about, but I somehow managed to not connect the dots. :-) 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. > > Taking Markus' vdso as an example, the PT_LOAD header covers file > offsets from 0 to 0xffd and page size is 0x1000. If ld.so were > loading a similar image, it would just load in 0 to 0xfff (assuming > ld.so's dl_pagesize is also 0x1000). The section headers are at file > offset 0x10e0 so would miss being loaded. Nor should they be loaded, > since they are completely extraneous to executing the image it would > be foolish to waste another page to load them. *nod* >> "This command may not really be worth having, but it serves to exercise the >> underlying function symbol_file_add_from_memory. That function does the >> work of reading symbols and unwind info from the Linux vsyscall DSO." > > Heh, OK, so don't let my comments about more general uses of > bfd_from_remote_memory get in your way of fixing this problem. Hmm. Thinking further ahead, it would be good to make GDB be able to read deleted DSOs off of memory like elfutils is now doing. With that in mind, it does seem to make sense to have this bfd_elf_bfd_from_remote_memory code in place as is, but extend it to treat section-less elfs just like cores, creating pseudo bfd sections from segments... -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-21 15:48 ` Pedro Alves @ 2014-03-28 6:13 ` Alan Modra 2014-03-28 13:38 ` Pedro Alves 2014-04-02 8:04 ` Hans-Peter Nilsson 0 siblings, 2 replies; 41+ messages in thread From: Alan Modra @ 2014-03-28 6:13 UTC (permalink / raw) To: Pedro Alves Cc: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb-patches, binutils 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. 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. Gah, I've been sucked into looking at this long enough that I may as well fix it. Does this look OK? bfd/ * elfcode.h (bfd_from_remote_memory): Add "size" parameter. Consolidate code handling possible section headers past end of segment. Don't use p_align for page size guess, instead use minpagesize. Take note of ld.so clearing section headers when p_memsz > p_filesz. Handle file header specifying no section headers. Handle zero p_align throughout. Default loadbase to zero. Add comments. Rename contents_size to high_offset, and make it a bfd_vma. Delete unnecessary bfd_set_error calls. * bfd-in.h (bfd_elf_bfd_from_remote_memory): Update prototpe. * elf-bfd.h (struct elf_backend_data <elf_backend_from_remote_memory>): Likewise. (_bfd_elf32_bfd_from_remote_memory): Likewise. (_bfd_elf64_bfd_from_remote_memory): Likewise. * elf.c (bfd_elf_bfd_from_remote_memory): Adjust. * bfd-in2.h: Regnerate. gdb/ * symfile-mem.c (symbol_file_add_from_memory): Add size parameter. Pass to bfd_elf_bfd_from_remote_memory. Adjust all callers. (struct symbol_file_add_from_memory_args): Add size field. (find_vdso_size): New function. (add_vsyscall_page): Attempt to find vdso size. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index da350a5..ddc8270 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -680,19 +680,21 @@ extern int bfd_get_elf_phdrs (bfd *abfd, void *phdrs); /* Create a new BFD as if by bfd_openr. Rather than opening a file, - reconstruct an ELF file by reading the segments out of remote memory - based on the ELF file header at EHDR_VMA and the ELF program headers it - points to. If not null, *LOADBASEP is filled in with the difference - between the VMAs from which the segments were read, and the VMAs the - file headers (and hence BFD's idea of each section's VMA) put them at. - - The function TARGET_READ_MEMORY is called to copy LEN bytes from the - remote memory at target address VMA into the local buffer at MYADDR; it - should return zero on success or an `errno' code on failure. TEMPL must - be a BFD for an ELF target with the word size and byte order found in - the remote memory. */ + reconstruct an ELF file by reading the segments out of remote + memory based on the ELF file header at EHDR_VMA and the ELF program + headers it points to. If non-zero, SIZE is the known extent of the + object. If not null, *LOADBASEP is filled in with the difference + between the VMAs from which the segments were read, and the VMAs + the file headers (and hence BFD's idea of each section's VMA) put + them at. + + The function TARGET_READ_MEMORY is called to copy LEN bytes from + the remote memory at target address VMA into the local buffer at + MYADDR; it should return zero on success or an `errno' code on + failure. TEMPL must be a BFD for a target with the word size and + byte order found in the remote memory. */ extern bfd *bfd_elf_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, + (bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, bfd_size_type len)); diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index ee6e6cb..6d07303 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1191,9 +1191,9 @@ struct elf_backend_data /* This function implements `bfd_elf_bfd_from_remote_memory'; see elf.c, elfcode.h. */ bfd *(*elf_backend_bfd_from_remote_memory) - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, - int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, - bfd_size_type len)); + (bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep, + int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, + bfd_size_type len)); /* This function is used by `_bfd_elf_get_synthetic_symtab'; see elf.c. */ @@ -2334,10 +2334,10 @@ extern char *elfcore_write_ppc_linux_prpsinfo32 (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *); extern bfd *_bfd_elf32_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, + (bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)); extern bfd *_bfd_elf64_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, + (bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)); extern bfd_vma bfd_elf_obj_attr_size (bfd *); diff --git a/bfd/elf.c b/bfd/elf.c index 3ded683..d67b917 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -9908,11 +9908,12 @@ bfd * bfd_elf_bfd_from_remote_memory (bfd *templ, bfd_vma ehdr_vma, + size_t size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)) { return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory) - (templ, ehdr_vma, loadbasep, target_read_memory); + (templ, ehdr_vma, size, loadbasep, target_read_memory); } \f long diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 20101be..31f67a8 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1587,22 +1587,25 @@ elf_debug_file (Elf_Internal_Ehdr *ehdrp) #endif \f /* Create a new BFD as if by bfd_openr. Rather than opening a file, - reconstruct an ELF file by reading the segments out of remote memory - based on the ELF file header at EHDR_VMA and the ELF program headers it - points to. If not null, *LOADBASEP is filled in with the difference - between the VMAs from which the segments were read, and the VMAs the - file headers (and hence BFD's idea of each section's VMA) put them at. - - The function TARGET_READ_MEMORY is called to copy LEN bytes from the - remote memory at target address VMA into the local buffer at MYADDR; it - should return zero on success or an `errno' code on failure. TEMPL must - be a BFD for a target with the word size and byte order found in the - remote memory. */ + reconstruct an ELF file by reading the segments out of remote + memory based on the ELF file header at EHDR_VMA and the ELF program + headers it points to. If non-zero, SIZE is the known extent of the + object. If not null, *LOADBASEP is filled in with the difference + between the VMAs from which the segments were read, and the VMAs + the file headers (and hence BFD's idea of each section's VMA) put + them at. + + The function TARGET_READ_MEMORY is called to copy LEN bytes from + the remote memory at target address VMA into the local buffer at + MYADDR; it should return zero on success or an `errno' code on + failure. TEMPL must be a BFD for a target with the word size and + byte order found in the remote memory. */ bfd * NAME(_bfd_elf,bfd_from_remote_memory) (bfd *templ, bfd_vma ehdr_vma, + size_t size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)) { @@ -1612,10 +1615,11 @@ NAME(_bfd_elf,bfd_from_remote_memory) Elf_Internal_Phdr *i_phdrs, *last_phdr; bfd *nbfd; struct bfd_in_memory *bim; - int contents_size; bfd_byte *contents; int err; unsigned int i; + bfd_vma high_offset; + bfd_vma shdr_end; bfd_vma loadbase; bfd_boolean loadbase_set; @@ -1677,10 +1681,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) x_phdrs = (Elf_External_Phdr *) bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs)); if (x_phdrs == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs, i_ehdr.e_phnum * sizeof x_phdrs[0]); if (err) @@ -1692,34 +1693,44 @@ NAME(_bfd_elf,bfd_from_remote_memory) } i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum]; - contents_size = 0; + high_offset = 0; last_phdr = NULL; - loadbase = ehdr_vma; + loadbase = 0; loadbase_set = FALSE; for (i = 0; i < i_ehdr.e_phnum; ++i) { elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]); if (i_phdrs[i].p_type == PT_LOAD) { - bfd_vma segment_end; - segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz - + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; - if (segment_end > (bfd_vma) contents_size) - contents_size = segment_end; - - /* LOADADDR is the `Base address' from the gELF specification: - `lowest p_vaddr value for a PT_LOAD segment' is P_VADDR from the - first PT_LOAD as PT_LOADs are ordered by P_VADDR. */ - if (!loadbase_set && (i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0) + bfd_vma segment_end = i_phdrs[i].p_offset + i_phdrs[i].p_filesz; + + if (segment_end > high_offset) { - loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align); - loadbase_set = TRUE; + high_offset = segment_end; + last_phdr = &i_phdrs[i]; } - last_phdr = &i_phdrs[i]; + /* If this program header covers offset zero, where the file + header sits, then we can figure out the loadbase. */ + if (!loadbase_set) + { + bfd_vma p_offset = i_phdrs[i].p_offset; + bfd_vma p_vaddr = i_phdrs[i].p_vaddr; + + if (i_phdrs[i].p_align > 1) + { + p_offset &= -i_phdrs[i].p_align; + p_vaddr &= -i_phdrs[i].p_align; + } + if (p_offset == 0) + { + loadbase = ehdr_vma - p_vaddr; + loadbase_set = TRUE; + } + } } } - if (last_phdr == NULL) + if (high_offset == 0) { /* There were no PT_LOAD segments, so we don't have anything to read. */ free (x_phdrs); @@ -1727,40 +1738,61 @@ NAME(_bfd_elf,bfd_from_remote_memory) return NULL; } - /* Trim the last segment so we don't bother with zeros in the last page - that are off the end of the file. However, if the extra bit in that - page includes the section headers, keep them. */ - if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz - && (bfd_vma) contents_size >= (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) + shdr_end = 0; + if (i_ehdr.e_shoff != 0 && i_ehdr.e_shnum != 0 && i_ehdr.e_shentsize != 0) { - contents_size = last_phdr->p_offset + last_phdr->p_filesz; - if ((bfd_vma) contents_size < (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; + shdr_end = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; + + if (last_phdr->p_filesz != last_phdr->p_memsz) + { + /* If the last PT_LOAD header has a bss area then ld.so will + have cleared anything past p_filesz, zapping the section + headers. */ + } + else if (size >= shdr_end) + 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 + section headers. */ + if (page_size > 1 && shdr_end > segment_end) + { + bfd_vma page_end = (segment_end + page_size - 1) & -page_size; + + if (page_end >= shdr_end) + /* Whee, section headers covered. */ + high_offset = shdr_end; + } + } } - else - contents_size = last_phdr->p_offset + last_phdr->p_filesz; /* Now we know the size of the whole image we want read in. */ - contents = (bfd_byte *) bfd_zmalloc (contents_size); + contents = (bfd_byte *) bfd_zmalloc (high_offset); if (contents == NULL) { free (x_phdrs); - bfd_set_error (bfd_error_no_memory); return NULL; } for (i = 0; i < i_ehdr.e_phnum; ++i) if (i_phdrs[i].p_type == PT_LOAD) { - bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align; - bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz - + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; - if (end > (bfd_vma) contents_size) - end = contents_size; - err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr) - & -i_phdrs[i].p_align, + 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; + + 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; + } + if (end > high_offset) + end = high_offset; + err = target_read_memory (loadbase + vaddr, contents + start, end - start); if (err) { @@ -1775,8 +1807,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) /* If the segments visible in memory didn't include the section headers, then clear them from the file header. */ - if ((bfd_vma) contents_size < (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) + if (high_offset < shdr_end) { memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); @@ -1792,7 +1823,6 @@ NAME(_bfd_elf,bfd_from_remote_memory) if (bim == NULL) { free (contents); - bfd_set_error (bfd_error_no_memory); return NULL; } nbfd = _bfd_new_bfd (); @@ -1800,12 +1830,11 @@ NAME(_bfd_elf,bfd_from_remote_memory) { free (bim); free (contents); - bfd_set_error (bfd_error_no_memory); return NULL; } nbfd->filename = xstrdup ("<in-memory>"); nbfd->xvec = templ->xvec; - bim->size = contents_size; + bim->size = high_offset; bim->buffer = contents; nbfd->iostream = bim; nbfd->flags = BFD_IN_MEMORY; diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c index e3230de..98764cd 100644 --- a/gdb/symfile-mem.c +++ b/gdb/symfile-mem.c @@ -76,13 +76,14 @@ target_read_memory_bfd (bfd_vma memaddr, bfd_byte *myaddr, bfd_size_type len) } /* Read inferior memory at ADDR to find the header of a loaded object file - and read its in-core symbols out of inferior memory. TEMPL is a bfd + and read its in-core symbols out of inferior memory. SIZE, if + non-zero, is the known size of the object. TEMPL is a bfd representing the target's format. NAME is the name to use for this symbol file in messages; it can be NULL or a malloc-allocated string which will be attached to the BFD. */ static struct objfile * -symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name, - int from_tty) +symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, + size_t size, char *name, int from_tty) { struct objfile *objf; struct bfd *nbfd; @@ -95,7 +96,7 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name, if (bfd_get_flavour (templ) != bfd_target_elf_flavour) error (_("add-symbol-file-from-memory not supported for this target")); - nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase, + nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, size, &loadbase, target_read_memory_bfd); if (nbfd == NULL) error (_("Failed to read a valid object file image from memory.")); @@ -158,7 +159,7 @@ add_symbol_file_from_memory_command (char *args, int from_tty) error (_("Must use symbol-file or exec-file " "before add-symbol-file-from-memory.")); - symbol_file_add_from_memory (templ, addr, NULL, from_tty); + symbol_file_add_from_memory (templ, addr, 0, NULL, from_tty); } /* Arguments for symbol_file_add_from_memory_wrapper. */ @@ -167,6 +168,7 @@ struct symbol_file_add_from_memory_args { struct bfd *bfd; CORE_ADDR sysinfo_ehdr; + size_t size; char *name; int from_tty; }; @@ -179,8 +181,26 @@ symbol_file_add_from_memory_wrapper (struct ui_out *uiout, void *data) { struct symbol_file_add_from_memory_args *args = data; - symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->name, - args->from_tty); + symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->size, + args->name, args->from_tty); + return 0; +} + +/* Rummage through mappings to find the vsyscall page size. */ + +static int +find_vdso_size (CORE_ADDR vaddr, unsigned long size, + int read ATTRIBUTE_UNUSED, int write ATTRIBUTE_UNUSED, + int exec ATTRIBUTE_UNUSED, int modified ATTRIBUTE_UNUSED, + void *data) +{ + struct symbol_file_add_from_memory_args *args = data; + + if (vaddr == args->sysinfo_ehdr) + { + args->size = size; + return 1; + } return 0; } @@ -217,6 +237,11 @@ add_vsyscall_page (struct target_ops *target, int from_tty) } args.bfd = bfd; args.sysinfo_ehdr = sysinfo_ehdr; + args.size = 0; + if (gdbarch_find_memory_regions_p (target_gdbarch ())) + (void) gdbarch_find_memory_regions (target_gdbarch (), + find_vdso_size, &args); + args.name = xstrprintf ("system-supplied DSO at %s", paddress (target_gdbarch (), sysinfo_ehdr)); /* Pass zero for FROM_TTY, because the action of loading the -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-28 6:13 ` Alan Modra @ 2014-03-28 13:38 ` Pedro Alves 2014-03-28 23:00 ` Alan Modra 2014-04-02 8:04 ` Hans-Peter Nilsson 1 sibling, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-03-28 13:38 UTC (permalink / raw) To: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb-patches, binutils 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 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-28 13:38 ` Pedro Alves @ 2014-03-28 23:00 ` Alan Modra 2014-04-01 13:46 ` Pedro Alves 0 siblings, 1 reply; 41+ messages in thread From: Alan Modra @ 2014-03-28 23:00 UTC (permalink / raw) To: Pedro Alves Cc: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb-patches, binutils On Fri, Mar 28, 2014 at 01:37:52PM +0000, Pedro Alves wrote: > 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. Ah ha! What's more, if the read did happen to succeed you'd overwrite contents written when processing the first PT_LOAD. I believe that will still happen with your fixup patch. Not that it's a problem, since ld.so reads the page holding the end of the first PT_LOAD and the beginning of the second PT_LOAD twice, but I think it would be better if BFD didn't rely on this ld.so behaviour (and an exact match between BFD and ld.so's page size). I believe the intent of rounding to a page was to pick up the file and program headers at the start of a file and section headers at the end, so let's do just that. On top of my last patch: diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 31f67a8..a005948 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1612,7 +1612,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ Elf_External_Phdr *x_phdrs; - Elf_Internal_Phdr *i_phdrs, *last_phdr; + Elf_Internal_Phdr *i_phdrs, *last_phdr, *first_phdr; bfd *nbfd; struct bfd_in_memory *bim; bfd_byte *contents; @@ -1621,7 +1621,6 @@ NAME(_bfd_elf,bfd_from_remote_memory) bfd_vma high_offset; bfd_vma shdr_end; 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); @@ -1694,9 +1693,9 @@ NAME(_bfd_elf,bfd_from_remote_memory) i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum]; high_offset = 0; - last_phdr = NULL; loadbase = 0; - loadbase_set = FALSE; + first_phdr = NULL; + last_phdr = NULL; for (i = 0; i < i_ehdr.e_phnum; ++i) { elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]); @@ -1712,7 +1711,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) /* If this program header covers offset zero, where the file header sits, then we can figure out the loadbase. */ - if (!loadbase_set) + if (first_phdr == NULL) { bfd_vma p_offset = i_phdrs[i].p_offset; bfd_vma p_vaddr = i_phdrs[i].p_vaddr; @@ -1725,7 +1724,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) if (p_offset == 0) { loadbase = ehdr_vma - p_vaddr; - loadbase_set = TRUE; + first_phdr = &i_phdrs[i]; } } } @@ -1784,13 +1783,15 @@ NAME(_bfd_elf,bfd_from_remote_memory) bfd_vma end = start + i_phdrs[i].p_filesz; bfd_vma vaddr = i_phdrs[i].p_vaddr; - if (i_phdrs[i].p_align > 1) + /* Extend the beginning of the first pt_load to cover file + header and program headers. */ + if (first_phdr == &i_phdrs[i]) { - 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; + vaddr -= start; + start = 0; } - if (end > high_offset) + /* Extend the end of the last pt_load to cover section headers. */ + if (last_phdr == &i_phdrs[i]) end = high_offset; err = target_read_memory (loadbase + vaddr, contents + start, end - start); -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-28 23:00 ` Alan Modra @ 2014-04-01 13:46 ` Pedro Alves 2014-04-02 1:50 ` Alan Modra 0 siblings, 1 reply; 41+ messages in thread From: Pedro Alves @ 2014-04-01 13:46 UTC (permalink / raw) To: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb-patches, binutils On 03/28/2014 11:00 PM, Alan Modra wrote: > I believe the intent of rounding to a page was to pick up the file > and program headers at the start of a file and section headers at the > end, so let's do just that. On top of my last patch: Agreed. This works for me. Thanks! > - if (i_phdrs[i].p_align > 1) > + /* Extend the beginning of the first pt_load to cover file > + header and program headers. */ > + if (first_phdr == &i_phdrs[i]) Minor nit: Perhaps the comment could say "first pt_load if it covers offset 0"? The computation below confused me a little until I scrolled up and realized that first_phdr is only set if the first segment covers offset 0, not whatever the first segment is. (I'd even consider renaming it to zero_phdr or zero_offset_phdr, but with the comment I'd already be super happy). On the GDB patch, sorry for not noticing earlier, but: > +static int > +find_vdso_size (CORE_ADDR vaddr, unsigned long size, > + int read ATTRIBUTE_UNUSED, int write ATTRIBUTE_UNUSED, > + int exec ATTRIBUTE_UNUSED, int modified ATTRIBUTE_UNUSED, > + void *data) > +{ Please don't use ATTRIBUTE_UNUSED under gdb/, it'd be flagged by the ARI as a regression: gdb/contrib/gdb_ari.sh: BEGIN { doc["ATTRIBUTE_UNUSED"] = "\ Do not use ATTRIBUTE_UNUSED, do not bother (GDB is compiled with -Werror and, \ consequently, is not able to tolerate false warnings. Since -Wunused-param \ produces such warnings, neither that warning flag nor ATTRIBUTE_UNUSED \ are used by GDB" category["ATTRIBUTE_UNUSED"] = ari_regression } /(^|[^_[:alnum:]])ATTRIBUTE_UNUSED([^_[:alnum:]]|$)/ { fail("ATTRIBUTE_UNUSED") } -- Pedro Alves ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-04-01 13:46 ` Pedro Alves @ 2014-04-02 1:50 ` Alan Modra 2014-04-02 8:05 ` Metzger, Markus T 0 siblings, 1 reply; 41+ messages in thread From: Alan Modra @ 2014-04-02 1:50 UTC (permalink / raw) To: Pedro Alves Cc: Metzger, Markus T, Mark Wielaard, Cary Coutant, Doug Evans, gdb-patches, binutils On Tue, Apr 01, 2014 at 02:46:38PM +0100, Pedro Alves wrote: > On 03/28/2014 11:00 PM, Alan Modra wrote: > > > I believe the intent of rounding to a page was to pick up the file > > and program headers at the start of a file and section headers at the > > end, so let's do just that. On top of my last patch: > > Agreed. This works for me. Thanks! > > > - if (i_phdrs[i].p_align > 1) > > + /* Extend the beginning of the first pt_load to cover file > > + header and program headers. */ > > + if (first_phdr == &i_phdrs[i]) > > Minor nit: Perhaps the comment could say "first pt_load > if it covers offset 0"? Fixed. /* Extend the beginning of the first pt_load to cover file header and program headers, if we proved earlier that its aligned offset is 0. */ > Please don't use ATTRIBUTE_UNUSED under gdb/, it'd be flagged by the > ARI as a regression: Hmm, OK. Fixed and pushed. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* RE: vdso handling 2014-04-02 1:50 ` Alan Modra @ 2014-04-02 8:05 ` Metzger, Markus T 0 siblings, 0 replies; 41+ messages in thread From: Metzger, Markus T @ 2014-04-02 8:05 UTC (permalink / raw) To: Alan Modra, Pedro Alves Cc: Mark Wielaard, Cary Coutant, Doug Evans, gdb-patches, binutils > -----Original Message----- > From: Alan Modra [mailto:amodra@gmail.com] > Sent: Wednesday, April 02, 2014 3:50 AM > Hmm, OK. Fixed and pushed. Thanks, Markus. Intel GmbH Dornacher Strasse 1 85622 Feldkirchen/Muenchen, Deutschland Sitz der Gesellschaft: Feldkirchen bei Muenchen Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk Registergericht: Muenchen HRB 47456 Ust.-IdNr./VAT Registration No.: DE129385895 Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-03-28 6:13 ` Alan Modra 2014-03-28 13:38 ` Pedro Alves @ 2014-04-02 8:04 ` Hans-Peter Nilsson 2014-04-03 1:06 ` Alan Modra 1 sibling, 1 reply; 41+ messages in thread From: Hans-Peter Nilsson @ 2014-04-02 8:04 UTC (permalink / raw) To: Alan Modra; +Cc: gdb-patches, binutils On Fri, 28 Mar 2014, Alan Modra wrote: > > 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. > > Gah, I've been sucked into looking at this long enough that I may as > well fix it. Does this look OK? The new size parameter uses size_t in bfd headers, breaking some simulators like cris-elf, frv-elf, h8300-elf, iq2000-elf, m32r-elf, mips-elf, mn10300-elf. The obvious change is to instead use bfd_size_type, like everything else in BFD headers. Any reason not to do that here? > * elfcode.h (bfd_from_remote_memory): Add "size" parameter. brgds, H-P ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-04-02 8:04 ` Hans-Peter Nilsson @ 2014-04-03 1:06 ` Alan Modra 2014-04-03 1:46 ` Alan Modra 0 siblings, 1 reply; 41+ messages in thread From: Alan Modra @ 2014-04-03 1:06 UTC (permalink / raw) To: Hans-Peter Nilsson; +Cc: gdb-patches, binutils On Wed, Apr 02, 2014 at 04:04:24AM -0400, Hans-Peter Nilsson wrote: > The new size parameter uses size_t in bfd headers, breaking some > simulators like cris-elf, frv-elf, h8300-elf, iq2000-elf, > m32r-elf, mips-elf, mn10300-elf. > > The obvious change is to instead use bfd_size_type, like > everything else in BFD headers. Any reason not to do that here? I originally had bfd_size_type and wondered if we could use size_t, which is the natural type to use here. (bfd_size_type might be 64-bit and it doesn't really make sense to use that when describing a memory area on a 32-bit host.) gdb and binutils built without trouble on a few targets, so I went with size_t. Sorry about the sim breakage. * elf-bfd.h (struct elf_backend_data <elf_backend_bfd_from_remote_memory>): Replace "size_t size" with "bfd_size_type size". (_bfd_elf32_bfd_from_remote_memory): Likewise. (_bfd_elf64_bfd_from_remote_memory): Likewise. * elf.c (bfd_elf_bfd_from_remote_memory): Likewise. * elfcode.h (bfd_from_remote_memory): Likewise. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 6d07303..f58a3b7 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1191,7 +1191,7 @@ struct elf_backend_data /* This function implements `bfd_elf_bfd_from_remote_memory'; see elf.c, elfcode.h. */ bfd *(*elf_backend_bfd_from_remote_memory) - (bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep, + (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, bfd_size_type len)); @@ -2334,10 +2334,10 @@ extern char *elfcore_write_ppc_linux_prpsinfo32 (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *); extern bfd *_bfd_elf32_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep, + (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)); extern bfd *_bfd_elf64_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep, + (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)); extern bfd_vma bfd_elf_obj_attr_size (bfd *); diff --git a/bfd/elf.c b/bfd/elf.c index d67b917..9e46f7c 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -9908,7 +9908,7 @@ bfd * bfd_elf_bfd_from_remote_memory (bfd *templ, bfd_vma ehdr_vma, - size_t size, + bfd_size_type size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)) { diff --git a/bfd/elfcode.h b/bfd/elfcode.h index f840065..a49a708 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1605,7 +1605,7 @@ bfd * NAME(_bfd_elf,bfd_from_remote_memory) (bfd *templ, bfd_vma ehdr_vma, - size_t size, + bfd_size_type size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)) { -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: vdso handling 2014-04-03 1:06 ` Alan Modra @ 2014-04-03 1:46 ` Alan Modra 0 siblings, 0 replies; 41+ messages in thread From: Alan Modra @ 2014-04-03 1:46 UTC (permalink / raw) To: Hans-Peter Nilsson, gdb-patches, binutils On Thu, Apr 03, 2014 at 11:36:44AM +1030, Alan Modra wrote: > * elf-bfd.h (struct elf_backend_data > <elf_backend_bfd_from_remote_memory>): Replace "size_t size" > with "bfd_size_type size". > (_bfd_elf32_bfd_from_remote_memory): Likewise. > (_bfd_elf64_bfd_from_remote_memory): Likewise. > * elf.c (bfd_elf_bfd_from_remote_memory): Likewise. > * elfcode.h (bfd_from_remote_memory): Likewise. Sigh. Here too. * bfd-in.h (bfd_elf_bfd_from_remote_memory): Likewise. * bfd-in2.h: Regenerate. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2014-06-06 12:45 UTC | newest] Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-03-10 13:05 vdso handling Metzger, Markus T 2014-03-12 7:17 ` Alan Modra 2014-03-12 11:31 ` Mike Frysinger 2014-03-12 17:34 ` Doug Evans 2014-03-12 20:23 ` Cary Coutant 2014-03-13 1:01 ` Alan Modra 2014-03-13 8:25 ` Metzger, Markus T 2014-03-13 9:48 ` Metzger, Markus T 2014-03-13 10:07 ` Pedro Alves 2014-03-13 10:46 ` Pedro Alves 2014-06-01 23:45 ` Samuel Bronson 2014-06-06 12:45 ` Pedro Alves 2014-03-13 13:13 ` Alan Modra 2014-03-13 9:52 ` Mark Wielaard 2014-03-13 13:03 ` Alan Modra 2014-03-13 14:38 ` Mark Wielaard 2014-03-13 14:59 ` Pedro Alves 2014-03-13 15:04 ` Pedro Alves 2014-03-13 15:26 ` Pedro Alves 2014-03-13 23:53 ` Alan Modra 2014-03-18 15:14 ` Metzger, Markus T 2014-03-18 23:10 ` Alan Modra 2014-03-19 8:11 ` Metzger, Markus T 2014-03-19 8:31 ` Metzger, Markus T 2014-03-19 12:04 ` Pedro Alves 2014-03-20 2:00 ` Alan Modra 2014-03-21 15:55 ` Pedro Alves 2014-03-26 9:32 ` Metzger, Markus T 2014-03-19 12:03 ` Pedro Alves 2014-03-20 1:33 ` Alan Modra 2014-03-21 8:10 ` Metzger, Markus T 2014-03-21 15:48 ` Pedro Alves 2014-03-28 6:13 ` Alan Modra 2014-03-28 13:38 ` Pedro Alves 2014-03-28 23:00 ` Alan Modra 2014-04-01 13:46 ` Pedro Alves 2014-04-02 1:50 ` Alan Modra 2014-04-02 8:05 ` Metzger, Markus T 2014-04-02 8:04 ` Hans-Peter Nilsson 2014-04-03 1:06 ` Alan Modra 2014-04-03 1:46 ` Alan Modra
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).