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