xref: /netbsd-src/external/gpl3/gdb/dist/libctf/testsuite/lib/ctf-lib.exp (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1# Support routines for libctf testsuite.
2#   Copyright (C) 1994-2024 Free Software Foundation, Inc.
3#
4# This file is part of the GNU Binutils.
5#
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
8# the Free Software Foundation; either version 3 of the License, or
9# (at your option) any later version.
10#
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.
15#
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
18# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19# MA 02110-1301, USA.
20
21load_file $srcdir/../../ld/testsuite/lib/ld-lib.exp
22
23proc run_native_host_cmd { command } {
24    global link_output
25    global ld
26
27    verbose -log "$command"
28    set run_output ""
29    try {
30	set run_output [exec "sh" "-c" "$command" "2>@1"]
31	set status 0
32    } trap CHILDSTATUS {results options} {
33	set status [lindex [dict get $options -errorcode] 2]
34	set run_output $results
35    }
36    regsub "\n$" $run_output "" run_output
37    if { [lindex $status 0] != 0 && [string match "" $run_output] } then {
38	append run_output "child process exited abnormally"
39    }
40
41    if [string match "" $run_output] then {
42	return ""
43    }
44
45    verbose -log "$run_output"
46    return "$run_output"
47}
48
49# Compile and link a C source file for execution on the host.
50proc compile_link_one_host_cc { src output additional_args } {
51    global CC
52    global CFLAGS
53
54    return [run_native_host_cmd "./libtool --quiet --tag=CC --mode=link $CC $CFLAGS $src -o $output $additional_args" ]
55}
56
57# run_lookup_test FILE
58#
59# Compile with the host compiler and link a .c file into a "lookup" binary, then
60# compile and optionally link together a bunch of .s or .c files with CTF info
61# and pass the name of the resulting binary to the "lookup" binary and check the
62# output.  (If none is specified, the binary is expected to generate its own CTF
63# for testing purposes.)
64#
65# As with run_dump_test, this is all driven by a file (in this case, a .lk file)
66# beginning with zero or more option lines, which specify the names of the
67# lookup binary's source file, the source file(s) with CTF info to compile
68# together, and whether to link them.  The optional lines have the syntax:
69#
70#	# OPTION: VALUE
71#
72# OPTION is the name of some option, like "name" or "lookup", and
73# VALUE is OPTION's value.  The valid options are described below.
74# Whitespace is ignored everywhere, except within VALUE.  The option
75# list ends with the first line that doesn't match the above syntax.
76# However, a line within the options that begins with a #, but doesn't
77# have a recognizable option name followed by a colon, is considered a
78# comment and entirely ignored.
79#
80# The interesting options are:
81#
82#   name: TEST-NAME
83#	The name of this test, passed to DejaGNU's `pass' and `fail'
84#	commands.  If omitted, this defaults to FILE, the root of the
85#	lookup .c file's name.
86#
87#   lookup: SOURCE
88#	Compile the file SOURCE.c.  If omitted, the lookup source defaults
89#	to FILE.c.
90#
91#   source: SOURCE
92#	Assemble the file SOURCE.c and pass it to the LOOKUP program.
93#
94#   nonshared:
95#	If set, do not link with -shared.
96#
97#   link:
98#	If set, link the SOURCE together even if only one file is specified.
99#
100#   link_flags:
101#	If set, extra flags to pass to the linker.
102#
103#   lookup_link:
104#       If set, extra libraries to link the lookup program with.
105#
106#   xfail: GLOB|PROC ...
107#	This test is expected to fail on a specified list of targets.
108#
109#   no_cross:
110#       If set, do not run this test when host != target.
111#
112#   host:
113#       If set, only run this test on hosts matching the given glob.
114#
115#   wrapper:
116#       Wrap invocations of LOOKUP in this command.  (Useful for valgrind
117#       invocations, etc.)
118#
119# Each option may occur at most once unless otherwise mentioned.
120#
121# After the option lines come regexp lines.  run_lookup_test calls
122# regexp_diff to compare the output of the lookup program against the
123# regexps in FILE.d.
124#
125proc run_lookup_test { name } {
126    global CC_FOR_TARGET CFLAGS_FOR_TARGET LIBS TEST_CROSS
127    global copyfile env runtests srcdir subdir verbose
128
129    if ![runtest_file_p $runtests $name] then {
130	return
131    }
132
133    if [string match "*/*" $name] {
134	set file $name
135	set name [file tail $name]
136    } else {
137	set file "$srcdir/$subdir/$name"
138    }
139
140    set opt_array [slurp_options "${file}.lk"]
141    if { $opt_array == -1 } {
142	perror "error reading options from $file.lk"
143	unresolved $subdir/$name
144	return
145    }
146    set run_ld 0
147    set shared "-shared"
148    set opts(link) {}
149    set opts(link_flags) {}
150    set opts(lookup_link) {}
151    set opts(nonshared) {}
152    set opts(lookup) {}
153    set opts(name) {}
154    set opts(source) {}
155    set opts(xfail) {}
156    set opts(no_cross) {}
157    set opts(host) {}
158    set opts(wrapper) {}
159
160    foreach i $opt_array {
161	set opt_name [lindex $i 0]
162	set opt_val [lindex $i 1]
163	if { $opt_name == "" } {
164	    set in_extra 1
165	    continue
166	}
167	if ![info exists opts($opt_name)] {
168	    perror "unknown option $opt_name in file $file.lk"
169	    unresolved $subdir/$name
170	    return
171	}
172
173	set opts($opt_name) [concat $opts($opt_name) $opt_val]
174    }
175
176    if { [llength $opts(no_cross)] != 0
177	 && "$TEST_CROSS" eq "yes" } {
178	untested "$subdir/$name not tested when cross-compiling"
179	return
180    }
181
182    if { [llength $opts(host)] != 0 && ![ishost $opts(host)] } {
183	untested "$subdir/$name only runs on $opts(host)"
184	return
185    }
186
187    if { [llength $opts(lookup)] == 0 } {
188	set opts(lookup) "$file.c"
189    } else {
190	set opts(lookup) "[file dirname $file]/$opts(lookup)"
191    }
192
193    if { [llength $opts(name)] == 0 } {
194	set opts(name) $opts(lookup)
195    }
196
197    if { [llength $opts(link)] != 0
198	 || [llength $opts(source)] > 1 } {
199	set run_ld 1
200    }
201
202    if { [llength $opts(nonshared)] != 0 } {
203	set shared ""
204    }
205
206    set testname $opts(name)
207    if { $opts(name) == "" } {
208	set testname "$subdir/$name"
209    }
210
211    # Compile and link the lookup program.
212    set comp_output [prune_warnings [compile_link_one_host_cc $opts(lookup) "tmpdir/lookup" "libctf.la $opts(lookup_link)"]]
213
214    if { $comp_output != ""} {
215	send_log "compilation of lookup program $opts(lookup) failed with <$comp_output>"
216	perror "compilation of lookup program $opts(lookup) failed"
217	fail $testname
218	return 0
219    }
220
221    # Compile the inputs and posibly link them together.
222
223    set lookup_output ""
224    if { [llength $opts(source)] > 0 } {
225	set lookup_flags ""
226	if { $run_ld } {
227	    set lookup_output "tmpdir/out.so"
228	    set lookup_flags "-gctf -fPIC $shared $opts(link_flags)"
229	} else {
230	    set lookup_output "tmpdir/out.o"
231	    set lookup_flags "-gctf -fPIC -c"
232	}
233	if [board_info [target_info name] exists cflags] {
234	    append lookup_flags " [board_info [target_info name] cflags]"
235	}
236	if [board_info [target_info name] exists ldflags] {
237	    append lookup_flags " [board_info [target_info name] ldflags]"
238	}
239	set src {}
240	foreach sfile $opts(source) {
241	    if [is_remote host] {
242		lappend src [remote_download host [file join [file dirname $file] $sfile]]
243	    } else {
244		lappend src [file join [file dirname $file] $sfile]
245	    }
246	}
247
248	set comp_output [prune_warnings [run_host_cmd "$CC_FOR_TARGET" "$CFLAGS_FOR_TARGET $lookup_flags [concat $src] -o $lookup_output"]]
249
250	if { $comp_output != ""} {
251	    send_log "compilation of CTF program [concat $src] failed with <$comp_output>"
252	    fail $testname
253	    return 0
254	}
255    }
256
257    # Time to setup xfailures.
258    foreach targ $opts(xfail) {
259	if [match_target $targ] {
260	    setup_xfail "*-*-*"
261	    break
262	}
263    }
264
265    # Invoke the lookup program on the outputs, possibly through the wrapper.
266
267    if { [llength $opts(wrapper)] == 0 } {
268	set results [run_host_cmd tmpdir/lookup $lookup_output]
269    } else {
270	set results [run_host_cmd "$opts(wrapper) tmpdir/lookup" $lookup_output]
271    }
272
273    set f [open "tmpdir/lookup.out" "w"]
274    puts $f $results
275    close $f
276
277    if { [regexp_diff "tmpdir/lookup.out" "${file}.lk"] } then {
278	fail $testname
279	if { $verbose == 2 } then { verbose "output is [file_contents tmpdir/lookup.out]" 2 }
280	return 0
281    }
282
283    pass $testname
284    return 0
285}
286