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