]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/testsuite/lib/binutils-common.exp
Emit a warning when -z relro is unsupported
[thirdparty/binutils-gdb.git] / binutils / testsuite / lib / binutils-common.exp
CommitLineData
b3adc24a 1# Copyright (C) 1993-2020 Free Software Foundation, Inc.
f3097f33
RS
2#
3# This file is part of the GNU Binutils.
4#
5# This file is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18# MA 02110-1301, USA.
19
20# True if the object format is known to be ELF.
21#
22proc is_elf_format {} {
b3066ae8
AM
23 # config.sub for these targets curiously transforms a target doublet
24 # ending in -elf to -none. eg. m68hc12-elf to m68hc12-unknown-none
25 # They are always elf.
7b4ae824 26 if { [istarget m68hc1*-*] || [istarget s12z*-*] || [istarget xgate-*] } {
b3066ae8
AM
27 return 1;
28 }
679ca975
AM
29# vxworks (and windiss) excluded due to number of ELF tests that need
30# modifying to pass on those targets.
31# && ![istarget *-*-vxworks*]
32# && ![istarget *-*-windiss*]
b3066ae8 33
679ca975
AM
34 if { ![istarget *-*-chorus*]
35 && ![istarget *-*-cloudabi*]
36 && ![istarget *-*-eabi*]
37 && ![istarget *-*-*elf*]
38 && ![istarget *-*-*freebsd*]
39 && ![istarget *-*-fuchsia*]
f3097f33 40 && ![istarget *-*-gnu*]
f3097f33
RS
41 && ![istarget *-*-irix5*]
42 && ![istarget *-*-irix6*]
679ca975
AM
43 && ![istarget *-*-kaos*]
44 && ![istarget *-*-*linux*]
c43b2c54 45 && ![istarget *-*-lynxos*]
4a85cc09 46 && ![istarget *-*-nacl*]
f3097f33 47 && ![istarget *-*-netbsd*]
679ca975 48 && ![istarget *-*-nto*]
f3097f33 49 && ![istarget *-*-openbsd*]
4a85cc09
SKS
50 && ![istarget *-*-rtems*]
51 && ![istarget *-*-solaris2*]
52 && ![istarget *-*-sysv4*]
53 && ![istarget *-*-unixware*]
f96bd6c2 54 && ![istarget *-*-wasm32*]
4a85cc09 55 && ![istarget avr-*-*]
4a85cc09 56 && ![istarget hppa*64*-*-hpux*]
679ca975 57 && ![istarget ia64-*-hpux*] } {
f3097f33
RS
58 return 0
59 }
60
c65c21e1
AM
61 if { [istarget *-*-linux*ecoff*]
62 || [istarget *-*-rtemscoff*] } {
f3097f33
RS
63 return 0
64 }
65
66 if { ![istarget *-*-netbsdelf*]
c65c21e1 67 && ( [istarget vax-*-netbsd*]
f3097f33
RS
68 || [istarget ns32k-*-netbsd*]) } {
69 return 0
70 }
71
4a85cc09 72 if { [istarget arm-*-openbsd*]
f3097f33 73 || [istarget ns32k-*-openbsd*]
f3097f33
RS
74 || [istarget vax-*-openbsd*] } {
75 return 0
76 }
77
78 return 1
79}
80
81# True if the object format is known to be a.out.
82#
83proc is_aout_format {} {
c65c21e1 84 if { [istarget *-*-*aout*]
f3097f33
RS
85 || [istarget *-*-bsd*]
86 || [istarget *-*-msdos*]
f3097f33
RS
87 || [istarget ns32k-*-*]
88 || [istarget pdp11-*-*]
f3097f33
RS
89 || [istarget vax-*-netbsd] } {
90 return 1
91 }
92 return 0
93}
94
95# True if the object format is known to be PE COFF.
96#
97proc is_pecoff_format {} {
5b537ffc
AM
98 if { [istarget *-*-beospe*]
99 || [istarget *-*-cegcc*]
100 || [istarget *-*-cygwin*]
101 || [istarget *-*-interix*]
102 || [istarget *-*-mingw*]
103 || [istarget *-*-netbsdpe*]
104 || [istarget *-*-pe*]
105 || [istarget *-*-winnt*] } {
106 return 1
f3097f33 107 }
5b537ffc 108 return 0
f3097f33
RS
109}
110
0b1352e0
AM
111proc is_som_format {} {
112 if { ![istarget hppa*-*-*] || [istarget hppa*64*-*-*] } {
113 return 0;
114 }
115 if { [istarget *-*-osf*] \
116 || [istarget {*-*-h[ip]ux*}] \
117 || [istarget *-*-mpeix*] \
118 || [istarget *-*-bsd*] } {
119 return 1;
120 }
121 return 0;
122}
123
f3097f33
RS
124# True if the object format is known to be 64-bit ELF.
125#
126proc is_elf64 { binary_file } {
127 global READELF
128 global READELFFLAGS
129
506b86a4 130 set tmpfile [file dirname $binary_file]/readelf.out
f3097f33 131 set readelf_size ""
506b86a4 132 catch "exec $READELF $READELFFLAGS -h $binary_file > $tmpfile" got
f3097f33
RS
133
134 if ![string match "" $got] then {
135 return 0
136 }
137
138 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
506b86a4 139 [file_contents $tmpfile] nil readelf_size] } {
f3097f33
RS
140 return 0
141 }
142
143 if { $readelf_size == "64" } {
144 return 1
145 }
146
147 return 0
148}
eb22018c 149
506b86a4
AM
150# True if the object format is known to use RELA relocations.
151#
152proc is_rela { binary_file } {
153 global READELF
154 global READELFFLAGS
155
156 set tmpfile [file dirname $binary_file]/readelf.out
157 catch "exec $READELF $READELFFLAGS -S $binary_file > $tmpfile" got
158
159 if ![string match "" $got] then {
160 return 0
161 }
162
163 if { ![regexp "RELA" [file_contents $tmpfile]] } {
164 return 0
165 }
166
167 return 1
168}
169
6d9dabbb
MR
170# True if the target matches TARGET, specified as a TCL procedure if
171# in square brackets or as machine triplet otherwise.
172#
173proc match_target { target } {
02e0be69 174 if [regexp {^!?\[.*\]$} $target] {
6d9dabbb
MR
175 return $target
176 } else {
177 return [istarget $target]
178 }
179}
180
02e0be69
AM
181# True if the ELF target supports setting the ELF header OSABI field
182# to ELFOSABI_GNU or ELFOSABI_FREEBSD, a requirement for STT_GNU_IFUNC
183# symbol and SHF_GNU_MBIND section support.
a43942db
MR
184#
185# This generally depends on the target OS only, however there are a
186# number of exceptions for bare metal targets as follows. The MSP430
02e0be69
AM
187# and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise
188# non-EABI ARM targets set OSABI to ELFOSABI_ARM
a43942db 189#
02e0be69
AM
190# Note that some TI C6X targets use ELFOSABI_C6000_* but one doesn't,
191# so we don't try to sort out tic6x here. (The effect is that linker
192# testcases will generally need to exclude tic6x or use a -m option.)
193#
194proc supports_gnu_osabi {} {
a43942db
MR
195 if { [istarget *-*-gnu*]
196 || [istarget *-*-linux*]
02e0be69
AM
197 || [istarget *-*-nacl*]
198 || ( [istarget *-*-*bsd*] && ![istarget arm*-*-netbsd*] )
199 || [istarget *-*-symbianelf]
200 || [istarget *-*-lynxos]
201 || ( [istarget *-*-nto*] && ![istarget arm*-*-*] )
202 || [istarget *-*-irix*]
203 || [istarget *-*-*eabi*]
bb897477 204 || [istarget *-*-rtems*] } {
a43942db
MR
205 return 1
206 }
f96bd6c2
PC
207 if { [istarget "wasm32*-*-*"] } {
208 return 1
209 }
a43942db
MR
210 if { ![istarget "*-*-elf*"] } {
211 return 0
212 }
213 if { [istarget "arm*-*-*"]
214 || [istarget "msp430-*-*"]
a43942db
MR
215 || [istarget "visium-*-*"] } {
216 return 0
217 }
02e0be69
AM
218 return 1
219}
220
221# Return true if target uses the generic_link_hash_table linker.
222proc is_generic { } {
223 if { [istarget "d30v-*-*"]
a43942db 224 || [istarget "dlx-*-*"]
be570f06 225 || [istarget "pj*-*-*"]
6ff185b8 226 || [istarget "s12z-*-*"]
be570f06 227 || [istarget "xgate-*-*"] } {
02e0be69
AM
228 return 1
229 }
230 return 0
231}
232
233# True if the ELF target supports STB_GNU_UNIQUE.
234#
235# This require ELFOSABI_GNU, and `bfd_elf_final_link'.
236#
237proc supports_gnu_unique {} {
238 if { [istarget *-*-freebsd*] } {
a43942db
MR
239 return 0
240 }
02e0be69
AM
241 if { [supports_gnu_osabi] && ![is_generic] } {
242 return 1
243 }
244 return 0
a43942db
MR
245}
246
9cc0123f
AM
247# True for targets that do not sort .symtab as per the ELF standard.
248# ie. any that have mips_elf32_be_vec, mips_elf32_le_vec,
249# mips_elf32_n_be_vec or mips_elf32_n_le_vec as the primary bfd target
250# vector in config.bfd. When syncing with config.bfd, don't forget that
251# earlier case-matches trump later ones.
252proc is_bad_symtab {} {
253 if { ![istarget "mips*-*-*"] } {
254 return 0;
255 }
256 if { [istarget "*-*-chorus*"]
257 || [istarget "*-*-irix5*"]
258 || [istarget "*-*-irix6*"]
259 || [istarget "*-*-none"]
260 || [istarget "*-*-rtems*"]
261 || [istarget "*-*-windiss"] } {
262 return 1;
263 }
264 if { [istarget "*-*-elf*"]
265 && ![istarget "*-sde-*"]
266 && ![istarget "*-mti-*"]
267 && ![istarget "*-img-*"] } {
268 return 1;
269 }
270 if { [istarget "*-*-openbsd*"]
271 && ![istarget "mips64*-*-*"] } {
272 return 1;
273 }
274 return 0;
275}
276
33ea299c
TP
277# Returns true if -shared is supported on the target
278
279proc check_shared_lib_support { } {
280 global shared_available_saved
281 global ld
282
283 if {![info exists shared_available_saved]} {
284 set ld_output [remote_exec host $ld "-shared"]
285 if { [ string first "not supported" $ld_output ] >= 0 } {
286 set shared_available_saved 0
287 } else {
288 set shared_available_saved 1
289 }
290 }
291 return $shared_available_saved
292}
293
8a8a1171
NC
294# Returns true if -pie is supported on the target
295
296proc check_pie_support { } {
297 global pie_available_saved
298 global ld
299
300 if {![info exists pie_available_saved]} {
301 set ld_output [remote_exec host $ld "-pie"]
302 if { [ string first "not supported" $ld_output ] >= 0 } {
303 set pie_available_saved 0
304 } else {
305 set pie_available_saved 1
306 }
307 }
308 return $pie_available_saved
309}
310
5fd104ad
AM
311proc check_relro_support { } {
312 global relro_available_saved
313 global ld
314
315 if {![info exists relro_available_saved]} {
316 remote_file host delete norelro
317 set ld_output [remote_exec host $ld "-z norelro"]
318 if { [string first "not supported" $ld_output] >= 0
319 || [string first "unrecognized option" $ld_output] >= 0
320 || [string first "-z norelro ignored" $ld_output] >= 0
321 || [string first "cannot find norelro" $ld_output] >= 0 } {
322 set relro_available_saved 0
323 } else {
324 set relro_available_saved 1
325 }
326 }
327 return $relro_available_saved
328}
329
eb22018c
RS
330# Compare two files line-by-line. FILE_1 is the actual output and FILE_2
331# is the expected output. Ignore blank lines in either file.
332#
333# FILE_2 is a series of regexps, comments and # directives. The directives
334# are:
335#
336# #pass
337# Treat the test as a PASS if everything up till this point has
338# matched. Ignore any remaining lines in either FILE_1 or FILE_2.
339#
340# #failif
341# Reverse the sense of the test: expect differences to exist.
342#
343# #...
344# REGEXP
345# Skip all lines in FILE_1 until the first that matches REGEXP.
346#
bc754168
AM
347# #?REGEXP
348# Optionally match REGEXP against line from FILE_1. If the REGEXP
349# does not match then the next line from FILE_2 is tried.
350#
738f4d98
MR
351# Other # lines are comments. Regexp lines starting with the `!' character
352# specify inverse matching (use `\!' for literal matching against a leading
353# `!'). Skip empty lines in both files.
eb22018c
RS
354#
355# The first optional argument is a list of regexp substitutions of the form:
356#
357# EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
358#
359# This tells the function to apply each regexp substitution EXPi->SUBSPECi
360# in order to every line of FILE_2.
361#
362# Return nonzero if differences exist.
363proc regexp_diff { file_1 file_2 args } {
364 set eof -1
365 set end_1 0
366 set end_2 0
367 set differences 0
368 set diff_pass 0
369 set fail_if_match 0
370 set ref_subst ""
371 if { [llength $args] > 0 } {
372 set ref_subst [lindex $args 0]
373 }
374 if { [llength $args] > 1 } {
375 perror "Too many arguments to regexp_diff"
376 return 1
377 }
378
379 if [file exists $file_1] then {
380 set file_a [open $file_1 r]
381 } else {
382 perror "$file_1 doesn't exist"
383 return 1
384 }
385
386 if [file exists $file_2] then {
387 set file_b [open $file_2 r]
388 } else {
389 perror "$file_2 doesn't exist"
390 close $file_a
391 return 1
392 }
393
394 verbose " Regexp-diff'ing: $file_1 $file_2" 2
395
396 while { 1 } {
397 set line_a ""
398 set line_b ""
399 while { [string length $line_a] == 0 } {
400 # Ignore blank line in FILE_1.
401 if { [gets $file_a line_a] == $eof } {
402 set end_1 1
403 break
404 }
405 }
406 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
407 if { [string match "#pass" $line_b] } {
408 set end_2 1
409 set diff_pass 1
410 break
411 } elseif { [string match "#failif" $line_b] } {
412 send_log "fail if no difference\n"
413 verbose "fail if no difference" 3
414 set fail_if_match 1
415 } elseif { [string match "#..." $line_b] } {
416 if { [gets $file_b line_b] == $eof } {
417 set end_2 1
418 set diff_pass 1
419 break
420 }
47a50e5b 421 set negated [expr { [string index $line_b 0] == "!" }]
738f4d98
MR
422 set line_bx [string range $line_b $negated end]
423 set n [expr { $negated ? "! " : "" }]
eb22018c
RS
424 # Substitute on the reference.
425 foreach {name value} $ref_subst {
738f4d98 426 regsub -- $name $line_bx $value line_bx
eb22018c 427 }
738f4d98
MR
428 verbose "looking for $n\"^$line_bx$\"" 3
429 while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
eb22018c
RS
430 verbose "skipping \"$line_a\"" 3
431 if { [gets $file_a line_a] == $eof } {
432 set end_1 1
433 break
434 }
435 }
436 break
bc754168
AM
437 } elseif { [string match "#\\?*" $line_b] } {
438 if { ! $end_1 } {
439 set line_b [string replace $line_b 0 1]
440 set negated [expr { [string index $line_b 0] == "!" }]
441 set line_bx [string range $line_b $negated end]
442 set n [expr { $negated ? "! " : "" }]
443 # Substitute on the reference.
444 foreach {name value} $ref_subst {
445 regsub -- $name $line_bx $value line_bx
446 }
447 verbose "optional match for $n\"^$line_bx$\"" 3
448 if { [expr [regexp "^$line_bx$" "$line_a"] != $negated] } {
449 break
450 }
451 }
eb22018c
RS
452 }
453 if { [gets $file_b line_b] == $eof } {
454 set end_2 1
455 break
456 }
457 }
458
459 if { $diff_pass } {
460 break
461 } elseif { $end_1 && $end_2 } {
462 break
463 } elseif { $end_1 } {
464 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
465 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
466 set differences 1
467 break
468 } elseif { $end_2 } {
469 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
470 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
471 set differences 1
472 break
473 } else {
47a50e5b 474 set negated [expr { [string index $line_b 0] == "!" }]
738f4d98
MR
475 set line_bx [string range $line_b $negated end]
476 set n [expr { $negated ? "! " : "" }]
477 set s [expr { $negated ? " " : "" }]
eb22018c
RS
478 # Substitute on the reference.
479 foreach {name value} $ref_subst {
738f4d98 480 regsub -- $name $line_bx $value line_bx
eb22018c 481 }
738f4d98
MR
482 verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3
483 if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
eb22018c 484 send_log "regexp_diff match failure\n"
738f4d98 485 send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n"
eb22018c
RS
486 verbose "regexp_diff match failure\n" 3
487 set differences 1
488 }
489 }
490 }
491
492 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
493 send_log "$file_1 and $file_2 are different lengths\n"
494 verbose "$file_1 and $file_2 are different lengths" 3
495 set differences 1
496 }
497
498 if { $fail_if_match } {
499 if { $differences == 0 } {
500 set differences 1
501 } else {
502 set differences 0
503 }
504 }
505
506 close $file_a
507 close $file_b
508
509 return $differences
510}
7dd36a6f
L
511
512# prune_warnings_extra -- delete extra warnings from TEXT.
513#
514# An example is:
515# ld: warning: /lib64/ld-linux-x86-64.so.2: unsupported GNU_PROPERTY_TYPE (5) type : 0xc0010001
516proc prune_warnings_extra { text } {
517 global experimental
518 # Warnings are only pruned from non-experimental code (ie code not
519 # on a release branch). For experimental code we want the warnings
520 # as they indicate that the sources need to be updated to recognise
521 # the new properties.
522 if { "$experimental" == "false" } {
523 # The "\\1" is to try to preserve a "\n" but only if necessary.
524 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*unsupported GNU_PROPERTY_TYPE\[^\n\]*\n?)+" $text "\\1" text
525 }
f92f9e87
L
526 # PR binutils/23898: It is OK to have gaps in build notes.
527 regsub -all "(^|\n)(\[^\n\]*: Warning: Gap in build notes detected from\[^\n\]*\n?)+" $text "\\1" text
7dd36a6f
L
528 return $text
529}
530
531# This definition is taken from an unreleased version of DejaGnu. Once
532# that version gets released, and has been out in the world for a few
533# months at least, it may be safe to delete this copy.
534if ![string length [info proc prune_warnings]] {
535 #
536 # prune_warnings -- delete various system verbosities from TEXT
537 #
538 # An example is:
539 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
540 #
541 # Sites with particular verbose os's may wish to override this in site.exp.
542 #
543 proc prune_warnings { text } {
544 # This is from sun4's. Do it for all machines for now.
545 # The "\\1" is to try to preserve a "\n" but only if necessary.
546 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
547 # It might be tempting to get carried away and delete blank lines, etc.
548 # Just delete *exactly* what we're ask to, and that's it.
549 set text [prune_warnings_extra $text]
550 return $text
551 }
552} elseif { [info procs saved-prune_warnings] == [list] } {
553 rename prune_warnings saved-prune_warnings
554 proc prune_warnings { text } {
555 set text [saved-prune_warnings $text]
556 set text [prune_warnings_extra $text]
557 return $text
558 }
559}
8ffb70eb
AM
560
561# run_dump_test FILE (optional:) EXTRA_OPTIONS
562#
563# Assemble a .s file, then run some utility on it and check the output.
564#
565# There should be an assembly language file named FILE.s in the test
566# suite directory, and a pattern file called FILE.d. run_dump_test
567# will assemble FILE.s, optionally run objcopy on the object file,
568# optionally run ld, optionally run another objcopy, optionally run
569# another tool under test specified by PROG, then run a dump tool like
570# addr2line, nm, objdump, readelf or size on the object file to produce
571# textual output, and then analyze that with regexps.
572# The FILE.d file specifies what program to run, and what to expect in
573# its output.
574#
575# The FILE.d file begins with zero or more option lines, which specify
576# flags to pass to the assembler, the program to run to dump the
577# assembler's output, and the options it wants. The option lines have
578# the syntax:
579#
580# # OPTION: VALUE
581#
582# OPTION is the name of some option, like "name" or "objdump", and
583# VALUE is OPTION's value. The valid options are described below.
584# Whitespace is ignored everywhere, except within VALUE. The option
585# list ends with the first line that doesn't match the above syntax.
586# However, a line within the options that begins with a #, but doesn't
587# have a recognizable option name followed by a colon, is considered a
588# comment and entirely ignored.
589#
590# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
591# two-element lists. The first element of each is an option name, and
592# the second additional arguments to be added on to the end of the
593# option list as given in FILE.d. (If omitted, no additional options
594# are added.)
595#
596# The interesting options are:
597#
598# name: TEST-NAME
599# The name of this test, passed to DejaGNU's `pass' and `fail'
600# commands. If omitted, this defaults to FILE, the root of the
601# .s and .d files' names.
602#
603# as: FLAGS
604# When assembling, pass FLAGS to the assembler.
605# If assembling several files, you can pass different assembler
606# options in the "source" directives. See below.
52d6f3ee
MM
607# Multiple instances of this directive tells run_dump_test to run the test
608# multiple times -- one time with each set of flags provided.
609# Each instance will run exactly as a file with a single "as" line, it is
610# not possible to condition any behaviour on which set of "as" flags is
611# used. That means that the "source" specific options are appended to
612# the "as" flags for their corresponding files, and any extra processing
613# (e.g. with "ld" and "objcopy") is repeated for each test.
8ffb70eb
AM
614#
615# ld: FLAGS
616# Link assembled files using FLAGS, in the order of the "source"
617# directives, when using multiple files.
618#
619# ld_after_inputfiles: FLAGS
620# Similar to "ld", but put FLAGS after all input files.
621#
622# objcopy_objects: FLAGS
623# Run objcopy with the specified flags after assembling any source
624# that has the special marker RUN_OBJCOPY in the source specific
625# flags.
626#
627# objcopy_linked_file: FLAGS
628# Run objcopy on the linked file with the specified flags.
629# This lets you transform the linked file using objcopy, before the
630# result is analyzed by an analyzer program specified below.
631#
632# PROG: PROGRAM-NAME
633# The name of a program under test, to run to modify or analyze the
634# .o file produced by the assembler. Recognised names are: ar,
635# elfedit, nm, objcopy, ranlib, strings, and strip.
636#
637# DUMPPROG: PROGRAM-NAME
638# The name of the program to run to analyze the file produced
639# by the assembler or the linker. This can be omitted;
640# run_dump_test will guess which program to run from which of
641# the flags options below is present.
642#
643# addr2line: FLAGS
644# nm: FLAGS
645# objdump: FLAGS
646# readelf: FLAGS
647# size: FLAGS
648# Use the specified program to analyze the output file, and pass it
649# FLAGS, in addition to the output name. Note that they are run
650# with LC_ALL=C in the environment to give consistent sorting of
651# symbols. If no FLAGS are needed then you can use:
652# DUMPPROG: [nm objdump readelf addr2line]
653# instead, or just pass a flag that happens to be the default.
654# If objdump is the dump tool and we're not dumping binary, nor
655# have run ld, then the standard section names (.text, .data and
656# .bss) are replaced by target ones if any (eg. rx-elf uses "P"
657# instead of .text). The substition is done for both the
658# objdump options (eg: "-j .text" is replaced by "-j P") and the
659# reference file.
660#
661# source: SOURCE [FLAGS]
662# Assemble the file SOURCE.s using the flags in the "as" directive
663# and the (optional) FLAGS. If omitted, the source defaults to
664# FILE.s.
665# This is useful if several .d files want to share a .s file.
666# More than one "source" directive can be given, which is useful
667# when testing linking.
668#
669# dump: DUMP
670# Match against DUMP.d. If omitted, this defaults to FILE.d. This
671# is useful if several .d files differ by options only. Options are
672# always read from FILE.d.
673#
674# target: GLOB|PROC ...
675# Run this test only on a specified list of targets. More precisely,
676# in the space-separated list each glob is passed to "istarget" and
677# each proc is called as a TCL procedure. List items are interpreted
678# such that procs are denoted by surrounding square brackets, and any
679# other items are consired globs. If the call evaluates true for any
680# of them, the test will be run, otherwise it will be marked
681# unsupported.
682#
683# notarget: GLOB|PROC ...
684# Do not run this test on a specified list of targets. Again, each
685# glob in the space-separated list is passed to "istarget" and each
686# proc is called as a TCL procedure, and the test is run if it
687# evaluates *false* for *all* of them. Otherwise it will be marked
688# unsupported.
689#
690# alltargets: GLOB|PROC ...
691# Run this test on a specified list of targets. Again, each
692# glob in the space-separated list is passed to "istarget" and each
693# proc is called as a TCL procedure, and the test is run if it
694# evaluates *true* for *all* of them. Otherwise it will be marked
695# unsupported.
696#
697# skip: GLOB|PROC ...
698# anyskip: GLOB|PROC ...
699# noskip: GLOB|PROC ...
700# These are exactly the same as "notarget", "alltargets" and
701# "target" respectively, except that they do nothing at all if the
702# check fails. They should only be used in groups, to construct a
703# single test which is run on all targets but with variant options
704# or expected output on some targets. (For example, see
705# gas/arm/inst.d and gas/arm/wince_inst.d.)
706#
707# xfail: GLOB|PROC ...
708# Run this test and it is is expected to fail on a specified list
709# of targets.
710#
711# error: REGEX
712# An error with message matching REGEX must be emitted for the test
713# to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size
714# options have no meaning and need not supplied if this is present.
715# Multiple "error" directives append to the expected error message.
716#
717# error_output: FILE
718# Means the same as 'error', except the regular expression lines
719# are contains in FILE.
720#
721# warning: REGEX
722# Expect a warning matching REGEX. It is an error to issue
723# both "error" and "warning". Multiple "warning" directives
724# append to the expected warning message.
725#
726# warning_output: FILE
727# Means the same as 'warning', except the regular expression
728# lines are contains in FILE.
729#
730# map: FILE
731# Adding this option will cause the linker to generate a linker
732# map file, using the -Map=MAPFILE command line option. If
733# there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
734# added to the linker command line. The contents of the
735# generated MAPFILE are then compared against the regexp lines
736# in FILE using `regexp_diff' (see below for details).
737#
738# section_subst: no
739# Means that the section substitution for objdump is disabled.
740#
741# Each option may occur at most once unless otherwise mentioned.
742#
743# After the option lines come regexp lines. run_dump_test calls
744# regexp_diff to compare the output of the dumping tool against the
745# regexps in FILE.d.
746#
747proc run_dump_test { name {extra_options {}} } {
748 global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS ELFEDIT ELFEDITFLAGS LD LDFLAGS
749 global NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS
750 global READELF READELFFLAGS STRIP STRIPFLAGS
5fd104ad 751 global copyfile env runtests srcdir subdir verbose
8ffb70eb
AM
752
753 if [string match "*/*" $name] {
754 set file $name
755 set name [file tail $name]
756 } else {
757 set file "$srcdir/$subdir/$name"
758 }
759
760 if ![runtest_file_p $runtests $name] then {
761 return
762 }
763
764 set opt_array [slurp_options "${file}.d"]
765 if { $opt_array == -1 } {
766 perror "error reading options from $file.d"
767 unresolved $subdir/$name
768 return
769 }
770 set dumpfile tmpdir/dump.out
771 set run_ld 0
772 set run_objcopy 0
773 set objfile_names {}
774 set opts(PROG) {}
775 set opts(DUMPPROG) {}
776 set opts(addr2line) {}
777 set opts(alltargets) {}
778 set opts(anyskip) {}
779 set opts(ar) {}
780 set opts(as) {}
52d6f3ee
MM
781 set as_final_flags {}
782 set as_additional_flags {}
8ffb70eb
AM
783 set opts(dump) {}
784 set opts(elfedit) {}
785 set opts(error) {}
786 set opts(error_output) {}
787 set opts(ld) {}
788 set opts(ld_after_inputfiles) {}
789 set opts(map) {}
790 set opts(name) {}
791 set opts(nm) {}
792 set opts(noskip) {}
793 set opts(notarget) {}
794 set opts(objcopy) {}
795 set opts(objcopy_linked_file) {}
796 set opts(objcopy_objects) {}
797 set opts(objdump) {}
798 set opts(ranlib) {}
799 set opts(readelf) {}
800 set opts(section_subst) {}
801 set opts(size) {}
802 set opts(strings) {}
803 set opts(strip) {}
804 set opts(skip) {}
805 set opts(source) {}
806 set opts(strip) {}
807 set opts(target) {}
808 set opts(warning) {}
809 set opts(warning_output) {}
810 set opts(xfail) {}
811
812 set in_extra 0
813 foreach i [concat $opt_array {{} {}} $extra_options] {
814 set opt_name [lindex $i 0]
815 set opt_val [lindex $i 1]
816 if { $opt_name == "" } {
817 set in_extra 1
818 continue
819 }
820 if ![info exists opts($opt_name)] {
821 perror "unknown option $opt_name in file $file.d"
822 unresolved $subdir/$name
823 return
824 }
825
826 # Allow more substitutions, including tcl functions, for as and ld.
827 # Not done in general because extra quoting is needed for glob
828 # args used for example in binutils-all/remove-relocs-04.d.
829 if { $opt_name == "as" || $opt_name == "ld" } {
830 set opt_val [subst $opt_val]
831 } else {
832 # Just substitute $srcdir and $subdir
833 regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val
834 regsub -all {\$subdir} "$opt_val" "$subdir" opt_val
835 }
836
837 switch -- $opt_name {
838 xfail {}
839 target {}
840 alltargets {}
841 notarget {}
842 skip {}
843 anyskip {}
844 noskip {}
845 warning {}
846 error {}
847 source {
848 # Move any source-specific as-flags to a separate list to
849 # simplify processing.
850 if { [llength $opt_val] > 1 } {
851 lappend asflags [lrange $opt_val 1 end]
852 set opt_val [lindex $opt_val 0]
853 } else {
854 lappend asflags {}
855 }
856
857 # Create the object file name based on nothing but the source
858 # file name.
859 set new_objfile \
860 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
861 # But, sometimes, we have the exact same source filename in
862 # different directories (foo/src.s bar/src.s) which would lead
863 # us to try and create two src.o files. We detect this
864 # conflict here, and instead create src.o and src1.o.
865 set j 0
866 while { [lsearch $objfile_names $new_objfile] != -1 } {
867 incr j
868 set new_objfile \
869 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
870 }
871 lappend objfile_names $new_objfile
872 }
873 default {
52d6f3ee
MM
874 if { !$in_extra
875 && [string length $opts($opt_name)]
876 && $opt_name != "as" } {
8ffb70eb
AM
877 perror "option $opt_name multiply set in $file.d"
878 unresolved $subdir/$name
879 return
880 }
881
882 # A single "#ld:" with no options should do the right thing.
883 if { $opt_name == "ld" } {
884 set run_ld 1
885 }
886 # Likewise objcopy_linked_file.
887 if { $opt_name == "objcopy_linked_file" } {
888 set run_objcopy 1
889 }
890 }
891 }
892
893 # Append differently whether it's a message (without space) or
894 # an option or list (with space).
895 switch -- $opt_name {
896 warning -
897 error {
898 append opts($opt_name) $opt_val
899 }
52d6f3ee
MM
900 as {
901 if { $in_extra } {
902 set as_additional_flags [concat $as_additional_flags $opt_val]
903 } else {
904 lappend opts(as) $opt_val
905 }
906 }
8ffb70eb
AM
907 default {
908 set opts($opt_name) [concat $opts($opt_name) $opt_val]
909 }
910 }
911 }
912
093f70cc 913 # Ensure there is something in $opts(as) for the foreach loop below.
52d6f3ee
MM
914 if { [llength $opts(as)] == 0 } {
915 set opts(as) [list " "]
8ffb70eb 916 }
093f70cc 917 foreach x $opts(as) {
52d6f3ee
MM
918 if { [string length $x] && [string length $as_additional_flags] } {
919 append x " "
920 }
921 append x $as_additional_flags
922 regsub {\[big_or_little_endian\]} $x \
923 [big_or_little_endian] x
093f70cc
MM
924 lappend as_final_flags $x
925 }
52d6f3ee
MM
926
927 regsub {\[big_or_little_endian\]} $opts(ld) \
928 [big_or_little_endian] opts(ld)
8ffb70eb
AM
929
930 if { $opts(name) == "" } {
931 set testname "$subdir/$name"
932 } else {
933 set testname $opts(name)
934 }
935
936 set err_warn 0
937 foreach opt { warning error warning_output error_output } {
938 if { $opts($opt) != "" } {
939 if { $err_warn } {
940 perror "$testname: bad mix of warning and error test directives"
941 unresolved $testname
942 return
943 }
944 set err_warn 1
945 }
946 }
947
948 # Decide early whether we should run the test for this target.
949 if { [llength $opts(noskip)] > 0 } {
950 set targmatch 0
951 foreach targ $opts(noskip) {
952 if [match_target $targ] {
953 set targmatch 1
954 break
955 }
956 }
957 if { $targmatch == 0 } {
958 return
959 }
960 }
961 foreach targ $opts(anyskip) {
962 if ![match_target $targ] {
963 return
964 }
965 }
966 foreach targ $opts(skip) {
967 if [match_target $targ] {
968 return
969 }
970 }
971 if { [llength $opts(target)] > 0 } {
972 set targmatch 0
973 foreach targ $opts(target) {
974 if [match_target $targ] {
975 set targmatch 1
976 break
977 }
978 }
979 if { $targmatch == 0 } {
980 unsupported $testname
981 return
982 }
983 }
984 foreach targ $opts(alltargets) {
985 if ![match_target $targ] {
986 unsupported $testname
987 return
988 }
989 }
990 foreach targ $opts(notarget) {
991 if [match_target $targ] {
992 unsupported $testname
993 return
994 }
995 }
996
997 set dumpprogram ""
998 # It's meaningless to require an output-testing method when we
999 # expect an error.
1000 if { $opts(error) == "" && $opts(error_output) == "" } {
1001 if { $opts(DUMPPROG) != "" } {
1002 switch -- $opts(DUMPPROG) {
1003 addr2line { set dumpprogram addr2line }
1004 nm { set dumpprogram nm }
1005 objdump { set dumpprogram objdump }
1006 readelf { set dumpprogram readelf }
1007 size { set dumpprogram size }
1008 default {
1009 perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d"
1010 unresolved $testname
1011 return
1012 }
1013 }
1014 } else {
1015 # Guess which program to run, by seeing which option was specified.
1016 foreach p {addr2line nm objdump readelf size} {
1017 if {$opts($p) != ""} {
1018 if {$dumpprogram != ""} {
1019 perror "ambiguous dump program in $file.d"
1020 unresolved $testname
1021 return
1022 } else {
1023 set dumpprogram $p
1024 }
1025 }
1026 }
1027 }
1028 if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } {
1029 perror "dump program unspecified in $file.d"
1030 unresolved $testname
1031 return
1032 }
1033 }
1034
1035 if { $opts(source) == "" } {
1036 set sourcefiles [list ${file}.s]
1037 set asflags [list ""]
1038 set objfile_names [list tmpdir/[file tail ${file}].o]
1039 } else {
1040 set sourcefiles {}
1041 foreach sf $opts(source) {
171b8e19 1042 if { [string match "./*" $sf] } {
8ffb70eb
AM
1043 lappend sourcefiles "$sf"
1044 } else {
1045 lappend sourcefiles "$srcdir/$subdir/$sf"
1046 }
1047 }
1048 }
1049
1050 if { $opts(dump) == "" } {
1051 set dfile ${file}.d
1052 } else {
1053 set dfile $srcdir/$subdir/$opts(dump)
1054 }
1055
1056 # Time to setup xfailures.
1057 foreach targ $opts(xfail) {
1336939d
AM
1058 if [match_target $targ] {
1059 setup_xfail "*-*-*"
1060 break
1061 }
8ffb70eb
AM
1062 }
1063
52d6f3ee
MM
1064 foreach as_flags $as_final_flags {
1065 # Assemble each file.
1066 set objfiles {}
1067 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
1068 set sourcefile [lindex $sourcefiles $i]
1069 set sourceasflags [lindex $asflags $i]
1070 set run_objcopy_objects 0
1071
1072 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
1073 set run_objcopy_objects 1
1074 }
1075 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
1076
1077 set objfile [lindex $objfile_names $i]
1078 catch "exec rm -f $objfile" exec_output
1079 lappend objfiles $objfile
1080
1081 if { $as_flags == "binary" } {
1082 while {[file type $sourcefile] eq "link"} {
1083 set newfile [file readlink $sourcefile]
1084 if {[string index $newfile 0] ne "/"} {
1085 set newfile [file dirname $sourcefile]/$newfile
1086 }
1087 set sourcefile $newfile
1088 }
1089 set newfile [remote_download host $sourcefile $objfile]
1090 set cmdret 0
1091 if { $newfile == "" } {
1092 set cmdret 1
1093 }
1094 } else {
1095 if { [istarget "hppa*-*-*"] \
1096 && ![istarget "*-*-linux*"] \
1097 && ![istarget "*-*-netbsd*" ] } {
1098 set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s"
1099 send_log "$cmd\n"
1100 set cmdret [remote_exec host [concat sh -c [list "$cmd"]]]
1101 set cmdret [lindex $cmdret 0]
1102 if { $cmdret != 0 } {
1103 perror "sed failure"
1104 unresolved $testname
1105 continue
1106 }
1107 set sourcefile tmpdir/asm.s
1108 }
1109 set cmd "$AS $ASFLAGS $as_flags $sourceasflags -o $objfile $sourcefile"
1110
1111 send_log "$cmd\n"
1112 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1113 remote_upload host "dump.tmp"
1114 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1115 remote_file host delete "dump.tmp"
1116 remote_file build delete "dump.tmp"
1117 set cmdret [lindex $cmdret 0]
1118 }
1119 if { $cmdret == 0 && $run_objcopy_objects } {
1120 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
1121
1122 send_log "$cmd\n"
1123 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
1124 "" "/dev/null" "dump.tmp"]
1125 remote_upload host "dump.tmp"
1126 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1127 remote_file host delete "dump.tmp"
1128 remote_file build delete "dump.tmp"
1129 set cmdret [lindex $cmdret 0]
1130 }
1131 }
1132
1133 # Perhaps link the file(s).
1134 if { $cmdret == 0 && $run_ld } {
1135 set objfile "tmpdir/dump"
1136 catch "exec rm -f $objfile" exec_output
1137
1138 set ld_extra_opt ""
1139 global ld
1140 set ld "$LD"
5fd104ad
AM
1141 if [check_relro_support] {
1142 set ld_extra_opt "-z norelro"
1143 }
52d6f3ee
MM
1144
1145 # Add -L$srcdir/$subdir so that the linker command can use
1146 # linker scripts in the source directory.
1147 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
8ffb70eb
AM
1148 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
1149
52d6f3ee
MM
1150 # If needed then check for, or add a -Map option.
1151 set mapfile ""
1152 if { $opts(map) != "" } then {
1153 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
1154 # Found existing mapfile option
1155 verbose -log "Existing mapfile '$mapfile' found"
1156 } else {
1157 # No mapfile option.
1158 set mapfile "tmpdir/dump.map"
1159 verbose -log "Adding mapfile '$mapfile'"
1160 set cmd "$cmd -Map=$mapfile"
1161 }
1162 }
1163
1164 send_log "$cmd\n"
1165 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1166 remote_upload host "dump.tmp"
1167 append comp_output [file_contents "dump.tmp"]
1168 remote_file host delete "dump.tmp"
1169 remote_file build delete "dump.tmp"
1170 set cmdret [lindex $cmdret 0]
1171
1172 if { $cmdret == 0 && $run_objcopy } {
1173 set infile $objfile
1174 set objfile "tmpdir/dump1"
1175 remote_file host delete $objfile
1176
1177 # Note that we don't use OBJCOPYFLAGS here; any flags must be
1178 # explicitly specified.
1179 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
1180
1181 send_log "$cmd\n"
1182 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1183 remote_upload host "dump.tmp"
1184 append comp_output [file_contents "dump.tmp"]
1185 remote_file host delete "dump.tmp"
1186 remote_file build delete "dump.tmp"
1187 set cmdret [lindex $cmdret 0]
1188 }
1189 } else {
1190 set objfile [lindex $objfiles 0]
1191 }
1192
1193 if { $cmdret == 0 && $opts(PROG) != "" } {
1194 set destopt ${copyfile}.o
1195 switch -- $opts(PROG) {
1196 ar { set program ar }
1197 elfedit {
1198 set program elfedit
1199 set destopt ""
1200 }
1201 nm { set program nm }
1202 objcopy { set program objcopy }
1203 ranlib { set program ranlib }
1204 strings { set program strings }
1205 strip {
1206 set program strip
1207 set destopt "-o $destopt"
1208 }
1209 default {
1210 perror "unrecognized PROG option $opts(PROG) in $file.d"
1211 unresolved $testname
1212 continue
1213 }
1214 }
1215
1216 set progopts1 $opts($program)
1217 eval set progopts \$[string toupper $program]FLAGS
1218 eval set binary \$[string toupper $program]
1219
1220 if { ![is_remote host] && [which $binary] == 0 } {
1221 untested $testname
1222 continue
1223 }
1224
1225 verbose "running $binary $progopts $progopts1" 3
1226 set cmd "$binary $progopts $progopts1 $objfile $destopt"
1227
1228 # Ensure consistent sorting of symbols
1229 if {[info exists env(LC_ALL)]} {
1230 set old_lc_all $env(LC_ALL)
1231 }
1232 set env(LC_ALL) "C"
1233 send_log "$cmd\n"
1234 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1235 set cmdret [lindex $cmdret 0]
1236 remote_upload host "dump.tmp"
1237 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1238 remote_file host delete "dump.tmp"
1239 remote_file build delete "dump.tmp"
1240 if {[info exists old_lc_all]} {
1241 set env(LC_ALL) $old_lc_all
1242 } else {
1243 unset env(LC_ALL)
1244 }
1245 if { $destopt != "" } {
1246 set objfile ${copyfile}.o
1247 }
1248 }
1249
1250 set want_out(source) ""
1251 set want_out(terminal) 0
1252 if { $err_warn } {
1253 if { $opts(error) != "" || $opts(error_output) != "" } {
1254 set want_out(terminal) 1
1255 }
1256
1257 if { $opts(error) != "" || $opts(warning) != "" } {
1258 set want_out(source) "regex"
1259 if { $opts(error) != "" } {
1260 set want_out(regex) $opts(error)
1261 } else {
1262 set want_out(regex) $opts(warning)
1263 }
1264 } else {
1265 set want_out(source) "file"
1266 if { $opts(error_output) != "" } {
1267 set want_out(file) $opts(error_output)
1268 } else {
1269 set want_out(file) $opts(warning_output)
1270 }
1271 }
1272 }
1273
1274 regsub "\n$" $comp_output "" comp_output
1275 if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } {
1276 set exitstat "succeeded"
1277 if { $cmdret != 0 } { set exitstat "failed" }
1278
1279 if { $want_out(source) == "regex" } {
1280 verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>"
1281 } elseif { $want_out(source) == "file" } {
1282 verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)"
1283 set_file_contents "tmpdir/ld.messages" "$comp_output"
1284 } else {
1285 verbose -log "$exitstat with: <$comp_output>, no expected output"
1286 }
1287
1288 if { (($want_out(source) == "") == ($comp_output == "")) \
1289 && (($cmdret == 0) == ($want_out(terminal) == 0)) \
1290 && ((($want_out(source) == "regex") \
1291 && [regexp -- $want_out(regex) $comp_output]) \
1292 || (($want_out(source) == "file") \
1293 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } {
1294 # We have the expected output.
1295 if { $want_out(terminal) || $dumpprogram == "" } {
1296 pass $testname
1297 continue
1298 }
1299 } else {
1300 fail $testname
1301 continue
1302 }
1303 }
1304
1305 # We must not have expected failure if we get here.
1306 if { $opts(error) != "" } {
1307 fail $testname
1308 continue
1309 }
1310
1311 if { $opts(map) != "" } then {
1312 # Check the map file matches.
1313 set map_pattern_file $srcdir/$subdir/$opts(map)
1314 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1315 if { [regexp_diff $mapfile $map_pattern_file] } then {
1316 fail "$testname (map file check)"
1317 } else {
1318 pass "$testname (map file check)"
1319 }
1320
1321 if { $dumpprogram == "" } then {
1322 continue
1323 }
1324 }
1325
1326 set progopts1 $opts($dumpprogram)
1327 eval set progopts \$[string toupper $dumpprogram]FLAGS
1328 eval set binary \$[string toupper $dumpprogram]
1329
1330 if { ![is_remote host] && [which $binary] == 0 } {
1331 untested $testname
1332 continue
1333 }
1334
1335 # For objdump of gas output, automatically translate standard section names
1336 set sect_names ""
1337 if { !$run_ld && $dumpprogram == "objdump" \
1338 && $opts(section_subst) != "no" \
1339 && ![string match "*-b binary*" $progopts1] } {
1340 set sect_names [get_standard_section_names]
1341 if { $sect_names != ""} {
1342 regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1
1343 regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1
1344 regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1
1345 }
1346 }
1347
1348 if { $progopts1 == "" } { set $progopts1 "-r" }
1349 verbose "running $binary $progopts $progopts1" 3
1350
1351 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1352
1353 # Ensure consistent sorting of symbols
1354 if {[info exists env(LC_ALL)]} {
1355 set old_lc_all $env(LC_ALL)
1356 }
1357 set env(LC_ALL) "C"
1358 send_log "$cmd\n"
1359 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1360 set cmdret [lindex $cmdret 0]
1361 remote_upload host "dump.tmp"
1362 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1363 remote_file host delete "dump.tmp"
1364 remote_file build delete "dump.tmp"
1365 if {[info exists old_lc_all]} {
1366 set env(LC_ALL) $old_lc_all
1367 } else {
1368 unset env(LC_ALL)
1369 }
1370 if { $cmdret != 0 || $comp_output != "" } {
1371 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1372 fail $testname
1373 continue
1374 }
1375
1376 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1377
1378 # Create the substition list for objdump output.
1379 set regexp_subst ""
1380 if { $sect_names != "" } {
1381 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \
1382 "\\\\?\\.data" [lindex $sect_names 1] \
1383 "\\\\?\\.bss" [lindex $sect_names 2] ]
1384 }
1385
1386 if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then {
1387 fail $testname
1388 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1389 continue
1390 }
1391
1392 pass $testname
8ffb70eb 1393 }
8ffb70eb
AM
1394}
1395
1396proc slurp_options { file } {
1397 # If options_regsub(foo) is set to {a b}, then the contents of a
1398 # "#foo:" line will have regsub -all applied to replace a with b.
1399 global options_regsub
1400
1401 if [catch { set f [open $file r] } x] {
1402 #perror "couldn't open `$file': $x"
1403 perror "$x"
1404 return -1
1405 }
1406 set opt_array {}
1407 # whitespace expression
1408 set ws {[ ]*}
1409 set nws {[^ ]*}
1410 # whitespace is ignored anywhere except within the options list;
1411 # option names are alphanumeric plus underscore.
1412 set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$"
1413 while { [gets $f line] != -1 } {
1414 set line [string trim $line]
1415 # Whitespace here is space-tab.
1416 if [regexp $pat $line xxx opt_name opt_val] {
1417 # match!
1418 if [info exists options_regsub($opt_name)] {
1419 set subst $options_regsub($opt_name)
1420 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1421 opt_val
1422 }
1423 lappend opt_array [list $opt_name $opt_val]
1424 } elseif {![regexp "^#" $line ]} {
1425 break
1426 }
1427 }
1428 close $f
1429 return $opt_array
1430}
1431
1432proc file_contents { filename } {
1433 set file [open $filename r]
1434 set contents [read $file]
1435 close $file
1436 return $contents
1437}
1438
1439proc set_file_contents { filename contents } {
1440 set file [open $filename w]
1441 puts $file "$contents"
1442 close $file
1443}
1444
1445# Look for big-endian or little-endian switches in the multlib
1446# options and translate these into a -EB or -EL switch. Note
1447# we cannot rely upon proc process_multilib_options to do this
1448# for us because for some targets the compiler does not support
1449# -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
1450# the site.exp file will include the switch "-mbig-endian"
1451# (rather than "big-endian") which is not detected by proc
1452# process_multilib_options.
1453#
1454proc big_or_little_endian {} {
1455
1456 if [board_info [target_info name] exists multilib_flags] {
1457 set tmp_flags " [board_info [target_info name] multilib_flags]"
1458
1459 foreach x $tmp_flags {
e3696f67
AM
1460 switch -glob $x {
1461 *big*endian -
1462 eb -
1463 EB -
1464 -eb -
1465 -EB -
1466 -mb -
1467 -meb {
8ffb70eb
AM
1468 set flags " -EB"
1469 return $flags
1470 }
e3696f67
AM
1471 *little*endian -
1472 el -
1473 EL -
1474 -el -
1475 -EL -
1476 -ml -
1477 -mel {
8ffb70eb
AM
1478 set flags " -EL"
1479 return $flags
1480 }
1481 }
1482 }
1483 }
1484
1485 set flags ""
1486 return $flags
1487}
1488
1489# Internal procedure: return the names of the standard sections
1490#
1491proc get_standard_section_names {} {
8d3c78e4 1492 if [istarget "rx-*-elf"] {
8ffb70eb
AM
1493 return { "P" "D_1" "B_1" }
1494 }
0b1352e0
AM
1495 if { [istarget "alpha*-*-*vms*"] || [is_som_format] } {
1496 return { {\$CODE\$} {\$DATA\$} {\$BSS\$} }
8ffb70eb
AM
1497 }
1498 return
1499}