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