]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/testsuite/lib/binutils-common.exp
elf: Add size_relative_relocs and finish_relative_relocs
[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
8ffb70eb
AM
858
859 if [string match "*/*" $name] {
860 set file $name
861 set name [file tail $name]
862 } else {
863 set file "$srcdir/$subdir/$name"
864 }
865
866 if ![runtest_file_p $runtests $name] then {
867 return
868 }
869
870 set opt_array [slurp_options "${file}.d"]
871 if { $opt_array == -1 } {
872 perror "error reading options from $file.d"
873 unresolved $subdir/$name
874 return
875 }
876 set dumpfile tmpdir/dump.out
877 set run_ld 0
878 set run_objcopy 0
879 set objfile_names {}
880 set opts(PROG) {}
881 set opts(DUMPPROG) {}
882 set opts(addr2line) {}
883 set opts(alltargets) {}
884 set opts(anyskip) {}
885 set opts(ar) {}
886 set opts(as) {}
52d6f3ee
MM
887 set as_final_flags {}
888 set as_additional_flags {}
0b884151 889 set opts(cc) {}
8ffb70eb
AM
890 set opts(dump) {}
891 set opts(elfedit) {}
892 set opts(error) {}
893 set opts(error_output) {}
894 set opts(ld) {}
895 set opts(ld_after_inputfiles) {}
896 set opts(map) {}
897 set opts(name) {}
898 set opts(nm) {}
899 set opts(noskip) {}
900 set opts(notarget) {}
901 set opts(objcopy) {}
902 set opts(objcopy_linked_file) {}
903 set opts(objcopy_objects) {}
904 set opts(objdump) {}
905 set opts(ranlib) {}
906 set opts(readelf) {}
907 set opts(section_subst) {}
908 set opts(size) {}
909 set opts(strings) {}
910 set opts(strip) {}
911 set opts(skip) {}
912 set opts(source) {}
913 set opts(strip) {}
914 set opts(target) {}
915 set opts(warning) {}
916 set opts(warning_output) {}
917 set opts(xfail) {}
918
919 set in_extra 0
920 foreach i [concat $opt_array {{} {}} $extra_options] {
921 set opt_name [lindex $i 0]
922 set opt_val [lindex $i 1]
923 if { $opt_name == "" } {
924 set in_extra 1
925 continue
926 }
927 if ![info exists opts($opt_name)] {
928 perror "unknown option $opt_name in file $file.d"
929 unresolved $subdir/$name
930 return
931 }
932
0b884151
NA
933 # Allow more substitutions, including tcl functions, for as, ld,
934 # and cc. Not done in general because extra quoting is needed for glob
8ffb70eb 935 # args used for example in binutils-all/remove-relocs-04.d.
0b884151 936 if { $opt_name == "as" || $opt_name == "ld" || $opt_name == "cc" } {
8ffb70eb
AM
937 set opt_val [subst $opt_val]
938 } else {
939 # Just substitute $srcdir and $subdir
940 regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val
941 regsub -all {\$subdir} "$opt_val" "$subdir" opt_val
942 }
943
944 switch -- $opt_name {
945 xfail {}
946 target {}
947 alltargets {}
948 notarget {}
949 skip {}
950 anyskip {}
951 noskip {}
952 warning {}
953 error {}
954 source {
955 # Move any source-specific as-flags to a separate list to
956 # simplify processing.
957 if { [llength $opt_val] > 1 } {
958 lappend asflags [lrange $opt_val 1 end]
959 set opt_val [lindex $opt_val 0]
960 } else {
961 lappend asflags {}
962 }
963
964 # Create the object file name based on nothing but the source
965 # file name.
966 set new_objfile \
967 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
968 # But, sometimes, we have the exact same source filename in
969 # different directories (foo/src.s bar/src.s) which would lead
970 # us to try and create two src.o files. We detect this
971 # conflict here, and instead create src.o and src1.o.
972 set j 0
973 while { [lsearch $objfile_names $new_objfile] != -1 } {
974 incr j
975 set new_objfile \
976 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
977 }
978 lappend objfile_names $new_objfile
979 }
980 default {
52d6f3ee 981 if { !$in_extra
4d496013
AM
982 && [string length $opts($opt_name)]
983 && $opt_name != "as" } {
8ffb70eb
AM
984 perror "option $opt_name multiply set in $file.d"
985 unresolved $subdir/$name
986 return
987 }
988
989 # A single "#ld:" with no options should do the right thing.
990 if { $opt_name == "ld" } {
991 set run_ld 1
992 }
993 # Likewise objcopy_linked_file.
994 if { $opt_name == "objcopy_linked_file" } {
995 set run_objcopy 1
996 }
997 }
998 }
999
1000 # Append differently whether it's a message (without space) or
1001 # an option or list (with space).
1002 switch -- $opt_name {
1003 warning -
1004 error {
1005 append opts($opt_name) $opt_val
1006 }
4d496013
AM
1007 as {
1008 if { $in_extra } {
1009 set as_additional_flags [concat $as_additional_flags $opt_val]
1010 } else {
1011 lappend opts(as) $opt_val
1012 }
1013 }
8ffb70eb
AM
1014 default {
1015 set opts($opt_name) [concat $opts($opt_name) $opt_val]
1016 }
1017 }
1018 }
1019
093f70cc 1020 # Ensure there is something in $opts(as) for the foreach loop below.
52d6f3ee 1021 if { [llength $opts(as)] == 0 } {
4d496013 1022 set opts(as) [list " "]
8ffb70eb 1023 }
093f70cc 1024 foreach x $opts(as) {
4d496013
AM
1025 if { [string length $x] && [string length $as_additional_flags] } {
1026 append x " "
1027 }
1028 append x $as_additional_flags
1029 regsub {\[big_or_little_endian\]} $x \
1030 [big_or_little_endian] x
1031 lappend as_final_flags $x
093f70cc 1032 }
52d6f3ee
MM
1033
1034 regsub {\[big_or_little_endian\]} $opts(ld) \
4d496013 1035 [big_or_little_endian] opts(ld)
8ffb70eb
AM
1036
1037 if { $opts(name) == "" } {
1038 set testname "$subdir/$name"
1039 } else {
1040 set testname $opts(name)
1041 }
1042
1043 set err_warn 0
1044 foreach opt { warning error warning_output error_output } {
1045 if { $opts($opt) != "" } {
1046 if { $err_warn } {
1047 perror "$testname: bad mix of warning and error test directives"
1048 unresolved $testname
1049 return
1050 }
1051 set err_warn 1
1052 }
1053 }
1054
1055 # Decide early whether we should run the test for this target.
1056 if { [llength $opts(noskip)] > 0 } {
1057 set targmatch 0
1058 foreach targ $opts(noskip) {
1059 if [match_target $targ] {
1060 set targmatch 1
1061 break
1062 }
1063 }
1064 if { $targmatch == 0 } {
1065 return
1066 }
1067 }
1068 foreach targ $opts(anyskip) {
1069 if ![match_target $targ] {
1070 return
1071 }
1072 }
1073 foreach targ $opts(skip) {
1074 if [match_target $targ] {
1075 return
1076 }
1077 }
1078 if { [llength $opts(target)] > 0 } {
1079 set targmatch 0
1080 foreach targ $opts(target) {
1081 if [match_target $targ] {
1082 set targmatch 1
1083 break
1084 }
1085 }
1086 if { $targmatch == 0 } {
1087 unsupported $testname
1088 return
1089 }
1090 }
1091 foreach targ $opts(alltargets) {
1092 if ![match_target $targ] {
1093 unsupported $testname
1094 return
1095 }
1096 }
1097 foreach targ $opts(notarget) {
1098 if [match_target $targ] {
1099 unsupported $testname
1100 return
1101 }
1102 }
1103
1104 set dumpprogram ""
1105 # It's meaningless to require an output-testing method when we
1106 # expect an error.
1107 if { $opts(error) == "" && $opts(error_output) == "" } {
1108 if { $opts(DUMPPROG) != "" } {
1109 switch -- $opts(DUMPPROG) {
1110 addr2line { set dumpprogram addr2line }
1111 nm { set dumpprogram nm }
1112 objdump { set dumpprogram objdump }
1113 readelf { set dumpprogram readelf }
1114 size { set dumpprogram size }
1115 default {
1116 perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d"
1117 unresolved $testname
1118 return
1119 }
1120 }
1121 } else {
1122 # Guess which program to run, by seeing which option was specified.
1123 foreach p {addr2line nm objdump readelf size} {
1124 if {$opts($p) != ""} {
1125 if {$dumpprogram != ""} {
1126 perror "ambiguous dump program in $file.d"
1127 unresolved $testname
1128 return
1129 } else {
1130 set dumpprogram $p
1131 }
1132 }
1133 }
1134 }
1135 if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } {
1136 perror "dump program unspecified in $file.d"
1137 unresolved $testname
1138 return
1139 }
1140 }
1141
0b884151
NA
1142 # Possibly compile some of the inputs, and build up a replacement
1143 # for opts(source) with the output .s names substituted in as we go.
1144 # Set the .s names from the objfile_names to take advantage of the
1145 # uniquification that happened earlier.
1146 if { $opts(cc) != ""} {
1147 set cmdret 0
1148 set new_source ""
1149
1150 foreach cfile $opts(source) ofile $objfile_names {
1151 if { [file extension $cfile] != ".c" } {
1152 lappend new_source "$cfile"
1153 continue
1154 }
1155
1156 if { ! [string match "./*" $cfile] } {
1157 set cfile "$srcdir/$subdir/$cfile"
1158 }
1159 # ofile is never absolute, so this always works to protect sfile
1160 # from later absolutization.
1161 set sfile "./[file rootname $ofile].s"
ad77db1c 1162 set cmd "$CC_FOR_TARGET $CFLAGS_FOR_TARGET -S $opts(cc) -o $sfile $cfile"
0b884151
NA
1163 send_log "$cmd\n"
1164 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1165 remote_upload host "dump.tmp"
1166 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1167 remote_file host delete "dump.tmp"
1168 remote_file build delete "dump.tmp"
1169 lappend new_source "$sfile"
1170 set cmdret [lindex $cmdret 0]
1171
1172 regsub "\n$" $comp_output "" comp_output
1173 if { $cmdret != 0} {
1174 send_log "compilation of $cfile failed, exit status $cmdret with <$comp_output>"
4d496013 1175 # Should this be 'unresolved', or is that too silent?
0b884151
NA
1176 fail $testname
1177 return 0
1178 }
1179 }
1180 set opts(source) $new_source
1181 }
1182
8ffb70eb
AM
1183 if { $opts(source) == "" } {
1184 set sourcefiles [list ${file}.s]
1185 set asflags [list ""]
1186 set objfile_names [list tmpdir/[file tail ${file}].o]
1187 } else {
1188 set sourcefiles {}
1189 foreach sf $opts(source) {
171b8e19 1190 if { [string match "./*" $sf] } {
8ffb70eb
AM
1191 lappend sourcefiles "$sf"
1192 } else {
1193 lappend sourcefiles "$srcdir/$subdir/$sf"
1194 }
1195 }
1196 }
1197
1198 if { $opts(dump) == "" } {
1199 set dfile ${file}.d
1200 } else {
1201 set dfile $srcdir/$subdir/$opts(dump)
1202 }
1203
1204 # Time to setup xfailures.
1205 foreach targ $opts(xfail) {
1336939d
AM
1206 if [match_target $targ] {
1207 setup_xfail "*-*-*"
1208 break
1209 }
8ffb70eb
AM
1210 }
1211
52d6f3ee 1212 foreach as_flags $as_final_flags {
4d496013
AM
1213 # Assemble each file.
1214 set objfiles {}
1215 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
1216 set sourcefile [lindex $sourcefiles $i]
1217 set sourceasflags [lindex $asflags $i]
1218 set run_objcopy_objects 0
1219
1220 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
1221 set run_objcopy_objects 1
1222 }
1223 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
1224
1225 set objfile [lindex $objfile_names $i]
1226 catch "exec rm -f $objfile" exec_output
1227 lappend objfiles $objfile
1228
1229 if { $as_flags == "binary" } {
1230 while {[file type $sourcefile] eq "link"} {
1231 set newfile [file readlink $sourcefile]
1232 if {[string index $newfile 0] ne "/"} {
1233 set newfile [file dirname $sourcefile]/$newfile
1234 }
1235 set sourcefile $newfile
1236 }
1237 set newfile [remote_download host $sourcefile $objfile]
1238 set cmdret 0
1239 if { $newfile == "" } {
1240 set cmdret 1
1241 }
1242 } else {
1243 if { [istarget "hppa*-*-*"] \
1244 && ![istarget "*-*-linux*"] \
1245 && ![istarget "*-*-netbsd*" ] } {
1246 set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s"
1247 send_log "$cmd\n"
1248 set cmdret [remote_exec host [concat sh -c [list "$cmd"]]]
1249 set cmdret [lindex $cmdret 0]
1250 if { $cmdret != 0 } {
1251 perror "sed failure"
1252 unresolved $testname
1253 continue
1254 }
1255 set sourcefile tmpdir/asm.s
1256 }
1257 set cmd "$AS $ASFLAGS $as_flags $sourceasflags -o $objfile $sourcefile"
1258
1259 send_log "$cmd\n"
1260 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1261 remote_upload host "dump.tmp"
1262 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1263 remote_file host delete "dump.tmp"
1264 remote_file build delete "dump.tmp"
1265 set cmdret [lindex $cmdret 0]
1266 }
1267 if { $cmdret == 0 && $run_objcopy_objects } {
1268 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
1269
1270 send_log "$cmd\n"
1271 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
1272 "" "/dev/null" "dump.tmp"]
1273 remote_upload host "dump.tmp"
1274 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1275 remote_file host delete "dump.tmp"
1276 remote_file build delete "dump.tmp"
1277 set cmdret [lindex $cmdret 0]
1278 }
1279 }
1280
1281 # Perhaps link the file(s).
1282 if { $cmdret == 0 && $run_ld } {
1283 set objfile "tmpdir/dump"
1284 catch "exec rm -f $objfile" exec_output
1285
1286 set ld_extra_opt ""
1287 global ld
1288 set ld "$LD"
5fd104ad
AM
1289 if [check_relro_support] {
1290 set ld_extra_opt "-z norelro"
1291 }
52d6f3ee 1292
4d496013
AM
1293 # Add -L$srcdir/$subdir so that the linker command can use
1294 # linker scripts in the source directory.
1295 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
8ffb70eb
AM
1296 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
1297
4d496013
AM
1298 # If needed then check for, or add a -Map option.
1299 set mapfile ""
1300 if { $opts(map) != "" } then {
1301 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
1302 # Found existing mapfile option
1303 verbose -log "Existing mapfile '$mapfile' found"
1304 } else {
1305 # No mapfile option.
1306 set mapfile "tmpdir/dump.map"
1307 verbose -log "Adding mapfile '$mapfile'"
1308 set cmd "$cmd -Map=$mapfile"
1309 }
1310 }
1311
1312 send_log "$cmd\n"
1313 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1314 remote_upload host "dump.tmp"
1315 append comp_output [file_contents "dump.tmp"]
1316 remote_file host delete "dump.tmp"
1317 remote_file build delete "dump.tmp"
1318 set cmdret [lindex $cmdret 0]
1319
1320 if { $cmdret == 0 && $run_objcopy } {
1321 set infile $objfile
1322 set objfile "tmpdir/dump1"
1323 remote_file host delete $objfile
1324
1325 # Note that we don't use OBJCOPYFLAGS here; any flags must be
1326 # explicitly specified.
1327 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
1328
1329 send_log "$cmd\n"
1330 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1331 remote_upload host "dump.tmp"
1332 append comp_output [file_contents "dump.tmp"]
1333 remote_file host delete "dump.tmp"
1334 remote_file build delete "dump.tmp"
1335 set cmdret [lindex $cmdret 0]
1336 }
1337 } else {
1338 set objfile [lindex $objfiles 0]
1339 }
1340
1341 if { $cmdret == 0 && $opts(PROG) != "" } {
1342 set destopt ${copyfile}.o
1343 switch -- $opts(PROG) {
1344 ar { set program ar }
1345 elfedit {
1346 set program elfedit
1347 set destopt ""
1348 }
1349 nm { set program nm }
1350 objcopy { set program objcopy }
1351 ranlib { set program ranlib }
1352 strings { set program strings }
1353 strip {
1354 set program strip
1355 set destopt "-o $destopt"
1356 }
1357 default {
1358 perror "unrecognized PROG option $opts(PROG) in $file.d"
1359 unresolved $testname
1360 continue
1361 }
1362 }
1363
1364 set progopts1 $opts($program)
1365 eval set progopts \$[string toupper $program]FLAGS
1366 eval set binary \$[string toupper $program]
1367
1368 if { ![is_remote host] && [which $binary] == 0 } {
1369 untested $testname
1370 continue
1371 }
1372
1373 verbose "running $binary $progopts $progopts1" 3
1374 set cmd "$binary $progopts $progopts1 $objfile $destopt"
1375
1376 # Ensure consistent sorting of symbols
1377 if {[info exists env(LC_ALL)]} {
1378 set old_lc_all $env(LC_ALL)
1379 }
1380 set env(LC_ALL) "C"
1381 send_log "$cmd\n"
1382 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1383 set cmdret [lindex $cmdret 0]
1384 remote_upload host "dump.tmp"
1385 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1386 remote_file host delete "dump.tmp"
1387 remote_file build delete "dump.tmp"
1388 if {[info exists old_lc_all]} {
1389 set env(LC_ALL) $old_lc_all
1390 } else {
1391 unset env(LC_ALL)
1392 }
1393 if { $destopt != "" } {
1394 set objfile ${copyfile}.o
1395 }
1396 }
1397
1398 set want_out(source) ""
1399 set want_out(terminal) 0
1400 if { $err_warn } {
1401 if { $opts(error) != "" || $opts(error_output) != "" } {
1402 set want_out(terminal) 1
1403 }
1404
1405 if { $opts(error) != "" || $opts(warning) != "" } {
1406 set want_out(source) "regex"
1407 if { $opts(error) != "" } {
1408 set want_out(regex) $opts(error)
1409 } else {
1410 set want_out(regex) $opts(warning)
1411 }
1412 } else {
1413 set want_out(source) "file"
1414 if { $opts(error_output) != "" } {
1415 set want_out(file) $opts(error_output)
1416 } else {
1417 set want_out(file) $opts(warning_output)
1418 }
1419 }
1420 }
1421
1422 regsub "\n$" $comp_output "" comp_output
1423 if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } {
1424 set exitstat "succeeded"
1425 if { $cmdret != 0 } { set exitstat "failed" }
1426
1427 if { $want_out(source) == "regex" } {
1428 verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>"
1429 } elseif { $want_out(source) == "file" } {
1430 verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)"
1431 set_file_contents "tmpdir/ld.messages" "$comp_output"
1432 } else {
1433 verbose -log "$exitstat with: <$comp_output>, no expected output"
1434 }
1435
1436 if { (($want_out(source) == "") == ($comp_output == "")) \
1437 && (($cmdret == 0) == ($want_out(terminal) == 0)) \
1438 && ((($want_out(source) == "regex") \
1439 && [regexp -- $want_out(regex) $comp_output]) \
1440 || (($want_out(source) == "file") \
1441 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } {
1442 # We have the expected output.
1443 if { $want_out(terminal) || $dumpprogram == "" } {
1444 pass $testname
1445 continue
1446 }
1447 } else {
1448 fail $testname
1449 continue
1450 }
1451 }
1452
1453 # We must not have expected failure if we get here.
1454 if { $want_out(terminal) } {
1455 fail $testname
1456 continue
1457 }
1458
1459 if { $opts(map) != "" } then {
1460 # Check the map file matches.
1461 set map_pattern_file $srcdir/$subdir/$opts(map)
1462 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1463 if { [regexp_diff $mapfile $map_pattern_file] } then {
1464 fail "$testname (map file check)"
1465 } else {
1466 pass "$testname (map file check)"
1467 }
1468
1469 if { $dumpprogram == "" } then {
1470 continue
1471 }
1472 }
1473
1474 set progopts1 $opts($dumpprogram)
1475 eval set progopts \$[string toupper $dumpprogram]FLAGS
1476 eval set binary \$[string toupper $dumpprogram]
1477
1478 if { ![is_remote host] && [which $binary] == 0 } {
1479 untested $testname
1480 continue
1481 }
1482
1483 # For objdump of gas output, automatically translate standard section names
1484 set sect_names ""
1485 if { !$run_ld && $dumpprogram == "objdump" \
1486 && $opts(section_subst) != "no" \
1487 && ![string match "*-b binary*" $progopts1] } {
1488 set sect_names [get_standard_section_names]
1489 if { $sect_names != ""} {
1490 regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1
1491 regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1
1492 regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1
1493 }
1494 }
1495
1496 if { $progopts1 == "" } { set $progopts1 "-r" }
1497 verbose "running $binary $progopts $progopts1" 3
1498
1499 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1500
1501 # Ensure consistent sorting of symbols
1502 if {[info exists env(LC_ALL)]} {
1503 set old_lc_all $env(LC_ALL)
1504 }
1505 set env(LC_ALL) "C"
1506 send_log "$cmd\n"
1507 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1508 set cmdret [lindex $cmdret 0]
1509 remote_upload host "dump.tmp"
1510 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1511 remote_file host delete "dump.tmp"
1512 remote_file build delete "dump.tmp"
1513 if {[info exists old_lc_all]} {
1514 set env(LC_ALL) $old_lc_all
1515 } else {
1516 unset env(LC_ALL)
1517 }
1518 if { $cmdret != 0 || $comp_output != "" } {
1519 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1520 fail $testname
1521 continue
1522 }
1523
1524 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1525
1526 # Create the substition list for objdump output.
1527 set regexp_subst ""
1528 if { $sect_names != "" } {
1529 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \
1530 "\\\\?\\.data" [lindex $sect_names 1] \
1531 "\\\\?\\.bss" [lindex $sect_names 2] ]
1532 }
1533
1534 if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then {
1535 fail $testname
1536 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1537 continue
1538 }
1539
1540 pass $testname
8ffb70eb 1541 }
8ffb70eb
AM
1542}
1543
1544proc slurp_options { file } {
1545 # If options_regsub(foo) is set to {a b}, then the contents of a
1546 # "#foo:" line will have regsub -all applied to replace a with b.
1547 global options_regsub
1548
1549 if [catch { set f [open $file r] } x] {
1550 #perror "couldn't open `$file': $x"
1551 perror "$x"
1552 return -1
1553 }
1554 set opt_array {}
1555 # whitespace expression
1556 set ws {[ ]*}
1557 set nws {[^ ]*}
1558 # whitespace is ignored anywhere except within the options list;
1559 # option names are alphanumeric plus underscore.
1560 set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$"
1561 while { [gets $f line] != -1 } {
1562 set line [string trim $line]
1563 # Whitespace here is space-tab.
1564 if [regexp $pat $line xxx opt_name opt_val] {
1565 # match!
1566 if [info exists options_regsub($opt_name)] {
1567 set subst $options_regsub($opt_name)
1568 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1569 opt_val
1570 }
1571 lappend opt_array [list $opt_name $opt_val]
1572 } elseif {![regexp "^#" $line ]} {
1573 break
1574 }
1575 }
1576 close $f
1577 return $opt_array
1578}
1579
1580proc file_contents { filename } {
1581 set file [open $filename r]
1582 set contents [read $file]
1583 close $file
1584 return $contents
1585}
1586
1587proc set_file_contents { filename contents } {
1588 set file [open $filename w]
1589 puts $file "$contents"
1590 close $file
1591}
1592
1593# Look for big-endian or little-endian switches in the multlib
1594# options and translate these into a -EB or -EL switch. Note
1595# we cannot rely upon proc process_multilib_options to do this
1596# for us because for some targets the compiler does not support
1597# -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
1598# the site.exp file will include the switch "-mbig-endian"
1599# (rather than "big-endian") which is not detected by proc
1600# process_multilib_options.
1601#
1602proc big_or_little_endian {} {
1603
1604 if [board_info [target_info name] exists multilib_flags] {
1605 set tmp_flags " [board_info [target_info name] multilib_flags]"
1606
1607 foreach x $tmp_flags {
e3696f67
AM
1608 switch -glob $x {
1609 *big*endian -
1610 eb -
1611 EB -
1612 -eb -
1613 -EB -
1614 -mb -
1615 -meb {
8ffb70eb
AM
1616 set flags " -EB"
1617 return $flags
1618 }
e3696f67
AM
1619 *little*endian -
1620 el -
1621 EL -
1622 -el -
1623 -EL -
1624 -ml -
1625 -mel {
8ffb70eb
AM
1626 set flags " -EL"
1627 return $flags
1628 }
1629 }
1630 }
1631 }
1632
1633 set flags ""
1634 return $flags
1635}
1636
1637# Internal procedure: return the names of the standard sections
1638#
1639proc get_standard_section_names {} {
8d3c78e4 1640 if [istarget "rx-*-elf"] {
8ffb70eb
AM
1641 return { "P" "D_1" "B_1" }
1642 }
0b1352e0
AM
1643 if { [istarget "alpha*-*-*vms*"] || [is_som_format] } {
1644 return { {\$CODE\$} {\$DATA\$} {\$BSS\$} }
8ffb70eb
AM
1645 }
1646 return
1647}