From 4313697959ffcaf3bf59556ef690914d0d7b84c3 Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Tue, 18 Oct 2011 14:00:42 +0000 Subject: [PATCH] * solib-svr4.c (read_program_header): New variables pt_phdr, pt_phdr_p, initialize them from target PT_PHDR p_vaddr, relocate sect_addr by pt_phdr if PT_PHDR was found. * gdb.base/attach-pie-noexec.c: New files. * gdb.base/attach-pie-noexec.exp: New files. --- gdb/ChangeLog | 6 ++ gdb/solib-svr4.c | 43 +++++++++++-- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.base/attach-pie-noexec.c | 25 ++++++++ gdb/testsuite/gdb.base/attach-pie-noexec.exp | 66 ++++++++++++++++++++ 5 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 gdb/testsuite/gdb.base/attach-pie-noexec.c create mode 100644 gdb/testsuite/gdb.base/attach-pie-noexec.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6862c260d92..5c8b7d4a68e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2011-10-18 Aleksandar Ristovski + + * solib-svr4.c (read_program_header): New variables pt_phdr, pt_phdr_p, + initialize them from target PT_PHDR p_vaddr, relocate sect_addr by + pt_phdr if PT_PHDR was found. + 2011-10-17 Joost van der Sluis * gdbtypes.h: Added TYPE_SAFE_NAME macro to get the name of a diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 2bb31a9829d..85bf27e75dd 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -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_sect_size, int *p_arch_size) /* 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_sect_size, int *p_arch_size) /* 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_sect_size, int *p_arch_size) 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)) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 52624e49de3..bbe607fc008 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-10-18 Jan Kratochvil + + * gdb.base/attach-pie-noexec.c: New files. + * gdb.base/attach-pie-noexec.exp: New files. + 2011-10-17 Joseph Myers * lib/gdb.exp (gdb_test_multiple): Expect newline and secondary diff --git a/gdb/testsuite/gdb.base/attach-pie-noexec.c b/gdb/testsuite/gdb.base/attach-pie-noexec.c new file mode 100644 index 00000000000..7f430ab473f --- /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 . */ + +#include + +int +main (void) +{ + sleep (600); + return 0; +} diff --git a/gdb/testsuite/gdb.base/attach-pie-noexec.exp b/gdb/testsuite/gdb.base/attach-pie-noexec.exp new file mode 100644 index 00000000000..a9da642d919 --- /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 . + +# 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 -- 2.30.2