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