gdb/
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.base / break-interp.exp
CommitLineData
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.
17if { ![isnative] || [is_remote host] || ![istarget *-linux*] } {
18 continue
19}
20
21set test "break-interp"
22set binprefix ${objdir}/${subdir}/${test}
23# Only to get the $interp_system name.
24set srcfile_test "start.c"
25set binfile_test ${test}-test
26set srcfile "start.c"
27if {[build_executable ${test}.exp $binfile_test ${srcfile_test} {}] == -1} {
28 return -1
29}
30
31# Return the interpreter filename string.
32# Return "" if no interpreter was found.
33proc section_get {exec section} {
34 global objdir
35 global subdir
36 set tmp "${objdir}/${subdir}/break-interp.interp"
37 set objcopy_program [transform objcopy]
38
39 set command "exec $objcopy_program -O binary --set-section-flags $section=A --change-section-address $section=0 -j $section $exec $tmp"
40 verbose -log "command is $command"
41 set result [catch $command output]
42 verbose -log "result is $result"
43 verbose -log "output is $output"
44 if {$result == 1} {
45 return ""
46 }
47 set fi [open $tmp]
48 fconfigure $fi -translation binary
49 set data [read $fi]
50 close $fi
51 #file delete $tmp
52 # .interp has size $len + 1 but .gnu_debuglink contains garbage after \000.
53 set len [string first \000 $data]
54 if {$len < 0} {
55 verbose -log "section $section not found"
56 return ""
57 }
58 set retval [string range $data 0 [expr $len - 1]]
59 verbose -log "section $section is <$retval>"
60 return $retval
61}
62
63# Note: The separate debug info file content build-id/crc32 are not verified
64# contrary to the GDB search algorithm skipping non-matching ones.
65proc system_debug_get {exec} {
66 global debug_root
67
68 set exec_build_id_debug [build_id_debug_filename_get $exec]
69 set debug_base "[file tail $exec].debug"
70 set exec_dir [file dirname $exec]
71
72 # isfile returns 1 even for symlinks to files.
73 set retval $debug_root/$exec_build_id_debug
74 if [file isfile $retval] {
75 return $retval
76 }
77 set retval $exec_dir/$debug_base
78 if [file isfile $retval] {
79 return $retval
80 }
81 set retval $exec_dir/.debug/$debug_base
82 if [file isfile $retval] {
83 return $retval
84 }
85 set retval $debug_root/$exec_dir/$debug_base
86 if [file isfile $retval] {
87 return $retval
88 }
89 return ""
90}
91
92gdb_exit
93gdb_start
94set debug_root ""
95set test "show debug-file-directory"
96gdb_test_multiple $test $test {
97 -re "The directory where separate debug symbols are searched for is \"(.*)\".\r\n$gdb_prompt $" {
98 set debug_root $expect_out(1,string)
99 }
100}
101
102set interp_system [section_get ${objdir}/${subdir}/$binfile_test .interp]
103set interp_system_debug [system_debug_get $interp_system]
104verbose -log "$interp_system has debug $interp_system_debug"
105
106proc prelinkNO_run {arg} {
107 set command "exec /usr/sbin/prelink -uN $arg"
108 verbose -log "command is $command"
109 set result [catch $command output]
110 verbose -log "result is $result"
111 verbose -log "output is $output"
112 return [list $result $output]
113}
114
115proc prelinkNO {arg {name {}}} {
116 if {$name == ""} {
117 set name [file tail $arg]
118 }
119 set test "unprelink $name"
120 set run [prelinkNO_run $arg]
121 set result [lindex $run 0]
122 set output [lindex $run 1]
123 if {$result == 0 && $output == ""} {
124 verbose -log "$name has been now unprelinked"
125 set run [prelinkNO_run $arg]
126 set result [lindex $run 0]
127 set output [lindex $run 1]
128 }
129 # Last line does miss the trailing \n.
130 if {$result == 1 && [regexp {^(/usr/sbin/prelink: [^ ]* does not have .gnu.prelink_undo section\n?)*$} $output]} {
131 pass $test
132 return 1
133 } else {
134 fail $test
135 return 0
136 }
137}
138
139proc prelinkYES {arg {name ""}} {
140 if {$name == ""} {
141 set name [file tail $arg]
142 }
143 set test "prelink $name"
144 set command "exec /usr/sbin/prelink -qNR --no-exec-shield $arg"
145 verbose -log "command is $command"
146 set result [catch $command output]
147 verbose -log "result is $result"
148 verbose -log "output is $output"
149 if {$result == 0 && $output == ""} {
150 pass $test
151 return 1
152 } else {
153 fail $test
154 return 0
155 }
156}
157
158# Resolve symlinks.
159proc symlink_resolve {file} {
160 set loop 0
161 while {[file type $file] == "link"} {
162 set target [file readlink $file]
163 if {[file pathtype $target] == "relative"} {
164 set src2 [file dirname $file]/$target
165 } else {
166 set src2 $target
167 }
168 verbose -log "Resolved symlink $file targetting $target as $src2"
169 set file $src2
170
171 set loop [expr $loop + 1]
172 if {$loop > 30} {
173 fail "Looping symlink resolution for $file"
174 return ""
175 }
176 }
177 return $file
178}
179
180proc copy {src dest} {
181 set src [symlink_resolve $src]
182 # Test name would contain build-id hash for symlink-unresolved $src.
183 set test "copy [file tail $src] to [file tail $dest]"
184 set command "file copy -force $src $dest"
185 verbose -log "command is $command"
186 if [catch $command] {
187 fail $test
188 return 0
189 } else {
190 pass $test
191 return 1
192 }
193}
194
195proc strip_debug {dest} {
196 set test "strip [file tail $dest]"
197 set strip_program [transform strip]
198 set command "exec $strip_program --strip-debug $dest"
199 verbose -log "command is $command"
200 if [catch $command] {
201 fail $test
202 return 0
203 } else {
204 pass $test
205 return 1
206 }
207}
208
209# `runto' does not check we stopped really at the function we specified.
210proc reach {func command} {
211 global gdb_prompt
212
213 if [gdb_breakpoint $func allow-pending] {
214 set test "reach $func"
215 gdb_test_multiple $command $test {
216 -re "Breakpoint \[0-9\]+, $func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" {
217 pass $test
218 }
219 -re "Breakpoint \[0-9\]+, \[0-9xa-f\]+ in $func \\(\\)( from .*)?\r\n$gdb_prompt $" {
220 pass $test
221 }
222 }
223 }
224}
225
226proc test_ld {file ifmain} {
227 global srcdir subdir gdb_prompt
228
229 # First test normal `file'-command loaded $FILE with symbols.
230
231 gdb_exit
232 gdb_start
233 # Clear it to never find any separate debug infos in $debug_root.
234 gdb_test "set debug-file-directory"
235 gdb_reinitialize_dir $srcdir/$subdir
236 gdb_load $file
237
238 reach "dl_main" run
239 if $ifmain {
240 reach "main" continue
241 }
242}
243
244# Create separate binaries for each testcase - to make the possible reported
245# problem reproducible after the whole test run finishes.
246
247set old_ldprefix $pf_prefix
248foreach ldprelink {NO YES} {
249 foreach ldsepdebug {NO IN SEP} {
250 # Skip running the ldsepdebug test if we do not have system separate
251 # debug info available.
252 if {$interp_system_debug == "" && $ldsepdebug == "SEP"} {
253 continue
254 }
255
256 set ldname "LDprelink${ldprelink}debug${ldsepdebug}"
257 set interp $binprefix-$ldname
258
259 # prelink needs to always prelink all the dependencies to do any file
260 # modifications of its files. ld.so also needs all the dependencies to
261 # be prelinked to omit the relocation process. In-memory file offsets
262 # are not dependent whether ld.so went the prelink way or through the
263 # relocation process.
264 #
265 # For GDB we are not interested whether prelink succeeds as it is
266 # transparent to GDB. GDB is being tested for differences of file
267 # offsets vs. in-memory offsets. So we have to prelink even ld.so for
268 # the BIN modification to happen but we need to restore the original
269 # possibly unprelinked ld.so to test all the combinations for GDB.
270 set interp_saved ${interp}-saved
271
272 set pf_prefix $old_ldprefix
273 lappend pf_prefix "$ldname:"
274
275 if {$ldsepdebug == "NO"} {
276 copy $interp_system $interp
277 # Never call strip-debug before unprelink:
278 # prelink: ...: Section .note.gnu.build-id created after prelinking
279 if ![prelinkNO $interp] {
280 continue
281 }
282 strip_debug $interp
283 } elseif {$ldsepdebug == "IN" && $interp_system_debug == ""} {
284 copy $interp_system $interp
285 } elseif {$ldsepdebug == "IN" && $interp_system_debug != ""} {
286 copy $interp_system $interp
287 copy $interp_system_debug "${interp}.debug"
288 # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u
289 if {![prelinkNO $interp] || ![prelinkNO "${interp}.debug"]} {
290 continue
291 }
292 set test "eu-unstrip unprelinked:[file tail $interp_system] + [file tail $interp_system_debug] to [file tail $interp]"
293 set command "exec eu-unstrip -o $interp $interp ${interp}.debug"
294 verbose -log "command is $command"
295 if [catch $command] {
296 setup_xfail *-*-*
297 fail $test
298 continue
299 } else {
300 pass $test
301 }
302 } elseif {$ldsepdebug == "SEP" && $interp_system_debug == ""} {
303 copy $interp_system $interp
304 # eu-unstrip: DWARF data in '...' not adjusted for prelinking bias; consider prelink -u
305 if ![prelinkNO $interp] {
306 continue
307 }
308 gdb_gnu_strip_debug $interp
309 } elseif {$ldsepdebug == "SEP" && $interp_system_debug != ""} {
310 copy $interp_system $interp
311 copy $interp_system_debug "${interp}.debug"
312 }
313
314 if {$ldsepdebug == "SEP"} {
315 if ![prelinkNO "${interp}.debug"] {
316 continue
317 }
318 } else {
319 file delete "${interp}.debug"
320 }
321
322 if ![prelink$ldprelink $interp] {
323 continue
324 }
325 test_ld $interp 0
326
327 if ![copy $interp $interp_saved] {
328 continue
329 }
330 set old_binprefix $pf_prefix
331 foreach binprelink {NO YES} {
332 foreach binsepdebug {NO IN SEP} {
333 foreach binpie {NO YES} {
334 # This combination is not possible, non-PIE (fixed address)
335 # binary cannot be prelinked to any (other) address.
336 if {$binprelink == "YES" && $binpie == "NO"} {
337 continue
338 }
339
340 set binname "BINprelink${binprelink}debug${binsepdebug}pie${binpie}"
341 set exec $binprefix-$binname
342 set dir ${exec}.d
343
344 set pf_prefix $old_binprefix
345 lappend pf_prefix "$binname:"
346
347 set opts "additional_flags=-Wl,--dynamic-linker,$interp,-rpath,$dir"
348 if {$binsepdebug != "NO"} {
349 lappend opts {debug}
350 }
351 if {$binpie == "YES"} {
352 lappend opts {additional_flags=-fPIE -pie}
353 }
354 if {[build_executable ${test}.exp [file tail $exec] $srcfile $opts] == -1} {
355 continue;
356 }
357 if {$binsepdebug == "SEP"} {
358 gdb_gnu_strip_debug $exec
359 # Just a sanity check. As gdb_gnu_strip_debug uses the
360 # "[file dirname $exec]/.debug/[file tail $exec].debug"
361 # variant delete the higher-priority exec.debug file.
362 file delete "$exec.debug"
363 }
364
365 # Supply a self-sufficent directory $dir with the required
366 # libraries. To make an executable properly prelinked all
367 # its dependencies on libraries must be also prelinked. If
368 # some of the system libraries is currently not prelinked
369 # we have no right to prelink (modify it) at its current
370 # system place.
371
372 file delete -force $dir
373 file mkdir $dir
374
375 set command "ldd $exec"
376 set result [catch "exec $command" output]
377 verbose -log "result of $command is $result"
378 verbose -log "output of $command is $output"
379 if {$result != 0 || $output == ""} {
380 fail $command
381 } else {
382 pass $command
383 }
384
385 # gdb testsuite will put there also needless -lm.
386 set test "$command output contains libc"
387 set libc [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output]
388 if {[llength $libc] == 0} {
389 fail $test
390 } else {
391 pass $test
392 }
393
394 set dests {}
395 for {set i 1} {$i < [llength $libc]} {incr i 2} {
396 set abspath [lindex $libc $i]
397 set dest "$dir/[file tail $abspath]"
398 copy $abspath $dest
399 lappend dests $dest
400 }
401
402 if {[prelink$binprelink "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]" $exec]
403 && [copy $interp_saved $interp]} {
404 test_ld $exec 1
405 }
406 }
407 }
408 }
409
410 file delete $interp_saved
411 }
412}
413set pf_prefix $old_ldprefix
This page took 0.037122 seconds and 4 git commands to generate.