2013-11-04 Doug Evans PR 11786 * solib-svr4.c (svr4_exec_displacement): Ignore filesz, memsz, flags and align fields for PT_GNU_RELRO segments. testsuite/ * gdb.base/gcore-relro-pie.c: New file. * gdb.base/gcore-relro-pie.exp: New file. diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 3eea057..9538af6 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -2604,6 +2604,28 @@ svr4_exec_displacement (CORE_ADDR *displacementp) if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0) continue; + /* Strip modifies the flags and alignment of PT_GNU_RELRO. + CentOS-5 has problems with filesz, memsz as well. + See PR 11786. */ + if (phdr2[i].p_type == PT_GNU_RELRO) + { + Elf32_External_Phdr tmp_phdr = *phdrp; + Elf32_External_Phdr tmp_phdr2 = *phdr2p; + + memset (tmp_phdr.p_filesz, 0, 4); + memset (tmp_phdr.p_memsz, 0, 4); + memset (tmp_phdr.p_flags, 0, 4); + memset (tmp_phdr.p_align, 0, 4); + memset (tmp_phdr2.p_filesz, 0, 4); + memset (tmp_phdr2.p_memsz, 0, 4); + memset (tmp_phdr2.p_flags, 0, 4); + memset (tmp_phdr2.p_align, 0, 4); + + if (memcmp (&tmp_phdr, &tmp_phdr2, sizeof (tmp_phdr)) + == 0) + continue; + } + /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS. */ plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt"); if (plt2_asect) @@ -2713,6 +2735,28 @@ svr4_exec_displacement (CORE_ADDR *displacementp) if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0) continue; + /* Strip modifies the flags and alignment of PT_GNU_RELRO. + CentOS-5 has problems with filesz, memsz as well. + See PR 11786. */ + if (phdr2[i].p_type == PT_GNU_RELRO) + { + Elf64_External_Phdr tmp_phdr = *phdrp; + Elf64_External_Phdr tmp_phdr2 = *phdr2p; + + memset (tmp_phdr.p_filesz, 0, 8); + memset (tmp_phdr.p_memsz, 0, 8); + memset (tmp_phdr.p_flags, 0, 4); + memset (tmp_phdr.p_align, 0, 8); + memset (tmp_phdr2.p_filesz, 0, 8); + memset (tmp_phdr2.p_memsz, 0, 8); + memset (tmp_phdr2.p_flags, 0, 4); + memset (tmp_phdr2.p_align, 0, 8); + + if (memcmp (&tmp_phdr, &tmp_phdr2, sizeof (tmp_phdr)) + == 0) + continue; + } + /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS. */ plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt"); if (plt2_asect) diff --git a/gdb/testsuite/gdb.base/gcore-relro-pie.c b/gdb/testsuite/gdb.base/gcore-relro-pie.c new file mode 100644 index 0000000..d72969b --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-relro-pie.c @@ -0,0 +1,41 @@ +/* Copyright 2013 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 . */ + +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/testsuite/gdb.base/gcore-relro-pie.exp b/gdb/testsuite/gdb.base/gcore-relro-pie.exp new file mode 100644 index 0000000..eb45c52 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-relro-pie.exp @@ -0,0 +1,75 @@ +# Copyright 2013 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 . + +# PR 11786 (Gold and strip differ on flags,align fields of PT_GNU_RELRO). +# 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 $testfile.exp $testfile $srcfile {debug additional_flags=-fpie "ldflags=-pie -Wl,-z,relro"}]} { + 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} + +# Does this gdb support gcore? +set test "help gcore" +gdb_test_multiple $test $test { + -re "Undefined command: .gcore.*\r\n$gdb_prompt $" { + # gcore command not supported -- nothing to test here. + unsupported "gdb does not support gcore on this target" + return -1 + } + -re "Save a core file .*\r\n$gdb_prompt $" { + pass $test + } +} + +# 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"