merge from gcc
[external/binutils.git] / binutils / testsuite / binutils-all / readelf.exp
1 #   Copyright 1999, 2000, 2001, 2003, 2004, 2007, 2009
2 #   Free Software Foundation, Inc.
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
17
18 # Please email any bugs, comments, and/or additions to this file to:
19 # bug-dejagnu@prep.ai.mit.edu
20
21 # Written by Nick Clifton <nickc@cygnus.com>
22 # Based on scripts written by Ian Lance Taylor <ian@cygnus.com>
23 # and Ken Raeburn <raeburn@cygnus.com>.
24
25 # Exclude non-ELF targets.
26 if ![is_elf_format] {
27     verbose "$READELF is only intended for ELF targets" 2
28     return
29 }
30
31 # First some helpful procedures, then the tests themselves
32
33 # Return the contents of the filename given
34 proc file_contents { filename } {
35     set file [open $filename r]
36     set contents [read $file]
37     close $file
38     return $contents
39 }
40
41 # Find out the size by reading the output of the EI_CLASS field.
42 # Similar to the test for readelf -h, but we're just looking for the
43 # EI_CLASS line here.
44 proc readelf_find_size { binary_file } {
45     global READELF
46     global READELFFLAGS
47     global readelf_size
48
49     set readelf_size ""
50     set testname "finding out ELF size with readelf -h"
51     set got [remote_exec host "$READELF $READELFFLAGS -h $binary_file" "" "/dev/null" "readelf.out"]
52     if [is_remote host] then {
53         remote_upload host "readelf.out"
54     }
55
56     if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]]} then {
57         send_log $got
58         fail $testname
59         return
60     }
61
62     if { ! [regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
63             [file_contents readelf.out] nil readelf_size] } {
64         verbose -log "EI_CLASS field not found in output"
65         verbose -log "output is \n[file_contents readelf.out]"
66         fail $testname
67         return
68     } else {
69         verbose -log "ELF size is $readelf_size"
70     }
71
72     pass $testname
73 }
74
75 # Run an individual readelf test.
76 # Basically readelf is run on the binary_file with the given options.
77 # Readelf's output is captured and then compared against the contents
78 # of the regexp_file-readelf_size if it exists, else regexp_file.
79
80 proc readelf_test { options binary_file regexp_file xfails } {
81
82     global READELF
83     global READELFFLAGS
84     global readelf_size
85     global srcdir
86     global subdir
87     
88     send_log "exec $READELF $READELFFLAGS $options $binary_file > readelf.out\n"
89     set got [remote_exec host "$READELF $READELFFLAGS $options $binary_file" "" "/dev/null" "readelf.out"]
90
91     foreach xfail $xfails {
92         setup_xfail $xfail
93     }
94
95     if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
96         fail "readelf $options (reason: unexpected output)"
97         send_log $got
98         send_log "\n"
99         return
100     }
101
102     set target_machine ""
103     if [istarget "mips*-*-*"] then {
104         if { [istarget "mips*-*-*linux*"] || [istarget "mips*-sde-elf*"] } then {
105             set target_machine tmips
106         } else {
107             set target_machine mips
108         }
109     }
110
111     if { $target_machine != "" && [file exists $srcdir/$subdir/$regexp_file-$readelf_size-$target_machine] } then {
112         set regexp_file $regexp_file-$readelf_size-$target_machine
113     } elseif { $target_machine != "" && [file exists $srcdir/$subdir/$regexp_file-$target_machine] } then {
114         set regexp_file $regexp_file-$target_machine
115     } elseif { [file exists $srcdir/$subdir/$regexp_file-$readelf_size] } then {
116         set regexp_file $regexp_file-$readelf_size
117     }
118
119     if { [regexp_diff readelf.out $srcdir/$subdir/$regexp_file] } then {
120         fail "readelf $options"
121         verbose "output is \n[file_contents readelf.out]" 2
122         return
123     }
124
125     pass "readelf $options"
126 }
127
128 # Simple proc to skip certain expected warning messages.
129
130 proc prune_readelf_wi_warnings { text } {
131     regsub -all "(^|\n)(.*Skipping unexpected symbol type.*)" $text "\\1" text
132     return $text
133 }
134
135 # Testing the "readelf -wi" option is difficult because there
136 # is no guaranteed order to the output, and because some ports
137 # will use indirect string references, whilst others will use
138 # direct references.  So instead of having an expected output
139 # file, like the other readelf tests, we grep for strings that
140 # really ought to be there.
141
142 proc readelf_wi_test {} {
143     global READELF
144     global READELFFLAGS
145     global srcdir
146     global subdir
147     
148     # Compile the second test file.
149     if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } {
150         verbose "Unable to compile test file."
151         untested "readelf -wi"
152         return
153     }
154
155     # Download it.
156     set tempfile [remote_download host tmpdir/testprog.o]
157
158     # Run "readelf -wi" on it.
159     set got [remote_exec host "$READELF $READELFFLAGS -wi $tempfile" "" "/dev/null" "readelf.out"]
160
161     # Upload the results.
162     set output [remote_upload host readelf.out]
163
164     file_on_host delete $tempfile
165     
166     # Strip any superflous warnings.
167     set got [prune_readelf_wi_warnings [lindex $got 1]]
168
169     if ![string match "" $got] then {
170         fail "readelf $READELFFLAGS -wi (reason: unexpected output)"
171         send_log $got
172         send_log "\n"
173         return
174     }
175
176     if ![file size $output] then {
177         # If the output file is empty, then this target does not
178         # generate dwarf2 output.  This is not a failure.
179         verbose "No output from 'readelf -wi'"
180         untested "readelf -wi"
181         return
182     }
183     
184     # Search for strings that should be in the output.
185     set sought {
186         ".*DW_TAG_compile_unit.*"
187         ".*DW_TAG_subprogram.*"
188         ".*DW_TAG_base_type.*"
189         ".*DW_AT_producer.*(GNU C|indirect string).*"
190         ".*DW_AT_language.*ANSI C.*"
191         ".*DW_AT_name.*(testprog.c|indirect string).*"
192         ".*DW_AT_name.*fn.*"
193         ".*DW_AT_name.*(main|indirect string).*"
194         ".*\(DW_OP_addr: 0\).*"
195     }
196     
197     foreach looked_for $sought {        
198         set lines [grep $output $looked_for]
199         if ![llength $lines] then {
200             fail "readelf -wi: missing: $looked_for"
201             send_log readelf.out
202             return
203         }
204     }
205
206     file_on_host delete $output
207     
208     # All done.
209     pass "readelf -wi"
210 }
211
212 # This tests "readelf -wa", but on a file with a compressed
213 # .debug_abbrev section.
214
215 proc readelf_compressed_wa_test {} {
216     global READELF
217     global READELFFLAGS
218     global srcdir
219     global subdir
220     
221     # Compile the compressed-debug-section test file.
222     if { [target_compile $srcdir/$subdir/dw2-compressed.S tmpdir/dw2-compressed.o object debug] != "" } {
223         verbose "Unable to compile test file."
224         untested "readelf -wa (compressed)"
225         return
226     }
227
228     # Download it.
229     set tempfile [remote_download host tmpdir/dw2-compressed.o]
230
231     # Run "readelf -wa" on it.
232     set got [remote_exec host "$READELF $READELFFLAGS -wa $tempfile" "" "/dev/null" "readelf.out"]
233
234     # Upload the results.
235     set output [remote_upload host readelf.out]
236
237     file_on_host delete $tempfile
238     
239     if { [string compare [file_contents readelf.out] [file_contents $srcdir/$subdir/readelf.wa]] != 0 } then {
240         fail "readelf -wa (compressed)"
241         verbose "output is \n[file_contents readelf.out]" 2
242         verbose "expected is \n[file_contents $srcdir/$subdir/readelf.wa]" 2
243         return
244     }
245
246     pass "readelf -wa (compressed)"
247 }
248
249 # Test readelf's dumping abilities.
250
251 proc readelf_dump_test {} {
252     global READELF
253     global READELFFLAGS
254     global srcdir
255     global subdir
256     
257     # Assemble the dump test file.
258     if {![binutils_assemble $srcdir/$subdir/dumptest.s tmpdir/dumptest.o]} then {
259       unresolved "readelf -p: failed to assemble dump test file"
260       return
261     }
262     # Download it.
263     set tempfile [remote_download host tmpdir/dumptest.o]
264
265     # Run "readelf -p.data" on it.
266     set got [remote_exec host "$READELF $READELFFLAGS -p.data $tempfile" "" "/dev/null" "readelf.out"]
267     set got [lindex $got 1]
268
269     # Upload the results.
270     set output [remote_upload host readelf.out]
271
272     # Check for something going wrong.
273     if ![string match "" $got] then {
274         fail "readelf -p: unexpected output"
275         send_log $got
276         send_log "\n"
277         return
278     }
279
280     # Search for strings that should be in the output.
281     set sought {
282         ".*test_string.*"
283     }
284     
285     foreach looked_for $sought {        
286         set lines [grep $output $looked_for]
287         if ![llength $lines] then {
288             fail "readelf -p: missing: $looked_for"
289             send_log readelf.out
290             return
291         }
292     }
293
294     file_on_host delete $tempfile    
295     file_on_host delete $output
296
297     # All done.
298     pass "readelf -p"
299
300     # XXX FIXME: Add test of readelf -x here
301 }
302
303 if ![is_remote host] {
304     if {[which $READELF] == 0} then {
305         perror "$READELF does not exist"
306         return
307     }
308 }
309
310 send_user "Version [binutil_version $READELF]"
311
312 # Assemble the test file.
313 if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
314     perror "could not assemble test file"
315     unresolved "readelf - failed to assemble"
316     return
317 }
318
319 if ![is_remote host] {
320     set tempfile tmpdir/bintest.o
321 } else {
322     set tempfile [remote_download host tmpdir/bintest.o]
323 }
324
325 # First, determine the size, so specific output matchers can be used.
326 readelf_find_size $tempfile
327
328 # Run the tests.
329 readelf_test -h $tempfile readelf.h  {}
330 readelf_test -S $tempfile readelf.s  {}
331 readelf_test -s $tempfile readelf.ss {}
332 readelf_test -r $tempfile readelf.r  {}
333
334 readelf_wi_test
335 readelf_compressed_wa_test
336
337 readelf_dump_test