ctf-lib.exp revision 1.1.1.1
1# Support routines for libctf testsuite.
2#   Copyright (C) 1994-2022 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#   xfail: GLOB|PROC ...
104#	This test is expected to fail on a specified list of targets.
105#
106# Each option may occur at most once unless otherwise mentioned.
107#
108# After the option lines come regexp lines.  run_lookup_test calls
109# regexp_diff to compare the output of the lookup program against the
110# regexps in FILE.d.
111#
112proc run_lookup_test { name } {
113    global CC_FOR_TARGET CFLAGS_FOR_TARGET LIBS
114    global copyfile env runtests srcdir subdir verbose
115
116    if ![runtest_file_p $runtests $name] then {
117	return
118    }
119
120    if [string match "*/*" $name] {
121	set file $name
122	set name [file tail $name]
123    } else {
124	set file "$srcdir/$subdir/$name"
125    }
126
127    set opt_array [slurp_options "${file}.lk"]
128    if { $opt_array == -1 } {
129	perror "error reading options from $file.lk"
130	unresolved $subdir/$name
131	return
132    }
133    set run_ld 0
134    set shared "-shared"
135    set opts(link) {}
136    set opts(link_flags) {}
137    set opts(nonshared) {}
138    set opts(lookup) {}
139    set opts(name) {}
140    set opts(source) {}
141    set opts(xfail) {}
142
143    foreach i $opt_array {
144	set opt_name [lindex $i 0]
145	set opt_val [lindex $i 1]
146	if { $opt_name == "" } {
147	    set in_extra 1
148	    continue
149	}
150	if ![info exists opts($opt_name)] {
151	    perror "unknown option $opt_name in file $file.lk"
152	    unresolved $subdir/$name
153	    return
154	}
155
156	set opts($opt_name) [concat $opts($opt_name) $opt_val]
157    }
158
159    if { [llength $opts(lookup)] == 0 } {
160	set opts(lookup) "$file.c"
161    } else {
162	set opts(lookup) "[file dirname $file]/$opts(lookup)"
163    }
164
165    if { [llength $opts(name)] == 0 } {
166	set opts(name) $opts(lookup)
167    }
168
169    if { [llength $opts(link)] != 0
170	 || [llength $opts(source)] > 1 } {
171	set run_ld 1
172    }
173
174    if { [llength $opts(nonshared)] != 0 } {
175	set shared ""
176    }
177
178    set testname $opts(name)
179    if { $opts(name) == "" } {
180	set testname "$subdir/$name"
181    }
182
183    # Compile and link the lookup program.
184    set comp_output [prune_warnings [compile_link_one_host_cc $opts(lookup) "tmpdir/lookup" "libctf.la"]]
185
186    if { $comp_output != ""} {
187	send_log "compilation of lookup program $opts(lookup) failed with <$comp_output>"
188	perror "compilation of lookup program $opts(lookup) failed"
189	fail $testname
190	return 0
191    }
192
193    # Compile the inputs and posibly link them together.
194
195    set lookup_output ""
196    if { [llength $opts(source)] > 0 } {
197	set lookup_flags ""
198	if { $run_ld } {
199	    set lookup_output "tmpdir/out.so"
200	    set lookup_flags "-gctf -fPIC $shared $opts(link_flags)"
201	} else {
202	    set lookup_output "tmpdir/out.o"
203	    set lookup_flags "-gctf -fPIC -c"
204	}
205	if [board_info [target_info name] exists cflags] {
206	    append lookup_flags " [board_info [target_info name] cflags]"
207	}
208	if [board_info [target_info name] exists ldflags] {
209	    append lookup_flags " [board_info [target_info name] ldflags]"
210	}
211	set src {}
212	foreach sfile $opts(source) {
213	    if [is_remote host] {
214		lappend src [remote_download host [file join [file dirname $file] $sfile]]
215	    } else {
216		lappend src [file join [file dirname $file] $sfile]
217	    }
218	}
219
220	set comp_output [prune_warnings [run_host_cmd "$CC_FOR_TARGET" "$CFLAGS_FOR_TARGET $lookup_flags [concat $src] -o $lookup_output"]]
221
222	if { $comp_output != ""} {
223	    send_log "compilation of CTF program [concat $src] failed with <$comp_output>"
224	    fail $testname
225	    return 0
226	}
227    }
228
229    # Time to setup xfailures.
230    foreach targ $opts(xfail) {
231	if [match_target $targ] {
232	    setup_xfail "*-*-*"
233	    break
234	}
235    }
236
237    # Invoke the lookup program on the outputs.
238
239    set results [run_host_cmd tmpdir/lookup $lookup_output]
240
241    set f [open "tmpdir/lookup.out" "w"]
242    puts $f $results
243    close $f
244
245    if { [regexp_diff "tmpdir/lookup.out" "${file}.lk"] } then {
246	fail $testname
247	if { $verbose == 2 } then { verbose "output is [file_contents tmpdir/lookup.out]" 2 }
248	return 0
249    }
250
251    pass $testname
252    return 0
253}
254