RFA: pie warning patch (was: Re: [RFC] PR/9723: gdb breakpoints silently fail on PIE binaries)

Thiago Jung Bauermann thiago.bauermann@gmail.com
Sun Aug 2 13:44:00 GMT 2009


Em Terça-feira 28 Julho 2009 14:00:35 Tom Tromey escreveu:
> >>>>> "Thiago" == Thiago Jung Bauermann <thiago.bauermann@gmail.com>
> >>>>> writes:
>
> Thiago> +  filename = bfd_get_filename (exec_bfd);
> Thiago> +  fp = fopen (filename, "r");
>
> [...]
>
> Thiago> +      is_pie = (*((uint16_t *) elfhdr32.e_type) == ET_DYN)? 1 : 0;
>
> It seems to me that you don't have to reopen the underlying file.
> This code from solib-svr4.c shows how:
>
> 	  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
> 	    {
> 	      Elf_Internal_Ehdr *ehdr = elf_tdata (abfd)->elf_header;
>
> GDB appears to do this sort of thing in many places, so I think it would
> be ok here as well.

Awesome BFD-fu. This tip has greatly simplified the patch, and IIUC it
even takes care of the endianness issue that Paul mentioned, right?

Here's an updated patch, with testcases. Please consider this an RFA now.
-- 
[]'s
Thiago Jung Bauermann


2009-08-02  Thiago Jung Bauermann  <thiago.bauermann@gmail.com>

gdb/
	* linux-tdep.c (check_is_pie_binary,
	_initialize_linux_tdep): New functions.

gdb/testsuite/
	* gdb.base/pie-support.exp: New file.
	* gdb.base/pie-support.c: New file.

diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 37770f5..6650b01 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -18,8 +18,12 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "gdbcore.h"
 #include "gdbtypes.h"
 #include "linux-tdep.h"
+#include "observer.h"
+
+#include "elf-bfd.h"
 
 /* This function is suitable for architectures that don't
    extend/override the standard siginfo structure.  */
@@ -134,3 +138,30 @@ linux_get_siginfo_type (struct gdbarch *gdbarch)
 
   return siginfo_type;
 }
+
+/* Observer for the executable_changed event, to check whether the new
+   exec binary is a PIE (Position Independent Executable) specimen, which
+   is currently unsupported.  */
+
+static void
+check_is_pie_binary (void)
+{
+  Elf_Internal_Ehdr *elf_hdr;
+
+  if (!exec_bfd)
+    return;
+  else if (bfd_get_flavour (exec_bfd) != bfd_target_elf_flavour)
+    return;
+
+  if (elf_tdata (exec_bfd)->elf_header->e_type == ET_DYN)
+    warning (_("\
+The current binary is a PIE (Position Independent Executable), which\n\
+GDB does NOT currently support. Most debugger features will fail if used\n\
+in this session.\n"));
+}
+
+void
+_initialize_linux_tdep (void)
+{
+  observer_attach_executable_changed (check_is_pie_binary);
+}
diff --git a/gdb/testsuite/gdb.base/pie-support.c b/gdb/testsuite/gdb.base/pie-support.c
new file mode 100644
index 0000000..63768b9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/pie-support.c
@@ -0,0 +1,34 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2009 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 <stdio.h>
+
+void
+f1 (int a)
+{
+  printf ("a = %d\n", a);
+}
+
+int
+main (int argc, char *argv[])
+{
+  f1 (1);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/pie-support.exp b/gdb/testsuite/gdb.base/pie-support.exp
new file mode 100644
index 0000000..a1affb3
--- /dev/null
+++ b/gdb/testsuite/gdb.base/pie-support.exp
@@ -0,0 +1,58 @@
+# Copyright 2009 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/>.
+
+set testfile pie-support
+set srcfile ${testfile}.c
+set objfile ${objdir}/${subdir}/${testfile}.o
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug additional_flags=-fpie}] != "" } {
+    untested "Couldn't compile test PIE object file."
+    return -1
+}
+if  { [gdb_compile "${objfile}" "${binfile}" executable {debug additional_flags=-pie}] != "" } {
+    untested "Couldn't compile test PIE binary."
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+if [is_remote host] {
+  set binfile [remote_download host $binfile]
+    if { $binfile == "" } {
+      untested "Couldn't download remote test binary."
+      return -1
+    }
+}
+
+# The file command used to kill the remote target.  For the benefit
+# of the testsuite, preserve this behavior.
+send_gdb "kill\n"
+gdb_expect 120 {
+    -re "Kill the program being debugged. .y or n. $" {
+	send_gdb "y\n"
+	verbose "\t\tKilling previous program being debugged"
+	exp_continue
+    }
+    -re "$gdb_prompt $" {
+	# OK.
+    }
+}
+
+gdb_test "file $binfile" "current binary is a PIE.*" "correctly detected PIE binary"



More information about the Gdb-patches mailing list