diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2010-07-05 18:00:40 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2010-07-05 18:00:40 +0000 |
commit | 86e4bafc3b0bb0148b95807d37b36aae14cdf56c (patch) | |
tree | fae9aeadc3fef5cca2aa8c66596edfa5c6a48169 /gdb/testsuite/gdb.base/attach-pie-misread.exp | |
parent | 3cd07d204baadc4b3d148a7494366fc92e7d42b1 (diff) | |
download | gdb-86e4bafc3b0bb0148b95807d37b36aae14cdf56c.zip gdb-86e4bafc3b0bb0148b95807d37b36aae14cdf56c.tar.gz gdb-86e4bafc3b0bb0148b95807d37b36aae14cdf56c.tar.bz2 |
gdb/
* auxv.c (memory_xfer_auxv): Update attach comment.
* solib-svr4.c (svr4_special_symbol_handling): Remove the call to
svr4_relocate_main_executable.
(svr4_solib_create_inferior_hook): Make the call to
svr4_relocate_main_executable unconditional.
gdb/testsuite/
* gdb.base/attach-pie-misread.exp, gdb.base/attach-pie-misread.c: New.
* gdb.base/break-interp.exp (reach, test_core, test_ld): Require each
displacement message exactly once.
Diffstat (limited to 'gdb/testsuite/gdb.base/attach-pie-misread.exp')
-rw-r--r-- | gdb/testsuite/gdb.base/attach-pie-misread.exp | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/attach-pie-misread.exp b/gdb/testsuite/gdb.base/attach-pie-misread.exp new file mode 100644 index 0000000..334272b --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-pie-misread.exp @@ -0,0 +1,209 @@ +# Copyright 2010 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/>. + +# This test only works on GNU/Linux. +if { ![isnative] || [is_remote host] || ![istarget *-linux*] || [skip_shlib_tests]} { + continue +} + +set test "attach-pie-misread" +set srcfile ${test}.c +set genfile ${objdir}/${subdir}/${test}-gen.h +set executable ${test} +set binfile ${objdir}/${subdir}/${executable} + +if {[build_executable ${test}.exp $executable $srcfile [list "additional_flags=-fPIE -pie"]] == -1} { + return -1 +} + +# Program Headers: +# Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x134f5ec 0x134f5ec R E 0x200000 +# LOAD 0x134f5f0 0x000000000194f5f0 0x000000000194f5f0 0x1dbc60 0x214088 RW 0x200000 +# DYNAMIC 0x134f618 0x000000000194f618 0x000000000194f618 0x000200 0x000200 RW 0x8 +# +proc read_phdr {binfile test} { + set readelf_program [transform readelf] + set command "exec $readelf_program -Wl $binfile" + verbose -log "command is $command" + set result [catch $command output] + verbose -log "result is $result" + verbose -log "output is $output" + if {$result != 0} { + fail $test + return + } + if ![regexp {\nProgram Headers:\n *Type [^\n]* Align\n(.*?)\n\n} $output trash phdr] { + fail "$test (no Program Headers)" + return + } + if ![regexp -line {^ *DYNAMIC +0x[0-9a-f]+ +(0x[0-9a-f]+) } $phdr trash dynamic_vaddr] { + fail "$test (no DYNAMIC found)" + return + } + verbose -log "dynamic_vaddr is $dynamic_vaddr" + set align_max -1 + foreach {trash align} [regexp -line -all -inline {^ *LOAD .* (0x[0-9]+)$} $phdr] { + if {$align_max < $align} { + set align_max $align + } + } + verbose -log "align_max is $align_max" + if {$align_max == -1} { + fail "$test (no LOAD found)" + return + } + pass $test + return [list $dynamic_vaddr $align_max] +} + +set phdr [read_phdr $binfile "readelf initial scan"] +set dynamic_vaddr [lindex $phdr 0] +set align_max [lindex $phdr 1] + +set stub_size [format 0x%x [expr "2 * $align_max - ($dynamic_vaddr & ($align_max - 1))"]] +verbose -log "stub_size is $stub_size" + +# On x86_64 it is commonly about 4MB. +if {$stub_size > 25000000} { + xfail "stub size $stub_size is too large" + return +} + +set test "generate stub" +set command "exec $binfile $stub_size >$genfile" +verbose -log "command is $command" +set result [catch $command output] +verbose -log "result is $result" +verbose -log "output is $output" +if {$result == 0} { + pass $test +} else { + fail $test +} + +if {[build_executable ${test}.exp $executable $srcfile [list "additional_flags=-fPIE -pie -DGEN=\"$genfile\""]] == -1} { + return -1 +} + +# x86_64 file has 25MB, no need to keep it. +file delete -- $genfile + +set phdr [read_phdr $binfile "readelf rebuilt with stub_size"] +set dynamic_vaddr_prelinkno [lindex $phdr 0] + +set command "exec /usr/sbin/prelink -q -N --no-exec-shield -R $binfile" +verbose -log "command is $command" +set result [catch $command output] +verbose -log "result is $result" +verbose -log "output is $output" + +set test "prelink -R" +if {$result == 0 && $output == ""} { + pass $test +} elseif {$result == 1 && [regexp {^(couldn't execute "/usr/sbin/prelink[^\r\n]*": no such file or directory\n?)*$} $output]} { + untested attach-pie-misread.exp + return -1 +} else { + fail $test +} + +set phdr [read_phdr $binfile "readelf with prelink -R"] +set dynamic_vaddr_prelinkyes [lindex $phdr 0] + +set first_offset [format 0x%x [expr $dynamic_vaddr_prelinkyes - $dynamic_vaddr_prelinkno]] +verbose -log "first_offset is $first_offset" + +set test "first offset is non-zero" +if {$first_offset == 0} { + fail "$test (-fPIE -pie in effect?)" +} else { + pass $test +} + +set test "start inferior" +gdb_exit + +set res [remote_spawn host $binfile]; +if { $res < 0 || $res == "" } { + perror "Spawning $binfile failed." + fail $test + return +} +set pid [exp_pid -i $res] +gdb_expect { + -re "sleeping\r\n" { + pass $test + } + eof { + fail "$test (eof)" + remote_exec host "kill -9 $pid" + return + } + timeout { + fail "$test (timeout)" + remote_exec host "kill -9 $pid" + return + } +} + +# Due to alignments it was reproducible with 1 on x86_64 but 2 on i686. +foreach align_mult {1 2} { + set old_ldprefix $pf_prefix + lappend pf_prefix "shift-by-$align_mult:" + + # FIXME: We believe there is enough room under FIRST_OFFSET. + set shifted_offset [format 0x%x [expr "$first_offset - $align_mult * $align_max"]] + verbose -log "shifted_offset is $shifted_offset" + + set command "exec /usr/sbin/prelink -q -N --no-exec-shield -r $shifted_offset $binfile" + verbose -log "command is $command" + set result [catch $command output] + verbose -log "result is $result" + verbose -log "output is $output" + + set test "prelink -r" + if {$result == 0 && $output == ""} { + pass $test + } else { + fail $test + } + + clean_restart $executable + + set test "attach" + gdb_test_multiple "attach $pid" $test { + -re "Attaching to program: .*, process $pid\r\n" { + # Missing "$gdb_prompt $" is intentional. + pass $test + } + } + + set test "error on Cannot access memory at address" + gdb_test_multiple "" $test { + -re "\r\nCannot access memory at address .*$gdb_prompt $" { + fail $test + } + -re "$gdb_prompt $" { + pass $test + } + } + + gdb_test "detach" "Detaching from program: .*" + + set pf_prefix $old_ldprefix +} + +remote_exec host "kill -9 $pid" |