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