1# Copyright (C) 1999-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, MA 02110-1301, USA. 16 17# Please email any bugs, comments, and/or additions to this file to: 18# bug-dejagnu@prep.ai.mit.edu 19 20# Written by Nick Clifton <nickc@cygnus.com> 21# Based on scripts written by Ian Lance Taylor <ian@cygnus.com> 22# and Ken Raeburn <raeburn@cygnus.com>. 23 24# Exclude non-ELF targets. 25if ![is_elf_format] { 26 verbose "$READELF is only intended for ELF targets" 2 27 return 28} 29 30# First some helpful procedures, then the tests themselves 31 32# Return the contents of the filename given 33proc file_contents { filename } { 34 set file [open $filename r] 35 set contents [read $file] 36 close $file 37 return $contents 38} 39 40# Find out the size by reading the output of the EI_CLASS field. 41# Similar to the test for readelf -h, but we're just looking for the 42# EI_CLASS line here. 43proc readelf_find_size { binary_file } { 44 global READELF 45 global READELFFLAGS 46 global readelf_size 47 48 set readelf_size "" 49 set testname "finding out ELF size with readelf -h" 50 set got [remote_exec host "$READELF $READELFFLAGS -h $binary_file" "" "/dev/null" "readelf.out"] 51 if [is_remote host] then { 52 remote_upload host "readelf.out" 53 } 54 55 if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]]} then { 56 send_log $got 57 fail $testname 58 return 59 } 60 61 if { ! [regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \ 62 [file_contents readelf.out] nil readelf_size] } { 63 verbose -log "EI_CLASS field not found in output" 64 verbose -log "output is \n[file_contents readelf.out]" 65 fail $testname 66 return 67 } else { 68 verbose -log "ELF size is $readelf_size" 69 } 70 71 pass $testname 72} 73 74# Run an individual readelf test. 75# Basically readelf is run on the binary_file with the given options. 76# Readelf's output is captured and then compared against the contents 77# of the regexp_file-readelf_size if it exists, else regexp_file. 78 79proc readelf_test { options binary_file regexp_file xfails } { 80 81 global READELF 82 global READELFFLAGS 83 global readelf_size 84 global srcdir 85 global subdir 86 87 send_log "exec $READELF $READELFFLAGS $options $binary_file > readelf.out\n" 88 set got [remote_exec host "$READELF $READELFFLAGS $options $binary_file" "" "/dev/null" "readelf.out"] 89 90 foreach xfail $xfails { 91 setup_xfail $xfail 92 } 93 94 if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { 95 fail "readelf $options (reason: unexpected output)" 96 send_log $got 97 send_log "\n" 98 return 99 } 100 101 set target_machine "" 102 if [istarget "mips*-*-*"] then { 103 if [is_bad_symtab] then { 104 set target_machine mips 105 } else { 106 set target_machine tmips 107 } 108 } 109 110 if { $target_machine != "" && [file exists $srcdir/$subdir/$regexp_file-$readelf_size-$target_machine] } then { 111 set regexp_file $regexp_file-$readelf_size-$target_machine 112 } elseif { $target_machine != "" && [file exists $srcdir/$subdir/$regexp_file-$target_machine] } then { 113 set regexp_file $regexp_file-$target_machine 114 } elseif { [file exists $srcdir/$subdir/$regexp_file-$readelf_size] } then { 115 set regexp_file $regexp_file-$readelf_size 116 } 117 118 if { [regexp_diff readelf.out $srcdir/$subdir/$regexp_file] } then { 119 fail "readelf $options" 120 verbose "output is \n[file_contents readelf.out]" 2 121 return 122 } 123 124 pass "readelf $options" 125} 126 127# Simple proc to skip certain expected warning messages. 128 129proc prune_readelf_wi_warnings { text } { 130 regsub -all "(^|\n)(.*Skipping unexpected symbol type.*)" $text "\\1" text 131 return $text 132} 133 134# Testing the "readelf -wi" option is difficult because there 135# is no guaranteed order to the output, and because some ports 136# will use indirect string references, whilst others will use 137# direct references. So instead of having an expected output 138# file, like the other readelf tests, we grep for strings that 139# really ought to be there. 140 141proc readelf_wi_test {} { 142 global READELF 143 global READELFFLAGS 144 global srcdir 145 global subdir 146 147 # Compile the second test file. 148 if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } { 149 verbose "Unable to compile test file." 150 untested "readelf -wi" 151 return 152 } 153 154 # Download it. 155 set tempfile [remote_download host tmpdir/testprog.o] 156 157 # Run "readelf -wi" on it. 158 set got [remote_exec host "$READELF $READELFFLAGS -wi $tempfile" "" "/dev/null" "readelf.out"] 159 160 # Upload the results. 161 set output [remote_upload host readelf.out] 162 163 file_on_host delete $tempfile 164 165 # Strip any superflous warnings. 166 set got [prune_readelf_wi_warnings [lindex $got 1]] 167 168 if ![string match "" $got] then { 169 fail "readelf $READELFFLAGS -wi (reason: unexpected output)" 170 send_log $got 171 send_log "\n" 172 return 173 } 174 175 if ![file size $output] then { 176 # If the output file is empty, then this target does not 177 # generate dwarf2 output. This is not a failure. 178 verbose "No output from 'readelf -wi'" 179 untested "readelf -wi" 180 return 181 } 182 183 # Search for strings that should be in the output. 184 set sought { 185 ".*DW_TAG_compile_unit.*" 186 ".*DW_TAG_subprogram.*" 187 ".*DW_TAG_base_type.*" 188 ".*DW_AT_producer.*(GNU C|indirect string).*" 189 ".*DW_AT_language.*ANSI C.*" 190 ".*DW_AT_name.*(testprog.c|indirect string).*" 191 ".*DW_AT_name.*fn.*" 192 ".*DW_AT_name.*(main|indirect string).*" 193 ".*\(DW_OP_addr: 0\).*" 194 } 195 196 # The MSP430 in LARGE mode does not generate a DW_OP_addr. 197 setup_xfail msp430*-*-* 198 199 foreach looked_for $sought { 200 set lines [grep $output $looked_for] 201 if ![llength $lines] then { 202 fail "readelf -wi: missing: $looked_for" 203 send_log readelf.out 204 return 205 } 206 } 207 208 file_on_host delete $output 209 210 # All done. 211 pass "readelf -wi" 212} 213 214# This tests "readelf -wa", but on a file with a compressed 215# .debug_abbrev section. 216 217proc readelf_compressed_wa_test {} { 218 global READELF 219 global READELFFLAGS 220 global srcdir 221 global subdir 222 223 # Compile the compressed-debug-section test file. 224 if { [target_compile $srcdir/$subdir/dw2-compressed.S tmpdir/dw2-compressed.o object debug] != "" } { 225 verbose "Unable to compile test file." 226 untested "readelf -wa (compressed)" 227 return 228 } 229 230 # Download it. 231 set tempfile [remote_download host tmpdir/dw2-compressed.o] 232 233 # Run "readelf -wa" on it. 234 set got [remote_exec host "$READELF $READELFFLAGS -wa $tempfile" "" "/dev/null" "readelf.out"] 235 236 # Upload the results. 237 set output [remote_upload host readelf.out] 238 239 file_on_host delete $tempfile 240 241 if { [string compare [file_contents readelf.out] [file_contents $srcdir/$subdir/readelf.wa]] != 0 } then { 242 fail "readelf -wa (compressed)" 243 verbose "output is \n[file_contents readelf.out]" 2 244 verbose "expected is \n[file_contents $srcdir/$subdir/readelf.wa]" 2 245 return 246 } 247 248 pass "readelf -wa (compressed)" 249} 250 251# Test readelf's dumping abilities. 252 253proc readelf_dump_test {} { 254 global READELF 255 global READELFFLAGS 256 global srcdir 257 global subdir 258 259 # Assemble the dump test file. 260 if {![binutils_assemble $srcdir/$subdir/dumptest.s tmpdir/dumptest.o]} then { 261 unresolved "readelf -p: failed to assemble dump test file" 262 return 263 } 264 # Download it. 265 set tempfile [remote_download host tmpdir/dumptest.o] 266 267 # Run "readelf -p.data" on it. 268 set sect_names [get_standard_section_names] 269 if { $sect_names != "" } { 270 set got [remote_exec host "$READELF $READELFFLAGS -p[lindex $sect_names 1] $tempfile" "" "/dev/null" "readelf.out"] 271 } else { 272 set got [remote_exec host "$READELF $READELFFLAGS -p.data $tempfile" "" "/dev/null" "readelf.out"] 273 } 274 set got [lindex $got 1] 275 276 # Upload the results. 277 set output [remote_upload host readelf.out] 278 279 # Check for something going wrong. 280 if ![string match "" $got] then { 281 fail "readelf -p: unexpected output" 282 send_log $got 283 send_log "\n" 284 return 285 } 286 287 # Search for strings that should be in the output. 288 set sought { 289 ".*test_string.*" 290 } 291 292 foreach looked_for $sought { 293 set lines [grep $output $looked_for] 294 if ![llength $lines] then { 295 fail "readelf -p: missing: $looked_for" 296 send_log readelf.out 297 return 298 } 299 } 300 301 file_on_host delete $tempfile 302 file_on_host delete $output 303 304 # All done. 305 pass "readelf -p" 306 307 # XXX FIXME: Add test of readelf -x here 308} 309 310if ![is_remote host] { 311 if {[which $READELF] == 0} then { 312 perror "$READELF does not exist" 313 return 314 } 315} 316 317send_user "Version [binutil_version $READELF]" 318 319# Assemble the test file. 320if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then { 321 perror "could not assemble test file" 322 unresolved "readelf - failed to assemble" 323 return 324} 325 326if ![is_remote host] { 327 set tempfile tmpdir/bintest.o 328} else { 329 set tempfile [remote_download host tmpdir/bintest.o] 330} 331 332# First, determine the size, so specific output matchers can be used. 333readelf_find_size $tempfile 334 335# Run the tests. 336readelf_test -h $tempfile readelf.h {} 337readelf_test -S $tempfile readelf.s {} 338setup_xfail "mips-*-*irix*" 339readelf_test -s $tempfile readelf.ss {} 340readelf_test -r $tempfile readelf.r {} 341 342readelf_wi_test 343readelf_compressed_wa_test 344 345readelf_dump_test 346 347# PR 13482 - Check for off-by-one errors when dumping .note sections. 348if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then { 349 perror "could not assemble version note test file" 350 unresolved "readelf - failed to assemble" 351 fail "readelf -n" 352} else { 353 354 if ![is_remote host] { 355 set tempfile tmpdir/version.o 356 } else { 357 set tempfile [remote_download host tmpdir/version.o] 358 } 359 360 readelf_test -n $tempfile readelf.n {} 361} 362 363 364# PR 18374 - Check that relocations against the .debug_loc section 365# do not prevent readelf from displaying all the location lists. 366if {![binutils_assemble $srcdir/$subdir/pr18374.s tmpdir/pr18374.o]} then { 367 perror "could not assemble PR18374 test file" 368 unresolved "readelf - failed to assemble" 369 fail "readelf --debug-loc" 370} else { 371 372 if ![is_remote host] { 373 set tempfile tmpdir/pr18374.o 374 } else { 375 set tempfile [remote_download host tmpdir/pr18374.o] 376 } 377 378 readelf_test --debug-dump=loc $tempfile readelf.pr18374 {} 379} 380 381 382# Check that decompressed dumps work. 383if {![binutils_assemble $srcdir/$subdir/z.s tmpdir/z.o]} then { 384 perror "could not assemble decompress dump test file" 385 unresolved "readelf - failed to assemble" 386 fail "readelf -z" 387} else { 388 389 if ![is_remote host] { 390 set tempfile tmpdir/z.o 391 } else { 392 set tempfile [remote_download host tmpdir/z.o] 393 } 394 395 readelf_test {--decompress --hex-dump .debug_loc} $tempfile readelf.z {} 396} 397