2ecff2ef20076727fef078b3a41858f7572b530b
[external/binutils.git] / gdb / testsuite / lib / future.exp
1 # Copyright 2004-2016 Free Software Foundation, Inc.
2 #
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 load_lib libgloss.exp
17
18 # FIXME:brobecker/2004-03-31:
19 # The following functions should eventually be part of dejagnu. Even after
20 # these functions becomes available in dejagnu, we will keep for a while
21 # a copy here in order to avoid increasing the dejagnu version
22 # requirement.
23
24 proc gdb_find_gnatmake {} {
25     global tool_root_dir
26
27     set root "$tool_root_dir/gcc"
28     set GM ""
29
30     if ![is_remote host] {
31         set file [lookfor_file $root gnatmake]
32         if { $file != "" } {
33             set GM "$file -I$root/ada/rts --GCC=$root/xgcc --GNATBIND=$root/gnatbind --GNATLINK=$root/gnatlink -cargs -B$root -largs --GCC=$root/xgcc -margs";
34         }   
35     }
36
37     if {$GM == ""} {
38         set GM [transform gnatmake]
39     }
40
41     return $GM
42 }   
43
44 proc gdb_find_gdc {} {
45     global tool_root_dir
46     print "Tool Root: $tool_root_dir"
47
48     if {![is_remote host]} {
49         set file [lookfor_file $tool_root_dir gdc]
50         if { $file == "" } {
51             set file [lookfor_file $tool_root_dir gcc/gdc]
52         }
53         if { $file != "" } {
54             set CC "$file -B[file dirname $file]/"
55         } else {
56             set CC [transform gdc]
57         }
58     } else {
59         set CC [transform gdc]
60     }
61     print "CC: $CC"
62     return $CC
63 }
64
65 proc gdb_find_gfortran {} {
66     global tool_root_dir
67
68     if {![is_remote host]} {
69         set file [lookfor_file $tool_root_dir gfortran]
70         if { $file == "" } {
71             set file [lookfor_file $tool_root_dir gcc/gfortran]
72         }
73         if { $file != "" } {
74             set CC "$file -B[file dirname $file]/"
75         } else {
76             set CC [transform gfortran]
77         }
78     } else {
79         set CC [transform gfortran]
80     }
81     return $CC
82 }
83
84 proc gdb_find_go {} {
85     global tool_root_dir
86
87     set GO ""
88
89     if {![is_remote host]} {
90         set file [lookfor_file $tool_root_dir gccgo]
91         if { $file != "" } {
92             set root [file dirname $file]
93             set GO "$file -B$root/gcc/"
94         }
95     }
96
97     if { $GO == "" } {
98         set GO [transform gccgo]
99     }
100
101     return $GO
102 }
103
104 proc gdb_find_go_linker {} {
105     return [find_go]
106 }
107
108 proc gdb_find_rustc {} {
109     global tool_root_dir
110     if {![is_remote host]} {
111         set rustc [lookfor_file $tool_root_dir rustc]
112         if {$rustc == ""} {
113             set rustc rustc
114         }
115     } else {
116         set rustc ""
117     }
118     if {$rustc != ""} {
119         append rustc " --color never"
120     }
121     return $rustc
122 }
123
124 proc gdb_find_ldd {} {
125     global LDD_FOR_TARGET
126     if [info exists LDD_FOR_TARGET] {
127         set ldd $LDD_FOR_TARGET
128     } else {
129         set ldd "ldd"
130     }
131     return $ldd
132 }
133
134 proc gdb_find_objcopy {} {
135     global OBJCOPY_FOR_TARGET
136     if [info exists OBJCOPY_FOR_TARGET] {
137         set objcopy $OBJCOPY_FOR_TARGET
138     } else {
139         set objcopy [transform objcopy]
140     }
141     return $objcopy
142 }
143
144 # find target objdump
145 proc gdb_find_objdump {} {
146     global OBJDUMP_FOR_TARGET
147     if [info exists OBJDUMP_FOR_TARGET] {
148         set objdump $OBJDUMP_FOR_TARGET
149     } else {
150         set objdump [transform objdump]
151     }
152     return $objdump
153 }
154
155 proc gdb_find_readelf {} {
156     global READELF_FOR_TARGET
157     if [info exists READELF_FOR_TARGET] {
158         set readelf $READELF_FOR_TARGET
159     } else {
160         set readelf [transform readelf]
161     }
162     return $readelf
163 }
164
165 proc gdb_default_target_compile {source destfile type options} {
166     global target_triplet
167     global tool_root_dir
168     global CFLAGS_FOR_TARGET
169     global compiler_flags
170
171     if { $destfile == "" && $type != "preprocess" && $type != "none" } {
172         error "Must supply an output filename for the compile to default_target_compile"
173     }
174
175     set early_flags ""
176     set add_flags ""
177     set libs ""
178     set compiler_type "c"
179     set compiler ""
180     set linker ""
181     # linker_opts_order is one of "sources-then-flags", "flags-then-sources".
182     # The order matters for things like -Wl,--as-needed.  The default is to
183     # preserve existing behavior.
184     set linker_opts_order "sources-then-flags"
185     set ldflags ""
186     set dest [target_info name]
187
188     if {[info exists CFLAGS_FOR_TARGET]} {
189         append add_flags " $CFLAGS_FOR_TARGET"
190     }
191
192     if {[info exists target_info(host,name)]} {
193         set host [host_info name]
194     } else {
195         set host "unix"
196     }
197
198     foreach i $options {
199
200         if { $i == "ada" } {
201             set compiler_type "ada"
202             if {[board_info $dest exists adaflags]} {
203                 append add_flags " [target_info adaflags]"
204             }
205             if {[board_info $dest exists gnatmake]} {
206                 set compiler [target_info gnatmake]
207             } else {
208                 set compiler [find_gnatmake]
209             }
210         }
211
212         if { $i == "c++" } {
213             set compiler_type "c++"
214             if {[board_info $dest exists cxxflags]} {
215                 append add_flags " [target_info cxxflags]"
216             }
217             append add_flags " [g++_include_flags]"
218             if {[board_info $dest exists c++compiler]} {
219                 set compiler [target_info c++compiler]
220             } else {
221                 set compiler [find_g++]
222             }
223         }
224
225         if { $i == "d" } {
226             set compiler_type "d"
227             if {[board_info $dest exists dflags]} {
228                 append add_flags " [target_info dflags]"
229             }
230             if {[board_info $dest exists dcompiler]} {
231                 set compiler [target_info dcompiler]
232             } else {
233                 set compiler [find_gdc]
234             }
235         }
236
237         if { $i == "f77" } {
238             set compiler_type "f77"
239             if {[board_info $dest exists f77flags]} {
240                 append add_flags " [target_info f77flags]"
241             }
242             if {[board_info $dest exists f77compiler]} {
243                 set compiler [target_info f77compiler]
244             } else {
245                 set compiler [find_g77]
246             }
247         }
248
249         if { $i == "f90" } {
250             set compiler_type "f90"
251             if {[board_info $dest exists f90flags]} {
252                 append add_flags " [target_info f90flags]"
253             }
254             if {[board_info $dest exists f90compiler]} {
255                 set compiler [target_info f90compiler]
256             } else {
257                 set compiler [find_gfortran]
258             }
259         }
260
261         if { $i == "go" } {
262             set compiler_type "go"
263             if {[board_info $dest exists goflags]} {
264                 append add_flags " [target_info goflags]"
265             }
266             if {[board_info $dest exists gocompiler]} {
267                 set compiler [target_info gocompiler]
268             } else {
269                 set compiler [find_go]
270             }
271             if {[board_info $dest exists golinker]} {
272                 set linker [target_info golinker]
273             } else {
274                 set linker [find_go_linker]
275             }
276             if {[board_info $dest exists golinker_opts_order]} {
277                 set linker_opts_order [target_info golinker_opts_order]
278             }
279         }
280
281         if { $i == "rust" } {
282             set compiler_type "rust"
283             if {[board_info $dest exists rustflags]} {
284                 append add_flags " [target_info rustflags]"
285             }
286             if {[board_info $dest exists rustflags]} {
287                 set compiler [target_info rustflags]
288             } else {
289                 set compiler [find_rustc]
290             }
291         }
292
293         if {[regexp "^dest=" $i]} {
294             regsub "^dest=" $i "" tmp
295             if {[board_info $tmp exists name]} {
296                 set dest [board_info $tmp name]
297             } else {
298                 set dest $tmp
299             }
300         }
301         if {[regexp "^compiler=" $i]} {
302             regsub "^compiler=" $i "" tmp
303             set compiler $tmp
304         }
305         if {[regexp "^early_flags=" $i]} {
306             regsub "^early_flags=" $i "" tmp
307             append early_flags " $tmp"
308         }
309         if {[regexp "^additional_flags=" $i]} {
310             regsub "^additional_flags=" $i "" tmp
311             append add_flags " $tmp"
312         }
313         if {[regexp "^ldflags=" $i]} {
314             regsub "^ldflags=" $i "" tmp
315             append ldflags " $tmp"
316         }
317         if {[regexp "^libs=" $i]} {
318             regsub "^libs=" $i "" tmp
319             append libs " $tmp"
320         }
321         if {[regexp "^incdir=" $i]} {
322             regsub "^incdir=" $i "-I" tmp
323             append add_flags " $tmp"
324         }
325         if {[regexp "^libdir=" $i]} {
326             regsub "^libdir=" $i "-L" tmp
327             append add_flags " $tmp"
328         }
329         if {[regexp "^ldscript=" $i]} {
330             regsub "^ldscript=" $i "" ldscript
331         }
332         if {[regexp "^redirect=" $i]} {
333             regsub "^redirect=" $i "" redirect
334         }
335         if {[regexp "^optimize=" $i]} {
336             regsub "^optimize=" $i "" optimize
337         }
338         if {[regexp "^timeout=" $i]} {
339             regsub "^timeout=" $i "" timeout
340         }
341     }
342
343     if {[board_info $host exists cflags_for_target]} {
344         append add_flags " [board_info $host cflags_for_target]"
345     }
346
347     global CC_FOR_TARGET
348     global CXX_FOR_TARGET
349     global D_FOR_TARGET
350     global F77_FOR_TARGET
351     global F90_FOR_TARGET
352     global GNATMAKE_FOR_TARGET
353     global GO_FOR_TARGET
354     global GO_LD_FOR_TARGET
355     global RUSTC_FOR_TARGET
356
357     if {[info exists GNATMAKE_FOR_TARGET]} {
358         if { $compiler_type == "ada" } {
359             set compiler $GNATMAKE_FOR_TARGET
360         }
361     }
362
363     if {[info exists CC_FOR_TARGET]} {
364         if { $compiler == "" } {
365             set compiler $CC_FOR_TARGET
366         }
367     }
368
369     if {[info exists CXX_FOR_TARGET]} {
370         if { $compiler_type == "c++" } {
371             set compiler $CXX_FOR_TARGET
372         }
373     }
374
375     if {[info exists D_FOR_TARGET]} {
376         if { $compiler_type == "d" } {
377             set compiler $D_FOR_TARGET
378         }
379     }
380
381     if {[info exists F77_FOR_TARGET]} {
382         if { $compiler_type == "f77" } {
383             set compiler $F77_FOR_TARGET
384         }
385     }
386
387     if {[info exists F90_FOR_TARGET]} {
388         if { $compiler_type == "f90" } {
389             set compiler $F90_FOR_TARGET
390         }
391     }
392
393     if { $compiler_type == "go" } {
394         if {[info exists GO_FOR_TARGET]} {
395             set compiler $GO_FOR_TARGET
396         }
397         if {[info exists GO_LD_FOR_TARGET]} {
398             set linker $GO_LD_FOR_TARGET
399         }
400     }
401
402     if {[info exists RUSTC_FOR_TARGET]} {
403         if {$compiler_type == "rust"} {
404             set compiler $RUSTC_FOR_TARGET
405         }
406     }
407
408     if { $type == "executable" && $linker != "" } {
409         set compiler $linker
410     }
411
412     if { $compiler == "" } {
413         set compiler [board_info $dest compiler]
414         if { $compiler == "" } {
415             return "default_target_compile: No compiler to compile with"
416         }
417     }
418
419     if {![is_remote host]} {
420         if { [which $compiler] == 0 } {
421             return "default_target_compile: Can't find $compiler."
422         }
423     }
424
425     if {$type == "object"} {
426         if {$compiler_type == "rust"} {
427             append add_flags "--emit obj"
428         } else {
429             append add_flags " -c"
430         }
431     }
432
433     if { $type == "preprocess" } {
434         append add_flags " -E"
435     }
436
437     if { $type == "assembly" } {
438         append add_flags " -S"
439     }
440
441     if {[board_info $dest exists cflags]} {
442         append add_flags " [board_info $dest cflags]"
443     }
444
445     if { $type == "executable" } {
446         if {[board_info $dest exists ldflags]} {
447             append add_flags " [board_info $dest ldflags]"
448         }
449         if { $compiler_type == "c++" } {
450             append add_flags " [g++_link_flags]"
451         }
452         if {[isnative]} {
453             # This is a lose.
454             catch "glob -nocomplain $tool_root_dir/libstdc++/libstdc++.so* $tool_root_dir/libstdc++/libstdc++.sl" tmp
455             if { ${tmp} != "" } {
456                 if {[regexp ".*solaris2.*" $target_triplet]} {
457                     # Solaris 2
458                     append add_flags " -R$tool_root_dir/libstdc++"
459                 } elseif {[regexp ".*(osf|irix5|linux).*" $target_triplet]} {
460                     # OSF/1 or IRIX 5
461                     append add_flags " -Wl,-rpath,$tool_root_dir/libstdc++"
462                 }
463             }
464         }
465     }
466
467     if {![info exists ldscript]} {
468         set ldscript [board_info $dest ldscript]
469     }
470
471     foreach i $options {
472         if { $i == "debug" } {
473             if {[board_info $dest exists debug_flags]} {
474                 append add_flags " [board_info $dest debug_flags]"
475             } else {
476                 append add_flags " -g"
477             }
478         }
479     }
480
481     if {[info exists optimize]} {
482         append add_flags " $optimize"
483     }
484
485     if { $type == "executable" } {
486         append add_flags " $ldflags"
487         foreach x $libs {
488             if {[file exists $x]} {
489                 append source " $x"
490             } else {
491                 append add_flags " $x"
492             }
493         }
494
495         if {[board_info $dest exists libs]} {
496             append add_flags " [board_info $dest libs]"
497         }
498
499         # This probably isn't such a good idea, but it avoids nasty
500         # hackiness in the testsuites.
501         # The math library must be linked in before the C library.  The C
502         # library is linked in by the linker script, so this must be before
503         # the linker script.
504         if {[board_info $dest exists mathlib]} {
505             append add_flags " [board_info $dest mathlib]"
506         } else {
507             append add_flags " -lm"
508         }
509
510         # This must be added here.
511         append add_flags " $ldscript"
512
513         if {[board_info $dest exists remote_link]} {
514             # Relink option.
515             append add_flags " -Wl,-r"
516         }
517         if {[board_info $dest exists output_format]} {
518             append add_flags " -Wl,-oformat,[board_info $dest output_format]"
519         }
520     }
521
522     if {[board_info $dest exists multilib_flags]} {
523         append add_flags " [board_info $dest multilib_flags]"
524     }
525
526     verbose "doing compile"
527
528     set sources ""
529     if {[is_remote host]} {
530         foreach x $source {
531             set file [remote_download host $x]
532             if { $file == "" } {
533                 warning "Unable to download $x to host."
534                 return "Unable to download $x to host."
535             } else {
536                 append sources " $file"
537             }
538         }
539     } else {
540         set sources $source
541     }
542
543     if {[is_remote host]} {
544         append add_flags " -o " [file tail $destfile]
545         remote_file host delete [file tail $destfile]
546     } else {
547         if { $destfile != "" } {
548             append add_flags " -o $destfile"
549         }
550     }
551
552     # This is obscure: we put SOURCES at the end when building an
553     # object, because otherwise, in some situations, libtool will
554     # become confused about the name of the actual source file.
555     switch $type {
556         "object" {
557             set opts "$early_flags $add_flags $sources"
558         }
559         "executable" {
560             switch $linker_opts_order {
561                 "flags-then-sources" {
562                     set opts "$early_flags $add_flags $sources"
563                 }
564                 "sources-then-flags" {
565                     set opts "$early_flags $sources $add_flags"
566                 }
567                 default {
568                     error "Invalid value for board_info linker_opts_order"
569                 }
570             }
571         }
572         default {
573             set opts "$early_flags $sources $add_flags"
574         }
575     }
576
577     if {[is_remote host]} {
578         if {[host_info exists use_at]} {
579             set fid [open "atfile" "w"]
580             puts $fid "$opts"
581             close $fid
582             set opts "@[remote_download host atfile]"
583             remote_file build delete atfile
584         }
585     }
586
587     verbose "Invoking the compiler as $compiler $opts" 2
588
589     if {[info exists redirect]} {
590         verbose "Redirecting output to $redirect" 2
591         set status [remote_exec host "$compiler $opts" "" "" $redirect]
592     } else {
593         if {[info exists timeout]} {
594             verbose "Setting timeout to $timeout" 2
595             set status [remote_exec host "$compiler $opts" "" "" "" $timeout]
596         } else {
597             set status [remote_exec host "$compiler $opts"]
598         }
599     }
600
601     set compiler_flags $opts
602     if {[is_remote host]} {
603         remote_upload host [file tail $destfile] $destfile
604         remote_file host delete [file tail $destfile]
605     }
606     set comp_output [prune_warnings [lindex $status 1]]
607     regsub "^\[\r\n\]+" $comp_output "" comp_output
608     if { [lindex $status 0] != 0 } {
609         verbose -log "compiler exited with status [lindex $status 0]"
610     }
611     if { [lindex $status 1] != "" } {
612         verbose -log "output is:\n[lindex $status 1]" 2
613     }
614     if { [lindex $status 0] != 0 && "${comp_output}" == "" } {
615         set comp_output "exit status is [lindex $status 0]"
616     }
617     return ${comp_output}
618 }
619
620 # See if the version of dejaGNU being used to run the testsuite is
621 # recent enough to contain support for building Ada programs or not.
622 # If not, then use the functions above in place of the ones provided
623 # by dejaGNU. This is only temporary (brobecker/2004-03-31).
624
625 set use_gdb_compile 0
626 if {[info procs find_gnatmake] == ""} {
627     rename gdb_find_gnatmake find_gnatmake
628     set use_gdb_compile 1
629 }
630
631 if {[info procs find_gfortran] == ""} {
632     rename gdb_find_gfortran find_gfortran
633     set use_gdb_compile 1
634 }
635
636 if {[info procs find_go_linker] == ""} {
637     rename gdb_find_go find_go
638     rename gdb_find_go_linker find_go_linker
639     set use_gdb_compile 1
640 }
641
642 if {[info procs find_gdc] == ""} {
643     rename gdb_find_gdc find_gdc
644     set use_gdb_compile 1
645 }
646
647 if {[info procs find_rustc] == ""} {
648     rename gdb_find_rustc find_rustc
649     set use_gdb_compile 1
650 }
651
652 if {$use_gdb_compile} {
653     catch {rename default_target_compile {}}
654     rename gdb_default_target_compile default_target_compile
655 }
656
657
658 # Provide 'lreverse' missing in Tcl before 7.5.
659
660 if {[info procs lreverse] == ""} {
661     proc lreverse { arg } {
662         set retval {}
663         while { [llength $retval] < [llength $arg] } {
664             lappend retval [lindex $arg end-[llength $retval]]
665         }
666         return $retval
667     }
668 }