Commit | Line | Data |
---|---|---|
b8040f19 JK |
1 | # Copyright 2010 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. | |
06a6f270 | 17 | if { ![isnative] || [is_remote host] || ![istarget *-linux*] || [skip_shlib_tests]} { |
b8040f19 JK |
18 | continue |
19 | } | |
20 | ||
21 | set test "break-interp" | |
22 | set binprefix ${objdir}/${subdir}/${test} | |
23 | # Only to get the $interp_system name. | |
24 | set srcfile_test "start.c" | |
25 | set binfile_test ${test}-test | |
06a6f270 JK |
26 | set binfile_lib ${objdir}/${subdir}/${test}.so |
27 | set srcfile "${test}-main.c" | |
28 | set srcfile_lib "${test}-lib.c" | |
29 | ||
30 | if [get_compiler_info ${binfile_lib}] { | |
31 | return -1 | |
32 | } | |
33 | ||
34 | # Use -soname so that it is listed with " => " by ldd and this testcase makes | |
35 | # a copy of ${binfile_lib} for each prelink variant. | |
36 | ||
37 | if {[gdb_compile_shlib ${srcdir}/${subdir}/${srcfile_lib} ${binfile_lib} [list debug additional_flags=-Wl,-soname,${test}.so]] != ""} { | |
38 | return -1 | |
39 | } | |
40 | ||
b8040f19 JK |
41 | if {[build_executable ${test}.exp $binfile_test ${srcfile_test} {}] == -1} { |
42 | return -1 | |
43 | } | |
44 | ||
45 | # Return the interpreter filename string. | |
46 | # Return "" if no interpreter was found. | |
47 | proc section_get {exec section} { | |
48 | global objdir | |
49 | global subdir | |
50 | set tmp "${objdir}/${subdir}/break-interp.interp" | |
51 | set objcopy_program [transform objcopy] | |
52 | ||
53 | set command "exec $objcopy_program -O binary --set-section-flags $section=A --change-section-address $section=0 -j $section $exec $tmp" | |
54 | verbose -log "command is $command" | |
55 | set result [catch $command output] | |
56 | verbose -log "result is $result" | |
57 | verbose -log "output is $output" | |
58 | if {$result == 1} { | |
59 | return "" | |
60 | } | |
61 | set fi [open $tmp] | |
62 | fconfigure $fi -translation binary | |
63 | set data [read $fi] | |
64 | close $fi | |
65 | #file delete $tmp | |
66 | # .interp has size $len + 1 but .gnu_debuglink contains garbage after \000. | |
67 | set len [string first \000 $data] | |
68 | if {$len < 0} { | |
69 | verbose -log "section $section not found" | |
70 | return "" | |
71 | } | |
72 | set retval [string range $data 0 [expr $len - 1]] | |
73 | verbose -log "section $section is <$retval>" | |
74 | return $retval | |
75 | } | |
76 | ||
77 | # Note: The separate debug info file content build-id/crc32 are not verified | |
78 | # contrary to the GDB search algorithm skipping non-matching ones. | |
79 | proc system_debug_get {exec} { | |
80 | global debug_root | |
81 | ||
82 | set exec_build_id_debug [build_id_debug_filename_get $exec] | |
83 | set debug_base "[file tail $exec].debug" | |
84 | set exec_dir [file dirname $exec] | |
85 | ||
86 | # isfile returns 1 even for symlinks to files. | |
87 | set retval $debug_root/$exec_build_id_debug | |
88 | if [file isfile $retval] { | |
89 | return $retval | |
90 | } | |
91 | set retval $exec_dir/$debug_base | |
92 | if [file isfile $retval] { | |
93 | return $retval | |
94 | } | |
95 | set retval $exec_dir/.debug/$debug_base | |
96 | if [file isfile $retval] { | |
97 | return $retval | |
98 | } | |
99 | set retval $debug_root/$exec_dir/$debug_base | |
100 | if [file isfile $retval] { | |
101 | return $retval | |
102 | } | |
103 | return "" | |
104 | } | |
105 | ||
106 | gdb_exit | |
107 | gdb_start | |
108 | set debug_root "" | |
109 | set test "show debug-file-directory" | |
110 | gdb_test_multiple $test $test { | |
111 | -re "The directory where separate debug symbols are searched for is \"(.*)\".\r\n$gdb_prompt $" { | |
112 | set debug_root $expect_out(1,string) | |
113 | } | |
114 | } | |
115 | ||
116 | set interp_system [section_get ${objdir}/${subdir}/$binfile_test .interp] | |
117 | set interp_system_debug [system_debug_get $interp_system] | |
118 | verbose -log "$interp_system has debug $interp_system_debug" | |
119 | ||
120 | proc prelinkNO_run {arg} { | |
121 | set command "exec /usr/sbin/prelink -uN $arg" | |
122 | verbose -log "command is $command" | |
123 | set result [catch $command output] | |
124 | verbose -log "result is $result" | |
125 | verbose -log "output is $output" | |
126 | return [list $result $output] | |
127 | } | |
128 | ||
129 | proc prelinkNO {arg {name {}}} { | |
130 | if {$name == ""} { | |
131 | set name [file tail $arg] | |
132 | } | |
133 | set test "unprelink $name" | |
134 | set run [prelinkNO_run $arg] | |
135 | set result [lindex $run 0] | |
136 | set output [lindex $run 1] | |
137 | if {$result == 0 && $output == ""} { | |
138 | verbose -log "$name has been now unprelinked" | |
139 | set run [prelinkNO_run $arg] | |
140 | set result [lindex $run 0] | |
141 | set output [lindex $run 1] | |
142 | } | |
143 | # Last line does miss the trailing \n. | |
d7d158ed | 144 | if {$result == 1 && [regexp {^(/usr/sbin/prelink[^\r\n]*: [^ ]* does not have .gnu.prelink_undo section\n?)*$} $output]} { |
b8040f19 JK |
145 | pass $test |
146 | return 1 | |
147 | } else { | |
148 | fail $test | |
149 | return 0 | |
150 | } | |
151 | } | |
152 | ||
153 | proc prelinkYES {arg {name ""}} { | |
154 | if {$name == ""} { | |
155 | set name [file tail $arg] | |
156 | } | |
157 | set test "prelink $name" | |
158 | set command "exec /usr/sbin/prelink -qNR --no-exec-shield $arg" | |
159 | verbose -log "command is $command" | |
160 | set result [catch $command output] | |
161 | verbose -log "result is $result" | |
162 | verbose -log "output is $output" | |
163 | if {$result == 0 && $output == ""} { | |
164 | pass $test | |
165 | return 1 | |
37cc8bfe JK |
166 | } elseif {$result == 1 \ |
167 | && [string match -nocase "*: Not enough room to add .dynamic entry" $output]} { | |
168 | # Linker should have reserved some entries for prelink. | |
169 | xfail $test | |
170 | return 0 | |
b8040f19 JK |
171 | } else { |
172 | fail $test | |
173 | return 0 | |
174 | } | |
175 | } | |
176 | ||
177 | # Resolve symlinks. | |
178 | proc symlink_resolve {file} { | |
179 | set loop 0 | |
180 | while {[file type $file] == "link"} { | |
181 | set target [file readlink $file] | |
182 | if {[file pathtype $target] == "relative"} { | |
183 | set src2 [file dirname $file]/$target | |
184 | } else { | |
185 | set src2 $target | |
186 | } | |
187 | verbose -log "Resolved symlink $file targetting $target as $src2" | |
188 | set file $src2 | |
189 | ||
190 | set loop [expr $loop + 1] | |
191 | if {$loop > 30} { | |
192 | fail "Looping symlink resolution for $file" | |
193 | return "" | |
194 | } | |
195 | } | |
196 | return $file | |
197 | } | |
198 | ||
199 | proc copy {src dest} { | |
200 | set src [symlink_resolve $src] | |
201 | # Test name would contain build-id hash for symlink-unresolved $src. | |
202 | set test "copy [file tail $src] to [file tail $dest]" | |
203 | set command "file copy -force $src $dest" | |
204 | verbose -log "command is $command" | |
205 | if [catch $command] { | |
206 | fail $test | |
207 | return 0 | |
208 | } else { | |
209 | pass $test | |
210 | return 1 | |
211 | } | |
212 | } | |
213 | ||
214 | proc strip_debug {dest} { | |
215 | set test "strip [file tail $dest]" | |
216 | set strip_program [transform strip] | |
217 | set command "exec $strip_program --strip-debug $dest" | |
218 | verbose -log "command is $command" | |
219 | if [catch $command] { | |
220 | fail $test | |
221 | return 0 | |
222 | } else { | |
223 | pass $test | |
224 | return 1 | |
225 | } | |
226 | } | |
227 | ||
228 | # `runto' does not check we stopped really at the function we specified. | |
ccf26247 JK |
229 | # DISPLACEMENT can be "NONE", "ZERO" or "NONZERO" |
230 | proc reach {func command displacement} { | |
231 | global gdb_prompt expect_out | |
232 | ||
233 | global pf_prefix | |
234 | set old_ldprefix $pf_prefix | |
235 | lappend pf_prefix "reach-$func:" | |
b8040f19 JK |
236 | |
237 | if [gdb_breakpoint $func allow-pending] { | |
ccf26247 JK |
238 | set test "reach" |
239 | set test_displacement "seen displacement message as $displacement" | |
b8040f19 | 240 | gdb_test_multiple $command $test { |
ccf26247 JK |
241 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { |
242 | # Missing "$gdb_prompt $" is intentional. | |
243 | if {$expect_out(1,string) == "0x0"} { | |
244 | set case "ZERO" | |
245 | } else { | |
246 | set case "NONZERO" | |
247 | } | |
248 | if {$displacement == $case} { | |
249 | pass $test_displacement | |
250 | # Permit multiple such messages. | |
251 | set displacement "FOUND-$displacement" | |
252 | } elseif {$displacement != "FOUND-$case"} { | |
253 | fail $test_displacement | |
254 | } | |
255 | exp_continue | |
256 | } | |
b8040f19 JK |
257 | -re "Breakpoint \[0-9\]+, $func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" { |
258 | pass $test | |
259 | } | |
de6a0421 | 260 | -re "Breakpoint \[0-9\]+, \[0-9xa-f\]+ in $func \\(\\).*\r\n$gdb_prompt $" { |
b8040f19 JK |
261 | pass $test |
262 | } | |
263 | } | |
ccf26247 JK |
264 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { |
265 | fail $test_displacement | |
266 | } | |
b8040f19 | 267 | } |
ccf26247 JK |
268 | |
269 | set pf_prefix $old_ldprefix | |
b8040f19 JK |
270 | } |
271 | ||
ccf26247 JK |
272 | proc test_core {file displacement} { |
273 | global srcdir subdir gdb_prompt expect_out | |
61f0d762 | 274 | |
bbfba9ed | 275 | set corefile [core_find $file {} "segv"] |
61f0d762 JK |
276 | if {$corefile == ""} { |
277 | return | |
278 | } | |
279 | ||
ccf26247 JK |
280 | global pf_prefix |
281 | set old_ldprefix $pf_prefix | |
282 | lappend pf_prefix "core:" | |
283 | ||
61f0d762 JK |
284 | gdb_exit |
285 | gdb_start | |
286 | # Clear it to never find any separate debug infos in $debug_root. | |
27d3a1a2 MS |
287 | gdb_test_no_output "set debug-file-directory" \ |
288 | "set debug-file-directory for core" | |
61f0d762 JK |
289 | gdb_reinitialize_dir $srcdir/$subdir |
290 | gdb_load $file | |
291 | ||
ccf26247 | 292 | # Print the "PIE (Position Independent Executable) displacement" message. |
27d3a1a2 | 293 | gdb_test_no_output "set verbose on" |
ccf26247 JK |
294 | |
295 | set test "core loaded" | |
09248348 | 296 | set test_displacement "seen displacement message as $displacement" |
ccf26247 JK |
297 | gdb_test_multiple "core-file $corefile" $test { |
298 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { | |
299 | # Missing "$gdb_prompt $" is intentional. | |
300 | if {$expect_out(1,string) == "0x0"} { | |
301 | set case "ZERO" | |
302 | } else { | |
303 | set case "NONZERO" | |
304 | } | |
305 | if {$displacement == $case} { | |
306 | pass $test_displacement | |
307 | # Permit multiple such messages. | |
308 | set displacement "FOUND-$displacement" | |
309 | } elseif {$displacement != "FOUND-$case"} { | |
310 | fail $test_displacement | |
311 | } | |
312 | exp_continue | |
313 | } | |
314 | -re "Core was generated by .*\r\n#0 .*$gdb_prompt $" { | |
315 | # Do not check the binary filename as it may be truncated. | |
316 | pass $test | |
317 | } | |
318 | } | |
319 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { | |
320 | fail $test_displacement | |
321 | } | |
61f0d762 JK |
322 | |
323 | gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "core main bt" | |
ccf26247 JK |
324 | |
325 | set pf_prefix $old_ldprefix | |
61f0d762 JK |
326 | } |
327 | ||
ccf26247 JK |
328 | proc test_attach {file displacement} { |
329 | global board_info gdb_prompt expect_out | |
bbfba9ed JK |
330 | |
331 | gdb_exit | |
332 | ||
333 | set test "sleep function started" | |
334 | ||
335 | set command "${file} sleep" | |
336 | set res [remote_spawn host $command]; | |
337 | if { $res < 0 || $res == "" } { | |
338 | perror "Spawning $command failed." | |
339 | fail $test | |
340 | return | |
341 | } | |
342 | set pid [exp_pid -i $res] | |
343 | gdb_expect { | |
344 | -re "sleeping\r\n" { | |
345 | pass $test | |
346 | } | |
347 | eof { | |
348 | fail "$test (eof)" | |
349 | return | |
350 | } | |
351 | timeout { | |
352 | fail "$test (timeout)" | |
353 | return | |
354 | } | |
355 | } | |
356 | ||
ccf26247 JK |
357 | global pf_prefix |
358 | set old_ldprefix $pf_prefix | |
359 | lappend pf_prefix "attach:" | |
360 | ||
bbfba9ed JK |
361 | gdb_exit |
362 | gdb_start | |
ccf26247 JK |
363 | |
364 | # Print the "PIE (Position Independent Executable) displacement" message. | |
27d3a1a2 | 365 | gdb_test_no_output "set verbose on" |
ccf26247 JK |
366 | |
367 | set test "attach" | |
368 | gdb_test_multiple "attach $pid" $test { | |
369 | -re "Attaching to process $pid\r\n" { | |
370 | # Missing "$gdb_prompt $" is intentional. | |
371 | pass $test | |
372 | } | |
373 | } | |
374 | ||
375 | set test "attach final prompt" | |
09248348 | 376 | set test_displacement "seen displacement message as $displacement" |
ccf26247 JK |
377 | gdb_test_multiple "" $test { |
378 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { | |
379 | # Missing "$gdb_prompt $" is intentional. | |
380 | if {$expect_out(1,string) == "0x0"} { | |
381 | set case "ZERO" | |
382 | } else { | |
383 | set case "NONZERO" | |
384 | } | |
385 | if {$displacement == $case} { | |
386 | pass $test_displacement | |
387 | # Permit multiple such messages. | |
388 | set displacement "FOUND-$displacement" | |
389 | } elseif {$displacement != "FOUND-$case"} { | |
390 | fail $test_displacement | |
391 | } | |
392 | exp_continue | |
393 | } | |
394 | -re "$gdb_prompt $" { | |
395 | pass $test | |
396 | } | |
397 | } | |
398 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { | |
399 | fail $test_displacement | |
400 | } | |
401 | ||
bbfba9ed JK |
402 | gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "attach main bt" |
403 | gdb_exit | |
404 | ||
405 | remote_exec host "kill -9 $pid" | |
ccf26247 JK |
406 | |
407 | set pf_prefix $old_ldprefix | |
bbfba9ed JK |
408 | } |
409 | ||
ccf26247 JK |
410 | proc test_ld {file ifmain trynosym displacement} { |
411 | global srcdir subdir gdb_prompt expect_out | |
b8040f19 JK |
412 | |
413 | # First test normal `file'-command loaded $FILE with symbols. | |
414 | ||
415 | gdb_exit | |
416 | gdb_start | |
417 | # Clear it to never find any separate debug infos in $debug_root. | |
27d3a1a2 | 418 | gdb_test_no_output "set debug-file-directory" |
b8040f19 JK |
419 | gdb_reinitialize_dir $srcdir/$subdir |
420 | gdb_load $file | |
421 | ||
ccf26247 | 422 | # Print the "PIE (Position Independent Executable) displacement" message. |
27d3a1a2 | 423 | gdb_test_no_output "set verbose on" |
ccf26247 JK |
424 | |
425 | reach "dl_main" "run segv" $displacement | |
06a6f270 JK |
426 | |
427 | gdb_test "bt" "#0 +\[^\r\n\]*\\mdl_main\\M.*" "dl bt" | |
428 | ||
b8040f19 | 429 | if $ifmain { |
ccf26247 JK |
430 | # Displacement message will be printed the second time on initializing |
431 | # the linker from svr4_special_symbol_handling. If any ANOFFSET has | |
432 | # been already set as non-zero the detection will no longer be run. | |
433 | if {$displacement == "NONZERO"} { | |
434 | set displacement_main "NONE" | |
435 | } else { | |
436 | set displacement_main $displacement | |
437 | } | |
438 | reach "main" continue $displacement_main | |
06a6f270 | 439 | |
ccf26247 | 440 | reach "libfunc" continue "NONE" |
06a6f270 JK |
441 | |
442 | gdb_test "bt" "#0 +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#1 +\[^\r\n\]*\\mmain\\M.*" "main bt" | |
61f0d762 | 443 | |
ccf26247 | 444 | test_core $file $displacement |
bbfba9ed | 445 | |
ccf26247 | 446 | test_attach $file $displacement |
b8040f19 | 447 | } |
51bee8e9 JK |
448 | |
449 | if !$trynosym { | |
450 | return | |
451 | } | |
452 | ||
453 | global pf_prefix | |
454 | set old_ldprefix $pf_prefix | |
455 | lappend pf_prefix "symbol-less:" | |
456 | ||
457 | # Test also `exec-file'-command loaded $FILE - therefore without symbols. | |
458 | # SYMBOL_OBJFILE is not available and only EXEC_BFD must be used. | |
459 | ||
460 | gdb_exit | |
461 | gdb_start | |
462 | # Clear it to never find any separate debug infos in $debug_root. | |
27d3a1a2 | 463 | gdb_test_no_output "set debug-file-directory" |
51bee8e9 JK |
464 | gdb_reinitialize_dir $srcdir/$subdir |
465 | ||
ccf26247 | 466 | # Print the "PIE (Position Independent Executable) displacement" message. |
27d3a1a2 | 467 | gdb_test_no_output "set verbose on" |
ccf26247 | 468 | |
51bee8e9 JK |
469 | # Test no (error) message has been printed by `exec-file'. |
470 | set escapedfile [string_to_regexp $file] | |
471 | gdb_test "exec-file $file" "exec-file $escapedfile" "load" | |
472 | ||
473 | if $ifmain { | |
ccf26247 | 474 | reach "dl_main" run $displacement |
51bee8e9 JK |
475 | |
476 | set test "info files" | |
477 | set entrynohex "" | |
478 | gdb_test_multiple $test $test { | |
479 | -re "\r\n\[\t \]*Entry point:\[\t \]*0x(\[0-9a-f\]+)\r\n.*$gdb_prompt $" { | |
ccf26247 | 480 | set entrynohex $expect_out(1,string) |
51bee8e9 JK |
481 | pass $test |
482 | } | |
483 | } | |
484 | if {$entrynohex != ""} { | |
485 | gdb_test "break *0x$entrynohex" "" "break at entry point" | |
486 | gdb_test "continue" "\r\nBreakpoint \[0-9\]+, 0x0*$entrynohex in .*" "entry point reached" | |
487 | } | |
488 | } else { | |
489 | # There is no symbol to break at ld.so. Moreover it can exit with an | |
490 | # error code. | |
ccf26247 JK |
491 | |
492 | set test "ld.so exit" | |
09248348 | 493 | set test_displacement "seen displacement message as $displacement" |
ccf26247 JK |
494 | gdb_test_multiple "run" $test { |
495 | -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " { | |
496 | # Missing "$gdb_prompt $" is intentional. | |
497 | if {$expect_out(1,string) == "0x0"} { | |
498 | set case "ZERO" | |
499 | } else { | |
500 | set case "NONZERO" | |
501 | } | |
502 | if {$displacement == $case} { | |
503 | pass $test_displacement | |
504 | # Permit multiple such messages. | |
505 | set displacement "FOUND-$displacement" | |
506 | } elseif {$displacement != "FOUND-$case"} { | |
507 | fail $test_displacement | |
508 | } | |
509 | exp_continue | |
510 | } | |
511 | -re "Program exited (normally|with code \[0-9\]+)\\.\r\n$gdb_prompt $" { | |
512 | # Do not check the binary filename as it may be truncated. | |
513 | pass $test | |
514 | } | |
515 | } | |
516 | if ![regexp {^(NONE|FOUND-.*)$} $displacement] { | |
517 | fail $test_displacement | |
518 | } | |
51bee8e9 JK |
519 | } |
520 | ||
521 | set pf_prefix $old_ldprefix | |
b8040f19 JK |
522 | } |
523 | ||
524 | # Create separate binaries for each testcase - to make the possible reported | |
525 | # problem reproducible after the whole test run finishes. | |
526 | ||
527 | set old_ldprefix $pf_prefix | |
528 | foreach ldprelink {NO YES} { | |
529 | foreach ldsepdebug {NO IN SEP} { | |
530 | # Skip running the ldsepdebug test if we do not have system separate | |
531 | # debug info available. | |
532 | if {$interp_system_debug == "" && $ldsepdebug == "SEP"} { | |
533 | continue | |
534 | } | |
535 | ||
536 | set ldname "LDprelink${ldprelink}debug${ldsepdebug}" | |
537 | set interp $binprefix-$ldname | |
538 | ||
539 | # prelink needs to always prelink all the dependencies to do any file | |
540 | # modifications of its files. ld.so also needs all the dependencies to | |
541 | # be prelinked to omit the relocation process. In-memory file offsets | |
542 | # are not dependent whether ld.so went the prelink way or through the | |
543 | # relocation process. | |
544 | # | |
545 | # For GDB we are not interested whether prelink succeeds as it is | |
546 | # transparent to GDB. GDB is being tested for differences of file | |
547 | # offsets vs. in-memory offsets. So we have to prelink even ld.so for | |
548 | # the BIN modification to happen but we need to restore the original | |
549 | # possibly unprelinked ld.so to test all the combinations for GDB. | |
550 | set interp_saved ${interp}-saved | |
551 | ||
552 | set pf_prefix $old_ldprefix | |
553 | lappend pf_prefix "$ldname:" | |
554 | ||
555 | if {$ldsepdebug == "NO"} { | |
556 | copy $interp_system $interp | |
557 | # Never call strip-debug before unprelink: | |
558 | # prelink: ...: Section .note.gnu.build-id created after prelinking | |
559 | if ![prelinkNO $interp] { | |
560 | continue | |
561 | } | |
562 | strip_debug $interp | |
563 | } elseif {$ldsepdebug == "IN" && $interp_system_debug == ""} { | |
564 | copy $interp_system $interp | |
565 | } elseif {$ldsepdebug == "IN" && $interp_system_debug != ""} { | |
566 | copy $interp_system $interp | |
567 | copy $interp_system_debug "${interp}.debug" | |
568 | # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u | |
569 | if {![prelinkNO $interp] || ![prelinkNO "${interp}.debug"]} { | |
570 | continue | |
571 | } | |
572 | set test "eu-unstrip unprelinked:[file tail $interp_system] + [file tail $interp_system_debug] to [file tail $interp]" | |
573 | set command "exec eu-unstrip -o $interp $interp ${interp}.debug" | |
574 | verbose -log "command is $command" | |
575 | if [catch $command] { | |
576 | setup_xfail *-*-* | |
577 | fail $test | |
578 | continue | |
579 | } else { | |
580 | pass $test | |
581 | } | |
582 | } elseif {$ldsepdebug == "SEP" && $interp_system_debug == ""} { | |
583 | copy $interp_system $interp | |
584 | # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u | |
585 | if ![prelinkNO $interp] { | |
586 | continue | |
587 | } | |
588 | gdb_gnu_strip_debug $interp | |
589 | } elseif {$ldsepdebug == "SEP" && $interp_system_debug != ""} { | |
590 | copy $interp_system $interp | |
591 | copy $interp_system_debug "${interp}.debug" | |
592 | } | |
593 | ||
594 | if {$ldsepdebug == "SEP"} { | |
595 | if ![prelinkNO "${interp}.debug"] { | |
596 | continue | |
597 | } | |
598 | } else { | |
599 | file delete "${interp}.debug" | |
600 | } | |
601 | ||
602 | if ![prelink$ldprelink $interp] { | |
603 | continue | |
604 | } | |
ccf26247 JK |
605 | if {$ldprelink == "NO"} { |
606 | set displacement "NONZERO" | |
607 | } else { | |
608 | set displacement "ZERO" | |
609 | } | |
610 | test_ld $interp 0 [expr {$ldsepdebug == "NO"}] $displacement | |
b8040f19 JK |
611 | |
612 | if ![copy $interp $interp_saved] { | |
613 | continue | |
614 | } | |
615 | set old_binprefix $pf_prefix | |
616 | foreach binprelink {NO YES} { | |
617 | foreach binsepdebug {NO IN SEP} { | |
618 | foreach binpie {NO YES} { | |
619 | # This combination is not possible, non-PIE (fixed address) | |
620 | # binary cannot be prelinked to any (other) address. | |
621 | if {$binprelink == "YES" && $binpie == "NO"} { | |
622 | continue | |
623 | } | |
624 | ||
625 | set binname "BINprelink${binprelink}debug${binsepdebug}pie${binpie}" | |
626 | set exec $binprefix-$binname | |
627 | set dir ${exec}.d | |
628 | ||
629 | set pf_prefix $old_binprefix | |
630 | lappend pf_prefix "$binname:" | |
631 | ||
632 | set opts "additional_flags=-Wl,--dynamic-linker,$interp,-rpath,$dir" | |
06a6f270 | 633 | lappend opts "additional_flags=-Wl,$binfile_lib,-rpath,[file dirname $binfile_lib]" |
b8040f19 JK |
634 | if {$binsepdebug != "NO"} { |
635 | lappend opts {debug} | |
636 | } | |
637 | if {$binpie == "YES"} { | |
638 | lappend opts {additional_flags=-fPIE -pie} | |
639 | } | |
640 | if {[build_executable ${test}.exp [file tail $exec] $srcfile $opts] == -1} { | |
641 | continue; | |
642 | } | |
643 | if {$binsepdebug == "SEP"} { | |
644 | gdb_gnu_strip_debug $exec | |
b8040f19 JK |
645 | } |
646 | ||
647 | # Supply a self-sufficent directory $dir with the required | |
648 | # libraries. To make an executable properly prelinked all | |
649 | # its dependencies on libraries must be also prelinked. If | |
650 | # some of the system libraries is currently not prelinked | |
651 | # we have no right to prelink (modify it) at its current | |
652 | # system place. | |
653 | ||
654 | file delete -force $dir | |
655 | file mkdir $dir | |
656 | ||
657 | set command "ldd $exec" | |
40b27cdc | 658 | set test "ldd [file tail $exec]" |
b8040f19 JK |
659 | set result [catch "exec $command" output] |
660 | verbose -log "result of $command is $result" | |
661 | verbose -log "output of $command is $output" | |
662 | if {$result != 0 || $output == ""} { | |
40b27cdc | 663 | fail $test |
b8040f19 | 664 | } else { |
40b27cdc | 665 | pass $test |
b8040f19 JK |
666 | } |
667 | ||
668 | # gdb testsuite will put there also needless -lm. | |
40b27cdc | 669 | set test "$test output contains libc" |
b8040f19 JK |
670 | set libc [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output] |
671 | if {[llength $libc] == 0} { | |
672 | fail $test | |
673 | } else { | |
674 | pass $test | |
675 | } | |
676 | ||
677 | set dests {} | |
678 | for {set i 1} {$i < [llength $libc]} {incr i 2} { | |
679 | set abspath [lindex $libc $i] | |
680 | set dest "$dir/[file tail $abspath]" | |
681 | copy $abspath $dest | |
682 | lappend dests $dest | |
683 | } | |
684 | ||
40b27cdc | 685 | if {[prelink$binprelink "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]" [file tail $exec]] |
b8040f19 | 686 | && [copy $interp_saved $interp]} { |
ccf26247 JK |
687 | if {$binpie == "NO"} { |
688 | set displacement "NONE" | |
689 | } elseif {$binprelink == "NO"} { | |
690 | set displacement "NONZERO" | |
691 | } else { | |
692 | set displacement "ZERO" | |
693 | } | |
694 | test_ld $exec 1 [expr {$binsepdebug == "NO"}] $displacement | |
b8040f19 JK |
695 | } |
696 | } | |
697 | } | |
698 | } | |
699 | ||
700 | file delete $interp_saved | |
701 | } | |
702 | } | |
703 | set pf_prefix $old_ldprefix |