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 (at) prep.ai.mit.edu 19 20 # Written by Nick Clifton <nickc (at) cygnus.com> 21 # Based on scripts written by Ian Lance Taylor <ian (at) cygnus.com> 22 # and Ken Raeburn <raeburn (at) cygnus.com>. 23 24 # Exclude non-ELF targets. 25 if ![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 33 proc 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. 43 proc 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 79 proc 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 129 proc 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 141 proc 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 217 proc 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 253 proc 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 310 if ![is_remote host] { 311 if {[which $READELF] == 0} then { 312 perror "$READELF does not exist" 313 return 314 } 315 } 316 317 send_user "Version [binutil_version $READELF]" 318 319 # Assemble the test file. 320 if {![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 326 if ![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. 333 readelf_find_size $tempfile 334 335 # Run the tests. 336 readelf_test -h $tempfile readelf.h {} 337 readelf_test -S $tempfile readelf.s {} 338 setup_xfail "mips-*-*irix*" 339 readelf_test -s $tempfile readelf.ss {} 340 readelf_test -r $tempfile readelf.r {} 341 342 readelf_wi_test 343 readelf_compressed_wa_test 344 345 readelf_dump_test 346 347 # PR 13482 - Check for off-by-one errors when dumping .note sections. 348 if {![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. 366 if {![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. 383 if {![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