* Re: [patch] Relocate phdr in read_program_header [not found] <j655em$75r$1@dough.gmane.org> @ 2011-10-12 18:50 ` Aleksandar Ristovski 2011-10-12 19:27 ` Jan Kratochvil 2011-10-16 19:42 ` Jan Kratochvil 1 sibling, 1 reply; 6+ messages in thread From: Aleksandar Ristovski @ 2011-10-12 18:50 UTC (permalink / raw) To: gdb-patches ping? On 11-09-30 03:31 PM, Aleksandar Ristovski wrote: > Hello, > > When attaching to a process without the executable file, gdb reads > pheaders from the target (solib-svr4.c: read_program_header). > > However, it does not take into account possibility of having PIE > executable on the other end, resulting in trying to read from > unrelocated phdr address. > > This patch addresses the issue by looking for PT_PHDR; if found, uses it > to determine relocation and adjusts address before reading it from > target memory. > > Testsuite on x86_64-unknown-linux-gnu did not show any regressions. > > > Thanks, > > > Aleksandar Ristovski > QNX Software Systems > > > > ... Aleksandar Ristovski <aristovski@qnx.com> > > * solib-svr4.c (read_program_header): If PT_PHDR is present, use it > to calculate correct address in case of PIE. > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] Relocate phdr in read_program_header 2011-10-12 18:50 ` [patch] Relocate phdr in read_program_header Aleksandar Ristovski @ 2011-10-12 19:27 ` Jan Kratochvil 0 siblings, 0 replies; 6+ messages in thread From: Jan Kratochvil @ 2011-10-12 19:27 UTC (permalink / raw) To: Aleksandar Ristovski; +Cc: gdb-patches On Wed, 12 Oct 2011 20:50:00 +0200, Aleksandar Ristovski wrote: > ping? It does not have a testcase for example - that would be good - maybe integrated with break-interp.exp, but I am already looking at it. Thanks, Jan ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] Relocate phdr in read_program_header [not found] <j655em$75r$1@dough.gmane.org> 2011-10-12 18:50 ` [patch] Relocate phdr in read_program_header Aleksandar Ristovski @ 2011-10-16 19:42 ` Jan Kratochvil 2011-10-17 16:29 ` Aleksandar Ristovski 1 sibling, 1 reply; 6+ messages in thread From: Jan Kratochvil @ 2011-10-16 19:42 UTC (permalink / raw) To: Aleksandar Ristovski; +Cc: gdb-patches On Fri, 30 Sep 2011 21:31:33 +0200, Aleksandar Ristovski wrote: > * solib-svr4.c (read_program_header): If PT_PHDR is present, use it > to calculate correct address in case of PIE. FSF ChangeLog should describe the changes, not their reason. Therefore: * solib-svr4.c (read_program_header): New variable pt_phdr, initialize it from target PT_PHDR p_vaddr, relocate sect_addr by it. > --- gdb/solib-svr4.c 30 Aug 2011 02:48:05 -0000 1.154 > +++ gdb/solib-svr4.c 30 Sep 2011 17:47:13 -0000 > @@ -385,7 +385,7 @@ static gdb_byte * > read_program_header (int type, int *p_sect_size, int *p_arch_size) > { > enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); > - CORE_ADDR at_phdr, at_phent, at_phnum; > + CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr; > int arch_size, sect_size; > CORE_ADDR sect_addr; > gdb_byte *buf; > @@ -408,6 +408,10 @@ read_program_header (int type, int *p_se > else > return 0; > > + pt_phdr = (CORE_ADDR)-1; /* Address of the first entry. If not PIE, > + this will be zero. > + For PIE, it will be unrelocated at_phdr. */ There is CORE_ADDR_MAX. But I would prefer new `int pt_phdr_p' as "predicate" boolean flag for valid pt_phdr value, these special values are fragile and one has to think whether they can happen. > + > /* Find the requested segment. */ > if (type == -1) > { > @@ -427,6 +431,11 @@ read_program_header (int type, int *p_se > return 0; > > if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, > + 4, byte_order) == PT_PHDR) > + pt_phdr = extract_unsigned_integer ((gdb_byte *)phdr.p_vaddr, > + 4, byte_order); > + > + if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, > 4, byte_order) == type) That p_type could be decoded only once. Also any casta are `(type) val' with a space accoridng to GCS (GNU Coding Standards). > break; > } > @@ -453,6 +462,11 @@ read_program_header (int type, int *p_se > return 0; > > if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, > + 4, byte_order) == PT_PHDR) > + pt_phdr = extract_unsigned_integer ((gdb_byte *)phdr.p_vaddr, > + 8, byte_order); > + > + if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, > 4, byte_order) == type) > break; > } > @@ -467,6 +481,16 @@ read_program_header (int type, int *p_se > 8, byte_order); > } > > + /* at_phdr is real address in memory. pt_phdr is what pheader says it is. > + Relocation offset is the difference between the two. */ > + if (pt_phdr != (CORE_ADDR)-1) > + { > + /* PT_PHDR is optional in the execution view, but we really need it > + for PIE to make this work in general. However, if not found, > + work with what you have. */ > + sect_addr = sect_addr + (at_phdr - pt_phdr); > + } > + > /* Read in requested program header. */ > buf = xmalloc (sect_size); > if (target_read_memory (sect_addr, buf, sect_size)) Just about the style, I do not see any problems of the patch, thanks. Wrote the testcase, it is probably GNU/Linux-specific. I would like to review yet the changes. Thanks, Jan 2011-10-16 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/attach-pie-noexec.c: New files. * gdb.base/attach-pie-noexec.exp: New files. --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-pie-noexec.c @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> + +int +main (void) +{ + sleep (600); + return 0; +} --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-pie-noexec.exp @@ -0,0 +1,66 @@ +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Manipulation with PID on target is not supported. +if [is_remote target] then { + return 0 +} + +set testfile attach-pie-noexec +set executable ${testfile} +set binfile ${objdir}/${subdir}/${executable} + +if { [prepare_for_testing ${testfile}.exp $executable "" [list debug "additional_flags=-fPIE -pie"]] } { + return -1 +} + +clean_restart $executable +set arch "" +set test "show architecture" +gdb_test_multiple $test $test { + -re "The target architecture is set automatically \\(currently (.*)\\)\r\n$gdb_prompt $" { + set arch $expect_out(1,string) + pass $test + } +} +if ![runto_main] { + return 0 +} +set test "sanity check info shared" +gdb_test_multiple "info shared" $test { + -re "From\[ \t\]+To\[ \t\]+Syms Read\[ \t\]+Shared Object Library\r\n0x.*\r\n$gdb_prompt $" { + pass $test + } + -re "No shared libraries loaded at this time\\.\r\n$gdb_prompt $" { + untested ${testfile}.exp + } +} +gdb_exit + +if {$arch == ""} { + untested ${testfile}.exp + return 0 +} + +set testpid [eval exec $binfile &] +exec sleep 2 + +gdb_start +file delete -- $binfile +gdb_test "attach $testpid" "Attaching to process $testpid\r\n.*: No such file or directory\\." "attach" +gdb_test "set architecture $arch" "The target architecture is assumed to be $arch" +gdb_test "info shared" "From\[ \t\]+To\[ \t\]+Syms Read\[ \t\]+Shared Object Library\r\n0x.*" + +eval exec kill -9 $testpid ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] Relocate phdr in read_program_header 2011-10-16 19:42 ` Jan Kratochvil @ 2011-10-17 16:29 ` Aleksandar Ristovski 2011-10-18 13:41 ` Jan Kratochvil 0 siblings, 1 reply; 6+ messages in thread From: Aleksandar Ristovski @ 2011-10-17 16:29 UTC (permalink / raw) To: gdb-patches; +Cc: Jan Kratochvil [-- Attachment #1: Type: text/plain, Size: 2283 bytes --] On 11-10-16 03:21 PM, Jan Kratochvil wrote: > On Fri, 30 Sep 2011 21:31:33 +0200, Aleksandar Ristovski wrote: >> * solib-svr4.c (read_program_header): If PT_PHDR is present, use it >> to calculate correct address in case of PIE. > > FSF ChangeLog should describe the changes, not their reason. Therefore: > * solib-svr4.c (read_program_header): New variable pt_phdr, initialize > it from target PT_PHDR p_vaddr, relocate sect_addr by it. Change log changed (see below). >> >> + pt_phdr = (CORE_ADDR)-1; /* Address of the first entry. If not PIE, >> + this will be zero. >> + For PIE, it will be unrelocated at_phdr. */ > > There is CORE_ADDR_MAX. But I would prefer new `int pt_phdr_p' as "predicate" > boolean flag for valid pt_phdr value, these special values are fragile and one > has to think whether they can happen. pt_phdr_p introduced. Also, pt_phdr initialized to 0 even though not strictly necessary, but gcc complained about possible uninitialized use. > > >> + >> /* Find the requested segment. */ >> if (type == -1) >> { >> @@ -427,6 +431,11 @@ read_program_header (int type, int *p_se >> return 0; >> >> if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, >> + 4, byte_order) == PT_PHDR) >> + pt_phdr = extract_unsigned_integer ((gdb_byte *)phdr.p_vaddr, >> + 4, byte_order); >> + >> + if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, >> 4, byte_order) == type) > > That p_type could be decoded only once. Also any casta are `(type) val' with > a space accoridng to GCS (GNU Coding Standards). Cast fixed, p_type decoded only once. >> if (target_read_memory (sect_addr, buf, sect_size)) > > > Just about the style, I do not see any problems of the patch, thanks. > > Wrote the testcase, it is probably GNU/Linux-specific. I was contemplating a testcase but I couldn't think of a trick to "make" gdb not find the executable... Thanks for the test. > > I would like to review yet the changes. Revised patch attached. Thanks, Aleksandar New change log: <date> Aleksandar Ristovski <aristovski@qnx.com> * solib-svr4.c (read_program_header): New variable pt_phdr, initialize it from target PT_PHDR p_vaddr, relocate sect_addr by it. [-- Attachment #2: PIE_read_program_header-201110170900.patch --] [-- Type: text/x-patch, Size: 2678 bytes --] Index: gdb/solib-svr4.c =================================================================== RCS file: /cvs/src/src/gdb/solib-svr4.c,v retrieving revision 1.157 diff -u -p -r1.157 solib-svr4.c --- gdb/solib-svr4.c 14 Oct 2011 07:58:58 -0000 1.157 +++ gdb/solib-svr4.c 17 Oct 2011 14:48:31 -0000 @@ -364,10 +364,11 @@ static gdb_byte * read_program_header (int type, int *p_sect_size, int *p_arch_size) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); - CORE_ADDR at_phdr, at_phent, at_phnum; + CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0; int arch_size, sect_size; CORE_ADDR sect_addr; gdb_byte *buf; + int pt_phdr_p = 0; /* Get required auxv elements from target. */ if (target_auxv_search (¤t_target, AT_PHDR, &at_phdr) <= 0) @@ -401,12 +402,23 @@ read_program_header (int type, int *p_se /* Search for requested PHDR. */ for (i = 0; i < at_phnum; i++) { + int p_type; + if (target_read_memory (at_phdr + i * sizeof (phdr), (gdb_byte *)&phdr, sizeof (phdr))) return 0; - if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, - 4, byte_order) == type) + p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type, + 4, byte_order); + + if (p_type == PT_PHDR) + { + pt_phdr_p = 1; + pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr, + 4, byte_order); + } + + if (p_type == type) break; } @@ -427,12 +439,23 @@ read_program_header (int type, int *p_se /* Search for requested PHDR. */ for (i = 0; i < at_phnum; i++) { + int p_type; + if (target_read_memory (at_phdr + i * sizeof (phdr), (gdb_byte *)&phdr, sizeof (phdr))) return 0; - if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, - 4, byte_order) == type) + p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type, + 4, byte_order); + + if (p_type == PT_PHDR) + { + pt_phdr_p = 1; + pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr, + 8, byte_order); + } + + if (p_type == type) break; } @@ -446,6 +469,16 @@ read_program_header (int type, int *p_se 8, byte_order); } + /* PT_PHDR is optional, but we really need it + for PIE to make this work in general. */ + + if (pt_phdr_p) + { + /* at_phdr is real address in memory. pt_phdr is what pheader says it is. + Relocation offset is the difference between the two. */ + sect_addr = sect_addr + (at_phdr - pt_phdr); + } + /* Read in requested program header. */ buf = xmalloc (sect_size); if (target_read_memory (sect_addr, buf, sect_size)) ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] Relocate phdr in read_program_header 2011-10-17 16:29 ` Aleksandar Ristovski @ 2011-10-18 13:41 ` Jan Kratochvil 2011-10-18 14:14 ` Aleksandar Ristovski 0 siblings, 1 reply; 6+ messages in thread From: Jan Kratochvil @ 2011-10-18 13:41 UTC (permalink / raw) To: Aleksandar Ristovski; +Cc: gdb-patches On Mon, 17 Oct 2011 18:26:28 +0200, Aleksandar Ristovski wrote: > I was contemplating a testcase but I couldn't think of a trick to > "make" gdb not find the executable... Thanks for the test. The testcase of mine has a problem it will stop working in future. [patch] Attach to running but deleted executable http://sourceware.org/ml/gdb-patches/2010-03/msg00950.html The problem is the patch above is not so useful as it still does not work for deleted libraries, there was discussed some Linux kernel support like /proc/PID/mappedfileshandlesdirectory/ but it probably has not happened yet. Anyway one could also use gdbserver - which is probably the case your fix targets IIUC, the testcase will regress with a fix like above. > <date> Aleksandar Ristovski <aristovski@qnx.com> > > * solib-svr4.c (read_program_header): New variable pt_phdr, > initialize > it from target PT_PHDR p_vaddr, relocate sect_addr by it. There should be now two new variables pt_phdr and pt_phdr_p. :-) OK with that ChangeLog change in a single commit with my testcase. Thanks, Jan ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] Relocate phdr in read_program_header 2011-10-18 13:41 ` Jan Kratochvil @ 2011-10-18 14:14 ` Aleksandar Ristovski 0 siblings, 0 replies; 6+ messages in thread From: Aleksandar Ristovski @ 2011-10-18 14:14 UTC (permalink / raw) To: gdb-patches On 11-10-18 09:31 AM, Jan Kratochvil wrote: > > OK with that ChangeLog change in a single commit with my testcase. Committed with fixed change log, testcase and accompanying testcase ChangeLog. Thanks, Aleksandar ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-10-18 14:03 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <j655em$75r$1@dough.gmane.org>
2011-10-12 18:50 ` [patch] Relocate phdr in read_program_header Aleksandar Ristovski
2011-10-12 19:27 ` Jan Kratochvil
2011-10-16 19:42 ` Jan Kratochvil
2011-10-17 16:29 ` Aleksandar Ristovski
2011-10-18 13:41 ` Jan Kratochvil
2011-10-18 14:14 ` Aleksandar Ristovski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox