aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/lib
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2010-07-05 18:01:53 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2010-07-05 18:01:53 +0000
commit5e3b36f8799d7928f5c5ac5e871c0968b5874369 (patch)
tree819e2ed544aa1320a504ea740f2435ba9a6a395c /gdb/testsuite/lib
parent86e4bafc3b0bb0148b95807d37b36aae14cdf56c (diff)
downloadgdb-5e3b36f8799d7928f5c5ac5e871c0968b5874369.zip
gdb-5e3b36f8799d7928f5c5ac5e871c0968b5874369.tar.gz
gdb-5e3b36f8799d7928f5c5ac5e871c0968b5874369.tar.bz2
gdb/testsuite/
* gdb.base/attach-pie-misread.exp: Load prelink-support.exp. Replace build_executable by build_executable_own_libs. Replace "prelink -R" execution by a call of prelink_yes. Comment why "prelink -r" needs no change. * gdb.base/break-interp.exp: Load prelink-support.exp. Rename calls of copy to file_copy. Move setting opts --dynamic-linker and -rpath, mkdir $dir and ldd its parsing and copying to lib/prelink-support.exp. Replace build_executable by build_executable_own_libs's function build_executable_own_libs. (prelinkNO): Create new stub to call prelink_no. (prelinkYES): Create new stub to call prelink_yes. (test_attach): Rename calls of copy to file_copy. (section_get, prelinkNO_run, prelinkNO, prelinkYES, symlink_resolve) (copy): Move to ... * lib/prelink-support.exp: ... a new file. Rename prelinkNO to prelink_no, prelinkYES to prelink_yes, copy to file_copy. * gdb.base/prelink.exp: Disable testcase also for is_remote and skip_shlib_tests. Load prelink-support.exp. Replace gdb_compile with special flags by gdb_compile_shlib. Replace second gdb_compile by build_executable_own_libs. Replace "prelink -R" execution by a call of prelink_yes. Replace "prelink -u" and second "prelink -R" execution by a second call of prelink_yes. Replace restart commands by clean_restart. (prelink): Rename to ... (seen displacement message): ... this test. Extend its expectation strictness.
Diffstat (limited to 'gdb/testsuite/lib')
-rw-r--r--gdb/testsuite/lib/prelink-support.exp254
1 files changed, 254 insertions, 0 deletions
diff --git a/gdb/testsuite/lib/prelink-support.exp b/gdb/testsuite/lib/prelink-support.exp
new file mode 100644
index 0000000..6d9e909
--- /dev/null
+++ b/gdb/testsuite/lib/prelink-support.exp
@@ -0,0 +1,254 @@
+# Copyright (C) 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/>.
+
+# Return nul-terminated string read from section SECTION of EXEC. Return ""
+# if no such section or nul-terminated string was found. Function is useful
+# for sections ".interp" or ".gnu_debuglink".
+
+proc section_get {exec section} {
+ global objdir
+ global subdir
+ set tmp "${objdir}/${subdir}/section_get.tmp"
+ set objcopy_program [transform objcopy]
+
+ set command "exec $objcopy_program -O binary --set-section-flags $section=A --change-section-address $section=0 -j $section $exec $tmp"
+ verbose -log "command is $command"
+ set result [catch $command output]
+ verbose -log "result is $result"
+ verbose -log "output is $output"
+ if {$result == 1} {
+ return ""
+ }
+ set fi [open $tmp]
+ fconfigure $fi -translation binary
+ set data [read $fi]
+ close $fi
+ file delete $tmp
+ # .interp has size $len + 1 but .gnu_debuglink contains garbage after \000.
+ set len [string first \000 $data]
+ if {$len < 0} {
+ verbose -log "section $section not found"
+ return ""
+ }
+ set retval [string range $data 0 [expr $len - 1]]
+ verbose -log "section $section is <$retval>"
+ return $retval
+}
+
+# Resolve symlinks.
+
+proc symlink_resolve {file} {
+ set loop 0
+ while {[file type $file] == "link"} {
+ set target [file readlink $file]
+ if {[file pathtype $target] == "relative"} {
+ set src2 [file dirname $file]/$target
+ } else {
+ set src2 $target
+ }
+ verbose -log "Resolved symlink $file targetting $target as $src2"
+ set file $src2
+
+ set loop [expr $loop + 1]
+ if {$loop > 30} {
+ fail "Looping symlink resolution for $file"
+ return ""
+ }
+ }
+ return $file
+}
+
+# Copy SRC to DEST, resolving any symlinks in SRC. Return nonzero iff
+# the copy was succesful.
+#
+# This function is guaranteed to never raise any exception, even when the copy
+# fails.
+
+proc file_copy {src dest} {
+ set src [symlink_resolve $src]
+ # Test name would contain unstable directory name for symlink-unresolved
+ # $src.
+ set test "copy [file tail $src] to [file tail $dest]"
+ set command "file copy -force -- $src $dest"
+ verbose -log "command is $command"
+ if [catch $command] {
+ fail $test
+ return 0
+ } else {
+ pass $test
+ return 1
+ }
+}
+
+# Wrap function build_executable so that the resulting executable is fully
+# self-sufficient (without dependencies on system libraries). Parameter
+# INTERP may be used to specify a loader (ld.so) to be used that is
+# different from the default system one. Libraries on which the executable
+# depends are copied into directory DIR. Default DIR value to
+# `${objdir}/${subdir}/${EXECUTABLE}.d'.
+#
+# In case of success, return a string containing the arguments to be used
+# in order to perform a prelink of the executable obtained. Return the
+# empty string in case of failure.
+#
+# This can be useful when trying to prelink an executable which might
+# depend on system libraries. To properly prelink an executable, all
+# of its dynamically linked libraries must be prelinked as well. If
+# the executable depends on some system libraries, we may not have
+# sufficient write priviledges on these files to perform the prelink.
+# This is why we make a copy of these shared libraries, and link the
+# executable against these copies instead.
+#
+# Function recognizes only libraries listed by `ldd' after
+# its ` => ' separator. That means $INTERP and any libraries not being linked
+# with -Wl,-soname,NAME.so are not copied.
+
+proc build_executable_own_libs {testname executable sources options {interp ""} {dir ""}} {
+ global objdir subdir
+
+ if {[build_executable $testname $executable $sources $options] == -1} {
+ return ""
+ }
+ set binfile ${objdir}/${subdir}/${executable}
+
+ set command "ldd $binfile"
+ set test "ldd $executable"
+ set result [catch "exec $command" output]
+ verbose -log "result of $command is $result"
+ verbose -log "output of $command is $output"
+ if {$result != 0 || $output == ""} {
+ fail $test
+ } else {
+ pass $test
+ }
+
+ # gdb testsuite will put there also needless -lm.
+ set test "$test output contains libs"
+ set libs [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output]
+ if {[llength $libs] == 0} {
+ fail $test
+ } else {
+ pass $test
+ }
+
+ if {$dir == ""} {
+ set dir ${binfile}.d
+ }
+ file delete -force -- $dir
+ file mkdir $dir
+
+ if {$interp == ""} {
+ set interp_system [section_get $binfile .interp]
+ set interp ${dir}/[file tail $interp_system]
+ file_copy $interp_system $interp
+ }
+
+ set dests {}
+ foreach {trash abspath} $libs {
+ set dest "$dir/[file tail $abspath]"
+ file_copy $abspath $dest
+ lappend dests $dest
+ }
+
+ # Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s
+ # specified by the caller to be able to link it for ldd" above.
+ set options [linsert $options 0 "additional_flags=-Wl,--dynamic-linker,$interp,-rpath,$dir"]
+
+ if {[build_executable $testname $executable $sources $options] == -1} {
+ return ""
+ }
+
+ set prelink_args "--dynamic-linker=$interp --ld-library-path=$dir $binfile $interp [concat $dests]"
+ return $prelink_args
+}
+
+# Unprelink ARG. Reported test name can be specified by NAME. Return non-zero
+# on success, zero on failure.
+
+proc prelink_no {arg {name {}}} {
+ if {$name == ""} {
+ set name [file tail $arg]
+ }
+ set test "unprelink $name"
+ set command "exec /usr/sbin/prelink -uN $arg"
+ verbose -log "command is $command"
+ set result [catch $command output]
+ verbose -log "result is $result"
+ verbose -log "output is $output"
+ if {$result == 0 && $output == ""} {
+ verbose -log "$name has been now unprelinked"
+ set command "exec /usr/sbin/prelink -uN $arg"
+ verbose -log "command is $command"
+ set result [catch $command output]
+ verbose -log "result is $result"
+ verbose -log "output is $output"
+ }
+ # Last line does miss the trailing \n. There can be multiple such messages
+ # as ARG may list multiple files.
+ if {$result == 1 && [regexp {^(/usr/sbin/prelink[^\r\n]*: [^ ]* does not have .gnu.prelink_undo section\n?)*$} $output]} {
+ pass $test
+ return 1
+ } else {
+ fail $test
+ return 0
+ }
+}
+
+# Prelink ARG. Reported test name can be specified by NAME. Return non-zero
+# on success, zero on failure.
+
+proc prelink_yes {arg {name ""}} {
+ if {$name == ""} {
+ set name [file tail $arg]
+ }
+
+ # Try to unprelink it first so that, if it has been already prelinked
+ # before, we get a different address now, making the new result unaffected
+ # by any previous prelinking.
+ prelink_no $arg "$name pre-unprelink"
+
+ set test "prelink $name"
+
+ # `--no-exec-shield' is for i386, where prelink in the exec-shield mode is
+ # forced to push all the libraries tight together, in order to fit into
+ # the first two memory areas (either the ASCII Shield area or at least
+ # below the executable). If the prelink was performed in exec-shield
+ # mode, prelink could have no choice on how to randomize the single new
+ # unprelinked library address without wasting space in the first one/two
+ # memory areas. In such case prelink could place $ARG repeatedly at the
+ # same place and we could have false prelink results on
+ # gdb.base/prelink.exp and others. To prevent this from happening, we use
+ # the --no-exec-shield switch. This may have some consequences in terms
+ # of security, but we do not care in our case.
+
+ set command "exec /usr/sbin/prelink -qNR --no-exec-shield $arg"
+
+ verbose -log "command is $command"
+ set result [catch $command output]
+ verbose -log "result is $result"
+ verbose -log "output is $output"
+ if {$result == 0 && $output == ""} {
+ pass $test
+ return 1
+ } elseif {$result == 1 \
+ && [string match -nocase "*: Not enough room to add .dynamic entry" $output]} {
+ # Linker should have reserved some entries for prelink.
+ xfail $test
+ return 0
+ } else {
+ fail $test
+ return 0
+ }
+}