Commit | Line | Data |
---|---|---|
5b9b7d81 JR |
1 | # Copyright (C) 2004 |
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 | ||
18 | # Please email any bugs, comments, and/or additions to this file to: | |
e38bc3b5 | 19 | # binutils@sources.redhat.com |
5b9b7d81 JR |
20 | |
21 | # This scripts tests of all available SH architectures with all other SH | |
22 | # architectures. It ensures that those combinations which should not work | |
23 | # do not work, and that those that should work produce the correct output | |
24 | # architecture. | |
25 | # | |
26 | # It looks for files in the same directory as this file named sh*.s . | |
27 | # Each file must contain one or more instructions which uniquely identifies | |
28 | # that architecture. The architecture name is inferred from the file name. | |
e38bc3b5 | 29 | # It is best to use the same files used by the assembler testsuite. |
5b9b7d81 JR |
30 | # |
31 | # It also creates another architecture named 'sh-unknown' by modifying | |
32 | # another arch type (there is no way to assemble such an arch) in order | |
33 | # to test what the linker would do with an older object file. | |
34 | # | |
e38bc3b5 | 35 | # The script generates the architecture permutations automatically, |
5b9b7d81 JR |
36 | # but it reads the expected results from the file arch_expected.txt (also |
37 | # found in the same directory as this script). | |
38 | # | |
39 | # The arch_expected.txt file should NOT be hand edited. Whenever the script | |
40 | # is run (e.g. with 'make check') it creates a new (usually identical) file | |
41 | # named arch_results.txt in the <objdir>/ld/testsuite directory. When the | |
42 | # expected results change (or new architectures are added) this new file | |
43 | # can be used to replace arch_expected.txt with no modification required. | |
44 | ||
45 | ||
46 | # The procedure extracts the architecture name from the objdump output. | |
47 | # If there is no architecture name (or objdump output changes significantly) | |
48 | # then the behaviour is undefined, but it will most likely return junk. | |
49 | ||
50 | proc get_sh_arch { ofile } { | |
51 | global OBJDUMP | |
52 | ||
53 | set cmd "$OBJDUMP -f $ofile" | |
54 | verbose -log $cmd | |
55 | catch "exec $cmd" objdump_output | |
56 | verbose -log $objdump_output | |
57 | ||
58 | set objdump_output [string replace $objdump_output 0 \ | |
59 | [expr [string first "architecture:" $objdump_output] + 13] ""] | |
60 | ||
61 | return [string range $objdump_output 0 [expr [string first "," $objdump_output] - 1]] | |
62 | } | |
63 | ||
64 | ||
65 | # This procedure runs two tests: | |
66 | # Test 1: Check the linker can link the given files. | |
67 | # Test 2: Check that the resultant architecture is as expected. | |
68 | # It also writes an entry to the arch_results.txt file. | |
69 | ||
70 | proc test_arch { file1 file2 arch resultfile } { | |
71 | global LD | |
72 | ||
73 | set name1 [file tail $file1] | |
74 | set rootname1 [file rootname $name1] | |
75 | ||
76 | set name2 [file tail $file2] | |
77 | set rootname2 [file rootname $name2] | |
78 | ||
e38bc3b5 NC |
79 | # This must use -r to prevent LD trying to relocate the (unrealistic) file |
80 | send_log "$LD -r -o ${rootname1}_${rootname2}.o $file1 $file2\n" | |
81 | catch "exec $LD -r -o ${rootname1}_${rootname2}.o $file1 $file2" ld_output | |
82 | send_log $ld_output | |
5b9b7d81 | 83 | |
e38bc3b5 | 84 | if {[string equal $ld_output ""] == 1} then { |
5b9b7d81 JR |
85 | pass "$rootname1 file should link with $rootname2 file" |
86 | ||
87 | set result [get_sh_arch "${rootname1}_${rootname2}.o"] | |
88 | puts $resultfile [format "%-20s %-20s %s" $file1 $file2 $result] | |
89 | ||
90 | if {$result == $arch} then { | |
91 | pass "$rootname1 file with $rootname2 file should link to arch $arch" | |
92 | file delete "${rootname1}_${rootname2}.o" | |
93 | } else { | |
94 | fail "$rootname1 file with $rootname2 file should link to arch $arch" | |
95 | } | |
96 | } else { | |
97 | fail "$rootname1 file should link with $rootname2 file" | |
98 | ||
99 | puts $resultfile [format "%-20s %-20s ERROR" $file1 $file2] | |
100 | untested "$rootname2 file with $rootname2 file should link to arch $arch" | |
101 | } | |
102 | ||
103 | } | |
104 | ||
105 | ||
106 | ||
107 | # This procedure tests that a pair of files that are not | |
108 | # suposed to link does, in fact, not link. | |
109 | # It also writes an entry to the arch_results.txt file. | |
110 | ||
111 | proc test_arch_error { file1 file2 resultfile} { | |
112 | global link_output LD | |
113 | ||
114 | set name1 [file tail $file1] | |
115 | set rootname1 [file rootname $name1] | |
116 | ||
117 | set name2 [file tail $file2] | |
118 | set rootname2 [file rootname $name2] | |
119 | ||
e38bc3b5 NC |
120 | # This must use -r to prevent LD trying to relocate the (unrealistic) file |
121 | send_log "$LD -r -o ${rootname1}_${rootname2}.o $file1 $file2\n" | |
122 | catch "exec $LD -r -o ${rootname1}_${rootname2}.o $file1 $file2" ld_output | |
123 | send_log $ld_output | |
5b9b7d81 | 124 | |
e38bc3b5 | 125 | if {[string equal $ld_output ""] == 1} then { |
5b9b7d81 JR |
126 | fail "$rootname1 file should NOT link with $rootname2 file" |
127 | puts $resultfile [format "%-20s %-20s [get_sh_arch ${rootname1}_${rootname2}.o]" $file1 $file2] | |
128 | } else { | |
129 | pass "$rootname1 file should NOT link with $rootname2 file" | |
130 | puts $resultfile [format "%-20s %-20s ERROR" $file1 $file2] | |
131 | } | |
132 | } | |
133 | ||
134 | # These tests are not suitable for sh-coff because | |
135 | # coff does not store the architecture information. | |
136 | ||
137 | if [istarget sh*-*-elf] then { | |
138 | global subdir srcdir | |
139 | global AS | |
140 | ||
141 | # Find all the architectures and assemble all the files | |
142 | # we will use for the linker tests. | |
143 | ||
144 | set sfilelist [lsort -ascii [glob "$srcdir/$subdir/sh*.s"]] | |
145 | set ofilelist {} | |
146 | foreach sfile $sfilelist { | |
147 | set ofile "[file rootname [file tail $sfile]].o" | |
148 | lappend ofilelist $ofile | |
149 | ||
150 | set endian "-big" | |
151 | if [string equal [big_or_little_endian] " -EL"] then { | |
152 | set endian "-little" | |
153 | } | |
154 | ||
155 | set cmd "$AS $endian -isa=any $sfile -o $ofile" | |
156 | verbose -log $cmd | |
157 | catch "exec $cmd" as_output | |
158 | if ![file exists $ofile] then { | |
159 | verbose -log $as_output | |
160 | perror "$sfile: assembly failed" | |
161 | } | |
162 | } | |
163 | ||
164 | # Create the default arch ofile | |
165 | # This cannot be created with the assembler | |
166 | # sh4al-dsp is number 6, sh-unknown is 0 | |
167 | ||
168 | lappend ofilelist "sh-unknown.o" | |
169 | ||
170 | if [string equal [big_or_little_endian] " -EL"] then { | |
171 | set cmd {xxd sh4al-dsp.o | sed {s/\(^0000020: .... .... \)06/\100/} | xxd -r - sh-unknown.o} | |
172 | } else { | |
173 | set cmd {xxd sh4al-dsp.o | sed {s/\(^0000020: .... .... .... ..\)06/\100/} | xxd -r - sh-unknown.o} | |
174 | } | |
175 | verbose -log $cmd | |
176 | catch "exec $cmd" xxd_output | |
177 | verbose -log $xxd_output | |
178 | if [string equal [get_sh_arch "sh-unknown.o"] "sh4al-dsp"] then { | |
179 | perror "sh-unknown.o not generated correctly" | |
180 | } | |
181 | ||
182 | ||
183 | # Initialise the results file | |
184 | ||
185 | set outfile [open "arch_results.txt" w 0666] | |
186 | puts $outfile "# Generated file. DO NOT EDIT" | |
187 | puts $outfile "#" | |
188 | puts $outfile "# This file is generated by ld/testsuite/ld-sh/arch/arch.exp ." | |
189 | puts $outfile "# It contains the expected results of the tests." | |
190 | puts $outfile "# If the tests are failing because the expected results" | |
191 | puts $outfile "# have changed then run 'make check' and copy the new file" | |
192 | puts $outfile "# from <objdir>/ld/arch_results.txt" | |
193 | puts $outfile "# to <srcdir>/ld/testsuite/ld-sh/arch/arch_expected.txt ." | |
194 | puts $outfile "# Make sure the new expected results are ALL correct." | |
195 | puts $outfile "#" | |
196 | puts $outfile [format "# %-18s %-20s %s" "FILE1" "FILE2" "OUTPUT"] | |
197 | puts $outfile [format "# %-18s %-20s %s" "-----" "-----" "------"] | |
198 | ||
199 | # Open the expected results file and skip the header | |
200 | ||
201 | set infile [open "$srcdir/$subdir/arch_expected.txt" r] | |
202 | while {[gets $infile line] >= 0 && [string match {\#*} $line]} {verbose -log "reading '$line'"} | |
203 | ||
204 | foreach file1 $ofilelist { | |
205 | foreach file2 $ofilelist { | |
206 | set name1 [file tail $file1] | |
207 | set rootname1 [file rootname $name1] | |
208 | ||
209 | set name2 [file tail $file2] | |
210 | set rootname2 [file rootname $name2] | |
211 | ||
212 | # Decode the expected result from the file | |
213 | ||
214 | scan $line "%s %s %s" exfile1 exfile2 exarch | |
215 | verbose -log "exfile1 = '$exfile1', exfile2 = '$exfile2', exarch = '$exarch'" | |
216 | verbose -log " name1 = '$name1', name2 = '$name2'" | |
217 | ||
218 | if {[string equal $exfile1 $name1] && [string equal $exfile2 $file2]} then { | |
219 | # The expected result file makes sense and | |
220 | # appears up-to-date (the file and options match) | |
221 | ||
222 | if {[string equal $exarch "ERROR"]} then { | |
223 | test_arch_error $file1 $file2 $outfile | |
224 | } else { | |
225 | test_arch $file1 $file2 $exarch $outfile | |
226 | } | |
227 | } else { | |
228 | # The expected result file isn't right somehow | |
229 | # so just try any old test. This will cause | |
230 | # many failures, but will genrate the results file. | |
231 | ||
232 | test_arch $file1 $file2 $rootname1 $outfile | |
233 | } | |
234 | ||
235 | # Read the next line from the expected result file. | |
236 | # This is at the end because the process of skipping | |
237 | # the header reads the first real line | |
238 | ||
239 | if [gets $infile line] then { | |
240 | verbose -log "reading '$line'" | |
241 | } | |
242 | } | |
243 | } | |
244 | ||
245 | close $infile | |
246 | close $outfile | |
247 | ||
248 | foreach file $ofilelist { | |
249 | file delete $file | |
250 | } | |
251 | } |