Commit | Line | Data |
---|---|---|
a2b64bed | 1 | # Support routines for LD testsuite. |
250d07de | 2 | # Copyright (C) 1994-2021 Free Software Foundation, Inc. |
a2b64bed | 3 | # |
f96b4a7b NC |
4 | # This file is part of the GNU Binutils. |
5 | # | |
a2b64bed NC |
6 | # This file is free software; you can redistribute it and/or modify |
7 | # it under the terms of the GNU General Public License as published by | |
f96b4a7b | 8 | # the Free Software Foundation; either version 3 of the License, or |
a2b64bed | 9 | # (at your option) any later version. |
3e8cba19 | 10 | # |
a2b64bed NC |
11 | # This program is distributed in the hope that it will be useful, |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
3e8cba19 | 15 | # |
a2b64bed NC |
16 | # You should have received a copy of the GNU General Public License |
17 | # along with this program; if not, write to the Free Software | |
f96b4a7b NC |
18 | # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
19 | # MA 02110-1301, USA. | |
3b6fe0cc | 20 | |
f3097f33 RS |
21 | proc load_common_lib { name } { |
22 | global srcdir | |
23 | load_file $srcdir/../../binutils/testsuite/lib/$name | |
24 | } | |
25 | ||
26 | load_common_lib binutils-common.exp | |
27 | ||
fb35d3d8 DD |
28 | # Returns 1 if the gcc for the target is at least version MAJOR.MINOR |
29 | # Returns 0 otherwise. | |
30 | # | |
31 | proc at_least_gcc_version { major minor } { | |
68bce020 | 32 | global CC |
5a68afcf | 33 | |
fb35d3d8 DD |
34 | if {![info exists CC]} { |
35 | set CC [find_gcc] | |
36 | } | |
37 | if { $CC == "" } { | |
8be1e369 | 38 | return 0 |
fb35d3d8 | 39 | } |
e6a6c767 L |
40 | # Filter out -Wl, options. |
41 | regsub -all -- "-Wl,\[^ ^\t\]+" $CC "" cc_cmd | |
42 | set state [remote_exec host $cc_cmd --version] | |
8be1e369 AM |
43 | if { [lindex $state 0] != 0 } { |
44 | return 0; | |
45 | } | |
fb35d3d8 DD |
46 | set tmp "[lindex $state 1]\n" |
47 | # Look for (eg) 4.6.1 in the version output. | |
8b5b2228 MR |
48 | set ver_re "\[^\\.0-9\]+(\[1-9\]\[0-9\]*)\\.(\[0-9\]+)(?:\\.\[0-9\]+)?" |
49 | regexp $ver_re $tmp fred maj min | |
fb35d3d8 | 50 | verbose "gcc version: $tmp" |
8b5b2228 MR |
51 | if { ![info exists maj] || ![info exists min] } then { |
52 | perror "can't decipher gcc version number, fix the framework!" | |
53 | return 0 | |
54 | } | |
fb35d3d8 DD |
55 | verbose "major gcc version is $maj, want at least $major" |
56 | if { $maj == $major } then { | |
57 | verbose "minor gcc version is $min, want at least $minor" | |
8b5b2228 | 58 | return [expr $min >= $minor] |
fb35d3d8 | 59 | } else { |
8b5b2228 | 60 | return [expr $maj > $major] |
fb35d3d8 DD |
61 | } |
62 | } | |
63 | ||
3b6fe0cc | 64 | # Extract and print the version number of ld. |
252b5132 RH |
65 | # |
66 | proc default_ld_version { ld } { | |
67 | global host_triplet | |
68 | ||
7f6a71ff | 69 | if { ![is_remote host] && [which $ld] == 0 } then { |
252b5132 RH |
70 | perror "$ld does not exist" |
71 | exit 1 | |
72 | } | |
3e8cba19 | 73 | |
7f6a71ff JM |
74 | remote_exec host "$ld --version" "" "/dev/null" "ld.version" |
75 | remote_upload host "ld.version" | |
76 | set tmp [prune_warnings [file_contents "ld.version"]] | |
77 | remote_file build delete "ld.version" | |
78 | remote_file host delete "ld.version" | |
79 | ||
252b5132 RH |
80 | regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number |
81 | if [info exists number] then { | |
82 | clone_output "$ld $number\n" | |
83 | } | |
84 | } | |
85 | ||
7f6a71ff JM |
86 | proc run_host_cmd { prog command } { |
87 | global link_output | |
f1d7f4a6 AM |
88 | global gcc_B_opt |
89 | global ld_L_opt | |
5a8edf8e AM |
90 | global gcc_ld_B_opt_tested |
91 | global ld | |
3e8cba19 | 92 | |
7f6a71ff JM |
93 | if { ![is_remote host] && [which "$prog"] == 0 } then { |
94 | perror "$prog does not exist" | |
252b5132 RH |
95 | return 0 |
96 | } | |
3e8cba19 | 97 | |
f1d7f4a6 AM |
98 | # If we are compiling with gcc, we want to add gcc_B_opt and |
99 | # ld_L_opt to flags. However, if $prog already has -B options, | |
100 | # which might be the case when running gcc out of a build | |
101 | # directory, we want our -B options to come first. | |
102 | set gccexe $prog | |
103 | set gccparm [string first " " $gccexe] | |
104 | set gccflags "" | |
105 | if { $gccparm > 0 } then { | |
106 | set gccflags [string range $gccexe $gccparm end] | |
107 | set gccexe [string range $gccexe 0 $gccparm] | |
108 | set prog $gccexe | |
109 | } | |
110 | set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""] | |
111 | if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then { | |
112 | set gccflags "$gcc_B_opt $gccflags $ld_L_opt" | |
5a8edf8e AM |
113 | if {![info exists gcc_ld_B_opt_tested]} { |
114 | set gcc_ld_B_opt_tested 1 | |
115 | set ld_version_message [run_host_cmd "$ld" "--version"] | |
116 | set gcc_ld_version_message [run_host_cmd "$prog" "$gccflags -Wl,--version"] | |
117 | if {[string first $ld_version_message $gcc_ld_version_message] < 0} { | |
118 | perror "************************************************************************" | |
119 | perror "Your compiler driver ignores -B when choosing ld." | |
120 | perror "You will not be testing the new ld in many of the following tests." | |
121 | set gcc_ld_version [run_host_cmd "$prog" "$gccflags --print-prog-name=ld"] | |
122 | if {![string match "" $gcc_ld_version] && ![string match "ld" $gcc_ld_version]} { | |
123 | ||
124 | perror "It seems you will be testing $gcc_ld_version instead." | |
125 | } | |
126 | perror "************************************************************************" | |
127 | } | |
128 | } | |
f1d7f4a6 AM |
129 | } |
130 | ||
131 | verbose -log "$prog $gccflags $command" | |
132 | set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "ld.tmp"] | |
7f6a71ff JM |
133 | remote_upload host "ld.tmp" |
134 | set link_output [file_contents "ld.tmp"] | |
135 | regsub "\n$" $link_output "" link_output | |
136 | if { [lindex $status 0] != 0 && [string match "" $link_output] } then { | |
137 | append link_output "child process exited abnormally" | |
138 | } | |
139 | remote_file build delete ld.tmp | |
140 | remote_file host delete ld.tmp | |
fab4a87f | 141 | |
7f6a71ff JM |
142 | if [string match "" $link_output] then { |
143 | return "" | |
144 | } | |
3e8cba19 | 145 | |
7f6a71ff JM |
146 | verbose -log "$link_output" |
147 | return "$link_output" | |
148 | } | |
149 | ||
150 | proc run_host_cmd_yesno { prog command } { | |
151 | global exec_output | |
d76b6207 | 152 | global errcnt warncnt |
7f6a71ff JM |
153 | |
154 | set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]] | |
d76b6207 L |
155 | # Ignore error and warning. |
156 | set errcnt 0 | |
157 | set warncnt 0 | |
252b5132 | 158 | if [string match "" $exec_output] then { |
7f6a71ff | 159 | return 1; |
252b5132 | 160 | } |
7f6a71ff JM |
161 | return 0; |
162 | } | |
163 | ||
164 | # Link an object using relocation. | |
165 | # | |
166 | proc default_ld_relocate { ld target objects } { | |
167 | global HOSTING_EMU | |
168 | ||
169 | remote_file host delete $target | |
170 | return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"] | |
252b5132 RH |
171 | } |
172 | ||
1688b748 | 173 | # Check to see if ld is being invoked with a non-endian output format |
3b6fe0cc | 174 | # |
1688b748 MH |
175 | proc is_endian_output_format { object_flags } { |
176 | ||
177 | if {[string match "*-oformat binary*" $object_flags] || \ | |
178 | [string match "*-oformat ieee*" $object_flags] || \ | |
179 | [string match "*-oformat ihex*" $object_flags] || \ | |
180 | [string match "*-oformat netbsd-core*" $object_flags] || \ | |
181 | [string match "*-oformat srec*" $object_flags] || \ | |
182 | [string match "*-oformat tekhex*" $object_flags] || \ | |
183 | [string match "*-oformat trad-core*" $object_flags] } then { | |
184 | return 0 | |
185 | } else { | |
186 | return 1 | |
187 | } | |
188 | } | |
189 | ||
d9816402 | 190 | # Link a program using ld |
252b5132 RH |
191 | # |
192 | proc default_ld_link { ld target objects } { | |
252b5132 | 193 | global host_triplet |
fab4a87f | 194 | global exec_output |
7cda33a1 | 195 | |
f1d7f4a6 | 196 | set flags "" |
1688b748 MH |
197 | if [is_endian_output_format $objects] then { |
198 | set flags [big_or_little_endian] | |
b765d4e3 L |
199 | } |
200 | ||
7f6a71ff | 201 | remote_file host delete $target |
f1d7f4a6 | 202 | set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"] |
7f6a71ff | 203 | set exec_output [prune_warnings $exec_output] |
252b5132 RH |
204 | |
205 | # We don't care if we get a warning about a non-existent start | |
206 | # symbol, since the default linker script might use ENTRY. | |
207 | regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output | |
208 | ||
f1d7f4a6 | 209 | return [string match "" $exec_output] |
252b5132 RH |
210 | } |
211 | ||
3b6fe0cc | 212 | # Compile an object using cc. |
252b5132 RH |
213 | # |
214 | proc default_ld_compile { cc source object } { | |
215 | global CFLAGS | |
58ffc3bd | 216 | global CXXFLAGS |
252b5132 RH |
217 | global srcdir |
218 | global subdir | |
219 | global host_triplet | |
f1d7f4a6 | 220 | global gcc_B_opt |
252b5132 RH |
221 | |
222 | set cc_prog $cc | |
223 | if {[llength $cc_prog] > 1} then { | |
224 | set cc_prog [lindex $cc_prog 0] | |
225 | } | |
7f6a71ff | 226 | if {![is_remote host] && [which $cc_prog] == 0} then { |
252b5132 RH |
227 | perror "$cc_prog does not exist" |
228 | return 0 | |
229 | } | |
230 | ||
7f6a71ff JM |
231 | remote_file build delete "$object" |
232 | remote_file host delete "$object" | |
252b5132 | 233 | |
f1d7f4a6 | 234 | set flags "$gcc_B_opt -I$srcdir/$subdir" |
252b5132 | 235 | |
f1d7f4a6 AM |
236 | # If we are compiling with gcc, we want to add gcc_B_opt to flags. |
237 | # However, if $prog already has -B options, which might be the | |
238 | # case when running gcc out of a build directory, we want our -B | |
239 | # options to come first. | |
b0fe1bf3 AM |
240 | set ccexe $cc |
241 | set ccparm [string first " " $cc] | |
dec20c9e | 242 | set ccflags "" |
b0fe1bf3 | 243 | if { $ccparm > 0 } then { |
dec20c9e | 244 | set ccflags [string range $cc $ccparm end] |
b0fe1bf3 | 245 | set ccexe [string range $cc 0 $ccparm] |
dec20c9e | 246 | set cc $ccexe |
b0fe1bf3 | 247 | } |
252b5132 | 248 | |
f1d7f4a6 | 249 | set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""] |
58ffc3bd | 250 | if {[string match "*++*" $ccexe]} { |
f1d7f4a6 | 251 | append flags " $CXXFLAGS" |
58ffc3bd | 252 | } else { |
f1d7f4a6 | 253 | append flags " $CFLAGS" |
58ffc3bd MF |
254 | } |
255 | ||
3046b3d3 VP |
256 | if [board_info [target_info name] exists cflags] { |
257 | append flags " [board_info [target_info name] cflags]" | |
258 | } | |
259 | ||
38e31547 | 260 | if [board_info [target_info name] exists multilib_flags] { |
b24f926d | 261 | append flags " [board_info [target_info name] multilib_flags]" |
38e31547 NC |
262 | } |
263 | ||
f1d7f4a6 AM |
264 | set cmd "$cc $flags $ccflags -c $source -o $object" |
265 | verbose -log "$cmd" | |
252b5132 | 266 | |
f1d7f4a6 | 267 | set status [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"] |
7f6a71ff JM |
268 | remote_upload host "ld.tmp" |
269 | set exec_output [file_contents "ld.tmp"] | |
270 | remote_file build delete "ld.tmp" | |
271 | remote_file host delete "ld.tmp" | |
252b5132 | 272 | set exec_output [prune_warnings $exec_output] |
6f9dbcd4 AM |
273 | # Versions of gcc up to and including pre-release gcc-7, at least on |
274 | # some targets, generate .section directives with incorrect type. | |
275 | # Ignore warnings from the assembler about this. | |
276 | regsub -all "(^|\n)\[^\n\]*: ignoring incorrect section type \[^\n\]*" $exec_output "" exec_output | |
277 | regsub -all "^\[^\n\]*: Assembler messages:\n" $exec_output "" exec_output | |
252b5132 RH |
278 | if [string match "" $exec_output] then { |
279 | if {![file exists $object]} then { | |
280 | regexp ".*/(\[^/\]*)$" $source all dobj | |
281 | regsub "\\.c" $dobj ".o" realobj | |
282 | verbose "looking for $realobj" | |
7f6a71ff | 283 | if {[remote_file host exists $realobj]} then { |
252b5132 | 284 | verbose -log "mv $realobj $object" |
7f6a71ff | 285 | remote_upload "$realobj" "$object" |
252b5132 RH |
286 | } else { |
287 | perror "$object not found after compilation" | |
288 | return 0 | |
289 | } | |
290 | } | |
291 | return 1 | |
292 | } else { | |
293 | verbose -log "$exec_output" | |
252b5132 RH |
294 | return 0 |
295 | } | |
296 | } | |
297 | ||
3b6fe0cc | 298 | # Assemble a file. |
252b5132 | 299 | # |
de1491f0 | 300 | proc default_ld_assemble { as in_flags source object } { |
252b5132 RH |
301 | global ASFLAGS |
302 | global host_triplet | |
690f47bf RS |
303 | global srcdir |
304 | global subdir | |
3e8cba19 | 305 | |
252b5132 RH |
306 | if ![info exists ASFLAGS] { set ASFLAGS "" } |
307 | ||
740341b9 AM |
308 | set flags [big_or_little_endian] |
309 | if [info exists subdir] { | |
310 | append flags " -I$srcdir/$subdir" | |
311 | } | |
de1491f0 | 312 | set exec_output [run_host_cmd "$as" "$flags $in_flags $ASFLAGS -o $object $source"] |
252b5132 RH |
313 | set exec_output [prune_warnings $exec_output] |
314 | if [string match "" $exec_output] then { | |
315 | return 1 | |
316 | } else { | |
252b5132 RH |
317 | return 0 |
318 | } | |
319 | } | |
320 | ||
3b6fe0cc | 321 | # Run nm on a file, putting the result in the array nm_output. |
252b5132 | 322 | # |
992c450d | 323 | proc default_ld_nm { nm nmflags object } { |
252b5132 RH |
324 | global NMFLAGS |
325 | global nm_output | |
326 | global host_triplet | |
327 | ||
77e0b0ef ILT |
328 | if {[info exists nm_output]} { |
329 | unset nm_output | |
330 | } | |
331 | ||
252b5132 RH |
332 | if ![info exists NMFLAGS] { set NMFLAGS "" } |
333 | ||
3e8cba19 AM |
334 | # Ensure consistent sorting of symbols |
335 | if {[info exists env(LC_ALL)]} { | |
336 | set old_lc_all $env(LC_ALL) | |
337 | } | |
338 | set env(LC_ALL) "C" | |
7f6a71ff | 339 | |
992c450d | 340 | verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out" |
252b5132 | 341 | |
7f6a71ff | 342 | set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"] |
3e8cba19 AM |
343 | if {[info exists old_lc_all]} { |
344 | set env(LC_ALL) $old_lc_all | |
345 | } else { | |
346 | unset env(LC_ALL) | |
347 | } | |
7f6a71ff JM |
348 | remote_upload host "ld.stderr" |
349 | remote_upload host "tmpdir/nm.out" "tmpdir/nm.out" | |
350 | set exec_output [prune_warnings [file_contents "ld.stderr"]] | |
351 | remote_file host delete "ld.stderr" | |
352 | remote_file build delete "ld.stderr" | |
252b5132 RH |
353 | if [string match "" $exec_output] then { |
354 | set file [open tmpdir/nm.out r] | |
355 | while { [gets $file line] != -1 } { | |
356 | verbose "$line" 2 | |
dbc37f89 | 357 | if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] { |
252b5132 RH |
358 | set name [string trimleft $name "_"] |
359 | verbose "Setting nm_output($name) to 0x$value" 2 | |
360 | set nm_output($name) 0x$value | |
361 | } | |
362 | } | |
363 | close $file | |
364 | return 1 | |
365 | } else { | |
366 | verbose -log "$exec_output" | |
252b5132 RH |
367 | return 0 |
368 | } | |
369 | } | |
370 | ||
1b662205 AM |
371 | # Define various symbols needed when not linking against all |
372 | # target libs. | |
d9816402 | 373 | proc ld_link_defsyms {} { |
1b662205 AM |
374 | |
375 | set flags "--defsym __stack_chk_fail=0" | |
376 | ||
377 | # ARM targets call __gccmain | |
8c5fc800 | 378 | if {[istarget arm*-*-*]} { |
1b662205 AM |
379 | append flags " --defsym __gccmain=0" |
380 | } | |
381 | ||
5a1431e6 | 382 | # Windows targets need __main, some prefixed with underscore. |
36fe835f | 383 | if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} { |
6194b866 | 384 | append flags " --defsym __main=main --defsym ___main=main" |
36fe835f DK |
385 | } |
386 | ||
1b662205 AM |
387 | # PowerPC EABI code calls __eabi. |
388 | if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} { | |
389 | append flags " --defsym __eabi=0" | |
390 | } | |
391 | ||
392 | # mn10200 code calls __truncsipsi2_d0_d2. | |
393 | if {[istarget mn10200*-*-*]} then { | |
394 | append flags " --defsym __truncsipsi2_d0_d2=0" | |
395 | } | |
396 | ||
397 | # m6811/m6812 code has references to soft registers. | |
32d79e68 | 398 | if {[istarget m6811-*-*] || [istarget m6812-*-*] || [istarget m68hc1*-*-*]} { |
1b662205 AM |
399 | append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0" |
400 | append flags " --defsym _.d3=0 --defsym _.d4=0" | |
401 | append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0" | |
402 | } | |
403 | ||
404 | # Some OpenBSD targets have ProPolice and reference __guard and | |
405 | # __stack_smash_handler. | |
406 | if [istarget *-*-openbsd*] { | |
407 | append flags " --defsym __guard=0" | |
408 | append flags " --defsym __stack_smash_handler=0" | |
409 | } | |
410 | ||
411 | return $flags | |
412 | } | |
413 | ||
d8880531 L |
414 | # Create an archive using ar |
415 | # | |
fa0a16b1 | 416 | proc ar_simple_create { ar aropts target objects } { |
d8880531 L |
417 | remote_file host delete $target |
418 | ||
babcb2ea | 419 | set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"] |
d8880531 L |
420 | set exec_output [prune_warnings $exec_output] |
421 | ||
422 | if [string match "" $exec_output] then { | |
423 | send_log "$exec_output\n" | |
424 | return 1 | |
425 | } else { | |
426 | return 0 | |
427 | } | |
428 | } | |
429 | ||
9147e853 JJ |
430 | # List contains test-items with 3 items followed by 2 lists, one item and |
431 | # one optional item: | |
894891db | 432 | # 0:name |
897aea50 MR |
433 | # 1:ld/ar leading options, placed before object files |
434 | # 2:ld/ar trailing options, placed after object files | |
435 | # 3:assembler options | |
436 | # 4:filenames of assembler files | |
437 | # 5:list of actions, options and expected outputs. | |
438 | # 6:name of output file | |
439 | # 7:compiler flags (optional) | |
3b6fe0cc | 440 | # |
894891db NC |
441 | # Actions: { command command-line-options file-containg-expected-output-regexps } |
442 | # Commands: | |
443 | # objdump: Apply objdump options on result. | |
444 | # nm: Apply nm options on result. | |
445 | # readelf: Apply readelf options on result. | |
5a68afcf | 446 | # ld: Don't apply anything on result. Compare output during linking with |
894891db NC |
447 | # the file containing regexps (which is the second arg, not the third). |
448 | # Note that this *must* be the first action if it is to be used at all; | |
449 | # in all other cases, any output from the linker during linking is | |
450 | # treated as a sign of an error and FAILs the test. | |
3b6fe0cc | 451 | # |
5df1bc57 AM |
452 | # args is an optional list of target triplets to be xfailed. |
453 | # | |
454 | proc run_ld_link_tests { ldtests args } { | |
bffbf940 | 455 | global ld |
740341b9 | 456 | global LDFLAGS |
bffbf940 JJ |
457 | global as |
458 | global nm | |
d8880531 | 459 | global ar |
bffbf940 JJ |
460 | global objdump |
461 | global READELF | |
462 | global srcdir | |
463 | global subdir | |
464 | global env | |
9147e853 JJ |
465 | global CC |
466 | global CFLAGS | |
eca41774 | 467 | global runtests |
5d3236ee | 468 | global exec_output |
647e4d46 | 469 | |
740341b9 | 470 | set ld_extra_opt $LDFLAGS |
5fd104ad | 471 | if [check_relro_support] { |
740341b9 | 472 | append ld_extra_opt " -z norelro" |
647e4d46 | 473 | } |
bffbf940 JJ |
474 | |
475 | foreach testitem $ldtests { | |
476 | set testname [lindex $testitem 0] | |
eca41774 DK |
477 | |
478 | if ![runtest_file_p $runtests $testname] then { | |
479 | continue | |
480 | } | |
481 | ||
5df1bc57 | 482 | foreach target $args { |
1336939d AM |
483 | if [match_target $target] { |
484 | setup_xfail "*-*-*" | |
485 | break | |
486 | } | |
5df1bc57 AM |
487 | } |
488 | ||
bffbf940 | 489 | set ld_options [lindex $testitem 1] |
897aea50 MR |
490 | set ld_after [lindex $testitem 2] |
491 | set as_options [lindex $testitem 3] | |
492 | set src_files [lindex $testitem 4] | |
493 | set actions [lindex $testitem 5] | |
494 | set binfile tmpdir/[lindex $testitem 6] | |
495 | set cflags [lindex $testitem 7] | |
bffbf940 JJ |
496 | set objfiles {} |
497 | set is_unresolved 0 | |
498 | set failed 0 | |
5d3236ee DK |
499 | set maybe_failed 0 |
500 | set ld_output "" | |
bffbf940 | 501 | |
c6d47bff L |
502 | # Add -fno-lto. LTO should be tested explicitly by $cflags. |
503 | if {[check_lto_available]} { | |
504 | set cflags "-fno-lto $cflags" | |
505 | } | |
506 | ||
bffbf940 JJ |
507 | # verbose -log "Testname is $testname" |
508 | # verbose -log "ld_options is $ld_options" | |
897aea50 | 509 | # verbose -log "ld_after is $ld_after" |
bffbf940 | 510 | # verbose -log "as_options is $as_options" |
9147e853 | 511 | # verbose -log "src_files is $src_files" |
bffbf940 JJ |
512 | # verbose -log "actions is $actions" |
513 | # verbose -log "binfile is $binfile" | |
514 | ||
515 | # Assemble each file in the test. | |
9147e853 | 516 | foreach src_file $src_files { |
74d44110 | 517 | set fileroot "[file rootname [file tail $src_file]]" |
bffbf940 | 518 | |
36068e2f L |
519 | if { [file extension $src_file] == ".bz2" } { |
520 | set objfile tmpdir/[file rootname $src_file] | |
521 | set unbzip2 "system \"bzip2 -dc $srcdir/$subdir/$src_file > $objfile\"" | |
522 | send_log "$unbzip2\n" | |
523 | catch "$unbzip2" exec_output | |
524 | if ![string match "" $exec_output] then { | |
525 | send_log "$exec_output\n" | |
9147e853 JJ |
526 | set is_unresolved 1 |
527 | break | |
528 | } | |
529 | } else { | |
36068e2f L |
530 | set objfile "tmpdir/$fileroot.o" |
531 | if { [file extension $src_file] == ".c" } { | |
532 | set as_file "tmpdir/$fileroot.s" | |
533 | if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] { | |
534 | set is_unresolved 1 | |
535 | break | |
536 | } | |
537 | } else { | |
538 | set as_file "$srcdir/$subdir/$src_file" | |
539 | } | |
540 | if ![ld_assemble $as "$as_options $as_file" $objfile] { | |
541 | set failed 1 | |
542 | break | |
543 | } | |
bffbf940 | 544 | } |
36068e2f | 545 | lappend objfiles $objfile |
bffbf940 JJ |
546 | } |
547 | ||
548 | # Catch assembler errors. | |
348fe36b AM |
549 | if { $failed } { |
550 | fail $testname | |
551 | continue | |
552 | } | |
553 | # Catch compiler errors. | |
77c56f44 | 554 | if { $is_unresolved } { |
bffbf940 JJ |
555 | unresolved $testname |
556 | continue | |
557 | } | |
558 | ||
abc868c6 AM |
559 | if { $binfile eq "tmpdir/" } { |
560 | # compile only | |
561 | } elseif { [regexp ".*\\.a$" $binfile] } { | |
897aea50 | 562 | if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } { |
d8880531 | 563 | set failed 1 |
d8880531 | 564 | } |
d9816402 | 565 | } elseif { ![ld_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } { |
5d3236ee DK |
566 | set maybe_failed 1 |
567 | set ld_output "$exec_output" | |
d8880531 L |
568 | } |
569 | ||
77c56f44 | 570 | if { !$failed } { |
bffbf940 JJ |
571 | foreach actionlist $actions { |
572 | set action [lindex $actionlist 0] | |
573 | set progopts [lindex $actionlist 1] | |
574 | ||
575 | # There are actions where we run regexp_diff on the | |
576 | # output, and there are other actions (presumably). | |
577 | # Handling of the former look the same. | |
578 | set dump_prog "" | |
579 | switch -- $action { | |
580 | objdump | |
581 | { set dump_prog $objdump } | |
582 | nm | |
583 | { set dump_prog $nm } | |
584 | readelf | |
585 | { set dump_prog $READELF } | |
5d3236ee DK |
586 | ld |
587 | { set dump_prog "ld" } | |
bffbf940 JJ |
588 | default |
589 | { | |
590 | perror "Unrecognized action $action" | |
591 | set is_unresolved 1 | |
592 | break | |
593 | } | |
594 | } | |
595 | ||
5d3236ee | 596 | if { $action == "ld" } { |
894891db NC |
597 | set regexpfile $progopts |
598 | verbose "regexpfile is $srcdir/$subdir/$regexpfile" | |
5d3236ee DK |
599 | set_file_contents "tmpdir/ld.messages" "$ld_output" |
600 | verbose "ld.messages has '[file_contents tmpdir/ld.messages]'" | |
894891db | 601 | if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then { |
5d3236ee DK |
602 | verbose "output is $ld_output" 2 |
603 | set failed 1 | |
604 | break | |
605 | } | |
606 | set maybe_failed 0 | |
77c56f44 | 607 | } elseif { !$maybe_failed && $dump_prog != "" } { |
bffbf940 JJ |
608 | set dumpfile [lindex $actionlist 2] |
609 | set binary $dump_prog | |
610 | ||
611 | # Ensure consistent sorting of symbols | |
612 | if {[info exists env(LC_ALL)]} { | |
613 | set old_lc_all $env(LC_ALL) | |
614 | } | |
615 | set env(LC_ALL) "C" | |
7f6a71ff JM |
616 | set cmd "$binary $progopts $binfile" |
617 | set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"] | |
bffbf940 | 618 | send_log "$cmd\n" |
7f6a71ff JM |
619 | remote_upload host "ld.stderr" |
620 | set comp_output [prune_warnings [file_contents "ld.stderr"]] | |
621 | remote_file host delete "ld.stderr" | |
622 | remote_file build delete "ld.stderr" | |
5a68afcf | 623 | |
bffbf940 JJ |
624 | if {[info exists old_lc_all]} { |
625 | set env(LC_ALL) $old_lc_all | |
626 | } else { | |
627 | unset env(LC_ALL) | |
628 | } | |
bffbf940 JJ |
629 | |
630 | if ![string match "" $comp_output] then { | |
631 | send_log "$comp_output\n" | |
632 | set failed 1 | |
633 | break | |
634 | } | |
635 | ||
7f6a71ff JM |
636 | remote_upload host "dump.out" |
637 | ||
bffbf940 JJ |
638 | if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then { |
639 | verbose "output is [file_contents "dump.out"]" 2 | |
640 | set failed 1 | |
7f6a71ff JM |
641 | remote_file build delete "dump.out" |
642 | remote_file host delete "dump.out" | |
bffbf940 JJ |
643 | break |
644 | } | |
7f6a71ff JM |
645 | remote_file build delete "dump.out" |
646 | remote_file host delete "dump.out" | |
bffbf940 JJ |
647 | } |
648 | } | |
bffbf940 JJ |
649 | } |
650 | ||
77c56f44 | 651 | if { $is_unresolved } { |
bffbf940 | 652 | unresolved $testname |
77c56f44 RS |
653 | } elseif { $maybe_failed || $failed } { |
654 | fail $testname | |
655 | } else { | |
656 | pass $testname | |
bffbf940 JJ |
657 | } |
658 | } | |
659 | } | |
660 | ||
c8c140d9 | 661 | # ldtests contains test-items with 3 items followed by 1 lists, 2 items |
fab4a87f | 662 | # and 3 optional items: |
c8c140d9 | 663 | # 0:name |
fef75122 | 664 | # 1:ld leading options, placed before object files |
c8c140d9 | 665 | # 2:assembler options |
55255dae | 666 | # 3:filenames of source files |
c8c140d9 BE |
667 | # 4:name of output file |
668 | # 5:expected output | |
669 | # 6:compiler flags (optional) | |
55255dae | 670 | # 7:language (optional) |
fab4a87f | 671 | # 8:linker warning (optional) |
fef75122 | 672 | # 9:ld trailing options, placed after object files (optional) |
982c6f26 | 673 | # args is an optional list of target triplets to be xfailed. |
c8c140d9 | 674 | |
982c6f26 | 675 | proc run_ld_link_exec_tests { ldtests args } { |
24edc24d L |
676 | global ld |
677 | global as | |
678 | global srcdir | |
679 | global subdir | |
680 | global env | |
681 | global CC | |
55255dae | 682 | global CXX |
24edc24d | 683 | global CFLAGS |
58ffc3bd | 684 | global CXXFLAGS |
22ec3bd1 | 685 | global errcnt |
fab4a87f | 686 | global exec_output |
9966f7ee | 687 | global board_cflags |
98d72909 | 688 | global STATIC_LDFLAGS |
9966f7ee JW |
689 | |
690 | # When using GCC as the linker driver, we need to specify board cflags when | |
691 | # linking because cflags may contain linker options. For example when | |
692 | # linker options are included in GCC spec files then we need the -specs | |
693 | # option. | |
694 | if [board_info [target_info name] exists cflags] { | |
695 | set board_cflags " [board_info [target_info name] cflags]" | |
696 | } else { | |
697 | set board_cflags "" | |
698 | } | |
24edc24d L |
699 | |
700 | foreach testitem $ldtests { | |
701 | set testname [lindex $testitem 0] | |
702 | set ld_options [lindex $testitem 1] | |
703 | set as_options [lindex $testitem 2] | |
704 | set src_files [lindex $testitem 3] | |
705 | set binfile tmpdir/[lindex $testitem 4] | |
706 | set expfile [lindex $testitem 5] | |
707 | set cflags [lindex $testitem 6] | |
55255dae | 708 | set lang [lindex $testitem 7] |
fab4a87f | 709 | set warning [lindex $testitem 8] |
fef75122 | 710 | set ld_after [lindex $testitem 9] |
24edc24d | 711 | set objfiles {} |
24edc24d L |
712 | set failed 0 |
713 | ||
44ed8092 SL |
714 | if { ![check_compiler_available] } { |
715 | unsupported $testname | |
716 | continue | |
717 | } | |
718 | ||
e6a6c767 L |
719 | # Add -fno-lto. LTO should be tested explicitly by $cflags. |
720 | if {[check_lto_available]} { | |
721 | set cflags "-fno-lto $cflags" | |
722 | } | |
723 | ||
1336939d AM |
724 | foreach target $args { |
725 | if [match_target $target] { | |
726 | setup_xfail "*-*-*" | |
727 | break | |
728 | } | |
729 | } | |
730 | ||
24edc24d L |
731 | # verbose -log "Testname is $testname" |
732 | # verbose -log "ld_options is $ld_options" | |
733 | # verbose -log "as_options is $as_options" | |
734 | # verbose -log "src_files is $src_files" | |
24edc24d L |
735 | # verbose -log "binfile is $binfile" |
736 | ||
737 | # Assemble each file in the test. | |
738 | foreach src_file $src_files { | |
74d44110 MR |
739 | set fileroot "[file rootname [file tail $src_file]]" |
740 | set objfile "tmpdir/$fileroot.o" | |
24edc24d L |
741 | lappend objfiles $objfile |
742 | ||
58ffc3bd | 743 | if { [ string match "c++" $lang ] } { |
a44d0bd7 | 744 | set cmd "$CXX -c $CXXFLAGS $cflags" |
58ffc3bd | 745 | } else { |
a44d0bd7 | 746 | set cmd "$CC -c $CFLAGS $cflags" |
58ffc3bd | 747 | } |
a44d0bd7 AM |
748 | if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] { |
749 | set failed 1 | |
750 | break | |
751 | } | |
752 | } | |
753 | if { $failed != 0 } { | |
754 | unresolved $testname | |
755 | continue | |
cb5ab6c8 | 756 | } |
a10e6b21 | 757 | |
241e64e3 L |
758 | if { [ string match "asm" $lang ] } { |
759 | set link_proc ld_link | |
760 | set link_cmd $ld | |
761 | } elseif { [ string match "c++" $lang ] } { | |
d9816402 | 762 | set link_proc ld_link |
cb5ab6c8 | 763 | set link_cmd $CXX |
cb5ab6c8 L |
764 | } else { |
765 | set link_proc ld_link | |
d9816402 | 766 | set link_cmd $CC |
cb5ab6c8 | 767 | } |
24edc24d | 768 | |
abc868c6 AM |
769 | if { $binfile eq "tmpdir/" } { |
770 | # compile only | |
771 | pass $testname | |
772 | continue; | |
98d72909 L |
773 | } else { |
774 | if { [string match "" $STATIC_LDFLAGS] \ | |
775 | && [regexp -- ".* \[-\]+static .*" " $board_cflags $ld_options $objfiles $ld_after "] } { | |
776 | untested $testname | |
777 | continue | |
778 | } | |
779 | if ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles $ld_after"] { | |
780 | set failed 1 | |
781 | } | |
cb5ab6c8 L |
782 | } |
783 | ||
784 | # Check if exec_output is expected. | |
785 | if { $warning != "" } then { | |
786 | verbose -log "returned with: <$exec_output>, expected: <$warning>" | |
787 | if { [regexp $warning $exec_output] } then { | |
a10e6b21 | 788 | set failed 0 |
cb5ab6c8 L |
789 | } else { |
790 | set failed 1 | |
fab4a87f | 791 | } |
cb5ab6c8 | 792 | } |
fab4a87f | 793 | |
d9816402 | 794 | if { $failed == 0 && [isnative] } { |
cb5ab6c8 L |
795 | send_log "Running: $binfile > $binfile.out\n" |
796 | verbose "Running: $binfile > $binfile.out" | |
797 | catch "exec $binfile > $binfile.out" exec_output | |
fab4a87f | 798 | |
cb5ab6c8 L |
799 | if ![string match "" $exec_output] then { |
800 | send_log "$exec_output\n" | |
801 | verbose "$exec_output" 1 | |
802 | set failed 1 | |
803 | } else { | |
84df1f9d AM |
804 | send_log [file_contents $binfile.out] |
805 | verbose [file_contents $binfile.out] 2 | |
806 | if [regexp_diff "$binfile.out" "$srcdir/$subdir/$expfile"] { | |
24edc24d L |
807 | set failed 1 |
808 | } | |
809 | } | |
cb5ab6c8 | 810 | } |
24edc24d | 811 | |
cb5ab6c8 L |
812 | if { $failed != 0 } { |
813 | fail $testname | |
d9816402 AM |
814 | } elseif ![isnative] { |
815 | unsupported $testname | |
cb5ab6c8 L |
816 | } else { |
817 | set errcnt 0 | |
818 | pass $testname | |
24edc24d | 819 | } |
24edc24d L |
820 | } |
821 | } | |
d2dee3b2 L |
822 | |
823 | # List contains test-items with 3 items followed by 2 lists, one item and | |
824 | # one optional item: | |
55255dae | 825 | # 0:name |
fa0a16b1 | 826 | # 1:ld or ar options |
55255dae L |
827 | # 2:compile options |
828 | # 3:filenames of source files | |
829 | # 4:action and options. | |
830 | # 5:name of output file | |
831 | # 6:language (optional) | |
d2dee3b2 L |
832 | # |
833 | # Actions: | |
834 | # objdump: Apply objdump options on result. Compare with regex (last arg). | |
835 | # nm: Apply nm options on result. Compare with regex (last arg). | |
836 | # readelf: Apply readelf options on result. Compare with regex (last arg). | |
2bd7f877 AB |
837 | # warning: Check linker output against regex (last arg). |
838 | # error: Like 'warning' but checking output in error case. | |
839 | # warning_output: Check linker output against regex in a file (last arg). | |
840 | # error_output: Like 'warning_output' but checking output in error case. | |
d2dee3b2 L |
841 | # |
842 | proc run_cc_link_tests { ldtests } { | |
843 | global nm | |
844 | global objdump | |
845 | global READELF | |
846 | global srcdir | |
847 | global subdir | |
848 | global env | |
849 | global CC | |
55255dae | 850 | global CXX |
d2dee3b2 | 851 | global CFLAGS |
58ffc3bd | 852 | global CXXFLAGS |
d8880531 | 853 | global ar |
dd98f8d2 | 854 | global exec_output |
603c4399 | 855 | global board_cflags |
98d72909 | 856 | global STATIC_LDFLAGS |
603c4399 JW |
857 | |
858 | if [board_info [target_info name] exists cflags] { | |
859 | set board_cflags " [board_info [target_info name] cflags]" | |
860 | } else { | |
861 | set board_cflags "" | |
862 | } | |
d2dee3b2 L |
863 | |
864 | foreach testitem $ldtests { | |
865 | set testname [lindex $testitem 0] | |
866 | set ldflags [lindex $testitem 1] | |
867 | set cflags [lindex $testitem 2] | |
868 | set src_files [lindex $testitem 3] | |
869 | set actions [lindex $testitem 4] | |
870 | set binfile tmpdir/[lindex $testitem 5] | |
55255dae | 871 | set lang [lindex $testitem 6] |
d2dee3b2 L |
872 | set objfiles {} |
873 | set is_unresolved 0 | |
874 | set failed 0 | |
2bd7f877 AB |
875 | set check_ld(terminal) 0 |
876 | set check_ld(source) "" | |
d2dee3b2 | 877 | |
44ed8092 SL |
878 | if { ![check_compiler_available] } { |
879 | unsupported $testname | |
880 | continue | |
881 | } | |
882 | ||
e6a6c767 L |
883 | # Add -fno-lto. LTO should be tested explicitly by $cflags. |
884 | if {[check_lto_available]} { | |
885 | set cflags "-fno-lto $cflags" | |
886 | } | |
887 | ||
c3e11cbe AM |
888 | #verbose -log "testname is $testname" |
889 | #verbose -log "ldflags is $ldflags" | |
890 | #verbose -log "cflags is $cflags" | |
891 | #verbose -log "src_files is $src_files" | |
892 | #verbose -log "actions is $actions" | |
893 | #verbose -log "binfile is $binfile" | |
894 | #verbose -log "lang is $lang" | |
2bd7f877 AB |
895 | |
896 | foreach actionlist $actions { | |
897 | set action [lindex $actionlist 0] | |
898 | set progopts [lindex $actionlist 1] | |
899 | ||
900 | # Find actions related to error/warning processing. | |
901 | switch -- $action { | |
902 | error | |
903 | { | |
904 | set check_ld(source) "regexp" | |
905 | set check_ld(regexp) $progopts | |
906 | set check_ld(terminal) 1 | |
907 | } | |
908 | warning | |
909 | { | |
910 | set check_ld(source) "regexp" | |
911 | set check_ld(regexp) $progopts | |
912 | } | |
913 | error_output | |
914 | { | |
915 | set check_ld(source) "file" | |
916 | set check_ld(file) $progopts | |
917 | set check_ld(terminal) 1 | |
918 | } | |
919 | warning_output | |
920 | { | |
921 | set check_ld(source) "file" | |
922 | set check_ld(file) $progopts | |
923 | } | |
924 | } | |
925 | } | |
c3e11cbe | 926 | |
d2dee3b2 L |
927 | # Compile each file in the test. |
928 | foreach src_file $src_files { | |
74d44110 MR |
929 | set fileroot "[file rootname [file tail $src_file]]" |
930 | set objfile "tmpdir/$fileroot.o" | |
d2dee3b2 L |
931 | lappend objfiles $objfile |
932 | ||
58ffc3bd | 933 | if { [ string match "c++" $lang ] } { |
a44d0bd7 | 934 | set cmd "$CXX -c $CXXFLAGS $cflags" |
58ffc3bd | 935 | } else { |
a44d0bd7 | 936 | set cmd "$CC -c $CFLAGS $cflags" |
58ffc3bd | 937 | } |
a44d0bd7 AM |
938 | if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] { |
939 | set failed 1 | |
940 | break | |
941 | } | |
942 | } | |
943 | if { $failed != 0 } { | |
944 | unresolved $testname | |
945 | continue | |
d2dee3b2 L |
946 | } |
947 | ||
948 | # Clear error and warning counts. | |
949 | reset_vars | |
950 | ||
55255dae L |
951 | if { [ string match "c++" $lang ] } { |
952 | set cc_cmd $CXX | |
953 | } else { | |
954 | set cc_cmd $CC | |
955 | } | |
956 | ||
abc868c6 AM |
957 | if { $binfile eq "tmpdir/" } { |
958 | # compile only | |
0aa99dcd | 959 | set binfile $objfile |
abc868c6 | 960 | } elseif { [regexp ".*\\.a$" $binfile] } { |
fa0a16b1 | 961 | if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } { |
d8880531 | 962 | set failed 1 |
d8880531 | 963 | } |
741e0128 | 964 | } else { |
98d72909 L |
965 | if { [string match "" $STATIC_LDFLAGS] \ |
966 | && [regexp -- ".* \[-\]+static .*" " $board_cflags $ldflags $objfiles "] } { | |
967 | untested $testname | |
968 | continue | |
969 | } | |
2bd7f877 AB |
970 | ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles" |
971 | set ld_output "$exec_output" | |
741e0128 | 972 | |
2bd7f877 AB |
973 | if { $check_ld(source) == "regexp" } then { |
974 | # Match output against regexp argument. | |
975 | verbose -log "returned with: <$ld_output>, expected: <$check_ld(regexp)>" | |
976 | if { ![regexp $check_ld(regexp) $ld_output] } then { | |
dd98f8d2 NC |
977 | set failed 1 |
978 | } | |
2bd7f877 AB |
979 | } elseif { $check_ld(source) == "file" } then { |
980 | # Match output against patterns in a file. | |
981 | set_file_contents "tmpdir/ld.messages" "$ld_output" | |
982 | verbose "ld.messages has '[file_contents tmpdir/ld.messages]'" | |
983 | if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"] } then { | |
984 | verbose "output is $ld_output" 2 | |
985 | set failed 1 | |
986 | } | |
987 | } | |
988 | ||
989 | if { $check_ld(source) != "" } then { | |
990 | if { $ld_output == "" } then { | |
991 | verbose -log "Linker was expected to give error or warning" | |
992 | set failed 1 | |
993 | } | |
994 | } else { | |
995 | if { $ld_output != "" } then { | |
996 | verbose -log "Unexpected linker warning or error" | |
997 | set failed 1 | |
998 | } | |
741e0128 | 999 | } |
d8880531 L |
1000 | } |
1001 | ||
1002 | if { $failed == 0 } { | |
d2dee3b2 L |
1003 | foreach actionlist $actions { |
1004 | set action [lindex $actionlist 0] | |
1005 | set progopts [lindex $actionlist 1] | |
1006 | ||
1007 | # There are actions where we run regexp_diff on the | |
1008 | # output, and there are other actions (presumably). | |
1009 | # Handling of the former look the same. | |
1010 | set dump_prog "" | |
1011 | switch -- $action { | |
1012 | objdump | |
1013 | { set dump_prog $objdump } | |
1014 | nm | |
1015 | { set dump_prog $nm } | |
1016 | readelf | |
1017 | { set dump_prog $READELF } | |
2bd7f877 AB |
1018 | error {} |
1019 | warning {} | |
1020 | error_output {} | |
1021 | warning_output {} | |
d2dee3b2 L |
1022 | default |
1023 | { | |
1024 | perror "Unrecognized action $action" | |
1025 | set is_unresolved 1 | |
1026 | break | |
1027 | } | |
1028 | } | |
1029 | ||
1030 | if { $dump_prog != "" } { | |
1031 | set dumpfile [lindex $actionlist 2] | |
1032 | set binary $dump_prog | |
1033 | ||
1034 | # Ensure consistent sorting of symbols | |
1035 | if {[info exists env(LC_ALL)]} { | |
1036 | set old_lc_all $env(LC_ALL) | |
1037 | } | |
1038 | set env(LC_ALL) "C" | |
1039 | set cmd "$binary $progopts $binfile > dump.out" | |
1040 | send_log "$cmd\n" | |
1041 | catch "exec $cmd" comp_output | |
1042 | if {[info exists old_lc_all]} { | |
1043 | set env(LC_ALL) $old_lc_all | |
1044 | } else { | |
1045 | unset env(LC_ALL) | |
1046 | } | |
1047 | set comp_output [prune_warnings $comp_output] | |
1048 | ||
1049 | if ![string match "" $comp_output] then { | |
1050 | send_log "$comp_output\n" | |
1051 | set failed 1 | |
1052 | break | |
1053 | } | |
1054 | ||
1055 | if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then { | |
1056 | verbose "output is [file_contents "dump.out"]" 2 | |
1057 | set failed 1 | |
1058 | break | |
1059 | } | |
1060 | } | |
1061 | } | |
d2dee3b2 L |
1062 | } |
1063 | ||
d44ea5d0 | 1064 | if { $failed } { |
abc868c6 | 1065 | fail $testname |
d44ea5d0 | 1066 | } elseif { $is_unresolved } { |
d2dee3b2 | 1067 | unresolved $testname |
d44ea5d0 AM |
1068 | } else { |
1069 | pass $testname | |
d2dee3b2 L |
1070 | } |
1071 | } | |
1072 | } | |
430a16a5 NC |
1073 | |
1074 | # Returns true if --gc-sections is supported on the target. | |
1075 | ||
1076 | proc check_gc_sections_available { } { | |
1077 | global gc_sections_available_saved | |
1078 | global ld | |
5a68afcf | 1079 | |
430a16a5 NC |
1080 | if {![info exists gc_sections_available_saved]} { |
1081 | # Some targets don't support gc-sections despite whatever's | |
1082 | # advertised by ld's options. | |
be570f06 | 1083 | if { [istarget alpha-*-*] |
8376927b | 1084 | || [istarget bpf-*-*] |
be570f06 | 1085 | || [istarget d30v-*-*] |
59c108f7 | 1086 | || [istarget dlx-*-*] |
59c108f7 | 1087 | || [istarget hppa*64-*-*] |
59c108f7 NC |
1088 | || [istarget ia64-*-*] |
1089 | || [istarget mep-*-*] | |
be570f06 AM |
1090 | || [istarget mn10200-*-*] |
1091 | || [istarget pj*-*-*] | |
1092 | || [istarget pru*-*-*] | |
fce97736 | 1093 | || [istarget s12z-*-*] |
9e4d08bb L |
1094 | || [istarget xgate-*-*] |
1095 | || [istarget z80-*-*] } { | |
430a16a5 NC |
1096 | set gc_sections_available_saved 0 |
1097 | return 0 | |
1098 | } | |
1099 | ||
1100 | # elf2flt uses -q (--emit-relocs), which is incompatible with | |
1101 | # --gc-sections. | |
1102 | if { [board_info target exists ldflags] | |
1103 | && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } { | |
1104 | set gc_sections_available_saved 0 | |
1105 | return 0 | |
1106 | } | |
1107 | ||
430a16a5 | 1108 | # Check if the ld used by gcc supports --gc-sections. |
1d5316ab AM |
1109 | # FIXME: this test is useless since ld --help always says |
1110 | # --gc-sections is available | |
430a16a5 NC |
1111 | set ld_output [remote_exec host $ld "--help"] |
1112 | if { [ string first "--gc-sections" $ld_output ] >= 0 } { | |
1113 | set gc_sections_available_saved 1 | |
1114 | } else { | |
1115 | set gc_sections_available_saved 0 | |
1116 | } | |
1117 | } | |
1118 | return $gc_sections_available_saved | |
1119 | } | |
33aa234e | 1120 | |
1336939d AM |
1121 | # Return true if target uses genelf.em. |
1122 | proc uses_genelf { } { | |
b62b1f71 AM |
1123 | if { [istarget "d30v-*-*"] |
1124 | || [istarget "dlx-*-*"] | |
1125 | || [istarget "fr30-*-*"] | |
1126 | || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"]) | |
1127 | || [istarget "ft32-*-*"] | |
b62b1f71 AM |
1128 | || [istarget "iq2000-*-*"] |
1129 | || [istarget "mn10200-*-*"] | |
b62b1f71 AM |
1130 | || [istarget "msp430-*-*"] |
1131 | || [istarget "mt-*-*"] | |
be570f06 | 1132 | || [istarget "pj*-*-*"] |
6ff185b8 | 1133 | || [istarget "s12z-*-*"] |
be570f06 | 1134 | || [istarget "xgate-*-*"] } { |
1336939d | 1135 | return 1 |
b62b1f71 | 1136 | } |
1336939d | 1137 | return 0 |
b62b1f71 AM |
1138 | } |
1139 | ||
bdd32e03 AM |
1140 | proc is_underscore_target { } { |
1141 | global is_underscore_target_saved | |
1142 | global target_triplet | |
1143 | global srcdir | |
1144 | ||
1145 | if { ![info exists is_underscore_target_saved] } { | |
1146 | set cmd "targ=$target_triplet . $srcdir/../../bfd/config.bfd &&" | |
1147 | append cmd { echo "$targ_underscore"} | |
1148 | verbose -log "$cmd" | |
1149 | set status [catch {exec sh -c $cmd} result] | |
1150 | if { $status == 0 && [string match "yes" $result] } { | |
1151 | set is_underscore_target_saved 1 | |
1152 | } else { | |
1153 | set is_underscore_target_saved 0 | |
1154 | } | |
1155 | } | |
1156 | return $is_underscore_target_saved | |
1157 | } | |
1158 | ||
5d3236ee DK |
1159 | # Returns true if the target ld supports the plugin API. |
1160 | proc check_plugin_api_available { } { | |
1161 | global plugin_api_available_saved | |
1162 | global ld | |
1163 | if {![info exists plugin_api_available_saved]} { | |
1164 | # Check if the ld used by gcc supports --plugin. | |
1165 | set ld_output [remote_exec host $ld "--help"] | |
070558eb AM |
1166 | if { [regexp -- "-plugin PLUGIN \[^\n\r\]*" $ld_output line] |
1167 | && ![regexp "ignored" $line] } { | |
5d3236ee DK |
1168 | set plugin_api_available_saved 1 |
1169 | } else { | |
1170 | set plugin_api_available_saved 0 | |
1171 | } | |
1172 | } | |
1173 | return $plugin_api_available_saved | |
1174 | } | |
1175 | ||
3f730821 HPN |
1176 | # Sets ld_sysroot to the current sysroot (empty if not supported) and |
1177 | # returns true if the target ld supports sysroot. | |
bdd65db9 | 1178 | proc check_sysroot_available { } { |
3f730821 | 1179 | global ld_sysroot_available_saved ld ld_sysroot |
bdd65db9 | 1180 | if {![info exists ld_sysroot_available_saved]} { |
3f730821 HPN |
1181 | # Check if ld supports --sysroot *other* than empty. |
1182 | set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]] | |
1183 | if { $ld_sysroot == "" } { | |
bdd65db9 HPN |
1184 | set ld_sysroot_available_saved 0 |
1185 | } else { | |
1186 | set ld_sysroot_available_saved 1 | |
1187 | } | |
1188 | } | |
1189 | return $ld_sysroot_available_saved | |
1190 | } | |
1191 | ||
44ed8092 SL |
1192 | # Return true if we can build a program with the compiler. |
1193 | # On some targets, CC might be defined, but libraries and startup | |
1194 | # code might be missing or require special options that the ld test | |
1195 | # harness doesn't know about. | |
1196 | ||
1197 | proc check_compiler_available { } { | |
1198 | global compiler_available_saved | |
1199 | global CC | |
1200 | ||
1201 | if {![info exists compiler_available_saved]} { | |
1202 | if { [which $CC] == 0 } { | |
1203 | set compiler_available_saved 0 | |
1204 | return 0 | |
1205 | } | |
1206 | ||
1207 | set flags "" | |
1208 | if [board_info [target_info name] exists cflags] { | |
1209 | append flags " [board_info [target_info name] cflags]" | |
1210 | } | |
1211 | if [board_info [target_info name] exists ldflags] { | |
1212 | append flags " [board_info [target_info name] ldflags]" | |
1213 | } | |
1214 | ||
1215 | set basename "tmpdir/compiler[pid]" | |
1216 | set src ${basename}.c | |
1217 | set output ${basename}.out | |
1218 | set f [open $src "w"] | |
1219 | puts $f "int main (void)" | |
1220 | puts $f "{" | |
1221 | puts $f " return 0; " | |
1222 | puts $f "}" | |
1223 | close $f | |
1224 | if [is_remote host] { | |
1225 | set src [remote_download host $src] | |
1226 | } | |
1227 | set compiler_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"] | |
1228 | remote_file host delete $src | |
1229 | remote_file host delete $output | |
1230 | file delete $src | |
1231 | } | |
1232 | return $compiler_available_saved | |
1233 | } | |
1234 | ||
5ff55910 L |
1235 | # Returns 1 if plugin is enabled in gcc. Returns 0 otherwise. |
1236 | proc check_gcc_plugin_enabled { } { | |
1237 | global CC | |
1238 | ||
1239 | if {![info exists CC]} { | |
1240 | set CC [find_gcc] | |
1241 | } | |
7f6bf02d | 1242 | if { $CC == ""} { |
8be1e369 | 1243 | return 0 |
5ff55910 | 1244 | } |
e6a6c767 L |
1245 | # Filter out -Wl, options. |
1246 | regsub -all -- "-Wl,\[^ ^\t\]+" $CC "" cc_cmd | |
1247 | set state [remote_exec host $cc_cmd -v] | |
8be1e369 AM |
1248 | if { [lindex $state 0] != 0 } { |
1249 | return 0; | |
1250 | } | |
1251 | for { set i 1 } { $i < [llength $state] } { incr i } { | |
5ff55910 L |
1252 | set v [lindex $state $i] |
1253 | if { [ string match "*--disable-plugin*" $v ] } { | |
1254 | verbose "plugin is disabled by $v" | |
1255 | return 0; | |
1256 | } | |
1257 | } | |
1258 | ||
1259 | return 1; | |
1260 | } | |
1261 | ||
3bd58fbe L |
1262 | # Returns true if the target compiler supports LTO |
1263 | proc check_lto_available { } { | |
1264 | global lto_available_saved | |
1265 | global CC | |
7174e19f | 1266 | |
3bd58fbe | 1267 | if {![info exists lto_available_saved]} { |
5ff55910 | 1268 | if { ![check_gcc_plugin_enabled] } { |
19aef622 NC |
1269 | set lto_available_saved 0 |
1270 | return 0 | |
1271 | } | |
00f4a602 L |
1272 | # This test will hide LTO bugs in ld. Since GCC 4.9 adds |
1273 | # -ffat-lto-objects, we always run LTO tests on Linux with | |
1274 | # GCC 4.9 or newer. | |
1275 | if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } { | |
1276 | set lto_available_saved 1 | |
1277 | return 1 | |
1278 | } | |
3bd58fbe | 1279 | # Check if gcc supports -flto -fuse-linker-plugin |
f1d7f4a6 AM |
1280 | set flags "" |
1281 | if [board_info [target_info name] exists cflags] { | |
1282 | append flags " [board_info [target_info name] cflags]" | |
1283 | } | |
1284 | if [board_info [target_info name] exists ldflags] { | |
1285 | append flags " [board_info [target_info name] ldflags]" | |
3bd58fbe | 1286 | } |
f1d7f4a6 AM |
1287 | |
1288 | set basename "tmpdir/lto[pid]" | |
1289 | set src ${basename}.c | |
1290 | set output ${basename}.out | |
3bd58fbe | 1291 | set f [open $src "w"] |
7174e19f | 1292 | puts $f "int main() { return 0; }" |
3bd58fbe | 1293 | close $f |
010f98a5 L |
1294 | if [is_remote host] { |
1295 | set src [remote_download host $src] | |
1296 | } | |
c3e11cbe | 1297 | set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"] |
f1d7f4a6 AM |
1298 | remote_file host delete $src |
1299 | remote_file host delete $output | |
3bd58fbe | 1300 | file delete $src |
3bd58fbe L |
1301 | } |
1302 | return $lto_available_saved | |
1303 | } | |
1304 | ||
c3e11cbe AM |
1305 | # Returns true if the target compiler supports LTO -ffat-lto-objects |
1306 | proc check_lto_fat_available { } { | |
1307 | global lto_fat_available_saved | |
1308 | global CC | |
1309 | ||
1310 | if {![info exists lto_fat_available_saved]} { | |
5ff55910 | 1311 | if { ![check_gcc_plugin_enabled] } { |
c3e11cbe AM |
1312 | set lto_fat_available_saved 0 |
1313 | return 0 | |
1314 | } | |
00f4a602 L |
1315 | # This test will hide LTO bugs in ld. Since GCC 4.9 adds |
1316 | # -ffat-lto-objects, we always run LTO tests on Linux with | |
1317 | # GCC 4.9 or newer. | |
1318 | if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } { | |
1319 | set lto_fat_available_saved 1 | |
1320 | return 1 | |
1321 | } | |
c3e11cbe AM |
1322 | # Check if gcc supports -flto -fuse-linker-plugin |
1323 | set flags "" | |
1324 | if [board_info [target_info name] exists cflags] { | |
1325 | append flags " [board_info [target_info name] cflags]" | |
1326 | } | |
1327 | if [board_info [target_info name] exists ldflags] { | |
1328 | append flags " [board_info [target_info name] ldflags]" | |
1329 | } | |
1330 | ||
1331 | set basename "tmpdir/lto[pid]" | |
1332 | set src ${basename}.c | |
1333 | set output ${basename}.out | |
1334 | set f [open $src "w"] | |
1335 | puts $f "int main() { return 0; }" | |
1336 | close $f | |
010f98a5 L |
1337 | if [is_remote host] { |
1338 | set src [remote_download host $src] | |
1339 | } | |
c3e11cbe AM |
1340 | set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"] |
1341 | remote_file host delete $src | |
1342 | remote_file host delete $output | |
1343 | file delete $src | |
1344 | } | |
1345 | return $lto_fat_available_saved | |
1346 | } | |
1347 | ||
92c09111 L |
1348 | # Returns true if the target compiler supports LTO and -shared |
1349 | proc check_lto_shared_available { } { | |
1350 | global lto_shared_available_saved | |
1351 | global CC | |
1352 | ||
92c09111 | 1353 | if {![info exists lto_shared_available_saved]} { |
5ff55910 | 1354 | if { ![check_gcc_plugin_enabled] } { |
3bb9e7b4 AM |
1355 | set lto_shared_available_saved 0 |
1356 | return 0 | |
1357 | } | |
00f4a602 L |
1358 | # This test will hide LTO bugs in ld. Since GCC 4.9 adds |
1359 | # -ffat-lto-objects, we always run LTO tests on Linux with | |
1360 | # GCC 4.9 or newer. | |
1361 | if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } { | |
1362 | set lto_shared_available_saved 1 | |
1363 | return 1 | |
1364 | } | |
92c09111 | 1365 | # Check if gcc supports -flto -fuse-linker-plugin -shared |
f1d7f4a6 AM |
1366 | set flags "" |
1367 | if [board_info [target_info name] exists cflags] { | |
1368 | append flags " [board_info [target_info name] cflags]" | |
1369 | } | |
1370 | if [board_info [target_info name] exists ldflags] { | |
1371 | append flags " [board_info [target_info name] ldflags]" | |
92c09111 | 1372 | } |
f1d7f4a6 AM |
1373 | |
1374 | set basename "tmpdir/lto_shared[pid]" | |
1375 | set src ${basename}.c | |
1376 | set output ${basename}.so | |
92c09111 L |
1377 | set f [open $src "w"] |
1378 | puts $f "" | |
1379 | close $f | |
010f98a5 L |
1380 | if [is_remote host] { |
1381 | set src [remote_download host $src] | |
1382 | } | |
f1d7f4a6 AM |
1383 | set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"] |
1384 | remote_file host delete $src | |
1385 | remote_file host delete $output | |
92c09111 | 1386 | file delete $src |
92c09111 L |
1387 | } |
1388 | return $lto_shared_available_saved | |
1389 | } | |
1390 | ||
33aa234e JK |
1391 | # Check if the assembler supports CFI statements. |
1392 | ||
1393 | proc check_as_cfi { } { | |
1394 | global check_as_cfi_result | |
1395 | global as | |
1396 | if [info exists check_as_cfi_result] { | |
1397 | return $check_as_cfi_result | |
1398 | } | |
1399 | set as_file "tmpdir/check_as_cfi.s" | |
1400 | set as_fh [open $as_file w 0666] | |
1401 | puts $as_fh "# Generated file. DO NOT EDIT" | |
1402 | puts $as_fh "\t.cfi_startproc" | |
1403 | puts $as_fh "\t.cfi_endproc" | |
1404 | close $as_fh | |
1405 | remote_download host $as_file | |
1406 | verbose -log "Checking CFI support:" | |
33aa234e | 1407 | set success [ld_assemble $as $as_file "/dev/null"] |
33aa234e JK |
1408 | #remote_file host delete $as_file |
1409 | set check_as_cfi_result $success | |
1410 | return $success | |
1411 | } | |
1412 | ||
c22ee0ad L |
1413 | # Returns true if IFUNC works. |
1414 | ||
1415 | proc check_ifunc_available { } { | |
1416 | global ifunc_available_saved | |
1417 | global CC | |
1418 | ||
1419 | if {![info exists ifunc_available_saved]} { | |
44ed8092 | 1420 | if { ![check_compiler_available] } { |
c22ee0ad L |
1421 | set ifunc_available_saved 0 |
1422 | return 0 | |
1423 | } | |
1424 | # Check if gcc supports -flto -fuse-linker-plugin | |
1425 | set flags "" | |
1426 | if [board_info [target_info name] exists cflags] { | |
1427 | append flags " [board_info [target_info name] cflags]" | |
1428 | } | |
1429 | if [board_info [target_info name] exists ldflags] { | |
1430 | append flags " [board_info [target_info name] ldflags]" | |
1431 | } | |
1432 | ||
1433 | set basename "tmpdir/ifunc[pid]" | |
1434 | set src ${basename}.c | |
1435 | set output ${basename}.out | |
1436 | set f [open $src "w"] | |
1437 | puts $f "extern int library_func2 (void);" | |
1438 | puts $f "int main (void)" | |
1439 | puts $f "{" | |
1440 | puts $f " if (library_func2 () != 2) __builtin_abort ();" | |
1441 | puts $f " return 0; " | |
1442 | puts $f "}" | |
1443 | puts $f "static int library_func1 (void) {return 2; }" | |
1444 | puts $f "void *foo (void) __asm__ (\"library_func2\");" | |
1445 | puts $f "void *foo (void) { return library_func1; }" | |
1446 | puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");" | |
1447 | close $f | |
010f98a5 L |
1448 | if [is_remote host] { |
1449 | set src [remote_download host $src] | |
1450 | } | |
c22ee0ad | 1451 | set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"] |
77236b83 | 1452 | if { [isnative] && $ifunc_available_saved == 1 } { |
c22ee0ad L |
1453 | set ifunc_available_saved [run_host_cmd_yesno "$output" ""] |
1454 | } | |
1455 | remote_file host delete $src | |
1456 | remote_file host delete $output | |
1457 | file delete $src | |
1458 | } | |
1459 | return $ifunc_available_saved | |
1460 | } | |
1461 | ||
97dc35c8 L |
1462 | # Returns true if ifunc attribute works. |
1463 | ||
1464 | proc check_ifunc_attribute_available { } { | |
1465 | global ifunc_attribute_available_saved | |
1466 | global CC | |
1467 | ||
1468 | if {![info exists ifunc_attribute_available_saved]} { | |
44ed8092 | 1469 | if { ![check_compiler_available] } { |
97dc35c8 L |
1470 | set ifunc_attribute_available_saved 0 |
1471 | return 0 | |
1472 | } | |
1473 | # Check if gcc supports -flto -fuse-linker-plugin | |
1474 | set flags "" | |
1475 | if [board_info [target_info name] exists cflags] { | |
1476 | append flags " [board_info [target_info name] cflags]" | |
1477 | } | |
1478 | if [board_info [target_info name] exists ldflags] { | |
1479 | append flags " [board_info [target_info name] ldflags]" | |
1480 | } | |
1481 | ||
1482 | set basename "tmpdir/ifunc[pid]" | |
1483 | set src ${basename}.c | |
1484 | set output ${basename}.out | |
1485 | set f [open $src "w"] | |
1486 | puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));" | |
1487 | puts $f "int main (void)" | |
1488 | puts $f "{" | |
1489 | puts $f " if (library_func2 () != 2) __builtin_abort ();" | |
1490 | puts $f " return 0; " | |
1491 | puts $f "}" | |
1492 | puts $f "static int library_func1 (void) {return 2; }" | |
1493 | puts $f "void *foo (void) { return library_func1; }" | |
1494 | close $f | |
010f98a5 L |
1495 | if [is_remote host] { |
1496 | set src [remote_download host $src] | |
1497 | } | |
97dc35c8 | 1498 | set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"] |
77236b83 | 1499 | if { [isnative] && $ifunc_attribute_available_saved == 1 } { |
97dc35c8 L |
1500 | set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""] |
1501 | } | |
1502 | remote_file host delete $src | |
1503 | remote_file host delete $output | |
1504 | file delete $src | |
1505 | } | |
1506 | return $ifunc_attribute_available_saved | |
1507 | } | |
1508 | ||
fd121c5c JW |
1509 | # Return true if libdl is supported. |
1510 | ||
1511 | proc check_libdl_available { } { | |
1512 | global libdl_available_saved | |
1513 | global CC | |
1514 | ||
1515 | if {![info exists libdl_available_saved]} { | |
44ed8092 | 1516 | if { ![check_compiler_available] } { |
fd121c5c JW |
1517 | set libdl_available_saved 0 |
1518 | return 0 | |
1519 | } | |
1520 | ||
1521 | set basename "tmpdir/dl_avail_test[pid]" | |
1522 | set src ${basename}.c | |
1523 | set output ${basename}.out | |
1524 | set f [open $src "w"] | |
1525 | # Sample test file. | |
1526 | puts $f "#include <dlfcn.h>" | |
1527 | puts $f "int main (void)" | |
1528 | puts $f "{" | |
1529 | puts $f " dlopen (\"dummy.so\", RTLD_NOW);" | |
1530 | puts $f " return 0; " | |
1531 | puts $f "}" | |
1532 | close $f | |
1533 | if [is_remote host] { | |
1534 | set src [remote_download host $src] | |
1535 | } | |
1536 | set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"] | |
1537 | remote_file host delete $src | |
1538 | remote_file host delete $output | |
1539 | file delete $src | |
1540 | } | |
1541 | return $libdl_available_saved | |
1542 | } | |
0aae7e72 L |
1543 | |
1544 | # Returns true if GNU2 TLS works. | |
1545 | ||
1546 | proc check_gnu2_tls_available { } { | |
1547 | global gnu2_tls_available_saved | |
1548 | global CC | |
1549 | global GNU2_CFLAGS | |
1550 | ||
1551 | if {![info exists gnu2_tls_available_saved]} { | |
44ed8092 | 1552 | if { ![check_compiler_available] || "$GNU2_CFLAGS" == "" } { |
0aae7e72 L |
1553 | set gnu2_tls_available_saved 0 |
1554 | return 0 | |
1555 | } | |
1556 | # Check if GNU2 TLS works. | |
1557 | set flags "$GNU2_CFLAGS" | |
1558 | if [board_info [target_info name] exists cflags] { | |
1559 | append flags " [board_info [target_info name] cflags]" | |
1560 | } | |
1561 | if [board_info [target_info name] exists ldflags] { | |
1562 | append flags " [board_info [target_info name] ldflags]" | |
1563 | } | |
1564 | ||
1565 | set basename "tmpdir/gnu2_tls[pid]" | |
1566 | set src1 ${basename}1.c | |
1567 | set output1 ${basename}.so | |
1568 | set f [open $src1 "w"] | |
1569 | puts $f "extern __thread int zzz;" | |
1570 | puts $f "int foo (void)" | |
1571 | puts $f "{" | |
1572 | puts $f " return zzz;" | |
1573 | puts $f "}" | |
1574 | close $f | |
1575 | if [is_remote host] { | |
1576 | set src1 [remote_download host $src1] | |
1577 | } | |
1578 | set src2 ${basename}2.c | |
1579 | set output2 ${basename}.exe | |
1580 | set f [open $src2 "w"] | |
1581 | puts $f "__thread int zzz = 20;" | |
1582 | puts $f "extern int foo (void);" | |
1583 | puts $f "int main (void)" | |
1584 | puts $f "{" | |
1585 | puts $f " if (foo () != 20) __builtin_abort ();" | |
1586 | puts $f " return 0; " | |
1587 | puts $f "}" | |
1588 | close $f | |
1589 | if [is_remote host] { | |
1590 | set src2 [remote_download host $src2] | |
1591 | } | |
1592 | set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "-fPIC -shared $flags $src1 -o $output1"] | |
1593 | if { $gnu2_tls_available_saved == 1 } { | |
1594 | set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "$flags $src2 $output1 -o $output2"] | |
1595 | if { $gnu2_tls_available_saved == 1 } { | |
1596 | set gnu2_tls_available_saved [run_host_cmd_yesno "$output2" ""] | |
1597 | } | |
1598 | } | |
1599 | remote_file host delete $src1 | |
1600 | remote_file host delete $output1 | |
1601 | remote_file host delete $src2 | |
1602 | remote_file host delete $output2 | |
1603 | file delete $src1 $src2 | |
1604 | } | |
1605 | return $gnu2_tls_available_saved | |
1606 | } | |
7cdfc346 NA |
1607 | |
1608 | # Compile a C source file, with the specified additional_flags. | |
1609 | proc compile_one_cc { src output additional_flags } { | |
1610 | global CC | |
1611 | global CFLAGS | |
1612 | ||
1613 | set flags "" | |
1614 | if [board_info [target_info name] exists cflags] { | |
1615 | append flags " [board_info [target_info name] cflags]" | |
1616 | } | |
1617 | if [board_info [target_info name] exists ldflags] { | |
1618 | append flags " [board_info [target_info name] ldflags]" | |
1619 | } | |
1620 | ||
1621 | if [is_remote host] { | |
1622 | set src [remote_download host $src] | |
1623 | } | |
1624 | return [run_host_cmd_yesno "$CC" "$flags $CFLAGS $additional_flags $src -o $output"] | |
1625 | } | |
1626 | ||
1627 | # Returns true if the target compiler supports -gt | |
1628 | proc check_ctf_available { } { | |
1629 | global ctf_available_saved | |
1630 | ||
1631 | if {![info exists ctf_available_saved]} { | |
344e6653 AM |
1632 | if { ![check_compiler_available] } { |
1633 | set ctf_available_saved 0 | |
1634 | } else { | |
1635 | set basename "tmpdir/ctf_available[pid]" | |
1636 | set src ${basename}.c | |
1637 | set output ${basename}.o | |
1638 | set f [open $src "w"] | |
1639 | puts $f "int main() { return 0; }" | |
1640 | close $f | |
1641 | set ctf_available_saved [compile_one_cc $src $output "-gt -c"] | |
1642 | remote_file host delete $src | |
1643 | remote_file host delete $output | |
1644 | file delete $src | |
1645 | } | |
7cdfc346 NA |
1646 | } |
1647 | return $ctf_available_saved | |
1648 | } | |
1649 | ||
1650 | proc skip_ctf_tests { } { | |
1651 | global enable_libctf | |
1652 | ||
1653 | if {$enable_libctf eq "no"} { | |
1654 | return 1 | |
1655 | } | |
1656 | ||
1657 | if [check_ctf_available] { | |
1658 | return 0 | |
1659 | } | |
1660 | ||
1661 | return 1 | |
1662 | } |