| 1 | # Copyright 2010-2013 Free Software Foundation, Inc. |
| 2 | |
| 3 | # This program is free software; you can redistribute it and/or modify |
| 4 | # it under the terms of the GNU General Public License as published by |
| 5 | # the Free Software Foundation; either version 3 of the License, or |
| 6 | # (at your option) any later version. |
| 7 | # |
| 8 | # This program is distributed in the hope that it will be useful, |
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | # GNU General Public License for more details. |
| 12 | # |
| 13 | # You should have received a copy of the GNU General Public License |
| 14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | |
| 16 | # This test only works on GNU/Linux. |
| 17 | if { ![isnative] || [is_remote host] || [target_info exists use_gdb_stub] |
| 18 | || ![istarget *-linux*] || [skip_shlib_tests]} { |
| 19 | continue |
| 20 | } |
| 21 | |
| 22 | load_lib prelink-support.exp |
| 23 | |
| 24 | set test "break-interp" |
| 25 | set binprefix [standard_output_file ${test}] |
| 26 | # Only to get the $interp_system name. |
| 27 | set srcfile_test "start.c" |
| 28 | set binfile_test ${test}-test |
| 29 | set binfile_lib ${binprefix}.so |
| 30 | set srcfile "${test}-main.c" |
| 31 | set srcfile_lib "${test}-lib.c" |
| 32 | |
| 33 | if [get_compiler_info] { |
| 34 | return -1 |
| 35 | } |
| 36 | |
| 37 | # Use -soname so that the new library gets copied by build_executable_own_libs. |
| 38 | |
| 39 | if {[gdb_compile_shlib ${srcdir}/${subdir}/${srcfile_lib} ${binfile_lib} [list debug ldflags=-Wl,-soname,${test}.so]] != ""} { |
| 40 | return -1 |
| 41 | } |
| 42 | |
| 43 | if {[build_executable ${test}.exp $binfile_test ${srcfile_test} {}] == -1} { |
| 44 | return -1 |
| 45 | } |
| 46 | |
| 47 | # Note: The separate debug info file content build-id/crc32 are not verified |
| 48 | # contrary to the GDB search algorithm skipping non-matching ones. |
| 49 | proc system_debug_get {exec} { |
| 50 | global debug_root |
| 51 | |
| 52 | set exec_build_id_debug [build_id_debug_filename_get $exec] |
| 53 | set debug_base "[file tail $exec].debug" |
| 54 | set exec_dir [file dirname $exec] |
| 55 | |
| 56 | # isfile returns 1 even for symlinks to files. |
| 57 | set retval $debug_root/$exec_build_id_debug |
| 58 | if [file isfile $retval] { |
| 59 | return $retval |
| 60 | } |
| 61 | set retval $exec_dir/$debug_base |
| 62 | if [file isfile $retval] { |
| 63 | return $retval |
| 64 | } |
| 65 | set retval $exec_dir/.debug/$debug_base |
| 66 | if [file isfile $retval] { |
| 67 | return $retval |
| 68 | } |
| 69 | set retval $debug_root/$exec_dir/$debug_base |
| 70 | if [file isfile $retval] { |
| 71 | return $retval |
| 72 | } |
| 73 | return "" |
| 74 | } |
| 75 | |
| 76 | gdb_exit |
| 77 | gdb_start |
| 78 | set debug_root "" |
| 79 | set test "show debug-file-directory" |
| 80 | gdb_test_multiple $test $test { |
| 81 | -re "The directory where separate debug symbols are searched for is \"(.*)\".\r\n$gdb_prompt $" { |
| 82 | set debug_root $expect_out(1,string) |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | set interp_system [section_get [standard_output_file $binfile_test] .interp] |
| 87 | set interp_system_debug [system_debug_get $interp_system] |
| 88 | verbose -log "$interp_system has debug $interp_system_debug" |
| 89 | |
| 90 | proc prelinkNO {arg {name ""}} { |
| 91 | return [prelink_no $arg $name] |
| 92 | } |
| 93 | |
| 94 | proc prelinkYES {arg {name ""}} { |
| 95 | return [prelink_yes $arg $name] |
| 96 | } |
| 97 | |
| 98 | proc strip_debug {dest} { |
| 99 | set test "strip [file tail $dest]" |
| 100 | set strip_program [transform strip] |
| 101 | set command "exec $strip_program --strip-debug $dest" |
| 102 | verbose -log "command is $command" |
| 103 | if [catch $command] { |
| 104 | fail $test |
| 105 | return 0 |
| 106 | } else { |
| 107 | pass $test |
| 108 | return 1 |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | # The marker function for the standard runtime linker interface is |
| 113 | # _dl_debug_state. The probes-based interface has no specific marker |
| 114 | # function; the probe we will stop on (init_start) is in dl_main so we |
| 115 | # check for that. |
| 116 | |
| 117 | set solib_bp {(_dl_debug_state|dl_main)} |
| 118 | |
| 119 | # Implementation of reach. |
| 120 | |
| 121 | proc reach_1 {func command displacement} { |
| 122 | global gdb_prompt expect_out solib_bp |
| 123 | |
| 124 | if {$func == $solib_bp} { |
| 125 | # Breakpoint on _dl_debug_state can have problems due to its overlap |
| 126 | # with the existing internal breakpoint from GDB. |
| 127 | gdb_test_no_output "set stop-on-solib-events 1" |
| 128 | } elseif {! [gdb_breakpoint $func allow-pending]} { |
| 129 | return |
| 130 | } |
| 131 | |
| 132 | set test "reach" |
| 133 | set test_displacement "seen displacement message as $displacement" |
| 134 | set debug_state_count 0 |
| 135 | gdb_test_multiple $command $test { |
| 136 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { |
| 137 | # Missing "$gdb_prompt $" is intentional. |
| 138 | if {$expect_out(1,string) == "0x0"} { |
| 139 | set case "ZERO" |
| 140 | } else { |
| 141 | set case "NONZERO" |
| 142 | } |
| 143 | if {$displacement == $case || $displacement == "PRESENT"} { |
| 144 | pass $test_displacement |
| 145 | set displacement "FOUND-$displacement" |
| 146 | } else { |
| 147 | fail $test_displacement |
| 148 | } |
| 149 | exp_continue |
| 150 | } |
| 151 | -re "Breakpoint \[0-9\]+, \\.?(__GI_)?$func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" { |
| 152 | if {$func == $solib_bp} { |
| 153 | fail $test |
| 154 | } else { |
| 155 | pass $test |
| 156 | } |
| 157 | } |
| 158 | -re "Breakpoint \[0-9\]+, \[0-9xa-f\]+ in \\.?(__GI_)?$func \\(\\).*\r\n$gdb_prompt $" { |
| 159 | if {$func == $solib_bp} { |
| 160 | fail $test |
| 161 | } else { |
| 162 | pass $test |
| 163 | } |
| 164 | } |
| 165 | -re "Stopped due to (spurious )?shared library event.*\r\n$gdb_prompt $" { |
| 166 | if {$func == $solib_bp} { |
| 167 | if {$debug_state_count == 0} { |
| 168 | # First stop does not yet relocate the _start function |
| 169 | # descriptor on ppc64. |
| 170 | set debug_state_count 1 |
| 171 | send_gdb "continue\n" |
| 172 | exp_continue |
| 173 | } else { |
| 174 | pass $test |
| 175 | } |
| 176 | } else { |
| 177 | fail $test |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { |
| 182 | fail $test_displacement |
| 183 | } |
| 184 | |
| 185 | if {$func == $solib_bp} { |
| 186 | gdb_test_no_output "set stop-on-solib-events 0" |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | # `runto' does not check we stopped really at the function we specified. |
| 191 | # DISPLACEMENT can be "NONE" for no message to be present, "ZERO" for |
| 192 | # displacement of 0 bytes to be present, "NONZERO" for displacement of non-0 |
| 193 | # bytes to be present and "PRESENT" if both "ZERO" and "NONZERO" are valid. |
| 194 | proc reach {func command displacement} { |
| 195 | with_test_prefix "reach-$func" { |
| 196 | reach_1 $func $command $displacement |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | proc test_core {file displacement} { |
| 201 | with_test_prefix "core" { |
| 202 | global srcdir subdir gdb_prompt expect_out |
| 203 | |
| 204 | set corefile [core_find $file {} "segv"] |
| 205 | if {$corefile == ""} { |
| 206 | return |
| 207 | } |
| 208 | |
| 209 | gdb_exit |
| 210 | gdb_start |
| 211 | # Clear it to never find any separate debug infos in $debug_root. |
| 212 | gdb_test_no_output "set debug-file-directory" \ |
| 213 | "set debug-file-directory for core" |
| 214 | gdb_reinitialize_dir $srcdir/$subdir |
| 215 | gdb_load $file |
| 216 | |
| 217 | # Print the "PIE (Position Independent Executable) displacement" message. |
| 218 | gdb_test_no_output "set verbose on" |
| 219 | |
| 220 | set test "core loaded" |
| 221 | set test_displacement "seen displacement message as $displacement" |
| 222 | gdb_test_multiple "core-file $corefile" $test { |
| 223 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { |
| 224 | # Missing "$gdb_prompt $" is intentional. |
| 225 | if {$expect_out(1,string) == "0x0"} { |
| 226 | set case "ZERO" |
| 227 | } else { |
| 228 | set case "NONZERO" |
| 229 | } |
| 230 | if {$displacement == $case || $displacement == "PRESENT"} { |
| 231 | pass $test_displacement |
| 232 | set displacement "FOUND-$displacement" |
| 233 | } else { |
| 234 | fail $test_displacement |
| 235 | } |
| 236 | exp_continue |
| 237 | } |
| 238 | -re "Core was generated by .*\r\n#0 .*$gdb_prompt $" { |
| 239 | # Do not check the binary filename as it may be truncated. |
| 240 | pass $test |
| 241 | } |
| 242 | } |
| 243 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { |
| 244 | fail $test_displacement |
| 245 | } |
| 246 | |
| 247 | gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "core main bt" |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | proc test_attach_gdb {file pid displacement prefix} { |
| 252 | with_test_prefix "$prefix" { |
| 253 | global gdb_prompt expect_out |
| 254 | |
| 255 | gdb_exit |
| 256 | gdb_start |
| 257 | |
| 258 | # Print the "PIE (Position Independent Executable) displacement" message. |
| 259 | gdb_test_no_output "set verbose on" |
| 260 | |
| 261 | gdb_test "file $file" "Reading symbols from .*done\\." "file" |
| 262 | |
| 263 | set test "attach" |
| 264 | gdb_test_multiple "attach $pid" $test { |
| 265 | -re "Attaching to (program: .*, )?process $pid\r\n" { |
| 266 | # Missing "$gdb_prompt $" is intentional. |
| 267 | pass $test |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | set test "attach final prompt" |
| 272 | set test_displacement "seen displacement message as $displacement" |
| 273 | gdb_test_multiple "" $test { |
| 274 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { |
| 275 | # Missing "$gdb_prompt $" is intentional. |
| 276 | if {$expect_out(1,string) == "0x0"} { |
| 277 | set case "ZERO" |
| 278 | } else { |
| 279 | set case "NONZERO" |
| 280 | } |
| 281 | if {$displacement == $case || $displacement == "PRESENT"} { |
| 282 | pass $test_displacement |
| 283 | set displacement "FOUND-$displacement" |
| 284 | } else { |
| 285 | fail $test_displacement |
| 286 | } |
| 287 | exp_continue |
| 288 | } |
| 289 | -re "$gdb_prompt $" { |
| 290 | pass $test |
| 291 | } |
| 292 | } |
| 293 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { |
| 294 | fail $test_displacement |
| 295 | } |
| 296 | |
| 297 | gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "attach main bt" |
| 298 | gdb_exit |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | proc test_attach {file displacement {relink_args ""}} { |
| 303 | global board_info |
| 304 | global exec |
| 305 | |
| 306 | gdb_exit |
| 307 | |
| 308 | set test "sleep function started" |
| 309 | |
| 310 | set command "${file} sleep" |
| 311 | set res [remote_spawn host $command] |
| 312 | if { $res < 0 || $res == "" } { |
| 313 | perror "Spawning $command failed." |
| 314 | fail $test |
| 315 | return |
| 316 | } |
| 317 | set pid [exp_pid -i $res] |
| 318 | gdb_expect { |
| 319 | -re "sleeping\r\n" { |
| 320 | pass $test |
| 321 | } |
| 322 | eof { |
| 323 | fail "$test (eof)" |
| 324 | return |
| 325 | } |
| 326 | timeout { |
| 327 | fail "$test (timeout)" |
| 328 | return |
| 329 | } |
| 330 | } |
| 331 | |
| 332 | if {$relink_args == ""} { |
| 333 | test_attach_gdb $exec $pid $displacement "attach" |
| 334 | } else { |
| 335 | # These could be rather passed as arguments. |
| 336 | global interp_saved interp |
| 337 | |
| 338 | foreach relink {YES NO} { |
| 339 | # Formerly this test was testing only prelinking of $EXEC. As the |
| 340 | # prelink command automatically prelinks all of $EXEC's libraries, |
| 341 | # even $INTERP got prelinked. Therefore, we formerly had to |
| 342 | # `[file_copy $interp_saved $interp]' to make $INTERP not affected |
| 343 | # by this prelinking of $EXEC. |
| 344 | # |
| 345 | # But now we need to test even prelinking of $INTERP. We could |
| 346 | # create a separate test to test just the $INTERP prelinking. For |
| 347 | # test simplicity, we merged this test and the test above by not |
| 348 | # restoring $INTERP after $EXEC prelink. $INTERP gets restored |
| 349 | # later below. |
| 350 | # |
| 351 | # `(wrong library or version mismatch?)' messages are printed for |
| 352 | # $binfile_lib on platforms converting REL->RELA relocations by |
| 353 | # prelink (such as on i386). There is no reliable way to verify |
| 354 | # the library file matches the running library in such case but |
| 355 | # GDB at least attempts to set the right displacement. We test |
| 356 | # `libfunc' is present in the backtrace and therefore the |
| 357 | # displacement has been guessed right. |
| 358 | |
| 359 | if [prelink$relink $relink_args [file tail $exec]] { |
| 360 | # /proc/PID/exe cannot be loaded as it is "EXECNAME (deleted)". |
| 361 | test_attach_gdb $exec $pid $displacement "attach-relink$relink" |
| 362 | } |
| 363 | } |
| 364 | file_copy $interp_saved $interp |
| 365 | } |
| 366 | |
| 367 | remote_exec host "kill -9 $pid" |
| 368 | } |
| 369 | |
| 370 | proc test_ld {file ifmain trynosym displacement} { |
| 371 | global srcdir subdir gdb_prompt expect_out inferior_exited_re solib_bp |
| 372 | |
| 373 | # First test normal `file'-command loaded $FILE with symbols. |
| 374 | |
| 375 | gdb_exit |
| 376 | gdb_start |
| 377 | # Clear it to never find any separate debug infos in $debug_root. |
| 378 | gdb_test_no_output "set debug-file-directory" |
| 379 | gdb_reinitialize_dir $srcdir/$subdir |
| 380 | gdb_load $file |
| 381 | |
| 382 | # Print the "PIE (Position Independent Executable) displacement" message. |
| 383 | gdb_test_no_output "set verbose on" |
| 384 | |
| 385 | # We want to test the re-run of a PIE in the case where the executable |
| 386 | # is loaded with a different displacement, but disable-randomization |
| 387 | # prevents that from happening. So turn it off. |
| 388 | gdb_test "set disable-randomization off" |
| 389 | |
| 390 | if $ifmain { |
| 391 | gdb_test_no_output "set args segv" |
| 392 | } else { |
| 393 | global binfile_test |
| 394 | |
| 395 | # ld.so needs some executable to run to reach _dl_debug_state. |
| 396 | gdb_test_no_output "set args [standard_output_file $binfile_test]" \ |
| 397 | "set args OBJDIR/${subdir}/$binfile_test" |
| 398 | } |
| 399 | |
| 400 | reach $solib_bp "run" $displacement |
| 401 | |
| 402 | gdb_test "bt" "#0 +\[^\r\n\]*\\m(__GI_)?$solib_bp\\M.*" "dl bt" |
| 403 | |
| 404 | if $ifmain { |
| 405 | reach "main" continue "NONE" |
| 406 | |
| 407 | reach "libfunc" continue "NONE" |
| 408 | |
| 409 | gdb_test "bt" "#0 +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#1 +\[^\r\n\]*\\mmain\\M.*" "main bt" |
| 410 | } |
| 411 | |
| 412 | # Try re-run if the new PIE displacement takes effect. |
| 413 | gdb_test "kill" "" "kill" {Kill the program being debugged\? \(y or n\) } "y" |
| 414 | reach $solib_bp "run" $displacement |
| 415 | |
| 416 | if $ifmain { |
| 417 | test_core $file $displacement |
| 418 | |
| 419 | test_attach $file $displacement |
| 420 | } |
| 421 | |
| 422 | if !$trynosym { |
| 423 | return |
| 424 | } |
| 425 | |
| 426 | with_test_prefix "symbol-less" { |
| 427 | # Test also `exec-file'-command loaded $FILE - therefore |
| 428 | # without symbols. SYMBOL_OBJFILE is not available and only |
| 429 | # EXEC_BFD must be used. |
| 430 | |
| 431 | gdb_exit |
| 432 | gdb_start |
| 433 | # Clear it to never find any separate debug infos in $debug_root. |
| 434 | gdb_test_no_output "set debug-file-directory" |
| 435 | gdb_reinitialize_dir $srcdir/$subdir |
| 436 | |
| 437 | # Print the "PIE (Position Independent Executable) |
| 438 | # displacement" message. |
| 439 | gdb_test_no_output "set verbose on" |
| 440 | |
| 441 | # Test no (error) message has been printed by `exec-file'. |
| 442 | set escapedfile [string_to_regexp $file] |
| 443 | gdb_test "exec-file $file" "exec-file $escapedfile" "load" |
| 444 | |
| 445 | if $ifmain { |
| 446 | reach $solib_bp run $displacement |
| 447 | |
| 448 | # Use two separate gdb_test_multiple statements to avoid timeouts due |
| 449 | # to slow processing of wildcard capturing long output |
| 450 | set test "info files" |
| 451 | set entrynohex "" |
| 452 | gdb_test_multiple $test $test { |
| 453 | -re "\r\n\[\t \]*Entry point:\[\t \]*0x(\[0-9a-f\]+)\r\n" { |
| 454 | set entrynohex $expect_out(1,string) |
| 455 | gdb_test_multiple "" $test { |
| 456 | -re "\r\n$gdb_prompt $" { |
| 457 | pass $test |
| 458 | } |
| 459 | } |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | # `info sym' cannot be tested for .opd as the binary may not have |
| 464 | # symbols. |
| 465 | if {[istarget powerpc64-*] && [is_lp64_target]} { |
| 466 | set test "convert entry point" |
| 467 | gdb_test_multiple "p *(void(*)(void) *) 0x$entrynohex" $test { |
| 468 | -re " =( \\(\[^0-9\]*\\))? 0x(\[0-9a-f\]+)( < \[^\r\n\]*)?\r\n$gdb_prompt $" { |
| 469 | set entrynohex $expect_out(2,string) |
| 470 | pass $test |
| 471 | } |
| 472 | } |
| 473 | } |
| 474 | if {$entrynohex != ""} { |
| 475 | gdb_test "break *0x$entrynohex" "" "break at entry point" |
| 476 | gdb_test "continue" "\r\nBreakpoint \[0-9\]+, 0x0*$entrynohex in .*" "entry point reached" |
| 477 | } |
| 478 | } else { |
| 479 | # There is no symbol to break at ld.so. Moreover it can |
| 480 | # exit with an error code. |
| 481 | |
| 482 | set test "ld.so exit" |
| 483 | set test_displacement "seen displacement message as $displacement" |
| 484 | gdb_test_multiple "run" $test { |
| 485 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { |
| 486 | # Missing "$gdb_prompt $" is intentional. |
| 487 | if {$expect_out(1,string) == "0x0"} { |
| 488 | set case "ZERO" |
| 489 | } else { |
| 490 | set case "NONZERO" |
| 491 | } |
| 492 | if {$displacement == $case || $displacement == "PRESENT"} { |
| 493 | pass $test_displacement |
| 494 | set displacement "FOUND-$displacement" |
| 495 | } else { |
| 496 | fail $test_displacement |
| 497 | } |
| 498 | exp_continue |
| 499 | } |
| 500 | -re "$inferior_exited_re (normally|with code \[0-9\]+).\r\n$gdb_prompt $" { |
| 501 | # Do not check the binary filename as it may be truncated. |
| 502 | pass $test |
| 503 | } |
| 504 | } |
| 505 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { |
| 506 | fail $test_displacement |
| 507 | } |
| 508 | } |
| 509 | } |
| 510 | } |
| 511 | |
| 512 | # Create separate binaries for each testcase - to make the possible reported |
| 513 | # problem reproducible after the whole test run finishes. |
| 514 | |
| 515 | foreach ldprelink {NO YES} { |
| 516 | foreach ldsepdebug {NO IN SEP} { |
| 517 | # Skip running the ldsepdebug test if we do not have system separate |
| 518 | # debug info available. |
| 519 | if {$interp_system_debug == "" && $ldsepdebug == "SEP"} { |
| 520 | continue |
| 521 | } |
| 522 | |
| 523 | set ldname "LDprelink${ldprelink}debug${ldsepdebug}" |
| 524 | set interp $binprefix-$ldname |
| 525 | |
| 526 | # prelink needs to always prelink all the dependencies to do any file |
| 527 | # modifications of its files. ld.so also needs all the dependencies to |
| 528 | # be prelinked to omit the relocation process. In-memory file offsets |
| 529 | # are not dependent whether ld.so went the prelink way or through the |
| 530 | # relocation process. |
| 531 | # |
| 532 | # For GDB we are not interested whether prelink succeeds as it is |
| 533 | # transparent to GDB. GDB is being tested for differences of file |
| 534 | # offsets vs. in-memory offsets. So we have to prelink even ld.so for |
| 535 | # the BIN modification to happen but we need to restore the original |
| 536 | # possibly unprelinked ld.so to test all the combinations for GDB. |
| 537 | set interp_saved ${interp}-saved |
| 538 | |
| 539 | with_test_prefix "$ldname" { |
| 540 | if {$ldsepdebug == "NO"} { |
| 541 | file_copy $interp_system $interp |
| 542 | # Never call strip-debug before unprelink: |
| 543 | # prelink: ...: Section .note.gnu.build-id created after prelinking |
| 544 | if ![prelinkNO $interp] { |
| 545 | continue |
| 546 | } |
| 547 | strip_debug $interp |
| 548 | } elseif {$ldsepdebug == "IN" && $interp_system_debug == ""} { |
| 549 | file_copy $interp_system $interp |
| 550 | } elseif {$ldsepdebug == "IN" && $interp_system_debug != ""} { |
| 551 | file_copy $interp_system $interp |
| 552 | file_copy $interp_system_debug "${interp}.debug" |
| 553 | # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u |
| 554 | if {![prelinkNO $interp] || ![prelinkNO "${interp}.debug"]} { |
| 555 | continue |
| 556 | } |
| 557 | set test "eu-unstrip unprelinked:[file tail $interp_system] + [file tail $interp_system_debug] to [file tail $interp]" |
| 558 | set command "exec eu-unstrip -o $interp $interp ${interp}.debug" |
| 559 | verbose -log "command is $command" |
| 560 | if [catch $command] { |
| 561 | setup_xfail *-*-* |
| 562 | fail $test |
| 563 | continue |
| 564 | } else { |
| 565 | pass $test |
| 566 | } |
| 567 | } elseif {$ldsepdebug == "SEP" && $interp_system_debug == ""} { |
| 568 | file_copy $interp_system $interp |
| 569 | # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u |
| 570 | if ![prelinkNO $interp] { |
| 571 | continue |
| 572 | } |
| 573 | gdb_gnu_strip_debug $interp |
| 574 | } elseif {$ldsepdebug == "SEP" && $interp_system_debug != ""} { |
| 575 | file_copy $interp_system $interp |
| 576 | file_copy $interp_system_debug "${interp}.debug" |
| 577 | } |
| 578 | |
| 579 | if {$ldsepdebug == "SEP"} { |
| 580 | if ![prelinkNO "${interp}.debug"] { |
| 581 | continue |
| 582 | } |
| 583 | } else { |
| 584 | file delete "${interp}.debug" |
| 585 | } |
| 586 | |
| 587 | if ![prelink$ldprelink $interp] { |
| 588 | continue |
| 589 | } |
| 590 | if {$ldprelink == "NO"} { |
| 591 | set displacement "NONZERO" |
| 592 | } else { |
| 593 | # x86* kernel loads prelinked PIE binary at its |
| 594 | # prelinked address but ppc* kernel loads it at a |
| 595 | # random address. prelink normally skips PIE binaries |
| 596 | # during the system scan. |
| 597 | set displacement "PRESENT" |
| 598 | } |
| 599 | test_ld $interp 0 [expr {$ldsepdebug == "NO"}] $displacement |
| 600 | |
| 601 | if ![file_copy $interp $interp_saved] { |
| 602 | continue |
| 603 | } |
| 604 | |
| 605 | foreach binprelink {NO YES} { |
| 606 | foreach binsepdebug {NO IN SEP} { |
| 607 | # "ATTACH" is like "YES" but it is modified during |
| 608 | # run. It cannot be used for problem |
| 609 | # reproducibility after the testcase ends. |
| 610 | foreach binpie {NO YES ATTACH} { |
| 611 | # This combination is not possible, non-PIE (fixed address) |
| 612 | # binary cannot be prelinked to any (other) address. |
| 613 | if {$binprelink == "YES" && $binpie == "NO"} { |
| 614 | continue |
| 615 | } |
| 616 | |
| 617 | set binname "BINprelink${binprelink}debug${binsepdebug}pie${binpie}" |
| 618 | set exec $binprefix-$binname |
| 619 | |
| 620 | with_test_prefix "$binname" { |
| 621 | set opts "ldflags=-Wl,$binfile_lib,-rpath,[file dirname $binfile_lib]" |
| 622 | if {$binsepdebug != "NO"} { |
| 623 | lappend opts {debug} |
| 624 | } |
| 625 | if {$binpie != "NO"} { |
| 626 | lappend opts {additional_flags=-fPIE -pie} |
| 627 | } |
| 628 | |
| 629 | set dir ${exec}.d |
| 630 | set relink_args [build_executable_own_libs ${test}.exp [file tail $exec] $srcfile $opts $interp $dir] |
| 631 | if {$relink_args == ""} { |
| 632 | continue |
| 633 | } |
| 634 | |
| 635 | if {$binsepdebug == "SEP"} { |
| 636 | gdb_gnu_strip_debug $exec |
| 637 | } |
| 638 | |
| 639 | if {$binpie == "NO"} { |
| 640 | set displacement "NONE" |
| 641 | } elseif {$binprelink == "NO"} { |
| 642 | set displacement "NONZERO" |
| 643 | } else { |
| 644 | # x86* kernel loads prelinked PIE binary at its prelinked |
| 645 | # address but ppc* kernel loads it at a random address. |
| 646 | # prelink normally skips PIE binaries during the system scan. |
| 647 | set displacement "PRESENT" |
| 648 | } |
| 649 | |
| 650 | if {[prelink$binprelink $relink_args [file tail $exec]] |
| 651 | && [file_copy $interp_saved $interp]} { |
| 652 | if {$binpie != "ATTACH"} { |
| 653 | test_ld $exec 1 [expr {$binsepdebug == "NO"}] $displacement |
| 654 | } else { |
| 655 | # If the file has been randomly prelinked it must be |
| 656 | # "NONZERO". We could see "ZERO" only if it was unprelinked |
| 657 | # and it is now running at the same address - which is 0 but |
| 658 | # executable can never run at address 0. |
| 659 | |
| 660 | set displacement "NONZERO" |
| 661 | test_attach $exec $displacement $relink_args |
| 662 | |
| 663 | # ATTACH means that executables and libraries have been |
| 664 | # modified after they have been run. They cannot be reused |
| 665 | # for problem reproducibility after the testcase ends in |
| 666 | # the ATTACH case. Therefore they are rather deleted not |
| 667 | # to confuse after the run finishes. |
| 668 | set exec_debug [system_debug_get $exec] |
| 669 | if {$exec_debug != ""} { |
| 670 | # `file delete [glob "${exec_debug}*"]' does not work. |
| 671 | foreach f [glob "${exec_debug}*"] { |
| 672 | file delete $f |
| 673 | } |
| 674 | } |
| 675 | file delete -force $dir |
| 676 | # `file delete [glob "${exec}*"]' does not work. |
| 677 | foreach f [glob "${exec}*"] { |
| 678 | file delete $f |
| 679 | } |
| 680 | } |
| 681 | } |
| 682 | } |
| 683 | } |
| 684 | } |
| 685 | } |
| 686 | |
| 687 | file delete $interp_saved |
| 688 | } |
| 689 | } |
| 690 | } |