1# Copyright (C) 1993-2014 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 if { ![istarget *-*-sysv4*] 24 && ![istarget *-*-unixware*] 25 && ![istarget *-*-elf*] 26 && ![istarget *-*-eabi*] 27 && ![istarget *-*-rtems*] 28 && ![istarget hppa*64*-*-hpux*] 29 && ![istarget ia64-*-hpux*] 30 && ![istarget *-*-linux*] 31 && ![istarget *-*-gnu*] 32 && ![istarget *-*-nacl*] 33 && ![istarget frv-*-uclinux*] 34 && ![istarget bfin-*-uclinux] 35 && ![istarget sh*-*-uclinux*] 36 && ![istarget tic6x*-*-uclinux*] 37 && ![istarget *-*-irix5*] 38 && ![istarget *-*-irix6*] 39 && ![istarget *-*-netbsd*] 40 && ![istarget *-*-openbsd*] 41 && ![istarget *-*-solaris2*] } { 42 return 0 43 } 44 45 if { [istarget *-*-linux*aout*] 46 || [istarget *-*-linux*ecoff*] 47 || [istarget *-*-linux*oldld*] 48 || [istarget h8500-*-rtems*] 49 || [istarget i960-*-rtems*] 50 || [istarget *-*-rtemscoff*] } { 51 return 0 52 } 53 54 if { ![istarget *-*-netbsdelf*] 55 && ([istarget *-*-netbsd*aout*] 56 || [istarget *-*-netbsdpe*] 57 || [istarget arm*-*-netbsd*] 58 || [istarget sparc-*-netbsd*] 59 || [istarget i*86-*-netbsd*] 60 || [istarget m68*-*-netbsd*] 61 || [istarget vax-*-netbsd*] 62 || [istarget ns32k-*-netbsd*]) } { 63 return 0 64 } 65 66 if { [istarget arm-*-openbsd*] 67 || [istarget i386-*-openbsd\[0-2\].*] 68 || [istarget i386-*-openbsd3.\[0-2\]] 69 || [istarget m68*-*-openbsd*] 70 || [istarget ns32k-*-openbsd*] 71 || [istarget sparc-*-openbsd\[0-2\].*] 72 || [istarget sparc-*-openbsd3.\[0-1\]] 73 || [istarget vax-*-openbsd*] } { 74 return 0 75 } 76 77 return 1 78} 79 80# True if the object format is known to be a.out. 81# 82proc is_aout_format {} { 83 if { [istarget *-*-netbsdelf] 84 || [istarget sparc64-*-netbsd*] 85 || [istarget sparc64-*-openbsd*] } { 86 return 0 87 } 88 if { [istarget *-*-*\[ab\]out*] 89 || [istarget *-*-linux*oldld*] 90 || [istarget *-*-bsd*] 91 || [istarget *-*-msdos*] 92 || [istarget arm-*-netbsd*] 93 || [istarget arm-*-openbsd*] 94 || [istarget arm-*-riscix*] 95 || [istarget i?86-*-freebsd\[12\]*] 96 || [istarget i?86-*-netbsd*] 97 || [istarget i?86-*-openbsd\[0-2\]*] 98 || [istarget i?86-*-openbsd3.\[0-2\]*] 99 || [istarget i?86-*-vsta] 100 || [istarget i?86-*-mach*] 101 || [istarget m68*-*-netbsd*] 102 || [istarget m68*-*-openbsd*] 103 || [istarget ns32k-*-*] 104 || [istarget pdp11-*-*] 105 || [istarget sparc*-*-sunos4*] 106 || [istarget sparc*-*-netbsd*] 107 || [istarget sparc*-*-openbsd\[0-2\]*] 108 || [istarget sparc*-*-openbsd3.\[0-1\]*] 109 || [istarget sparc*-fujitsu-none] 110 || [istarget vax-dec-ultrix*] 111 || [istarget vax-*-netbsd] } { 112 return 1 113 } 114 return 0 115} 116 117# True if the object format is known to be PE COFF. 118# 119proc is_pecoff_format {} { 120 if { ![istarget *-*-mingw*] 121 && ![istarget *-*-cygwin*] 122 && ![istarget *-*-cegcc*] 123 && ![istarget *-*-pe*] } { 124 return 0 125 } 126 127 return 1 128} 129 130# True if the object format is known to be 64-bit ELF. 131# 132proc is_elf64 { binary_file } { 133 global READELF 134 global READELFFLAGS 135 136 set readelf_size "" 137 catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got 138 139 if ![string match "" $got] then { 140 return 0 141 } 142 143 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \ 144 [file_contents readelf.out] nil readelf_size] } { 145 return 0 146 } 147 148 if { $readelf_size == "64" } { 149 return 1 150 } 151 152 return 0 153} 154 155# True if the build supports zlib compression. 156proc is_zlib_supported {} { 157 158 # This replicates the AS selection logic of dejagnu's target_assemble. 159 global AS_FOR_TARGET 160 if [info exists AS_FOR_TARGET] { 161 set AS $AS_FOR_TARGET 162 } else { 163 if {![board_info target exists assembler]} { 164 set AS [find_gas] 165 } else { 166 set AS [board_info target assembler] 167 } 168 } 169 170 set as_output [remote_exec host "$AS --help"] 171 172 set have_zlib 0 173 if {[string first "--compress-debug-sections" $as_output] >= 0} { 174 set have_zlib 1 175 } 176 177 return $have_zlib 178} 179 180# Compare two files line-by-line. FILE_1 is the actual output and FILE_2 181# is the expected output. Ignore blank lines in either file. 182# 183# FILE_2 is a series of regexps, comments and # directives. The directives 184# are: 185# 186# #pass 187# Treat the test as a PASS if everything up till this point has 188# matched. Ignore any remaining lines in either FILE_1 or FILE_2. 189# 190# #failif 191# Reverse the sense of the test: expect differences to exist. 192# 193# #... 194# REGEXP 195# Skip all lines in FILE_1 until the first that matches REGEXP. 196# 197# Other # lines are comments. Regexp lines starting with the `!' character 198# specify inverse matching (use `\!' for literal matching against a leading 199# `!'). Skip empty lines in both files. 200# 201# The first optional argument is a list of regexp substitutions of the form: 202# 203# EXP1 SUBSPEC1 EXP2 SUBSPEC2 ... 204# 205# This tells the function to apply each regexp substitution EXPi->SUBSPECi 206# in order to every line of FILE_2. 207# 208# Return nonzero if differences exist. 209proc regexp_diff { file_1 file_2 args } { 210 set eof -1 211 set end_1 0 212 set end_2 0 213 set differences 0 214 set diff_pass 0 215 set fail_if_match 0 216 set ref_subst "" 217 if { [llength $args] > 0 } { 218 set ref_subst [lindex $args 0] 219 } 220 if { [llength $args] > 1 } { 221 perror "Too many arguments to regexp_diff" 222 return 1 223 } 224 225 if [file exists $file_1] then { 226 set file_a [open $file_1 r] 227 } else { 228 perror "$file_1 doesn't exist" 229 return 1 230 } 231 232 if [file exists $file_2] then { 233 set file_b [open $file_2 r] 234 } else { 235 perror "$file_2 doesn't exist" 236 close $file_a 237 return 1 238 } 239 240 verbose " Regexp-diff'ing: $file_1 $file_2" 2 241 242 while { 1 } { 243 set line_a "" 244 set line_b "" 245 while { [string length $line_a] == 0 } { 246 # Ignore blank line in FILE_1. 247 if { [gets $file_a line_a] == $eof } { 248 set end_1 1 249 break 250 } 251 } 252 while { [string length $line_b] == 0 || [string match "#*" $line_b] } { 253 if { [string match "#pass" $line_b] } { 254 set end_2 1 255 set diff_pass 1 256 break 257 } elseif { [string match "#failif" $line_b] } { 258 send_log "fail if no difference\n" 259 verbose "fail if no difference" 3 260 set fail_if_match 1 261 } elseif { [string match "#..." $line_b] } { 262 if { [gets $file_b line_b] == $eof } { 263 set end_2 1 264 set diff_pass 1 265 break 266 } 267 set negated [expr { [string index $line_b 0] == "!" }] 268 set line_bx [string range $line_b $negated end] 269 set n [expr { $negated ? "! " : "" }] 270 # Substitute on the reference. 271 foreach {name value} $ref_subst { 272 regsub -- $name $line_bx $value line_bx 273 } 274 verbose "looking for $n\"^$line_bx$\"" 3 275 while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } { 276 verbose "skipping \"$line_a\"" 3 277 if { [gets $file_a line_a] == $eof } { 278 set end_1 1 279 break 280 } 281 } 282 break 283 } 284 if { [gets $file_b line_b] == $eof } { 285 set end_2 1 286 break 287 } 288 } 289 290 if { $diff_pass } { 291 break 292 } elseif { $end_1 && $end_2 } { 293 break 294 } elseif { $end_1 } { 295 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n" 296 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3 297 set differences 1 298 break 299 } elseif { $end_2 } { 300 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 301 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3 302 set differences 1 303 break 304 } else { 305 set negated [expr { [string index $line_b 0] == "!" }] 306 set line_bx [string range $line_b $negated end] 307 set n [expr { $negated ? "! " : "" }] 308 set s [expr { $negated ? " " : "" }] 309 # Substitute on the reference. 310 foreach {name value} $ref_subst { 311 regsub -- $name $line_bx $value line_bx 312 } 313 verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3 314 if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } { 315 send_log "regexp_diff match failure\n" 316 send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n" 317 verbose "regexp_diff match failure\n" 3 318 set differences 1 319 } 320 } 321 } 322 323 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } { 324 send_log "$file_1 and $file_2 are different lengths\n" 325 verbose "$file_1 and $file_2 are different lengths" 3 326 set differences 1 327 } 328 329 if { $fail_if_match } { 330 if { $differences == 0 } { 331 set differences 1 332 } else { 333 set differences 0 334 } 335 } 336 337 close $file_a 338 close $file_b 339 340 return $differences 341} 342