* solib-svr4.c (read_program_header): New variables pt_phdr, pt_phdr_p,
authorAleksandar Ristovski <aristovski@qnx.com>
Tue, 18 Oct 2011 14:00:42 +0000 (14:00 +0000)
committerAleksandar Ristovski <aristovski@qnx.com>
Tue, 18 Oct 2011 14:00:42 +0000 (14:00 +0000)
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
gdb/solib-svr4.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/attach-pie-noexec.c [new file with mode: 0644]
gdb/testsuite/gdb.base/attach-pie-noexec.exp [new file with mode: 0644]

index 6862c260d9261425fed5f2352dad6bd57853fddc..5c8b7d4a68e739eab848457d0a6a29b81c80986a 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-18  Aleksandar Ristovski  <aristovski@qnx.com>
+
+       * 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  <joost@cnoc.nl>
 
        * gdbtypes.h: Added TYPE_SAFE_NAME macro to get the name of a
index 2bb31a9829d02ace3f693fd752615b918162bbd1..85bf27e75dd3373f160014b3f941ebc2f65463c0 100644 (file)
@@ -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 (&current_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))
index 52624e49de35b2737c9b581c733ecdac159b8f9d..bbe607fc0085f0e9853d05fa1042faaddf693c1b 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.base/attach-pie-noexec.c: New files.
+       * gdb.base/attach-pie-noexec.exp: New files.
+
 2011-10-17  Joseph Myers  <joseph@codesourcery.com>
 
        * 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 (file)
index 0000000..7f430ab
--- /dev/null
@@ -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;
+}
diff --git a/gdb/testsuite/gdb.base/attach-pie-noexec.exp b/gdb/testsuite/gdb.base/attach-pie-noexec.exp
new file mode 100644 (file)
index 0000000..a9da642
--- /dev/null
@@ -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