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.
This commit is contained in:
parent
86e4bafc3b
commit
5e3b36f879
5 changed files with 338 additions and 225 deletions
|
@ -1,3 +1,33 @@
|
|||
2010-07-05 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Joel Brobecker <brobecker@adacore.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.
|
||||
|
||||
2010-07-05 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.base/attach-pie-misread.exp, gdb.base/attach-pie-misread.c: New.
|
||||
|
|
|
@ -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,10 @@ 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"
|
||||
|
||||
# For normal prelink (prelink_yes call), we need to supply $prelink_args.
|
||||
# For the prelink `-r' option below, $prelink_args is not required.
|
||||
# Moreover, if it was used, the problem would not longer be reproducible
|
||||
# as the libraries would also get relocated.
|
||||
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]
|
||||
|
|
|
@ -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.
|
||||
|
@ -31,8 +33,7 @@ if [get_compiler_info ${binfile_lib}] {
|
|||
return -1
|
||||
}
|
||||
|
||||
# Use -soname so that it is listed with " => " by ldd and this testcase makes
|
||||
# a copy of ${binfile_lib} for each prelink variant.
|
||||
# Use -soname so that the new library gets copied by build_executable_own_libs.
|
||||
|
||||
if {[gdb_compile_shlib ${srcdir}/${subdir}/${srcfile_lib} ${binfile_lib} [list debug additional_flags=-Wl,-soname,${test}.so]] != ""} {
|
||||
return -1
|
||||
|
@ -42,38 +43,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,104 +86,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
|
||||
} 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
|
||||
}
|
||||
}
|
||||
|
||||
# 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} {
|
||||
|
@ -425,8 +302,8 @@ proc test_attach {file displacement {relink_args ""}} {
|
|||
# Formerly this test was testing only prelinking of $EXEC. As the
|
||||
# prelink command automatically prelinks all of $EXEC's libraries,
|
||||
# even $INTERP got prelinked. Therefore, we formerly had to
|
||||
# `[copy $interp_saved $interp]' to make $INTERP not affected by
|
||||
# this prelinking of $EXEC.
|
||||
# `[file_copy $interp_saved $interp]' to make $INTERP not affected
|
||||
# by this prelinking of $EXEC.
|
||||
#
|
||||
# But now we need to test even prelinking of $INTERP. We could
|
||||
# create a separate test to test just the $INTERP prelinking. For
|
||||
|
@ -439,7 +316,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"
|
||||
|
@ -582,7 +459,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] {
|
||||
|
@ -590,10 +467,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
|
||||
|
@ -609,15 +486,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"} {
|
||||
|
@ -638,7 +515,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
|
||||
|
@ -656,64 +533,28 @@ 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 dir ${exec}.d
|
||||
set relink_args [build_executable_own_libs ${test}.exp [file tail $exec] $srcfile $opts $interp $dir]
|
||||
if {$relink_args == ""} {
|
||||
continue;
|
||||
}
|
||||
|
||||
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"} {
|
||||
|
@ -722,9 +563,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 {
|
||||
|
|
|
@ -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 the new library gets copied by build_executable_own_libs.
|
||||
|
||||
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"
|
||||
|
|
254
gdb/testsuite/lib/prelink-support.exp
Normal file
254
gdb/testsuite/lib/prelink-support.exp
Normal file
|
@ -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
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue