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