1# Copyright (C) 1993-2016 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 16# MA 02110-1301, USA. 17 18# Please email any bugs, comments, and/or additions to this file to: 19# dejagnu@gnu.org 20 21# This file was written by Ken Raeburn (raeburn@cygnus.com). 22 23proc load_common_lib { name } { 24 global srcdir 25 load_file $srcdir/../../binutils/testsuite/lib/$name 26} 27 28load_common_lib binutils-common.exp 29 30proc gas_version {} { 31 global AS 32 if [is_remote host] then { 33 remote_exec host "$AS -version < /dev/null" "" "" "gas.version" 34 remote_exec host "which $AS" "" "" "gas.which" 35 36 remote_upload host "gas.version" 37 remote_upload host "gas.which" 38 39 set which_as [file_contents "gas.which"] 40 set tmp [file_contents "gas.version"] 41 42 remote_file build delete "gas.version" 43 remote_file build delete "gas.which" 44 remote_file host delete "gas.version" 45 remote_file host delete "gas.which" 46 } else { 47 set which_as [which $AS] 48 catch "exec $AS -version < /dev/null" tmp 49 } 50 51 # Should find a way to discard constant parts, keep whatever's 52 # left, so the version string could be almost anything at all... 53 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number 54 if ![info exists number] then { 55 return "$which_as (no version number)\n" 56 } 57 clone_output "$which_as $number\n" 58 unset version 59} 60 61proc gas_host_run { cmd redir } { 62 verbose "Executing $cmd $redir" 63 set return_contents_of "" 64 if [regexp ">& */dev/null" $redir] then { 65 set output_file "" 66 set command "$cmd $redir" 67 } elseif [regexp "> */dev/null" $redir] then { 68 set output_file "" 69 set command "$cmd 2>gas.stderr" 70 set return_contents_of "gas.stderr" 71 } elseif [regexp ">&.*" $redir] then { 72 # See PR 5322 for why the following line is used. 73 regsub ">&" $redir "" output_file 74 set command "$cmd 2>&1" 75 } elseif [regexp "2>.*" $redir] then { 76 set output_file "gas.out" 77 set command "$cmd $redir" 78 set return_contents_of "gas.out" 79 } elseif [regexp ">.*" $redir] then { 80 set output_file "" 81 set command "$cmd $redir 2>gas.stderr" 82 set return_contents_of "gas.stderr" 83 } elseif { "$redir" == "" } then { 84 set output_file "gas.out" 85 set command "$cmd 2>&1" 86 set return_contents_of "gas.out" 87 } else { 88 fail "gas_host_run: unknown form of redirection string" 89 } 90 91 set status [remote_exec host [concat sh -c [list $command]] "" "/dev/null" "$output_file"] 92 set to_return "" 93 if { "$return_contents_of" != "" } then { 94 remote_upload host "$return_contents_of" 95 set to_return [file_contents "$return_contents_of"] 96 regsub "\n$" $to_return "" to_return 97 } 98 99 if { [lindex $status 0] == 0 && "$output_file" != "" 100 && "$output_file" != "$return_contents_of" } then { 101 remote_upload host "$output_file" 102 } 103 104 return [list [lindex $status 0] "$to_return"] 105} 106 107proc gas_run { prog as_opts redir } { 108 global AS 109 global ASFLAGS 110 global comp_output 111 global srcdir 112 global subdir 113 global host_triplet 114 115 set status [gas_host_run "$AS $ASFLAGS $as_opts $srcdir/$subdir/$prog" "$redir"] 116 set comp_output [lindex $status 1] 117 if { [lindex $status 0] != 0 && [regexp "2>.*" $redir] } then { 118 append comp_output "child process exited abnormally" 119 } 120 set comp_output [prune_warnings $comp_output] 121 verbose "output was $comp_output" 122 return [list $comp_output ""] 123} 124 125proc gas_run_stdin { prog as_opts redir } { 126 global AS 127 global ASFLAGS 128 global comp_output 129 global srcdir 130 global subdir 131 global host_triplet 132 133 set status [gas_host_run "$AS $ASFLAGS $as_opts < $srcdir/$subdir/$prog" "$redir"] 134 set comp_output [lindex $status 1] 135 if { [lindex $status 0] != 0 && [regexp "2>.*" $redir] } then { 136 append comp_output "child process exited abnormally" 137 } 138 set comp_output [prune_warnings $comp_output] 139 verbose "output was $comp_output" 140 return [list $comp_output ""] 141} 142 143proc all_ones { args } { 144 foreach x $args { if [expr $x!=1] { return 0 } } 145 return 1 146} 147 148# ${tool}_finish (gas_finish) will be called by runtest.exp. But 149# gas_finish should only be used with gas_start. We use gas_started 150# to tell gas_finish if gas_start has been called so that runtest.exp 151# can call gas_finish without closing the wrong fd. 152set gas_started 0 153 154proc gas_start { prog as_opts } { 155 global AS 156 global ASFLAGS 157 global srcdir 158 global subdir 159 global spawn_id 160 global gas_started 161 162 set gas_started 1 163 164 verbose -log "Starting $AS $ASFLAGS $as_opts $prog" 2 165 set status [gas_host_run "$AS $ASFLAGS $as_opts $srcdir/$subdir/$prog" ">&gas.out"] 166 spawn -noecho -nottycopy cat gas.out 167} 168 169proc gas_finish { } { 170 global spawn_id 171 global gas_started 172 173 if { $gas_started == 1 } { 174 catch "close" 175 catch "wait" 176 set gas_started 0 177 } 178} 179 180proc want_no_output { testname } { 181 global comp_output 182 183 if ![string match "" $comp_output] then { 184 send_log "$comp_output\n" 185 verbose "$comp_output" 3 186 } 187 if [string match "" $comp_output] then { 188 pass "$testname" 189 return 1 190 } else { 191 fail "$testname" 192 return 0 193 } 194} 195 196proc gas_test_old { file as_opts testname } { 197 gas_run $file $as_opts "" 198 return [want_no_output $testname] 199} 200 201proc gas_test { file as_opts var_opts testname } { 202 global comp_output 203 204 set i 0 205 foreach word $var_opts { 206 set ignore_stdout($i) [string match "*>" $word] 207 set opt($i) [string trim $word {>}] 208 incr i 209 } 210 set max [expr 1<<$i] 211 for {set i 0} {[expr $i<$max]} {incr i} { 212 set maybe_ignore_stdout "" 213 set extra_opts "" 214 for {set bit 0} {(1<<$bit)<$max} {incr bit} { 215 set num [expr 1<<$bit] 216 if [expr $i&$num] then { 217 set extra_opts "$extra_opts $opt($bit)" 218 if $ignore_stdout($bit) then { 219 set maybe_ignore_stdout ">/dev/null" 220 } 221 } 222 } 223 set extra_opts [string trim $extra_opts] 224 gas_run $file "$as_opts $extra_opts" $maybe_ignore_stdout 225 226 # Should I be able to use a conditional expression here? 227 if [string match "" $extra_opts] then { 228 want_no_output $testname 229 } else { 230 want_no_output "$testname ($extra_opts)" 231 } 232 } 233 if [info exists errorInfo] then { 234 unset errorInfo 235 } 236} 237 238proc gas_test_ignore_stdout { file as_opts testname } { 239 global comp_output 240 241 gas_run $file $as_opts ">/dev/null" 242 want_no_output $testname 243} 244 245proc gas_test_error { file as_opts testname } { 246 global comp_output 247 248 gas_run $file $as_opts ">/dev/null" 249 send_log "$comp_output\n" 250 verbose "$comp_output" 3 251 if { ![string match "" $comp_output] 252 && ![string match "*Assertion failure*" $comp_output] 253 && ![string match "*Internal error*" $comp_output] } then { 254 pass "$testname" 255 } else { 256 fail "$testname" 257 } 258} 259 260proc gas_exit {} {} 261 262proc gas_init { args } { 263 global target_cpu 264 global target_cpu_family 265 global target_family 266 global target_vendor 267 global target_os 268 global stdoptlist 269 270 case "$target_cpu" in { 271 "m68???" { set target_cpu_family m68k } 272 "i[3-7]86" { set target_cpu_family i386 } 273 default { set target_cpu_family $target_cpu } 274 } 275 276 set target_family "$target_cpu_family-$target_vendor-$target_os" 277 set stdoptlist "-a>" 278 279 if ![istarget "*-*-*"] { 280 perror "Target name [istarget] is not a triple." 281 } 282 # Need to return an empty string. 283 return 284} 285 286# Internal procedure: return the names of the standard sections 287# 288proc get_standard_section_names {} { 289 if [istarget "rx-*-*"] { 290 return { "P" "D_1" "B_1" } 291 } 292 if [istarget "alpha*-*-*vms*"] { 293 # Double quote: for TCL and for sh. 294 return { "\\\$CODE\\\$" "\\\$DATA\\\$" "\\\$BSS\\\$" } 295 } 296 return 297} 298 299# run_dump_tests TESTCASES EXTRA_OPTIONS 300# Wrapper for run_dump_test, which is suitable for invoking as 301# run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]] 302# EXTRA_OPTIONS are passed down to run_dump_test. Honors runtest_file_p. 303# Body cribbed from dg-runtest. 304 305proc run_dump_tests { testcases {extra_options {}} } { 306 global runtests 307 308 foreach testcase $testcases { 309 # If testing specific files and this isn't one of them, skip it. 310 if ![runtest_file_p $runtests $testcase] { 311 continue 312 } 313 run_dump_test [file rootname [file tail $testcase]] $extra_options 314 } 315} 316 317 318# run_dump_test FILE (optional:) EXTRA_OPTIONS 319# 320# Assemble a .s file, then run some utility on it and check the output. 321# 322# There should be an assembly language file named FILE.s in the test 323# suite directory, and a pattern file called FILE.d. `run_dump_test' 324# will assemble FILE.s, run some tool like `objdump', `objcopy', or 325# `nm' on the .o file to produce textual output, and then analyze that 326# with regexps. The FILE.d file specifies what program to run, and 327# what to expect in its output. 328# 329# The FILE.d file begins with zero or more option lines, which specify 330# flags to pass to the assembler, the program to run to dump the 331# assembler's output, and the options it wants. The option lines have 332# the syntax: 333# 334# # OPTION: VALUE 335# 336# OPTION is the name of some option, like "name" or "objdump", and 337# VALUE is OPTION's value. The valid options are described below. 338# Whitespace is ignored everywhere, except within VALUE. The option 339# list ends with the first line that doesn't match the above syntax. 340# However, a line within the options that begins with a #, but doesn't 341# have a recognizable option name followed by a colon, is considered a 342# comment and entirely ignored. 343# 344# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of 345# two-element lists. The first element of each is an option name, and 346# the second additional arguments to be added on to the end of the 347# option list as given in FILE.d. (If omitted, no additional options 348# are added.) 349# 350# The interesting options are: 351# 352# name: TEST-NAME 353# The name of this test, passed to DejaGNU's `pass' and `fail' 354# commands. If omitted, this defaults to FILE, the root of the 355# .s and .d files' names. 356# 357# as: FLAGS 358# When assembling FILE.s, pass FLAGS to the assembler. 359# 360# addr2line: FLAGS 361# nm: FLAGS 362# objcopy: FLAGS 363# objdump: FLAGS 364# readelf: FLAGS 365# Use the specified program to analyze the .o file, and pass it 366# FLAGS, in addition to the .o file name. Note that they are run 367# with LC_ALL=C in the environment to give consistent sorting 368# of symbols. If no FLAGS are needed then use: 369# PROG: [nm objcopy objdump readelf addr2line] 370# instead. 371# Note: for objdump, we automatically replaces the standard section 372# names (.text, .data and .bss) by target ones if any (eg. rx-elf 373# uses "P" instead of .text). The substition is done for both 374# the objdump options (eg: "-j .text" is replaced by "-j P") and the 375# reference file. 376# 377# source: SOURCE 378# Assemble the file SOURCE.s. If omitted, this defaults to FILE.s. 379# This is useful if several .d files want to share a .s file. 380# 381# dump: DUMP 382# Match against DUMP.d. If omitted, this defaults to FILE.d. This 383# is useful if several .d files differ by options only. Options are 384# always read from FILE.d. 385# 386# target: GLOBS... 387# Run this test only on a specified list of targets. More precisely, 388# each glob in the space-separated list is passed to "istarget"; if 389# it evaluates true for any of them, the test will be run, otherwise 390# it will be marked unsupported. 391# 392# not-target: GLOBS... 393# Do not run this test on a specified list of targets. Again, 394# the each glob in the space-separated list is passed to 395# "istarget", and the test is run if it evaluates *false* for 396# *all* of them. Otherwise it will be marked unsupported. 397# 398# skip: GLOBS... 399# not-skip: GLOBS... 400# These are exactly the same as "not-target" and "target", 401# respectively, except that they do nothing at all if the check 402# fails. They should only be used in groups, to construct a single 403# test which is run on all targets but with variant options or 404# expected output on some targets. (For example, see 405# gas/arm/inst.d and gas/arm/wince_inst.d.) 406# 407# error: REGEX 408# An error with message matching REGEX must be emitted for the test 409# to pass. The PROG, objdump, nm and objcopy options have no 410# meaning and need not supplied if this is present. 411# 412# warning: REGEX 413# Expect a gas warning matching REGEX. It is an error to issue 414# both "error" and "warning". 415# 416# stderr: FILE 417# FILE contains regexp lines to be matched against the diagnostic 418# output of the assembler. This does not preclude the use of 419# PROG, nm, objdump, or objcopy. 420# 421# error-output: FILE 422# Means the same as 'stderr', but also indicates that the assembler 423# is expected to exit unsuccessfully (therefore PROG, objdump, nm, 424# and objcopy have no meaning and should not be supplied). 425# 426# section-subst: no 427# Means that the section substitution for objdump is disabled. 428# 429# Each option may occur at most once. 430# 431# After the option lines come regexp lines. `run_dump_test' calls 432# `regexp_diff' to compare the output of the dumping tool against the 433# regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp; 434# see further comments there. 435 436proc run_dump_test { name {extra_options {}} } { 437 global subdir srcdir 438 global OBJDUMP NM AS OBJCOPY READELF 439 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS 440 global ADDR2LINE ADDR2LINEFLAGS 441 global host_triplet 442 global env 443 444 if [string match "*/*" $name] { 445 set file $name 446 set name [file tail $name] 447 } else { 448 set file "$srcdir/$subdir/$name" 449 } 450 set opt_array [slurp_options "${file}.d"] 451 if { $opt_array == -1 } { 452 perror "error reading options from $file.d" 453 unresolved $subdir/$name 454 return 455 } 456 set opts(addr2line) {} 457 set opts(as) {} 458 set opts(objdump) {} 459 set opts(nm) {} 460 set opts(objcopy) {} 461 set opts(readelf) {} 462 set opts(name) {} 463 set opts(PROG) {} 464 set opts(source) {} 465 set opts(dump) {} 466 set opts(stderr) {} 467 set opts(error) {} 468 set opts(error-output) {} 469 set opts(warning) {} 470 set opts(target) {} 471 set opts(not-target) {} 472 set opts(skip) {} 473 set opts(not-skip) {} 474 set opts(section-subst) {} 475 476 foreach i $opt_array { 477 set opt_name [lindex $i 0] 478 set opt_val [lindex $i 1] 479 if ![info exists opts($opt_name)] { 480 perror "unknown option $opt_name in file $file.d" 481 unresolved $subdir/$name 482 return 483 } 484 if [string length $opts($opt_name)] { 485 perror "option $opt_name multiply set in $file.d" 486 unresolved $subdir/$name 487 return 488 } 489 if { $opt_name == "as" } { 490 set opt_val [subst $opt_val] 491 } 492 set opts($opt_name) $opt_val 493 } 494 495 foreach i $extra_options { 496 set opt_name [lindex $i 0] 497 set opt_val [lindex $i 1] 498 if ![info exists opts($opt_name)] { 499 perror "unknown option $opt_name given in extra_opts" 500 unresolved $subdir/$name 501 return 502 } 503 # add extra option to end of existing option, adding space 504 # if necessary. 505 if [string length $opts($opt_name)] { 506 append opts($opt_name) " " 507 } 508 append opts($opt_name) $opt_val 509 } 510 511 if { $opts(name) == "" } { 512 set testname "$subdir/$name" 513 } else { 514 set testname $opts(name) 515 } 516 verbose "Testing $testname" 517 518 if { (($opts(warning) != "") && ($opts(error) != "")) \ 519 || (($opts(warning) != "") && ($opts(stderr) != "")) \ 520 || (($opts(error-output) != "") && ($opts(stderr) != "")) \ 521 || (($opts(error-output) != "") && ($opts(error) != "")) \ 522 || (($opts(error-output) != "") && ($opts(warning) != "")) } { 523 perror "$testname: bad mix of stderr, error-output, error, and warning test-directives" 524 unresolved $testname 525 return 526 } 527 if { $opts(error-output) != "" } then { 528 set opts(stderr) $opts(error-output) 529 } 530 531 set program "" 532 # It's meaningless to require an output-testing method when we 533 # expect an error. 534 if { $opts(error) == "" && $opts(error-output) == "" } { 535 if {$opts(PROG) != ""} { 536 switch -- $opts(PROG) { 537 addr2line { set program addr2line } 538 objdump { set program objdump } 539 nm { set program nm } 540 objcopy { set program objcopy } 541 readelf { set program readelf } 542 default { 543 perror "unrecognized program option $opts(PROG) in $file.d" 544 unresolved $testname 545 return } 546 } 547 } else { 548 # Guess which program to run, by seeing which option was specified. 549 foreach p {objdump objcopy nm readelf addr2line} { 550 if {$opts($p) != ""} { 551 if {$program != ""} { 552 perror "ambiguous dump program in $file.d" 553 unresolved $testname 554 return 555 } else { 556 set program $p 557 } 558 } 559 } 560 } 561 if { $program == "" && $opts(warning) == "" } { 562 perror "dump program unspecified in $file.d" 563 unresolved $testname 564 return 565 } 566 } 567 568 # Handle skipping the test on specified targets. 569 # You can have both skip/not-skip and target/not-target, but you can't 570 # have both skip and not-skip, or target and not-target, in the same file. 571 if { $opts(skip) != "" } then { 572 if { $opts(not-skip) != "" } then { 573 perror "$testname: mixing skip and not-skip directives is invalid" 574 unresolved $testname 575 return 576 } 577 foreach glob $opts(skip) { 578 if {[istarget $glob]} { return } 579 } 580 } 581 if { $opts(not-skip) != "" } then { 582 set skip 1 583 foreach glob $opts(not-skip) { 584 if {[istarget $glob]} { 585 set skip 0 586 break 587 } 588 } 589 if {$skip} { return } 590 } 591 if { $opts(target) != "" } then { 592 if { $opts(not-target) != "" } then { 593 perror "$testname: mixing target and not-target directives is invalid" 594 unresolved $testname 595 return 596 } 597 set skip 1 598 foreach glob $opts(target) { 599 if {[istarget $glob]} { 600 set skip 0 601 break 602 } 603 } 604 if {$skip} { 605 unsupported $testname 606 return 607 } 608 } 609 if { $opts(not-target) != "" } then { 610 foreach glob $opts(not-target) { 611 if {[istarget $glob]} { 612 unsupported $testname 613 return 614 } 615 } 616 } 617 618 if { $opts(source) == "" } { 619 set sourcefile ${file}.s 620 } else { 621 set sourcefile $srcdir/$subdir/$opts(source) 622 } 623 624 if { $opts(dump) == "" } { 625 set dumpfile ${file}.d 626 } else { 627 set dumpfile $srcdir/$subdir/$opts(dump) 628 } 629 630 set cmd "$AS $ASFLAGS $opts(as) -o dump.o $sourcefile" 631 send_log "$cmd\n" 632 set status [gas_host_run $cmd ""] 633 set cmdret [lindex $status 0] 634 set comp_output [prune_warnings [lindex $status 1]] 635 636 set expmsg $opts(error) 637 if { $opts(warning) != "" } { 638 set expmsg $opts(warning) 639 } 640 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then { 641 # If the executed program writes to stderr and stderr is not 642 # redirected, exec *always* returns failure, regardless of the 643 # program exit code. Thankfully, we can retrieve the true 644 # return status from a special variable. Redirection would 645 # cause a tcl-specific message to be appended, and we'd rather 646 # not deal with that if we can help it. 647 global errorCode 648 if { $cmdret != 0 && [lindex $errorCode 0] == "NONE" } { 649 set cmdret 0 650 } 651 652 set exitstat "succeeded" 653 if { $cmdret != 0 } { set exitstat "failed" } 654 655 send_log "$comp_output\n" 656 verbose "$comp_output" 3 657 if { $opts(stderr) == "" } then { 658 if { [regexp $expmsg $comp_output] \ 659 && (($cmdret == 0) == ($opts(warning) != "")) } { 660 # We have the expected output from gas. 661 # Return if there's nothing more to do. 662 if { $opts(error) != "" || $program == "" } { 663 pass $testname 664 return 665 } 666 } else { 667 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>" 668 669 fail $testname 670 return 671 } 672 } else { 673 catch {write_file dump.stderr "$comp_output"} write_output 674 if ![string match "" $write_output] then { 675 send_log "error writing dump.stderr: $write_output\n" 676 verbose "error writing dump.stderr: $write_output" 3 677 send_log "$comp_output\n" 678 verbose "$comp_output" 3 679 fail $testname 680 return 681 } 682 set stderrfile $srcdir/$subdir/$opts(stderr) 683 verbose "wrote pruned stderr to dump.stderr" 3 684 if { [regexp_diff "dump.stderr" "$stderrfile"] } then { 685 if { $opts(error) != "" } { 686 verbose -log "$exitstat with: <$comp_output>, expected: <$opts(error)>" 687 if [regexp $opts(error) $comp_output] { 688 pass $testname 689 return 690 } 691 } 692 fail $testname 693 verbose "pruned stderr is [file_contents "dump.stderr"]" 2 694 return 695 } elseif { $opts(error-output) != "" } then { 696 pass $testname 697 return 698 } 699 } 700 } else { 701 if { $opts(error) != "" || $opts(error-output) != "" } { 702 fail $testname 703 } 704 } 705 706 if { $program == "" } { 707 return 708 } 709 set progopts1 $opts($program) 710 eval set progopts \$[string toupper $program]FLAGS 711 eval set binary \$[string toupper $program] 712 713 if { ![is_remote host] && [which $binary] == 0 } { 714 untested $testname 715 return 716 } 717 718 # For objdump, automatically translate standard section names to the targets one, 719 # if they are different. 720 set sect_names [get_standard_section_names] 721 if { $sect_names != "" && $program == "objdump" && $opts(section-subst) == ""} { 722 regsub -- "-j \\.text" $progopts1 "-j [lindex $sect_names 0]" progopts1 723 regsub -- "-j \\.data" $progopts1 "-j [lindex $sect_names 1]" progopts1 724 regsub -- "-j \\.bss" $progopts1 "-j [lindex $sect_names 2]" progopts1 725 } 726 727 if { $progopts1 == "" } { set $progopts1 "-r" } 728 verbose "running $binary $progopts $progopts1" 3 729 730 # Objcopy, unlike the other two, won't send its output to stdout, 731 # so we have to run it specially. 732 set cmd "$binary $progopts $progopts1 dump.o" 733 set redir ">dump.out" 734 if { $program == "objcopy" } { 735 set cmd "$binary $progopts $progopts1 dump.o dump.out" 736 set redir "" 737 } 738 739 send_log "$cmd\n" 740 set status [gas_host_run "$cmd" "$redir"] 741 set comp_output [prune_warnings [lindex $status 1]] 742 set comp_output [prune_warnings $comp_output] 743 if ![string match "" $comp_output] then { 744 send_log "$comp_output\n" 745 fail $testname 746 return 747 } 748 749 # Create the substition list only for objdump reference. 750 if { $sect_names != "" && $program == "objdump" } { 751 # Some testcases use ".text" while others use "\.text". 752 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \ 753 "\\\\?\\.data" [lindex $sect_names 1] \ 754 "\\\\?\\.bss" [lindex $sect_names 2] ] 755 } else { 756 set regexp_subst "" 757 } 758 759 verbose_eval {[file_contents "dump.out"]} 3 760 if { [regexp_diff "dump.out" "${dumpfile}" $regexp_subst] } then { 761 fail $testname 762 verbose "output is [file_contents "dump.out"]" 2 763 return 764 } 765 766 pass $testname 767} 768 769proc slurp_options { file } { 770 if [catch { set f [open $file r] } x] { 771 #perror "couldn't open `$file': $x" 772 perror "$x" 773 return -1 774 } 775 set opt_array {} 776 # whitespace expression 777 set ws {[ ]*} 778 set nws {[^ ]*} 779 # whitespace is ignored anywhere except within the options list; 780 # option names are alphabetic plus dash 781 set pat "^#${ws}(\[a-zA-Z0-9-\]*)$ws:${ws}(.*)$ws\$" 782 while { [gets $f line] != -1 } { 783 set line [string trim $line] 784 # Whitespace here is space-tab. 785 if [regexp $pat $line xxx opt_name opt_val] { 786 # match! 787 lappend opt_array [list $opt_name $opt_val] 788 } elseif {![regexp "^#" $line ]} { 789 break 790 } 791 } 792 close $f 793 return $opt_array 794} 795 796proc objdump { opts } { 797 global OBJDUMP 798 global comp_output 799 global host_triplet 800 801 set status [gas_host_run "$OBJDUMP $opts" ""] 802 set comp_output [prune_warnings [lindex $status 1]] 803 verbose "objdump output=$comp_output\n" 3 804} 805 806proc objdump_start_no_subdir { prog opts } { 807 global OBJDUMP 808 global srcdir 809 global spawn_id 810 811 verbose "Starting $OBJDUMP $opts $prog" 2 812 set status [gas_host_run "$OBJDUMP $opts $prog" ">&gas.out"] 813 spawn -noecho -nottycopy cat gas.out 814} 815 816proc objdump_finish { } { 817 global spawn_id 818 819 catch "close" 820 catch "wait" 821} 822 823# Default timeout is 10 seconds, loses on a slow machine. But some 824# configurations of dejagnu may override it. 825if {$timeout<120} then { set timeout 120 } 826 827expect_after -i { 828 timeout { perror "timeout" } 829 "virtual memory exhausted" { perror "virtual memory exhausted" } 830 buffer_full { perror "buffer full" } 831 eof { perror "eof" } 832} 833 834proc file_contents { filename } { 835 set file [open $filename r] 836 set contents [read $file] 837 close $file 838 return $contents 839} 840 841proc write_file { filename contents } { 842 set file [open $filename w] 843 puts $file "$contents" 844 close $file 845} 846 847proc verbose_eval { expr { level 1 } } { 848 global verbose 849 if $verbose>$level then { eval verbose "$expr" $level } 850} 851 852# This definition is taken from an unreleased version of DejaGnu. Once 853# that version gets released, and has been out in the world for a few 854# months at least, it may be safe to delete this copy. 855if ![string length [info proc prune_warnings]] { 856 # 857 # prune_warnings -- delete various system verbosities from TEXT. 858 # 859 # An example is: 860 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9 861 # 862 # Sites with particular verbose os's may wish to override this in site.exp. 863 # 864 proc prune_warnings { text } { 865 # This is from sun4's. Do it for all machines for now. 866 # The "\\1" is to try to preserve a "\n" but only if necessary. 867 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text 868 869 # It might be tempting to get carried away and delete blank lines, etc. 870 # Just delete *exactly* what we're ask to, and that's it. 871 return $text 872 } 873} 874 875# run_list_test NAME (optional): OPTS TESTNAME 876# 877# Assemble the file "NAME.s" with command line options OPTS and 878# compare the assembler standard error output against the regular 879# expressions given in the file "NAME.l". If TESTNAME is provided, 880# it will be used as the name of the test. 881 882proc run_list_test { name {opts {}} {testname {}} } { 883 global srcdir subdir 884 if { [string length $testname] == 0 } then { 885 set testname "[file tail $subdir] $name" 886 } 887 set file $srcdir/$subdir/$name 888 gas_run ${name}.s $opts ">&dump.out" 889 if { [regexp_diff "dump.out" "${file}.l"] } then { 890 fail $testname 891 verbose "output is [file_contents "dump.out"]" 2 892 return 893 } 894 pass $testname 895} 896 897# run_list_test_stdin NAME (optional): OPTS TESTNAME 898# 899# Similar to run_list_test, but use stdin as input. 900 901proc run_list_test_stdin { name {opts {}} {testname {}} } { 902 global srcdir subdir 903 if { [string length $testname] == 0 } then { 904 set testname "[file tail $subdir] $name" 905 } 906 set file $srcdir/$subdir/$name 907 gas_run_stdin ${name}.s $opts ">&dump.out" 908 if { [regexp_diff "dump.out" "${file}.l"] } then { 909 fail $testname 910 verbose "output is [file_contents "dump.out"]" 2 911 return 912 } 913 pass $testname 914} 915