This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
ping: [patch 4/6] testsuite: Unify to lib/prelink-support.exp
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 9 Jun 2010 17:09:23 +0200
- Subject: ping: [patch 4/6] testsuite: Unify to lib/prelink-support.exp
- References: <20100329161753.GC2940@host0.dyn.jankratochvil.net>
Hi,
originally posted as:
[patch 4/6] testsuite: Unify to lib/prelink-support.exp
http://sourceware.org/ml/gdb-patches/2010-03/msg01002.html
Rediffed only.
------------------------------------------------------------------------------
when there are now two PIE/prelink related testcases (gdb.base/break-interp.exp
and gdb.base/attach-pie-misread.exp) there was some code duplicity. Unified it.
The gdb.base/prelink.exp part fixes a problem that default_target_compile
(either from dejagnu or from lib/ada.exp) currently always adds "-lm" making
the testcase dependent on whether the system libraries are already prelinked and being UNTESTED otherwise producing:
prelink: Could not set /lib64/libm-2.11.1.so owner or mode: Operation not permitted
Going to post an alternative fix of this problem for gdb.base/prelink.exp when
I had it accidentally already coded but I would prefer the variant attached
below - as it uses the same code as existing gdb.base/break-interp.exp and
gdb.base/attach-pie-misread.exp anyway). Moreover one can also follow that
testcases should represent real world cases where -nodefaultlibs is not in use
(OTOH the second opinion is that testcases should test only the absolutely
minimal artifically reproduced problem which would more match the use of
-nodefaultlibs).
gdb.base/prelink.exp [is_remote host] || [skip_shlib_tests] restrictions are
new but the code already has violated such cases.
No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu for the whole
patch series together.
Thanks,
Jan
gdb/testsuite/
2010-03-29 Jan Kratochvil <jan.kratochvil@redhat.com>
* 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.
--- a/gdb/testsuite/gdb.base/attach-pie-misread.exp
+++ b/gdb/testsuite/gdb.base/attach-pie-misread.exp
@@ -18,13 +18,15 @@ if { ![isnative] || [is_remote host] || ![istarget *-linux*] || [skip_shlib_test
continue
}
+load_lib prelink-support.exp
+
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} {
+if {[build_executable_own_libs ${test}.exp $executable $srcfile [list "additional_flags=-fPIE -pie"]] == ""} {
return -1
}
@@ -94,7 +96,8 @@ if {$result == 0} {
fail $test
}
-if {[build_executable ${test}.exp $executable $srcfile [list "additional_flags=-fPIE -pie -DGEN=\"$genfile\""]] == -1} {
+set prelink_args [build_executable_own_libs ${test}.exp $executable $srcfile [list "additional_flags=-fPIE -pie -DGEN=\"$genfile\""]]
+if {$prelink_args == ""} {
return -1
}
@@ -104,20 +107,8 @@ 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
+if ![prelink_yes $prelink_args] {
return -1
-} else {
- fail $test
}
set phdr [read_phdr $binfile "readelf with prelink -R"]
@@ -168,6 +159,8 @@ foreach align_mult {1 2} {
set shifted_offset [format 0x%x [expr "$first_offset - $align_mult * $align_max"]]
verbose -log "shifted_offset is $shifted_offset"
+ # $prelink_args are not need for "-r". Moreover it would relocated all the
+ # copied libraries making the problem no longer reproducible.
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]
--- a/gdb/testsuite/gdb.base/break-interp.exp
+++ b/gdb/testsuite/gdb.base/break-interp.exp
@@ -18,6 +18,8 @@ if { ![isnative] || [is_remote host] || ![istarget *-linux*] || [skip_shlib_test
continue
}
+load_lib prelink-support.exp
+
set test "break-interp"
set binprefix ${objdir}/${subdir}/${test}
# Only to get the $interp_system name.
@@ -42,38 +44,6 @@ if {[build_executable ${test}.exp $binfile_test ${srcfile_test} {}] == -1} {
return -1
}
-# Return the interpreter filename string.
-# Return "" if no interpreter was found.
-proc section_get {exec section} {
- global objdir
- global subdir
- set tmp "${objdir}/${subdir}/break-interp.interp"
- 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
-}
-
# Note: The separate debug info file content build-id/crc32 are not verified
# contrary to the GDB search algorithm skipping non-matching ones.
proc system_debug_get {exec} {
@@ -117,99 +87,12 @@ set interp_system [section_get ${objdir}/${subdir}/$binfile_test .interp]
set interp_system_debug [system_debug_get $interp_system]
verbose -log "$interp_system has debug $interp_system_debug"
-proc prelinkNO_run {arg} {
- 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"
- return [list $result $output]
-}
-
-proc prelinkNO {arg {name {}}} {
- if {$name == ""} {
- set name [file tail $arg]
- }
- set test "unprelink $name"
- set run [prelinkNO_run $arg]
- set result [lindex $run 0]
- set output [lindex $run 1]
- if {$result == 0 && $output == ""} {
- verbose -log "$name has been now unprelinked"
- set run [prelinkNO_run $arg]
- set result [lindex $run 0]
- set output [lindex $run 1]
- }
- # Last line does miss the trailing \n.
- 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
- }
+proc prelinkNO {arg {name ""}} {
+ return [prelink_no $arg $name]
}
proc prelinkYES {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 different address now and the result is not affected by the
- # previous $arg state..
- prelinkNO $arg "$name pre-unprelink"
-
- set test "prelink $name"
- 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
- } else {
- fail $test
- return 0
- }
-}
-
-# 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
-}
-
-proc copy {src dest} {
- set src [symlink_resolve $src]
- # Test name would contain build-id hash 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
- }
+ return [prelink_yes $arg $name]
}
proc strip_debug {dest} {
@@ -417,7 +300,7 @@ proc test_attach {file displacement {relink_args ""}} {
global exec interp_saved interp
foreach relink {YES NO} {
- # It would be more correct to also [copy $interp_saved $interp]
+ # It would be more correct to also [file_copy $interp_saved $interp]
# here to really test just different prelink of $exec.
# But we would need a separate test for different prelink of ld.so
# where a bug occured. It is now all merged into this single test.
@@ -426,7 +309,7 @@ proc test_attach {file displacement {relink_args ""}} {
test_attach_gdb $exec $pid $displacement "attach-relink$relink"
}
}
- copy $interp_saved $interp
+ file_copy $interp_saved $interp
}
remote_exec host "kill -9 $pid"
@@ -569,7 +452,7 @@ foreach ldprelink {NO YES} {
lappend pf_prefix "$ldname:"
if {$ldsepdebug == "NO"} {
- copy $interp_system $interp
+ file_copy $interp_system $interp
# Never call strip-debug before unprelink:
# prelink: ...: Section .note.gnu.build-id created after prelinking
if ![prelinkNO $interp] {
@@ -577,10 +460,10 @@ foreach ldprelink {NO YES} {
}
strip_debug $interp
} elseif {$ldsepdebug == "IN" && $interp_system_debug == ""} {
- copy $interp_system $interp
+ file_copy $interp_system $interp
} elseif {$ldsepdebug == "IN" && $interp_system_debug != ""} {
- copy $interp_system $interp
- copy $interp_system_debug "${interp}.debug"
+ file_copy $interp_system $interp
+ file_copy $interp_system_debug "${interp}.debug"
# eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u
if {![prelinkNO $interp] || ![prelinkNO "${interp}.debug"]} {
continue
@@ -596,15 +479,15 @@ foreach ldprelink {NO YES} {
pass $test
}
} elseif {$ldsepdebug == "SEP" && $interp_system_debug == ""} {
- copy $interp_system $interp
+ file_copy $interp_system $interp
# eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u
if ![prelinkNO $interp] {
continue
}
gdb_gnu_strip_debug $interp
} elseif {$ldsepdebug == "SEP" && $interp_system_debug != ""} {
- copy $interp_system $interp
- copy $interp_system_debug "${interp}.debug"
+ file_copy $interp_system $interp
+ file_copy $interp_system_debug "${interp}.debug"
}
if {$ldsepdebug == "SEP"} {
@@ -625,7 +508,7 @@ foreach ldprelink {NO YES} {
}
test_ld $interp 0 [expr {$ldsepdebug == "NO"}] $displacement
- if ![copy $interp $interp_saved] {
+ if ![file_copy $interp $interp_saved] {
continue
}
set old_binprefix $pf_prefix
@@ -643,64 +526,29 @@ foreach ldprelink {NO YES} {
set binname "BINprelink${binprelink}debug${binsepdebug}pie${binpie}"
set exec $binprefix-$binname
- set dir ${exec}.d
set pf_prefix $old_binprefix
lappend pf_prefix "$binname:"
- set opts "additional_flags=-Wl,--dynamic-linker,$interp,-rpath,$dir"
- lappend opts "additional_flags=-Wl,$binfile_lib,-rpath,[file dirname $binfile_lib]"
+ set opts "additional_flags=-Wl,$binfile_lib,-rpath,[file dirname $binfile_lib]"
if {$binsepdebug != "NO"} {
lappend opts {debug}
}
if {$binpie != "NO"} {
lappend opts {additional_flags=-fPIE -pie}
}
- if {[build_executable ${test}.exp [file tail $exec] $srcfile $opts] == -1} {
+
+ set relink_args [build_executable_own_libs ${test}.exp [file tail $exec] $srcfile $opts $interp]
+ if {$relink_args == ""} {
continue;
}
+ # This $dir is assumed in build_executable_own_libs.
+ set dir ${exec}.d
+
if {$binsepdebug == "SEP"} {
gdb_gnu_strip_debug $exec
}
- # Supply a self-sufficent directory $dir with the required
- # libraries. To make an executable properly prelinked all
- # its dependencies on libraries must be also prelinked. If
- # some of the system libraries is currently not prelinked
- # we have no right to prelink (modify it) at its current
- # system place.
-
- file delete -force $dir
- file mkdir $dir
-
- set command "ldd $exec"
- set test "ldd [file tail $exec]"
- 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 libc"
- set libc [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output]
- if {[llength $libc] == 0} {
- fail $test
- } else {
- pass $test
- }
-
- set dests {}
- for {set i 1} {$i < [llength $libc]} {incr i 2} {
- set abspath [lindex $libc $i]
- set dest "$dir/[file tail $abspath]"
- copy $abspath $dest
- lappend dests $dest
- }
-
if {$binpie == "NO"} {
set displacement "NONE"
} elseif {$binprelink == "NO"} {
@@ -709,9 +557,8 @@ foreach ldprelink {NO YES} {
set displacement "ZERO"
}
- set relink_args "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]"
if {[prelink$binprelink $relink_args [file tail $exec]]
- && [copy $interp_saved $interp]} {
+ && [file_copy $interp_saved $interp]} {
if {$binpie != "ATTACH"} {
test_ld $exec 1 [expr {$binsepdebug == "NO"}] $displacement
} else {
--- a/gdb/testsuite/gdb.base/prelink.exp
+++ b/gdb/testsuite/gdb.base/prelink.exp
@@ -23,8 +23,7 @@ if $tracelevel then {
}
-# are we on a target board
-if ![isnative] then {
+if { ![isnative] || [is_remote host] || [skip_shlib_tests]} {
return
}
@@ -36,32 +35,31 @@ if {$gcc_compiled == 0} {
return -1
}
+load_lib prelink-support.exp
+
set testfile "prelink"
set libsrcfile ${testfile}-lib.c
set libfile ${objdir}/${subdir}/${testfile}.so
-if { [gdb_compile "${srcdir}/${subdir}/${libsrcfile}" "${libfile}" executable [list debug "additional_flags=-fpic -shared -nodefaultlibs"]] != ""} {
+
+# Use -soname so that it is listed with " => " by ldd and this testcase makes
+# a copy of ${libfile} for each prelink variant.
+if { [gdb_compile_shlib "${srcdir}/${subdir}/${libsrcfile}" "${libfile}" [list debug "additional_flags=-Wl,-soname,[file tail ${libfile}]"]] != ""} {
# If creating the shared library fails, maybe we don't have the right tools
return -1
}
-# `--no-exec-shield' is for i386 where prelink in the exec-shield mode is
-# forced to push all the libraries tight together to fit into the first two
-# memory areas (either the ASCII Shield area or at least below the executable).
-# In this case its -R option cannot be applied and we falsely FAIL here as if
-# the system is already prelinked prelink has no choice how to randomize the
-# single new unprelinked library address without wasting the first one/two
-# memory areas. We do not care of the efficiency of loading such resulting
-# exec-shield unfriendly prelinked library.
-if {[catch "system \"prelink -qNR --no-exec-shield ${libfile}\""] != 0} {
- # Maybe we don't have prelink.
+set srcfile ${testfile}.c
+set executable ${testfile}t
+set binfile ${objdir}/${subdir}/${executable}
+set prelink_args [build_executable_own_libs ${testfile}.exp $executable $srcfile [list debug "additional_flags=-Wl,${libfile},-rpath,[file dirname ${libfile}]"]]
+if {$prelink_args == ""} {
return -1
}
-set srcfile ${testfile}.c
-set binfile ${objdir}/${subdir}/${testfile}t
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${libfile}" "${binfile}" executable [list debug "additional_flags=-Wl,-rpath,${objdir}/${subdir}"]] != ""} {
- return -1;
+if ![prelink_yes $prelink_args] {
+ # Maybe we don't have prelink.
+ return -1
}
set found 0
@@ -94,20 +92,16 @@ if { $found == 0 } {
return 0
}
-if {[catch "system \"prelink -uN ${libfile}\""] != 0} {
- untested "${testfile}.so was not prelinked, maybe system libraries are not prelinked?"
- return 0
+# Relink $libfile to a different address.
+if ![prelink_yes $prelink_args] {
+ return -1
}
-catch "system \"prelink -qNR --no-exec-shield ${libfile}\""
# Start with a fresh gdb
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
+clean_restart $executable
# Print the "adjusting expectations" message.
gdb_test_no_output "set verbose on"
-gdb_test "core-file $objdir/$subdir/prelink.core" {Using PIC \(Position Independent Code\) prelink displacement.*} "prelink"
+gdb_test "core-file $objdir/$subdir/prelink.core" "Using PIC \\(Position Independent Code\\) prelink displacement 0x\[^0\]\[0-9a-f\]* for \[^\r\n\]*[file tail ${libfile}].*" "seen displacement message"
--- /dev/null
+++ b/gdb/testsuite/lib/prelink-support.exp
@@ -0,0 +1,226 @@
+# 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 0 byte terminated string read from section SECTION of EXEC. Return ""
+# if no such section or 0 byte terminated string was found. Function is useful
+# for section ".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 of SRC. Protect script being aborted
+# if the copy fails. Return non-zero on success, zero on failure.
+
+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. The reason is that
+# making an executable properly prelinked requires all its dynamically linked
+# libraries must be also prelinked. If some of the system libraries is
+# currently not prelinked we may have no right to prelink (modify it) at its
+# current system place. Parameter INTERP may specify different ld.so to use
+# than the default system one. Libraries are copied into directory
+# `${objdir}/${subdir}/${executable}.d'.
+
+proc build_executable_own_libs {testname executable sources options {interp ""}} {
+ 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
+ }
+
+ 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 different address now and the result is not affected by the
+ # previous $arg state..
+ 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 to fit into the first two
+ # memory areas (either the ASCII Shield area or at least below the executable).
+ # In this case its -R option cannot be applied and we falsely FAIL here as if
+ # the system is already prelinked prelink has no choice how to randomize the
+ # single new unprelinked library address without wasting the first one/two
+ # memory areas. We do not care of the efficiency of loading such resulting
+ # exec-shield unfriendly prelinked library.
+ 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
+ } else {
+ fail $test
+ return 0
+ }
+}