1 | # Support routines for LD testsuite.
|
---|
2 | # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
---|
3 | # Free Software Foundation, Inc.
|
---|
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
---|
18 | #
|
---|
19 | #
|
---|
20 | # default_ld_version
|
---|
21 | # extract and print the version number of ld
|
---|
22 | #
|
---|
23 | proc default_ld_version { ld } {
|
---|
24 | global host_triplet
|
---|
25 |
|
---|
26 | if { [which $ld] == 0 } then {
|
---|
27 | perror "$ld does not exist"
|
---|
28 | exit 1
|
---|
29 | }
|
---|
30 |
|
---|
31 | catch "exec $ld --version" tmp
|
---|
32 | set tmp [prune_warnings $tmp]
|
---|
33 | regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
|
---|
34 | if [info exists number] then {
|
---|
35 | clone_output "$ld $number\n"
|
---|
36 | }
|
---|
37 | }
|
---|
38 |
|
---|
39 | #
|
---|
40 | # default_ld_relocate
|
---|
41 | # link an object using relocation
|
---|
42 | #
|
---|
43 | proc default_ld_relocate { ld target objects } {
|
---|
44 | global HOSTING_EMU
|
---|
45 | global host_triplet
|
---|
46 |
|
---|
47 | if { [which $ld] == 0 } then {
|
---|
48 | perror "$ld does not exist"
|
---|
49 | return 0
|
---|
50 | }
|
---|
51 |
|
---|
52 | verbose -log "$ld $HOSTING_EMU -o $target -r $objects"
|
---|
53 |
|
---|
54 | catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output
|
---|
55 | set exec_output [prune_warnings $exec_output]
|
---|
56 | if [string match "" $exec_output] then {
|
---|
57 | return 1
|
---|
58 | } else {
|
---|
59 | verbose -log "$exec_output"
|
---|
60 | return 0
|
---|
61 | }
|
---|
62 | }
|
---|
63 |
|
---|
64 | # Check to see if ld is being invoked with a non-endian output format
|
---|
65 |
|
---|
66 | proc is_endian_output_format { object_flags } {
|
---|
67 |
|
---|
68 | if {[string match "*-oformat binary*" $object_flags] || \
|
---|
69 | [string match "*-oformat ieee*" $object_flags] || \
|
---|
70 | [string match "*-oformat ihex*" $object_flags] || \
|
---|
71 | [string match "*-oformat netbsd-core*" $object_flags] || \
|
---|
72 | [string match "*-oformat srec*" $object_flags] || \
|
---|
73 | [string match "*-oformat tekhex*" $object_flags] || \
|
---|
74 | [string match "*-oformat trad-core*" $object_flags] } then {
|
---|
75 | return 0
|
---|
76 | } else {
|
---|
77 | return 1
|
---|
78 | }
|
---|
79 | }
|
---|
80 |
|
---|
81 | # Look for big-endian or little-endian switches in the multlib
|
---|
82 | # options and translate these into a -EB or -EL switch. Note
|
---|
83 | # we cannot rely upon proc process_multilib_options to do this
|
---|
84 | # for us because for some targets the compiler does not support
|
---|
85 | # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
|
---|
86 | # the site.exp file will include the switch "-mbig-endian"
|
---|
87 | # (rather than "big-endian") which is not detected by proc
|
---|
88 | # process_multilib_options.
|
---|
89 |
|
---|
90 | proc big_or_little_endian {} {
|
---|
91 |
|
---|
92 | if [board_info [target_info name] exists multilib_flags] {
|
---|
93 | set tmp_flags " [board_info [target_info name] multilib_flags]";
|
---|
94 |
|
---|
95 | foreach x $tmp_flags {
|
---|
96 | case $x in {
|
---|
97 | {*big*endian eb EB -eb -EB -mb} {
|
---|
98 | set flags " -EB"
|
---|
99 | return $flags
|
---|
100 | }
|
---|
101 | {*little*endian el EL -el -EL -ml} {
|
---|
102 | set flags " -EL"
|
---|
103 | return $flags
|
---|
104 | }
|
---|
105 | }
|
---|
106 | }
|
---|
107 | }
|
---|
108 |
|
---|
109 | set flags ""
|
---|
110 | return $flags
|
---|
111 | }
|
---|
112 |
|
---|
113 | #
|
---|
114 | # default_ld_link
|
---|
115 | # link a program using ld
|
---|
116 | #
|
---|
117 | proc default_ld_link { ld target objects } {
|
---|
118 | global HOSTING_EMU
|
---|
119 | global HOSTING_CRT0
|
---|
120 | global HOSTING_LIBS
|
---|
121 | global LIBS
|
---|
122 | global host_triplet
|
---|
123 | global link_output
|
---|
124 |
|
---|
125 | set objs "$HOSTING_CRT0 $objects"
|
---|
126 | set libs "$LIBS $HOSTING_LIBS"
|
---|
127 |
|
---|
128 | if { [which $ld] == 0 } then {
|
---|
129 | perror "$ld does not exist"
|
---|
130 | return 0
|
---|
131 | }
|
---|
132 |
|
---|
133 | if [is_endian_output_format $objects] then {
|
---|
134 | set flags [big_or_little_endian]
|
---|
135 | } else {
|
---|
136 | set flags ""
|
---|
137 | }
|
---|
138 | verbose -log "$ld $HOSTING_EMU $flags -o $target $objs $libs"
|
---|
139 |
|
---|
140 | catch "exec $ld $HOSTING_EMU $flags -o $target $objs $libs" link_output
|
---|
141 | set exec_output [prune_warnings $link_output]
|
---|
142 | if [string match "" $link_output] then {
|
---|
143 | return 1
|
---|
144 | } else {
|
---|
145 | verbose -log "$link_output"
|
---|
146 | return 0
|
---|
147 | }
|
---|
148 | }
|
---|
149 |
|
---|
150 | #
|
---|
151 | # default_ld_simple_link
|
---|
152 | # link a program using ld, without including any libraries
|
---|
153 | #
|
---|
154 | proc default_ld_simple_link { ld target objects } {
|
---|
155 | global host_triplet
|
---|
156 | global link_output
|
---|
157 |
|
---|
158 | if { [which $ld] == 0 } then {
|
---|
159 | perror "$ld does not exist"
|
---|
160 | return 0
|
---|
161 | }
|
---|
162 |
|
---|
163 | if [is_endian_output_format $objects] then {
|
---|
164 | set flags [big_or_little_endian]
|
---|
165 | } else {
|
---|
166 | set flags ""
|
---|
167 | }
|
---|
168 |
|
---|
169 | verbose -log "$ld $flags -o $target $objects"
|
---|
170 |
|
---|
171 | catch "exec $ld $flags -o $target $objects" link_output
|
---|
172 | set exec_output [prune_warnings $link_output]
|
---|
173 |
|
---|
174 | # We don't care if we get a warning about a non-existent start
|
---|
175 | # symbol, since the default linker script might use ENTRY.
|
---|
176 | regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
|
---|
177 |
|
---|
178 | if [string match "" $exec_output] then {
|
---|
179 | return 1
|
---|
180 | } else {
|
---|
181 | verbose -log "$exec_output"
|
---|
182 | return 0
|
---|
183 | }
|
---|
184 | }
|
---|
185 |
|
---|
186 | #
|
---|
187 | # default_ld_compile
|
---|
188 | # compile an object using cc
|
---|
189 | #
|
---|
190 | proc default_ld_compile { cc source object } {
|
---|
191 | global CFLAGS
|
---|
192 | global srcdir
|
---|
193 | global subdir
|
---|
194 | global host_triplet
|
---|
195 | global gcc_gas_flag
|
---|
196 |
|
---|
197 | set cc_prog $cc
|
---|
198 | if {[llength $cc_prog] > 1} then {
|
---|
199 | set cc_prog [lindex $cc_prog 0]
|
---|
200 | }
|
---|
201 | if {[which $cc_prog] == 0} then {
|
---|
202 | perror "$cc_prog does not exist"
|
---|
203 | return 0
|
---|
204 | }
|
---|
205 |
|
---|
206 | catch "exec rm -f $object" exec_output
|
---|
207 |
|
---|
208 | set flags "-I$srcdir/$subdir $CFLAGS"
|
---|
209 |
|
---|
210 | # If we are compiling with gcc, we want to add gcc_gas_flag to
|
---|
211 | # flags. Rather than determine this in some complex way, we guess
|
---|
212 | # based on the name of the compiler.
|
---|
213 | if {[string match "*gcc*" $cc] || [string match "*++*" $cc]} then {
|
---|
214 | set flags "$gcc_gas_flag $flags"
|
---|
215 | }
|
---|
216 |
|
---|
217 | if [board_info [target_info name] exists multilib_flags] {
|
---|
218 | append flags " [board_info [target_info name] multilib_flags]";
|
---|
219 | }
|
---|
220 |
|
---|
221 | verbose -log "$cc $flags -c $source -o $object"
|
---|
222 |
|
---|
223 | catch "exec $cc $flags -c $source -o $object" exec_output
|
---|
224 | set exec_output [prune_warnings $exec_output]
|
---|
225 | if [string match "" $exec_output] then {
|
---|
226 | if {![file exists $object]} then {
|
---|
227 | regexp ".*/(\[^/\]*)$" $source all dobj
|
---|
228 | regsub "\\.c" $dobj ".o" realobj
|
---|
229 | verbose "looking for $realobj"
|
---|
230 | if {[file exists $realobj]} then {
|
---|
231 | verbose -log "mv $realobj $object"
|
---|
232 | catch "exec mv $realobj $object" exec_output
|
---|
233 | set exec_output [prune_warnings $exec_output]
|
---|
234 | if {![string match "" $exec_output]} then {
|
---|
235 | verbose -log "$exec_output"
|
---|
236 | perror "could not move $realobj to $object"
|
---|
237 | return 0
|
---|
238 | }
|
---|
239 | } else {
|
---|
240 | perror "$object not found after compilation"
|
---|
241 | return 0
|
---|
242 | }
|
---|
243 | }
|
---|
244 | return 1
|
---|
245 | } else {
|
---|
246 | verbose -log "$exec_output"
|
---|
247 | perror "$source: compilation failed"
|
---|
248 | return 0
|
---|
249 | }
|
---|
250 | }
|
---|
251 |
|
---|
252 | #
|
---|
253 | # default_ld_assemble
|
---|
254 | # assemble a file
|
---|
255 | #
|
---|
256 | proc default_ld_assemble { as source object } {
|
---|
257 | global ASFLAGS
|
---|
258 | global host_triplet
|
---|
259 |
|
---|
260 | if {[which $as] == 0} then {
|
---|
261 | perror "$as does not exist"
|
---|
262 | return 0
|
---|
263 | }
|
---|
264 |
|
---|
265 | if ![info exists ASFLAGS] { set ASFLAGS "" }
|
---|
266 |
|
---|
267 | set flags [big_or_little_endian]
|
---|
268 |
|
---|
269 | verbose -log "$as $flags $ASFLAGS -o $object $source"
|
---|
270 |
|
---|
271 | catch "exec $as $flags $ASFLAGS -o $object $source" exec_output
|
---|
272 | set exec_output [prune_warnings $exec_output]
|
---|
273 | if [string match "" $exec_output] then {
|
---|
274 | return 1
|
---|
275 | } else {
|
---|
276 | verbose -log "$exec_output"
|
---|
277 | perror "$source: assembly failed"
|
---|
278 | return 0
|
---|
279 | }
|
---|
280 | }
|
---|
281 |
|
---|
282 | #
|
---|
283 | # default_ld_nm
|
---|
284 | # run nm on a file, putting the result in the array nm_output
|
---|
285 | #
|
---|
286 | proc default_ld_nm { nm nmflags object } {
|
---|
287 | global NMFLAGS
|
---|
288 | global nm_output
|
---|
289 | global host_triplet
|
---|
290 |
|
---|
291 | if {[which $nm] == 0} then {
|
---|
292 | perror "$nm does not exist"
|
---|
293 | return 0
|
---|
294 | }
|
---|
295 |
|
---|
296 | if {[info exists nm_output]} {
|
---|
297 | unset nm_output
|
---|
298 | }
|
---|
299 |
|
---|
300 | if ![info exists NMFLAGS] { set NMFLAGS "" }
|
---|
301 |
|
---|
302 | # Ensure consistent sorting of symbols
|
---|
303 | if {[info exists env(LC_ALL)]} {
|
---|
304 | set old_lc_all $env(LC_ALL)
|
---|
305 | }
|
---|
306 | set env(LC_ALL) "C"
|
---|
307 | verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
|
---|
308 |
|
---|
309 | catch "exec $nm $NMFLAGS $nmflags $object >tmpdir/nm.out" exec_output
|
---|
310 | if {[info exists old_lc_all]} {
|
---|
311 | set env(LC_ALL) $old_lc_all
|
---|
312 | } else {
|
---|
313 | unset env(LC_ALL)
|
---|
314 | }
|
---|
315 | set exec_output [prune_warnings $exec_output]
|
---|
316 | if [string match "" $exec_output] then {
|
---|
317 | set file [open tmpdir/nm.out r]
|
---|
318 | while { [gets $file line] != -1 } {
|
---|
319 | verbose "$line" 2
|
---|
320 | if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
|
---|
321 | set name [string trimleft $name "_"]
|
---|
322 | verbose "Setting nm_output($name) to 0x$value" 2
|
---|
323 | set nm_output($name) 0x$value
|
---|
324 | }
|
---|
325 | }
|
---|
326 | close $file
|
---|
327 | return 1
|
---|
328 | } else {
|
---|
329 | verbose -log "$exec_output"
|
---|
330 | perror "$object: nm failed"
|
---|
331 | return 0
|
---|
332 | }
|
---|
333 | }
|
---|
334 |
|
---|
335 | #
|
---|
336 | # is_elf_format
|
---|
337 | # true if the object format is known to be ELF
|
---|
338 | #
|
---|
339 | proc is_elf_format {} {
|
---|
340 | if { ![istarget *-*-sysv4*] \
|
---|
341 | && ![istarget *-*-unixware*] \
|
---|
342 | && ![istarget *-*-elf*] \
|
---|
343 | && ![istarget *-*-eabi*] \
|
---|
344 | && ![istarget *-*-linux*] \
|
---|
345 | && ![istarget *-*-irix5*] \
|
---|
346 | && ![istarget *-*-irix6*] \
|
---|
347 | && ![istarget *-*-netbsd*] \
|
---|
348 | && ![istarget *-*-solaris2*] } {
|
---|
349 | return 0
|
---|
350 | }
|
---|
351 |
|
---|
352 | if { [istarget *-*-linux*aout*] \
|
---|
353 | || [istarget *-*-linux*oldld*] } {
|
---|
354 | return 0
|
---|
355 | }
|
---|
356 |
|
---|
357 | if { ![istarget *-*-netbsdelf*] \
|
---|
358 | && ([istarget *-*-netbsd*aout*] \
|
---|
359 | || [istarget *-*-netbsdpe*] \
|
---|
360 | || [istarget arm*-*-netbsd*] \
|
---|
361 | || [istarget sparc-*-netbsd*] \
|
---|
362 | || [istarget i*86-*-netbsd*] \
|
---|
363 | || [istarget m68*-*-netbsd*] \
|
---|
364 | || [istarget vax-*-netbsd*] \
|
---|
365 | || [istarget ns32k-*-netbsd*]) } {
|
---|
366 | return 0
|
---|
367 | }
|
---|
368 | return 1
|
---|
369 | }
|
---|
370 |
|
---|
371 | #
|
---|
372 | # simple_diff
|
---|
373 | # compares two files line-by-line
|
---|
374 | # returns differences if exist
|
---|
375 | # returns null if file(s) cannot be opened
|
---|
376 | #
|
---|
377 | proc simple_diff { file_1 file_2 } {
|
---|
378 | global target
|
---|
379 |
|
---|
380 | set eof -1
|
---|
381 | set differences 0
|
---|
382 |
|
---|
383 | if [file exists $file_1] then {
|
---|
384 | set file_a [open $file_1 r]
|
---|
385 | } else {
|
---|
386 | warning "$file_1 doesn't exist"
|
---|
387 | return
|
---|
388 | }
|
---|
389 |
|
---|
390 | if [file exists $file_2] then {
|
---|
391 | set file_b [open $file_2 r]
|
---|
392 | } else {
|
---|
393 | fail "$file_2 doesn't exist"
|
---|
394 | return
|
---|
395 | }
|
---|
396 |
|
---|
397 | verbose "# Diff'ing: $file_1 $file_2\n" 2
|
---|
398 |
|
---|
399 | while { [gets $file_a line] != $eof } {
|
---|
400 | if [regexp "^#.*$" $line] then {
|
---|
401 | continue
|
---|
402 | } else {
|
---|
403 | lappend list_a $line
|
---|
404 | }
|
---|
405 | }
|
---|
406 | close $file_a
|
---|
407 |
|
---|
408 | while { [gets $file_b line] != $eof } {
|
---|
409 | if [regexp "^#.*$" $line] then {
|
---|
410 | continue
|
---|
411 | } else {
|
---|
412 | lappend list_b $line
|
---|
413 | }
|
---|
414 | }
|
---|
415 | close $file_b
|
---|
416 |
|
---|
417 | for { set i 0 } { $i < [llength $list_a] } { incr i } {
|
---|
418 | set line_a [lindex $list_a $i]
|
---|
419 | set line_b [lindex $list_b $i]
|
---|
420 |
|
---|
421 | verbose "\t$file_1: $i: $line_a\n" 3
|
---|
422 | verbose "\t$file_2: $i: $line_b\n" 3
|
---|
423 | if [string compare $line_a $line_b] then {
|
---|
424 | verbose -log "\t$file_1: $i: $line_a\n"
|
---|
425 | verbose -log "\t$file_2: $i: $line_b\n"
|
---|
426 |
|
---|
427 | fail "Test: $target"
|
---|
428 | return
|
---|
429 | }
|
---|
430 | }
|
---|
431 |
|
---|
432 | if { [llength $list_a] != [llength $list_b] } {
|
---|
433 | fail "Test: $target"
|
---|
434 | return
|
---|
435 | }
|
---|
436 |
|
---|
437 | if $differences<1 then {
|
---|
438 | pass "Test: $target"
|
---|
439 | }
|
---|
440 | }
|
---|
441 |
|
---|
442 | # run_dump_test FILE
|
---|
443 | # Copied from gas testsuite, tweaked and further extended.
|
---|
444 | #
|
---|
445 | # Assemble a .s file, then run some utility on it and check the output.
|
---|
446 | #
|
---|
447 | # There should be an assembly language file named FILE.s in the test
|
---|
448 | # suite directory, and a pattern file called FILE.d. `run_dump_test'
|
---|
449 | # will assemble FILE.s, run some tool like `objdump', `objcopy', or
|
---|
450 | # `nm' on the .o file to produce textual output, and then analyze that
|
---|
451 | # with regexps. The FILE.d file specifies what program to run, and
|
---|
452 | # what to expect in its output.
|
---|
453 | #
|
---|
454 | # The FILE.d file begins with zero or more option lines, which specify
|
---|
455 | # flags to pass to the assembler, the program to run to dump the
|
---|
456 | # assembler's output, and the options it wants. The option lines have
|
---|
457 | # the syntax:
|
---|
458 | #
|
---|
459 | # # OPTION: VALUE
|
---|
460 | #
|
---|
461 | # OPTION is the name of some option, like "name" or "objdump", and
|
---|
462 | # VALUE is OPTION's value. The valid options are described below.
|
---|
463 | # Whitespace is ignored everywhere, except within VALUE. The option
|
---|
464 | # list ends with the first line that doesn't match the above syntax
|
---|
465 | # (hmm, not great for error detection).
|
---|
466 | #
|
---|
467 | # The interesting options are:
|
---|
468 | #
|
---|
469 | # name: TEST-NAME
|
---|
470 | # The name of this test, passed to DejaGNU's `pass' and `fail'
|
---|
471 | # commands. If omitted, this defaults to FILE, the root of the
|
---|
472 | # .s and .d files' names.
|
---|
473 | #
|
---|
474 | # as: FLAGS
|
---|
475 | # When assembling, pass FLAGS to the assembler.
|
---|
476 | # If assembling several files, you can pass different assembler
|
---|
477 | # options in the "source" directives. See below.
|
---|
478 | #
|
---|
479 | # ld: FLAGS
|
---|
480 | # Link assembled files using FLAGS, in the order of the "source"
|
---|
481 | # directives, when using multiple files.
|
---|
482 | #
|
---|
483 | # objcopy_linked_file: FLAGS
|
---|
484 | # Run objcopy on the linked file with the specified flags.
|
---|
485 | # This lets you transform the linked file using objcopy, before the
|
---|
486 | # result is analyzed by an analyzer program specified below (which
|
---|
487 | # may in turn *also* be objcopy).
|
---|
488 | #
|
---|
489 | # PROG: PROGRAM-NAME
|
---|
490 | # The name of the program to run to analyze the .o file produced
|
---|
491 | # by the assembler or the linker output. This can be omitted;
|
---|
492 | # run_dump_test will guess which program to run by seeing which of
|
---|
493 | # the flags options below is present.
|
---|
494 | #
|
---|
495 | # objdump: FLAGS
|
---|
496 | # nm: FLAGS
|
---|
497 | # objcopy: FLAGS
|
---|
498 | # Use the specified program to analyze the assembler or linker
|
---|
499 | # output file, and pass it FLAGS, in addition to the output name.
|
---|
500 | # Note that they are run with LC_ALL=C in the environment to give
|
---|
501 | # consistent sorting of symbols.
|
---|
502 | #
|
---|
503 | # source: SOURCE [FLAGS]
|
---|
504 | # Assemble the file SOURCE.s using the flags in the "as" directive
|
---|
505 | # and the (optional) FLAGS. If omitted, the source defaults to
|
---|
506 | # FILE.s.
|
---|
507 | # This is useful if several .d files want to share a .s file.
|
---|
508 | # More than one "source" directive can be given, which is useful
|
---|
509 | # when testing linking.
|
---|
510 | #
|
---|
511 | # xfail: TARGET
|
---|
512 | # The test is expected to fail on TARGET. This may occur more than
|
---|
513 | # once.
|
---|
514 | #
|
---|
515 | # target: TARGET
|
---|
516 | # Only run the test for TARGET. This may occur more than once; the
|
---|
517 | # target being tested must match at least one.
|
---|
518 | #
|
---|
519 | # notarget: TARGET
|
---|
520 | # Do not run the test for TARGET. This may occur more than once;
|
---|
521 | # the target being tested must not match any of them.
|
---|
522 | #
|
---|
523 | # error: REGEX
|
---|
524 | # An error with message matching REGEX must be emitted for the test
|
---|
525 | # to pass. The PROG, objdump, nm and objcopy options have no
|
---|
526 | # meaning and need not supplied if this is present.
|
---|
527 | #
|
---|
528 | # Each option may occur at most once unless otherwise mentioned.
|
---|
529 | #
|
---|
530 | # After the option lines come regexp lines. `run_dump_test' calls
|
---|
531 | # `regexp_diff' to compare the output of the dumping tool against the
|
---|
532 | # regexps in FILE.d. `regexp_diff' is defined later in this file; see
|
---|
533 | # further comments there.
|
---|
534 |
|
---|
535 | proc run_dump_test { name } {
|
---|
536 | global subdir srcdir
|
---|
537 | global OBJDUMP NM AS OBJCOPY READELF LD
|
---|
538 | global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
|
---|
539 | global host_triplet runtests
|
---|
540 | global env
|
---|
541 |
|
---|
542 | if [string match "*/*" $name] {
|
---|
543 | set file $name
|
---|
544 | set name [file tail $name]
|
---|
545 | } else {
|
---|
546 | set file "$srcdir/$subdir/$name"
|
---|
547 | }
|
---|
548 |
|
---|
549 | if ![runtest_file_p $runtests $name] then {
|
---|
550 | return
|
---|
551 | }
|
---|
552 |
|
---|
553 | set opt_array [slurp_options "${file}.d"]
|
---|
554 | if { $opt_array == -1 } {
|
---|
555 | perror "error reading options from $file.d"
|
---|
556 | unresolved $subdir/$name
|
---|
557 | return
|
---|
558 | }
|
---|
559 | set dumpfile tmpdir/dump.out
|
---|
560 | set run_ld 0
|
---|
561 | set run_objcopy 0
|
---|
562 | set opts(as) {}
|
---|
563 | set opts(ld) {}
|
---|
564 | set opts(xfail) {}
|
---|
565 | set opts(target) {}
|
---|
566 | set opts(notarget) {}
|
---|
567 | set opts(objdump) {}
|
---|
568 | set opts(nm) {}
|
---|
569 | set opts(objcopy) {}
|
---|
570 | set opts(readelf) {}
|
---|
571 | set opts(name) {}
|
---|
572 | set opts(PROG) {}
|
---|
573 | set opts(source) {}
|
---|
574 | set opts(error) {}
|
---|
575 | set opts(objcopy_linked_file) {}
|
---|
576 | set asflags(${file}.s) {}
|
---|
577 |
|
---|
578 | foreach i $opt_array {
|
---|
579 | set opt_name [lindex $i 0]
|
---|
580 | set opt_val [lindex $i 1]
|
---|
581 | if ![info exists opts($opt_name)] {
|
---|
582 | perror "unknown option $opt_name in file $file.d"
|
---|
583 | unresolved $subdir/$name
|
---|
584 | return
|
---|
585 | }
|
---|
586 |
|
---|
587 | switch -- $opt_name {
|
---|
588 | xfail {}
|
---|
589 | target {}
|
---|
590 | notarget {}
|
---|
591 | source {
|
---|
592 | # Move any source-specific as-flags to a separate array to
|
---|
593 | # simplify processing.
|
---|
594 | if { [llength $opt_val] > 1 } {
|
---|
595 | set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
|
---|
596 | set opt_val [lindex $opt_val 0]
|
---|
597 | } else {
|
---|
598 | set asflags($opt_val) {}
|
---|
599 | }
|
---|
600 | }
|
---|
601 | default {
|
---|
602 | if [string length $opts($opt_name)] {
|
---|
603 | perror "option $opt_name multiply set in $file.d"
|
---|
604 | unresolved $subdir/$name
|
---|
605 | return
|
---|
606 | }
|
---|
607 |
|
---|
608 | # A single "# ld:" with no options should do the right thing.
|
---|
609 | if { $opt_name == "ld" } {
|
---|
610 | set run_ld 1
|
---|
611 | }
|
---|
612 | # Likewise objcopy_linked_file.
|
---|
613 | if { $opt_name == "objcopy_linked_file" } {
|
---|
614 | set run_objcopy 1
|
---|
615 | }
|
---|
616 | }
|
---|
617 | }
|
---|
618 | set opts($opt_name) [concat $opts($opt_name) $opt_val]
|
---|
619 | }
|
---|
620 |
|
---|
621 | # Decide early whether we should run the test for this target.
|
---|
622 | if { [llength $opts(target)] > 0 } {
|
---|
623 | set targmatch 0
|
---|
624 | foreach targ $opts(target) {
|
---|
625 | if [istarget $targ] {
|
---|
626 | set targmatch 1
|
---|
627 | break
|
---|
628 | }
|
---|
629 | }
|
---|
630 | if { $targmatch == 0 } {
|
---|
631 | return
|
---|
632 | }
|
---|
633 | }
|
---|
634 | foreach targ $opts(notarget) {
|
---|
635 | if [istarget $targ] {
|
---|
636 | return
|
---|
637 | }
|
---|
638 | }
|
---|
639 |
|
---|
640 | if {$opts(PROG) != ""} {
|
---|
641 | switch -- $opts(PROG) {
|
---|
642 | objdump
|
---|
643 | { set program objdump }
|
---|
644 | nm
|
---|
645 | { set program nm }
|
---|
646 | objcopy
|
---|
647 | { set program objcopy }
|
---|
648 | readelf
|
---|
649 | { set program readelf }
|
---|
650 | default
|
---|
651 | { perror "unrecognized program option $opts(PROG) in $file.d"
|
---|
652 | unresolved $subdir/$name
|
---|
653 | return }
|
---|
654 | }
|
---|
655 | } elseif { $opts(error) != "" } {
|
---|
656 | # It's meaningless to require an output-testing method when we
|
---|
657 | # expect an error. For simplicity, we fake an arbitrary method.
|
---|
658 | set program "nm"
|
---|
659 | } else {
|
---|
660 | # Guess which program to run, by seeing which option was specified.
|
---|
661 | set program ""
|
---|
662 | foreach p {objdump objcopy nm readelf} {
|
---|
663 | if {$opts($p) != ""} {
|
---|
664 | if {$program != ""} {
|
---|
665 | perror "ambiguous dump program in $file.d"
|
---|
666 | unresolved $subdir/$name
|
---|
667 | return
|
---|
668 | } else {
|
---|
669 | set program $p
|
---|
670 | }
|
---|
671 | }
|
---|
672 | }
|
---|
673 | if {$program == ""} {
|
---|
674 | perror "dump program unspecified in $file.d"
|
---|
675 | unresolved $subdir/$name
|
---|
676 | return
|
---|
677 | }
|
---|
678 | }
|
---|
679 |
|
---|
680 | set progopts1 $opts($program)
|
---|
681 | eval set progopts \$[string toupper $program]FLAGS
|
---|
682 | eval set binary \$[string toupper $program]
|
---|
683 | if { $opts(name) == "" } {
|
---|
684 | set testname "$subdir/$name"
|
---|
685 | } else {
|
---|
686 | set testname $opts(name)
|
---|
687 | }
|
---|
688 |
|
---|
689 | if { $opts(source) == "" } {
|
---|
690 | set sourcefiles [list ${file}.s]
|
---|
691 | } else {
|
---|
692 | set sourcefiles {}
|
---|
693 | foreach sf $opts(source) {
|
---|
694 | if { [string match "/*" $sf] } {
|
---|
695 | lappend sourcefiles "$sf"
|
---|
696 | } {
|
---|
697 | lappend sourcefiles "$srcdir/$subdir/$sf"
|
---|
698 | }
|
---|
699 | # Must have asflags indexed on source name.
|
---|
700 | set asflags($srcdir/$subdir/$sf) $asflags($sf)
|
---|
701 | }
|
---|
702 | }
|
---|
703 |
|
---|
704 | # Time to setup xfailures.
|
---|
705 | foreach targ $opts(xfail) {
|
---|
706 | setup_xfail $targ
|
---|
707 | }
|
---|
708 |
|
---|
709 | # Assemble each file.
|
---|
710 | set objfiles {}
|
---|
711 | for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
|
---|
712 | set sourcefile [lindex $sourcefiles $i]
|
---|
713 |
|
---|
714 | set objfile "tmpdir/dump$i.o"
|
---|
715 | lappend objfiles $objfile
|
---|
716 | set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
|
---|
717 |
|
---|
718 | send_log "$cmd\n"
|
---|
719 | set cmdret [catch "exec $cmd" comp_output]
|
---|
720 | set comp_output [prune_warnings $comp_output]
|
---|
721 |
|
---|
722 | # We accept errors at assembly stage too, unless we're supposed to
|
---|
723 | # link something.
|
---|
724 | if { $cmdret != 0 || ![string match "" $comp_output] } then {
|
---|
725 | send_log "$comp_output\n"
|
---|
726 | verbose "$comp_output" 3
|
---|
727 | if { $opts(error) != "" && $run_ld == 0 } {
|
---|
728 | if [regexp $opts(error) $comp_output] {
|
---|
729 | pass $testname
|
---|
730 | return
|
---|
731 | }
|
---|
732 | }
|
---|
733 | fail $testname
|
---|
734 | return
|
---|
735 | }
|
---|
736 | }
|
---|
737 |
|
---|
738 | # Perhaps link the file(s).
|
---|
739 | if { $run_ld } {
|
---|
740 | set objfile "tmpdir/dump"
|
---|
741 |
|
---|
742 | # Add -L$srcdir/$subdir so that the linker command can use
|
---|
743 | # linker scripts in the source directory.
|
---|
744 | set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
|
---|
745 | $opts(ld) -o $objfile $objfiles"
|
---|
746 |
|
---|
747 | send_log "$cmd\n"
|
---|
748 | set cmdret [catch "exec $cmd" comp_output]
|
---|
749 | set comp_output [prune_warnings $comp_output]
|
---|
750 |
|
---|
751 | if { $cmdret != 0 || ![string match "" $comp_output] } then {
|
---|
752 | verbose -log "failed with: <$comp_output>, expected: <$opts(error)>"
|
---|
753 | send_log "$comp_output\n"
|
---|
754 | verbose "$comp_output" 3
|
---|
755 | if { $opts(error) != "" && $run_objcopy == 0 } {
|
---|
756 | if [regexp $opts(error) $comp_output] {
|
---|
757 | pass $testname
|
---|
758 | return
|
---|
759 | }
|
---|
760 | }
|
---|
761 | fail $testname
|
---|
762 | return
|
---|
763 | }
|
---|
764 |
|
---|
765 | if { $run_objcopy } {
|
---|
766 | set infile $objfile
|
---|
767 | set objfile "tmpdir/dump1"
|
---|
768 |
|
---|
769 | # Note that we don't use OBJCOPYFLAGS here; any flags must be
|
---|
770 | # explicitly specified.
|
---|
771 | set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
|
---|
772 |
|
---|
773 | send_log "$cmd\n"
|
---|
774 | set cmdret [catch "exec $cmd" comp_output]
|
---|
775 | set comp_output [prune_warnings $comp_output]
|
---|
776 |
|
---|
777 | if { $cmdret != 0 || ![string match "" $comp_output] } then {
|
---|
778 | verbose -log "failed with: <$comp_output>, expected: <$opts(error)>"
|
---|
779 | send_log "$comp_output\n"
|
---|
780 | verbose "$comp_output" 3
|
---|
781 | if { $opts(error) != "" } {
|
---|
782 | if [regexp $opts(error) $comp_output] {
|
---|
783 | pass $testname
|
---|
784 | return
|
---|
785 | }
|
---|
786 | }
|
---|
787 | fail $testname
|
---|
788 | return
|
---|
789 | }
|
---|
790 | }
|
---|
791 | } else {
|
---|
792 | set objfile "tmpdir/dump0.o"
|
---|
793 | }
|
---|
794 |
|
---|
795 | # We must not have expected failure if we get here.
|
---|
796 | if { $opts(error) != "" } {
|
---|
797 | fail $testname
|
---|
798 | return
|
---|
799 | }
|
---|
800 |
|
---|
801 | if { [which $binary] == 0 } {
|
---|
802 | untested $testname
|
---|
803 | return
|
---|
804 | }
|
---|
805 |
|
---|
806 | if { $progopts1 == "" } { set $progopts1 "-r" }
|
---|
807 | verbose "running $binary $progopts $progopts1" 3
|
---|
808 |
|
---|
809 | # Objcopy, unlike the other two, won't send its output to stdout,
|
---|
810 | # so we have to run it specially.
|
---|
811 | set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
|
---|
812 | if { $program == "objcopy" } {
|
---|
813 | set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
|
---|
814 | }
|
---|
815 |
|
---|
816 | # Ensure consistent sorting of symbols
|
---|
817 | if {[info exists env(LC_ALL)]} {
|
---|
818 | set old_lc_all $env(LC_ALL)
|
---|
819 | }
|
---|
820 | set env(LC_ALL) "C"
|
---|
821 | send_log "$cmd\n"
|
---|
822 | catch "exec $cmd" comp_output
|
---|
823 | if {[info exists old_lc_all]} {
|
---|
824 | set env(LC_ALL) $old_lc_all
|
---|
825 | } else {
|
---|
826 | unset env(LC_ALL)
|
---|
827 | }
|
---|
828 | set comp_output [prune_warnings $comp_output]
|
---|
829 | if ![string match "" $comp_output] then {
|
---|
830 | send_log "$comp_output\n"
|
---|
831 | fail $testname
|
---|
832 | return
|
---|
833 | }
|
---|
834 |
|
---|
835 | verbose_eval {[file_contents $dumpfile]} 3
|
---|
836 | if { [regexp_diff $dumpfile "${file}.d"] } then {
|
---|
837 | fail $testname
|
---|
838 | verbose "output is [file_contents $dumpfile]" 2
|
---|
839 | return
|
---|
840 | }
|
---|
841 |
|
---|
842 | pass $testname
|
---|
843 | }
|
---|
844 |
|
---|
845 | proc slurp_options { file } {
|
---|
846 | if [catch { set f [open $file r] } x] {
|
---|
847 | #perror "couldn't open `$file': $x"
|
---|
848 | perror "$x"
|
---|
849 | return -1
|
---|
850 | }
|
---|
851 | set opt_array {}
|
---|
852 | # whitespace expression
|
---|
853 | set ws {[ ]*}
|
---|
854 | set nws {[^ ]*}
|
---|
855 | # whitespace is ignored anywhere except within the options list;
|
---|
856 | # option names are alphabetic plus underscore only.
|
---|
857 | set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
|
---|
858 | while { [gets $f line] != -1 } {
|
---|
859 | set line [string trim $line]
|
---|
860 | # Whitespace here is space-tab.
|
---|
861 | if [regexp $pat $line xxx opt_name opt_val] {
|
---|
862 | # match!
|
---|
863 | lappend opt_array [list $opt_name $opt_val]
|
---|
864 | } else {
|
---|
865 | break
|
---|
866 | }
|
---|
867 | }
|
---|
868 | close $f
|
---|
869 | return $opt_array
|
---|
870 | }
|
---|
871 |
|
---|
872 | # regexp_diff, copied from gas, based on simple_diff above.
|
---|
873 | # compares two files line-by-line
|
---|
874 | # file1 contains strings, file2 contains regexps and #-comments
|
---|
875 | # blank lines are ignored in either file
|
---|
876 | # returns non-zero if differences exist
|
---|
877 | #
|
---|
878 | proc regexp_diff { file_1 file_2 } {
|
---|
879 |
|
---|
880 | set eof -1
|
---|
881 | set end_1 0
|
---|
882 | set end_2 0
|
---|
883 | set differences 0
|
---|
884 | set diff_pass 0
|
---|
885 |
|
---|
886 | if [file exists $file_1] then {
|
---|
887 | set file_a [open $file_1 r]
|
---|
888 | } else {
|
---|
889 | warning "$file_1 doesn't exist"
|
---|
890 | return 1
|
---|
891 | }
|
---|
892 |
|
---|
893 | if [file exists $file_2] then {
|
---|
894 | set file_b [open $file_2 r]
|
---|
895 | } else {
|
---|
896 | fail "$file_2 doesn't exist"
|
---|
897 | close $file_a
|
---|
898 | return 1
|
---|
899 | }
|
---|
900 |
|
---|
901 | verbose " Regexp-diff'ing: $file_1 $file_2" 2
|
---|
902 |
|
---|
903 | while { 1 } {
|
---|
904 | set line_a ""
|
---|
905 | set line_b ""
|
---|
906 | while { [string length $line_a] == 0 } {
|
---|
907 | if { [gets $file_a line_a] == $eof } {
|
---|
908 | set end_1 1
|
---|
909 | break
|
---|
910 | }
|
---|
911 | }
|
---|
912 | while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
|
---|
913 | if [ string match "#pass" $line_b ] {
|
---|
914 | set end_2 1
|
---|
915 | set diff_pass 1
|
---|
916 | break
|
---|
917 | } elseif [ string match "#..." $line_b ] {
|
---|
918 | if { [gets $file_b line_b] == $eof } {
|
---|
919 | set end_2 1
|
---|
920 | break
|
---|
921 | }
|
---|
922 | verbose "looking for \"^$line_b$\"" 3
|
---|
923 | while { ![regexp "^$line_b$" "$line_a"] } {
|
---|
924 | verbose "skipping \"$line_a\"" 3
|
---|
925 | if { [gets $file_a line_a] == $eof } {
|
---|
926 | set end_1 1
|
---|
927 | break
|
---|
928 | }
|
---|
929 | }
|
---|
930 | break
|
---|
931 | }
|
---|
932 | if { [gets $file_b line_b] == $eof } {
|
---|
933 | set end_2 1
|
---|
934 | break
|
---|
935 | }
|
---|
936 | }
|
---|
937 |
|
---|
938 | if { $diff_pass } {
|
---|
939 | break
|
---|
940 | } elseif { $end_1 && $end_2 } {
|
---|
941 | break
|
---|
942 | } elseif { $end_1 } {
|
---|
943 | send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
|
---|
944 | verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
|
---|
945 | set differences 1
|
---|
946 | break
|
---|
947 | } elseif { $end_2 } {
|
---|
948 | send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
|
---|
949 | verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
|
---|
950 | set differences 1
|
---|
951 | break
|
---|
952 | } else {
|
---|
953 | verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
|
---|
954 | if ![regexp "^$line_b$" "$line_a"] {
|
---|
955 | send_log "regexp_diff match failure\n"
|
---|
956 | send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
|
---|
957 | set differences 1
|
---|
958 | }
|
---|
959 | }
|
---|
960 | }
|
---|
961 |
|
---|
962 | if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
|
---|
963 | send_log "$file_1 and $file_2 are different lengths\n"
|
---|
964 | verbose "$file_1 and $file_2 are different lengths" 3
|
---|
965 | set differences 1
|
---|
966 | }
|
---|
967 |
|
---|
968 | close $file_a
|
---|
969 | close $file_b
|
---|
970 |
|
---|
971 | return $differences
|
---|
972 | }
|
---|
973 |
|
---|
974 | proc file_contents { filename } {
|
---|
975 | set file [open $filename r]
|
---|
976 | set contents [read $file]
|
---|
977 | close $file
|
---|
978 | return $contents
|
---|
979 | }
|
---|
980 |
|
---|
981 | # List contains test-items with 3 items followed by 2 lists, one item and
|
---|
982 | # one optional item:
|
---|
983 | # 0:name 1:ld options 2:assembler options
|
---|
984 | # 3:filenames of assembler files 4: action and options. 5: name of output file
|
---|
985 | # 6:compiler flags (optional)
|
---|
986 |
|
---|
987 | # Actions:
|
---|
988 | # objdump: Apply objdump options on result. Compare with regex (last arg).
|
---|
989 | # nm: Apply nm options on result. Compare with regex (last arg).
|
---|
990 | # readelf: Apply readelf options on result. Compare with regex (last arg).
|
---|
991 |
|
---|
992 | proc run_ld_link_tests { ldtests } {
|
---|
993 | global ld
|
---|
994 | global as
|
---|
995 | global nm
|
---|
996 | global objdump
|
---|
997 | global READELF
|
---|
998 | global srcdir
|
---|
999 | global subdir
|
---|
1000 | global env
|
---|
1001 | global CC
|
---|
1002 | global CFLAGS
|
---|
1003 |
|
---|
1004 | foreach testitem $ldtests {
|
---|
1005 | set testname [lindex $testitem 0]
|
---|
1006 | set ld_options [lindex $testitem 1]
|
---|
1007 | set as_options [lindex $testitem 2]
|
---|
1008 | set src_files [lindex $testitem 3]
|
---|
1009 | set actions [lindex $testitem 4]
|
---|
1010 | set binfile tmpdir/[lindex $testitem 5]
|
---|
1011 | set cflags [lindex $testitem 6]
|
---|
1012 | set objfiles {}
|
---|
1013 | set is_unresolved 0
|
---|
1014 | set failed 0
|
---|
1015 |
|
---|
1016 | # verbose -log "Testname is $testname"
|
---|
1017 | # verbose -log "ld_options is $ld_options"
|
---|
1018 | # verbose -log "as_options is $as_options"
|
---|
1019 | # verbose -log "src_files is $src_files"
|
---|
1020 | # verbose -log "actions is $actions"
|
---|
1021 | # verbose -log "binfile is $binfile"
|
---|
1022 |
|
---|
1023 | # Assemble each file in the test.
|
---|
1024 | foreach src_file $src_files {
|
---|
1025 | set objfile "tmpdir/[file rootname $src_file].o"
|
---|
1026 | lappend objfiles $objfile
|
---|
1027 |
|
---|
1028 | if { [file extension $src_file] == ".c" } {
|
---|
1029 | set as_file "tmpdir/[file rootname $src_file].s"
|
---|
1030 | if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
|
---|
1031 | set is_unresolved 1
|
---|
1032 | break
|
---|
1033 | }
|
---|
1034 | } else {
|
---|
1035 | set as_file "$srcdir/$subdir/$src_file"
|
---|
1036 | }
|
---|
1037 | if ![ld_assemble $as "$as_options $as_file" $objfile] {
|
---|
1038 | set is_unresolved 1
|
---|
1039 | break
|
---|
1040 | }
|
---|
1041 | }
|
---|
1042 |
|
---|
1043 | # Catch assembler errors.
|
---|
1044 | if { $is_unresolved != 0 } {
|
---|
1045 | unresolved $testname
|
---|
1046 | continue
|
---|
1047 | }
|
---|
1048 |
|
---|
1049 | if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
|
---|
1050 | fail $testname
|
---|
1051 | } else {
|
---|
1052 | set failed 0
|
---|
1053 | foreach actionlist $actions {
|
---|
1054 | set action [lindex $actionlist 0]
|
---|
1055 | set progopts [lindex $actionlist 1]
|
---|
1056 |
|
---|
1057 | # There are actions where we run regexp_diff on the
|
---|
1058 | # output, and there are other actions (presumably).
|
---|
1059 | # Handling of the former look the same.
|
---|
1060 | set dump_prog ""
|
---|
1061 | switch -- $action {
|
---|
1062 | objdump
|
---|
1063 | { set dump_prog $objdump }
|
---|
1064 | nm
|
---|
1065 | { set dump_prog $nm }
|
---|
1066 | readelf
|
---|
1067 | { set dump_prog $READELF }
|
---|
1068 | default
|
---|
1069 | {
|
---|
1070 | perror "Unrecognized action $action"
|
---|
1071 | set is_unresolved 1
|
---|
1072 | break
|
---|
1073 | }
|
---|
1074 | }
|
---|
1075 |
|
---|
1076 | if { $dump_prog != "" } {
|
---|
1077 | set dumpfile [lindex $actionlist 2]
|
---|
1078 | set binary $dump_prog
|
---|
1079 |
|
---|
1080 | # Ensure consistent sorting of symbols
|
---|
1081 | if {[info exists env(LC_ALL)]} {
|
---|
1082 | set old_lc_all $env(LC_ALL)
|
---|
1083 | }
|
---|
1084 | set env(LC_ALL) "C"
|
---|
1085 | set cmd "$binary $progopts $binfile > dump.out"
|
---|
1086 | send_log "$cmd\n"
|
---|
1087 | catch "exec $cmd" comp_output
|
---|
1088 | if {[info exists old_lc_all]} {
|
---|
1089 | set env(LC_ALL) $old_lc_all
|
---|
1090 | } else {
|
---|
1091 | unset env(LC_ALL)
|
---|
1092 | }
|
---|
1093 | set comp_output [prune_warnings $comp_output]
|
---|
1094 |
|
---|
1095 | if ![string match "" $comp_output] then {
|
---|
1096 | send_log "$comp_output\n"
|
---|
1097 | set failed 1
|
---|
1098 | break
|
---|
1099 | }
|
---|
1100 |
|
---|
1101 | if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
|
---|
1102 | verbose "output is [file_contents "dump.out"]" 2
|
---|
1103 | set failed 1
|
---|
1104 | break
|
---|
1105 | }
|
---|
1106 | }
|
---|
1107 | }
|
---|
1108 |
|
---|
1109 | if { $failed != 0 } {
|
---|
1110 | fail $testname
|
---|
1111 | } else { if { $is_unresolved == 0 } {
|
---|
1112 | pass $testname
|
---|
1113 | } }
|
---|
1114 | }
|
---|
1115 |
|
---|
1116 | # Catch action errors.
|
---|
1117 | if { $is_unresolved != 0 } {
|
---|
1118 | unresolved $testname
|
---|
1119 | continue
|
---|
1120 | }
|
---|
1121 | }
|
---|
1122 | }
|
---|
1123 |
|
---|
1124 |
|
---|
1125 | proc verbose_eval { expr { level 1 } } {
|
---|
1126 | global verbose
|
---|
1127 | if $verbose>$level then { eval verbose "$expr" $level }
|
---|
1128 | }
|
---|
1129 |
|
---|
1130 | # This definition is taken from an unreleased version of DejaGnu. Once
|
---|
1131 | # that version gets released, and has been out in the world for a few
|
---|
1132 | # months at least, it may be safe to delete this copy.
|
---|
1133 | if ![string length [info proc prune_warnings]] {
|
---|
1134 | #
|
---|
1135 | # prune_warnings -- delete various system verbosities from TEXT
|
---|
1136 | #
|
---|
1137 | # An example is:
|
---|
1138 | # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
|
---|
1139 | #
|
---|
1140 | # Sites with particular verbose os's may wish to override this in site.exp.
|
---|
1141 | #
|
---|
1142 | proc prune_warnings { text } {
|
---|
1143 | # This is from sun4's. Do it for all machines for now.
|
---|
1144 | # The "\\1" is to try to preserve a "\n" but only if necessary.
|
---|
1145 | regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
|
---|
1146 |
|
---|
1147 | # It might be tempting to get carried away and delete blank lines, etc.
|
---|
1148 | # Just delete *exactly* what we're ask to, and that's it.
|
---|
1149 | return $text
|
---|
1150 | }
|
---|
1151 | }
|
---|