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