Home | History | Annotate | Download | only in binutils-all
      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