xref: /netbsd-src/external/gpl3/gdb/dist/libctf/testsuite/lib/ctf-lib.exp (revision c9055873d0546e63388f027d3d7f85381cde0545)
14b169a6bSchristos# Support routines for libctf testsuite.
2*c9055873Schristos#   Copyright (C) 1994-2024 Free Software Foundation, Inc.
34b169a6bSchristos#
44b169a6bSchristos# This file is part of the GNU Binutils.
54b169a6bSchristos#
64b169a6bSchristos# This file is free software; you can redistribute it and/or modify
74b169a6bSchristos# it under the terms of the GNU General Public License as published by
84b169a6bSchristos# the Free Software Foundation; either version 3 of the License, or
94b169a6bSchristos# (at your option) any later version.
104b169a6bSchristos#
114b169a6bSchristos# This program is distributed in the hope that it will be useful,
124b169a6bSchristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
134b169a6bSchristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144b169a6bSchristos# GNU General Public License for more details.
154b169a6bSchristos#
164b169a6bSchristos# You should have received a copy of the GNU General Public License
174b169a6bSchristos# along with this program; if not, write to the Free Software
184b169a6bSchristos# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
194b169a6bSchristos# MA 02110-1301, USA.
204b169a6bSchristos
214b169a6bSchristosload_file $srcdir/../../ld/testsuite/lib/ld-lib.exp
224b169a6bSchristos
234b169a6bSchristosproc run_native_host_cmd { command } {
244b169a6bSchristos    global link_output
254b169a6bSchristos    global ld
264b169a6bSchristos
274b169a6bSchristos    verbose -log "$command"
284b169a6bSchristos    set run_output ""
294b169a6bSchristos    try {
304b169a6bSchristos	set run_output [exec "sh" "-c" "$command" "2>@1"]
314b169a6bSchristos	set status 0
324b169a6bSchristos    } trap CHILDSTATUS {results options} {
334b169a6bSchristos	set status [lindex [dict get $options -errorcode] 2]
344b169a6bSchristos	set run_output $results
354b169a6bSchristos    }
364b169a6bSchristos    regsub "\n$" $run_output "" run_output
374b169a6bSchristos    if { [lindex $status 0] != 0 && [string match "" $run_output] } then {
384b169a6bSchristos	append run_output "child process exited abnormally"
394b169a6bSchristos    }
404b169a6bSchristos
414b169a6bSchristos    if [string match "" $run_output] then {
424b169a6bSchristos	return ""
434b169a6bSchristos    }
444b169a6bSchristos
454b169a6bSchristos    verbose -log "$run_output"
464b169a6bSchristos    return "$run_output"
474b169a6bSchristos}
484b169a6bSchristos
494b169a6bSchristos# Compile and link a C source file for execution on the host.
504b169a6bSchristosproc compile_link_one_host_cc { src output additional_args } {
514b169a6bSchristos    global CC
524b169a6bSchristos    global CFLAGS
534b169a6bSchristos
544b169a6bSchristos    return [run_native_host_cmd "./libtool --quiet --tag=CC --mode=link $CC $CFLAGS $src -o $output $additional_args" ]
554b169a6bSchristos}
564b169a6bSchristos
574b169a6bSchristos# run_lookup_test FILE
584b169a6bSchristos#
594b169a6bSchristos# Compile with the host compiler and link a .c file into a "lookup" binary, then
604b169a6bSchristos# compile and optionally link together a bunch of .s or .c files with CTF info
614b169a6bSchristos# and pass the name of the resulting binary to the "lookup" binary and check the
624b169a6bSchristos# output.  (If none is specified, the binary is expected to generate its own CTF
634b169a6bSchristos# for testing purposes.)
644b169a6bSchristos#
654b169a6bSchristos# As with run_dump_test, this is all driven by a file (in this case, a .lk file)
664b169a6bSchristos# beginning with zero or more option lines, which specify the names of the
674b169a6bSchristos# lookup binary's source file, the source file(s) with CTF info to compile
684b169a6bSchristos# together, and whether to link them.  The optional lines have the syntax:
694b169a6bSchristos#
704b169a6bSchristos#	# OPTION: VALUE
714b169a6bSchristos#
724b169a6bSchristos# OPTION is the name of some option, like "name" or "lookup", and
734b169a6bSchristos# VALUE is OPTION's value.  The valid options are described below.
744b169a6bSchristos# Whitespace is ignored everywhere, except within VALUE.  The option
754b169a6bSchristos# list ends with the first line that doesn't match the above syntax.
764b169a6bSchristos# However, a line within the options that begins with a #, but doesn't
774b169a6bSchristos# have a recognizable option name followed by a colon, is considered a
784b169a6bSchristos# comment and entirely ignored.
794b169a6bSchristos#
804b169a6bSchristos# The interesting options are:
814b169a6bSchristos#
824b169a6bSchristos#   name: TEST-NAME
834b169a6bSchristos#	The name of this test, passed to DejaGNU's `pass' and `fail'
844b169a6bSchristos#	commands.  If omitted, this defaults to FILE, the root of the
854b169a6bSchristos#	lookup .c file's name.
864b169a6bSchristos#
874b169a6bSchristos#   lookup: SOURCE
884b169a6bSchristos#	Compile the file SOURCE.c.  If omitted, the lookup source defaults
894b169a6bSchristos#	to FILE.c.
904b169a6bSchristos#
914b169a6bSchristos#   source: SOURCE
924b169a6bSchristos#	Assemble the file SOURCE.c and pass it to the LOOKUP program.
934b169a6bSchristos#
944b169a6bSchristos#   nonshared:
954b169a6bSchristos#	If set, do not link with -shared.
964b169a6bSchristos#
974b169a6bSchristos#   link:
984b169a6bSchristos#	If set, link the SOURCE together even if only one file is specified.
994b169a6bSchristos#
1004b169a6bSchristos#   link_flags:
1014b169a6bSchristos#	If set, extra flags to pass to the linker.
1024b169a6bSchristos#
103*c9055873Schristos#   lookup_link:
104*c9055873Schristos#       If set, extra libraries to link the lookup program with.
105*c9055873Schristos#
1064b169a6bSchristos#   xfail: GLOB|PROC ...
1074b169a6bSchristos#	This test is expected to fail on a specified list of targets.
1084b169a6bSchristos#
109*c9055873Schristos#   no_cross:
110*c9055873Schristos#       If set, do not run this test when host != target.
111*c9055873Schristos#
112*c9055873Schristos#   host:
113*c9055873Schristos#       If set, only run this test on hosts matching the given glob.
114*c9055873Schristos#
115*c9055873Schristos#   wrapper:
116*c9055873Schristos#       Wrap invocations of LOOKUP in this command.  (Useful for valgrind
117*c9055873Schristos#       invocations, etc.)
118*c9055873Schristos#
1194b169a6bSchristos# Each option may occur at most once unless otherwise mentioned.
1204b169a6bSchristos#
1214b169a6bSchristos# After the option lines come regexp lines.  run_lookup_test calls
1224b169a6bSchristos# regexp_diff to compare the output of the lookup program against the
1234b169a6bSchristos# regexps in FILE.d.
1244b169a6bSchristos#
1254b169a6bSchristosproc run_lookup_test { name } {
126*c9055873Schristos    global CC_FOR_TARGET CFLAGS_FOR_TARGET LIBS TEST_CROSS
1274b169a6bSchristos    global copyfile env runtests srcdir subdir verbose
1284b169a6bSchristos
1294b169a6bSchristos    if ![runtest_file_p $runtests $name] then {
1304b169a6bSchristos	return
1314b169a6bSchristos    }
1324b169a6bSchristos
1334b169a6bSchristos    if [string match "*/*" $name] {
1344b169a6bSchristos	set file $name
1354b169a6bSchristos	set name [file tail $name]
1364b169a6bSchristos    } else {
1374b169a6bSchristos	set file "$srcdir/$subdir/$name"
1384b169a6bSchristos    }
1394b169a6bSchristos
1404b169a6bSchristos    set opt_array [slurp_options "${file}.lk"]
1414b169a6bSchristos    if { $opt_array == -1 } {
1424b169a6bSchristos	perror "error reading options from $file.lk"
1434b169a6bSchristos	unresolved $subdir/$name
1444b169a6bSchristos	return
1454b169a6bSchristos    }
1464b169a6bSchristos    set run_ld 0
1474b169a6bSchristos    set shared "-shared"
1484b169a6bSchristos    set opts(link) {}
1494b169a6bSchristos    set opts(link_flags) {}
150*c9055873Schristos    set opts(lookup_link) {}
1514b169a6bSchristos    set opts(nonshared) {}
1524b169a6bSchristos    set opts(lookup) {}
1534b169a6bSchristos    set opts(name) {}
1544b169a6bSchristos    set opts(source) {}
1554b169a6bSchristos    set opts(xfail) {}
156*c9055873Schristos    set opts(no_cross) {}
157*c9055873Schristos    set opts(host) {}
158*c9055873Schristos    set opts(wrapper) {}
1594b169a6bSchristos
1604b169a6bSchristos    foreach i $opt_array {
1614b169a6bSchristos	set opt_name [lindex $i 0]
1624b169a6bSchristos	set opt_val [lindex $i 1]
1634b169a6bSchristos	if { $opt_name == "" } {
1644b169a6bSchristos	    set in_extra 1
1654b169a6bSchristos	    continue
1664b169a6bSchristos	}
1674b169a6bSchristos	if ![info exists opts($opt_name)] {
1684b169a6bSchristos	    perror "unknown option $opt_name in file $file.lk"
1694b169a6bSchristos	    unresolved $subdir/$name
1704b169a6bSchristos	    return
1714b169a6bSchristos	}
1724b169a6bSchristos
1734b169a6bSchristos	set opts($opt_name) [concat $opts($opt_name) $opt_val]
1744b169a6bSchristos    }
1754b169a6bSchristos
176*c9055873Schristos    if { [llength $opts(no_cross)] != 0
177*c9055873Schristos	 && "$TEST_CROSS" eq "yes" } {
178*c9055873Schristos	untested "$subdir/$name not tested when cross-compiling"
179*c9055873Schristos	return
180*c9055873Schristos    }
181*c9055873Schristos
182*c9055873Schristos    if { [llength $opts(host)] != 0 && ![ishost $opts(host)] } {
183*c9055873Schristos	untested "$subdir/$name only runs on $opts(host)"
184*c9055873Schristos	return
185*c9055873Schristos    }
186*c9055873Schristos
1874b169a6bSchristos    if { [llength $opts(lookup)] == 0 } {
1884b169a6bSchristos	set opts(lookup) "$file.c"
1894b169a6bSchristos    } else {
1904b169a6bSchristos	set opts(lookup) "[file dirname $file]/$opts(lookup)"
1914b169a6bSchristos    }
1924b169a6bSchristos
1934b169a6bSchristos    if { [llength $opts(name)] == 0 } {
1944b169a6bSchristos	set opts(name) $opts(lookup)
1954b169a6bSchristos    }
1964b169a6bSchristos
1974b169a6bSchristos    if { [llength $opts(link)] != 0
1984b169a6bSchristos	 || [llength $opts(source)] > 1 } {
1994b169a6bSchristos	set run_ld 1
2004b169a6bSchristos    }
2014b169a6bSchristos
2024b169a6bSchristos    if { [llength $opts(nonshared)] != 0 } {
2034b169a6bSchristos	set shared ""
2044b169a6bSchristos    }
2054b169a6bSchristos
2064b169a6bSchristos    set testname $opts(name)
2074b169a6bSchristos    if { $opts(name) == "" } {
2084b169a6bSchristos	set testname "$subdir/$name"
2094b169a6bSchristos    }
2104b169a6bSchristos
2114b169a6bSchristos    # Compile and link the lookup program.
212*c9055873Schristos    set comp_output [prune_warnings [compile_link_one_host_cc $opts(lookup) "tmpdir/lookup" "libctf.la $opts(lookup_link)"]]
2134b169a6bSchristos
2144b169a6bSchristos    if { $comp_output != ""} {
2154b169a6bSchristos	send_log "compilation of lookup program $opts(lookup) failed with <$comp_output>"
2164b169a6bSchristos	perror "compilation of lookup program $opts(lookup) failed"
2174b169a6bSchristos	fail $testname
2184b169a6bSchristos	return 0
2194b169a6bSchristos    }
2204b169a6bSchristos
2214b169a6bSchristos    # Compile the inputs and posibly link them together.
2224b169a6bSchristos
2234b169a6bSchristos    set lookup_output ""
2244b169a6bSchristos    if { [llength $opts(source)] > 0 } {
2254b169a6bSchristos	set lookup_flags ""
2264b169a6bSchristos	if { $run_ld } {
2274b169a6bSchristos	    set lookup_output "tmpdir/out.so"
2284b169a6bSchristos	    set lookup_flags "-gctf -fPIC $shared $opts(link_flags)"
2294b169a6bSchristos	} else {
2304b169a6bSchristos	    set lookup_output "tmpdir/out.o"
2314b169a6bSchristos	    set lookup_flags "-gctf -fPIC -c"
2324b169a6bSchristos	}
2334b169a6bSchristos	if [board_info [target_info name] exists cflags] {
2344b169a6bSchristos	    append lookup_flags " [board_info [target_info name] cflags]"
2354b169a6bSchristos	}
2364b169a6bSchristos	if [board_info [target_info name] exists ldflags] {
2374b169a6bSchristos	    append lookup_flags " [board_info [target_info name] ldflags]"
2384b169a6bSchristos	}
2394b169a6bSchristos	set src {}
2404b169a6bSchristos	foreach sfile $opts(source) {
2414b169a6bSchristos	    if [is_remote host] {
2424b169a6bSchristos		lappend src [remote_download host [file join [file dirname $file] $sfile]]
2434b169a6bSchristos	    } else {
2444b169a6bSchristos		lappend src [file join [file dirname $file] $sfile]
2454b169a6bSchristos	    }
2464b169a6bSchristos	}
2474b169a6bSchristos
2484b169a6bSchristos	set comp_output [prune_warnings [run_host_cmd "$CC_FOR_TARGET" "$CFLAGS_FOR_TARGET $lookup_flags [concat $src] -o $lookup_output"]]
2494b169a6bSchristos
2504b169a6bSchristos	if { $comp_output != ""} {
2514b169a6bSchristos	    send_log "compilation of CTF program [concat $src] failed with <$comp_output>"
2524b169a6bSchristos	    fail $testname
2534b169a6bSchristos	    return 0
2544b169a6bSchristos	}
2554b169a6bSchristos    }
2564b169a6bSchristos
2574b169a6bSchristos    # Time to setup xfailures.
2584b169a6bSchristos    foreach targ $opts(xfail) {
2594b169a6bSchristos	if [match_target $targ] {
2604b169a6bSchristos	    setup_xfail "*-*-*"
2614b169a6bSchristos	    break
2624b169a6bSchristos	}
2634b169a6bSchristos    }
2644b169a6bSchristos
265*c9055873Schristos    # Invoke the lookup program on the outputs, possibly through the wrapper.
2664b169a6bSchristos
267*c9055873Schristos    if { [llength $opts(wrapper)] == 0 } {
2684b169a6bSchristos	set results [run_host_cmd tmpdir/lookup $lookup_output]
269*c9055873Schristos    } else {
270*c9055873Schristos	set results [run_host_cmd "$opts(wrapper) tmpdir/lookup" $lookup_output]
271*c9055873Schristos    }
2724b169a6bSchristos
2734b169a6bSchristos    set f [open "tmpdir/lookup.out" "w"]
2744b169a6bSchristos    puts $f $results
2754b169a6bSchristos    close $f
2764b169a6bSchristos
2774b169a6bSchristos    if { [regexp_diff "tmpdir/lookup.out" "${file}.lk"] } then {
2784b169a6bSchristos	fail $testname
2794b169a6bSchristos	if { $verbose == 2 } then { verbose "output is [file_contents tmpdir/lookup.out]" 2 }
2804b169a6bSchristos	return 0
2814b169a6bSchristos    }
2824b169a6bSchristos
2834b169a6bSchristos    pass $testname
2844b169a6bSchristos    return 0
2854b169a6bSchristos}
286