* readelf.c (dump_type): New type used to classify the kinds of dump requested by...
[external/binutils.git] / binutils / testsuite / binutils-all / readelf.exp
1 #   Copyright 1999, 2000, 2001, 2003, 2004, 2007 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.
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 { [istarget "mips*-*-*linux*"] || [istarget "mips*-sde-elf*"] } then {
104             set target_machine tmips
105         } else {
106             set target_machine mips
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     foreach looked_for $sought {        
197         set lines [grep $output $looked_for]
198         if ![llength $lines] then {
199             fail "readelf -wi: missing: $looked_for"
200             send_log readelf.out
201             return
202         }
203     }
204
205     file_on_host delete $output
206     
207     # All done.
208     pass "readelf -wi"
209 }
210
211
212 # Test readelf's dumping abilities.
213
214 proc readelf_dump_test {} {
215     global READELF
216     global READELFFLAGS
217     global srcdir
218     global subdir
219     
220     # Assemble the dump test file.
221     if {![binutils_assemble $srcdir/$subdir/dumptest.s tmpdir/dumptest.o]} then {
222       unresolved "readelf -p: failed to assemble dump test file"
223       return
224     }
225     # Download it.
226     set tempfile [remote_download host tmpdir/dumptest.o]
227
228     # Run "readelf -p.data" on it.
229     set got [remote_exec host "$READELF $READELFFLAGS -p.data $tempfile" "" "/dev/null" "readelf.out"]
230     set got [lindex $got 1]
231
232     # Upload the results.
233     set output [remote_upload host readelf.out]
234
235     # Check for something going wrong.
236     if ![string match "" $got] then {
237         fail "readelf -p: unexpected output"
238         send_log $got
239         send_log "\n"
240         return
241     }
242
243     # Search for strings that should be in the output.
244     set sought {
245         ".*test_string.*"
246     }
247     
248     foreach looked_for $sought {        
249         set lines [grep $output $looked_for]
250         if ![llength $lines] then {
251             fail "readelf -p: missing: $looked_for"
252             send_log readelf.out
253             return
254         }
255     }
256
257     file_on_host delete $tempfile    
258     file_on_host delete $output
259
260     # All done.
261     pass "readelf -p"
262
263     # XXX FIXME: Add test of readelf -x here
264 }
265
266 if ![is_remote host] {
267     if {[which $READELF] == 0} then {
268         perror "$READELF does not exist"
269         return
270     }
271 }
272
273 send_user "Version [binutil_version $READELF]"
274
275 # Assemble the test file.
276 if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
277     perror "could not assemble test file"
278     unresolved "readelf - failed to assemble"
279     return
280 }
281
282 if ![is_remote host] {
283     set tempfile tmpdir/bintest.o
284 } else {
285     set tempfile [remote_download host tmpdir/bintest.o]
286 }
287
288 # First, determine the size, so specific output matchers can be used.
289 readelf_find_size $tempfile
290
291 # Run the tests.
292 readelf_test -h $tempfile readelf.h  {}
293 readelf_test -S $tempfile readelf.s  {}
294 readelf_test -s $tempfile readelf.ss {}
295 readelf_test -r $tempfile readelf.r  {}
296
297 readelf_wi_test
298
299 readelf_dump_test