summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Spang <spang@google.com>2018-08-20 13:39:20 -0400
committerMichael Spang <spang@google.com>2018-08-20 13:39:20 -0400
commit689b53dab1f782ff0ecc29f4d65e0d193c376703 (patch)
treec1f3c6004da548ee3c393ae32d9ecaa6dafdd478
parenta7e49fd02c21a496095c828841f209eef8ae2985 (diff)
downloadgdb-689b53dab1f782ff0ecc29f4d65e0d193c376703.tar.gz
Fix debugging of stripped PIE executables with padded PT_TLSndk-r19cndk-r19bndk-r19-beta2ndk-r19-beta1ndk-r19ndk-release-r19
Certain PIE executables produced by gold cannot be debugged by gdb after being stripped. GDB requires program headers of PIE executables to match, and those checks may fail due to adjustments made during stripping. One case of this occurs because strip recomputes the memsz of PT_TLS and does not add alignment, while gold does. This is another variant of PR 11786, so apply the same fix of relaxing the program header matching. gdb/ChangeLog: PR gdb/11786 * solib-svr4.c (svr4_exec_displacement): Ignore memsz fields for PT_TLS segments. gdb/testsuite/ChangeLog: PR gdb/11786 * gdb.base/gcore-tls-pie.c: New file. * gdb.base/gcore-tls-pie.exp: New file. (cherry picked from commit be2d111a878e1422c921226bc7714131a5c470fa) Change-Id: I33ea8f871d74f8822f5c836c1edcafb53cfc7beb
-rw-r--r--gdb-7.11/gdb/solib-svr4.c8
-rw-r--r--gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.c48
-rw-r--r--gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.exp62
-rw-r--r--gdb-8.0.1/gdb/solib-svr4.c8
-rw-r--r--gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.c48
-rw-r--r--gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.exp62
6 files changed, 232 insertions, 4 deletions
diff --git a/gdb-7.11/gdb/solib-svr4.c b/gdb-7.11/gdb/solib-svr4.c
index b4ec36379..fbb481147 100644
--- a/gdb-7.11/gdb/solib-svr4.c
+++ b/gdb-7.11/gdb/solib-svr4.c
@@ -2783,8 +2783,10 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
/* Strip modifies the flags and alignment of PT_GNU_RELRO.
CentOS-5 has problems with filesz, memsz as well.
+ Strip also modifies memsz of PT_TLS.
See PR 11786. */
- if (phdr2[i].p_type == PT_GNU_RELRO)
+ if (phdr2[i].p_type == PT_GNU_RELRO ||
+ phdr2[i].p_type == PT_TLS)
{
Elf32_External_Phdr tmp_phdr = *phdrp;
Elf32_External_Phdr tmp_phdr2 = *phdr2p;
@@ -2914,8 +2916,10 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
/* Strip modifies the flags and alignment of PT_GNU_RELRO.
CentOS-5 has problems with filesz, memsz as well.
+ Strip also modifies memsz of PT_TLS.
See PR 11786. */
- if (phdr2[i].p_type == PT_GNU_RELRO)
+ if (phdr2[i].p_type == PT_GNU_RELRO ||
+ phdr2[i].p_type == PT_TLS)
{
Elf64_External_Phdr tmp_phdr = *phdrp;
Elf64_External_Phdr tmp_phdr2 = *phdr2p;
diff --git a/gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.c b/gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.c
new file mode 100644
index 000000000..aaba20fcc
--- /dev/null
+++ b/gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.c
@@ -0,0 +1,48 @@
+/* Copyright 2013-2018 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+/* The size of these variables is chosen so that gold will add some padding
+ to the TLS program header (total size of 16 bytes on x86_64) which strip
+ will remove (bringing it down to 9 bytes). */
+
+__thread long j;
+__thread char i;
+
+void
+break_here (void)
+{
+ *(int *) 0 = 0;
+}
+
+void
+foo (void)
+{
+ break_here ();
+}
+
+void
+bar (void)
+{
+ foo ();
+}
+
+int
+main (void)
+{
+ bar ();
+ return 0;
+}
diff --git a/gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.exp b/gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.exp
new file mode 100644
index 000000000..1f7381e1b
--- /dev/null
+++ b/gdb-7.11/gdb/testsuite/gdb.base/gcore-tls-pie.exp
@@ -0,0 +1,62 @@
+# Copyright 2013-2018 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/>.
+
+# PR 11786 (Gold and strip differ on memsz field of PT_TLS).
+# Generate a core file from the stripped version of the program,
+# and then try to debug the core with the unstripped version.
+
+standard_testfile
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug additional_flags=-fpie "ldflags=-pie -fuse-ld=gold"}]} {
+ return -1
+}
+
+set stripped_binfile ${binfile}.stripped
+set gcorefile ${binfile}.gcore
+
+set strip_program [transform strip]
+remote_file host delete ${stripped_binfile}
+if [run_on_host "strip" "$strip_program" "-g -o ${stripped_binfile} $binfile"] {
+ return -1
+}
+
+# Workaround PR binutils/10802:
+# Preserve the 'x' bit also for PIEs (Position Independent Executables).
+set perm [file attributes ${binfile} -permissions]
+file attributes ${stripped_binfile} -permissions $perm
+
+clean_restart ${stripped_binfile}
+
+# The binary is stripped of debug info, but not minsyms.
+if ![runto break_here] {
+ fail "can't run to break_here"
+ return -1
+}
+
+if {![gdb_gcore_cmd $gcorefile "save a corefile"]} {
+ return -1
+}
+
+# Now restart gdb with the unstripped binary and load the corefile.
+
+clean_restart ${binfile}
+
+gdb_test "core ${gcorefile}" \
+ "Core was generated by .*" "re-load generated corefile"
+
+# Put $pc in gdb.log for debug purposes for comparison with stripped case.
+gdb_test "x/i \$pc" "break_here.*"
+
+gdb_test "frame" "#0 \[^\r\n\]* break_here .*" "unstripped + core ok"
diff --git a/gdb-8.0.1/gdb/solib-svr4.c b/gdb-8.0.1/gdb/solib-svr4.c
index 4cb6127af..9055d224c 100644
--- a/gdb-8.0.1/gdb/solib-svr4.c
+++ b/gdb-8.0.1/gdb/solib-svr4.c
@@ -2777,8 +2777,10 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
/* Strip modifies the flags and alignment of PT_GNU_RELRO.
CentOS-5 has problems with filesz, memsz as well.
+ Strip also modifies memsz of PT_TLS.
See PR 11786. */
- if (phdr2[i].p_type == PT_GNU_RELRO)
+ if (phdr2[i].p_type == PT_GNU_RELRO ||
+ phdr2[i].p_type == PT_TLS)
{
Elf32_External_Phdr tmp_phdr = *phdrp;
Elf32_External_Phdr tmp_phdr2 = *phdr2p;
@@ -2908,8 +2910,10 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
/* Strip modifies the flags and alignment of PT_GNU_RELRO.
CentOS-5 has problems with filesz, memsz as well.
+ Strip also modifies memsz of PT_TLS.
See PR 11786. */
- if (phdr2[i].p_type == PT_GNU_RELRO)
+ if (phdr2[i].p_type == PT_GNU_RELRO ||
+ phdr2[i].p_type == PT_TLS)
{
Elf64_External_Phdr tmp_phdr = *phdrp;
Elf64_External_Phdr tmp_phdr2 = *phdr2p;
diff --git a/gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.c b/gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.c
new file mode 100644
index 000000000..aaba20fcc
--- /dev/null
+++ b/gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.c
@@ -0,0 +1,48 @@
+/* Copyright 2013-2018 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+/* The size of these variables is chosen so that gold will add some padding
+ to the TLS program header (total size of 16 bytes on x86_64) which strip
+ will remove (bringing it down to 9 bytes). */
+
+__thread long j;
+__thread char i;
+
+void
+break_here (void)
+{
+ *(int *) 0 = 0;
+}
+
+void
+foo (void)
+{
+ break_here ();
+}
+
+void
+bar (void)
+{
+ foo ();
+}
+
+int
+main (void)
+{
+ bar ();
+ return 0;
+}
diff --git a/gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.exp b/gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.exp
new file mode 100644
index 000000000..1f7381e1b
--- /dev/null
+++ b/gdb-8.0.1/gdb/testsuite/gdb.base/gcore-tls-pie.exp
@@ -0,0 +1,62 @@
+# Copyright 2013-2018 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/>.
+
+# PR 11786 (Gold and strip differ on memsz field of PT_TLS).
+# Generate a core file from the stripped version of the program,
+# and then try to debug the core with the unstripped version.
+
+standard_testfile
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug additional_flags=-fpie "ldflags=-pie -fuse-ld=gold"}]} {
+ return -1
+}
+
+set stripped_binfile ${binfile}.stripped
+set gcorefile ${binfile}.gcore
+
+set strip_program [transform strip]
+remote_file host delete ${stripped_binfile}
+if [run_on_host "strip" "$strip_program" "-g -o ${stripped_binfile} $binfile"] {
+ return -1
+}
+
+# Workaround PR binutils/10802:
+# Preserve the 'x' bit also for PIEs (Position Independent Executables).
+set perm [file attributes ${binfile} -permissions]
+file attributes ${stripped_binfile} -permissions $perm
+
+clean_restart ${stripped_binfile}
+
+# The binary is stripped of debug info, but not minsyms.
+if ![runto break_here] {
+ fail "can't run to break_here"
+ return -1
+}
+
+if {![gdb_gcore_cmd $gcorefile "save a corefile"]} {
+ return -1
+}
+
+# Now restart gdb with the unstripped binary and load the corefile.
+
+clean_restart ${binfile}
+
+gdb_test "core ${gcorefile}" \
+ "Core was generated by .*" "re-load generated corefile"
+
+# Put $pc in gdb.log for debug purposes for comparison with stripped case.
+gdb_test "x/i \$pc" "break_here.*"
+
+gdb_test "frame" "#0 \[^\r\n\]* break_here .*" "unstripped + core ok"