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