diff options
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ChangeLog | 17 | ||||
-rw-r--r-- | libctf/Makefile.am | 35 | ||||
-rw-r--r-- | libctf/Makefile.in | 113 | ||||
-rw-r--r-- | libctf/testsuite/config/default.exp | 59 | ||||
-rw-r--r-- | libctf/testsuite/lib/ctf-lib.exp | 409 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/ambiguous-struct-A.c | 8 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/ambiguous-struct-B.c | 5 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/ambiguous-struct.c | 51 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/ambiguous-struct.lk | 4 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/enum-ctf.c | 8 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/enum.c | 78 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/enum.lk | 10 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/lookup.exp | 43 |
13 files changed, 816 insertions, 24 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 7e4997e..42ca1c6 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,5 +1,22 @@ 2021-01-05 Nick Alcock <nick.alcock@oracle.com> + * Makefile.am (EXPECT): New. + (RUNTEST): Likewise. + (RUNTESTFLAGS): Likewise. + (CC_FOR_TARGET): Likewise. + (check-DEJAGNU): Likewise. + (AUTOMAKE_OPTIONS): Add dejagnu. + * Makefile.in: Regenerated. + * testsuite/config/default.exp: New. + * testsuite/lib/ctf-lib.exp: Likewise. + * testsuite/libctf-lookup/enum.lk: New test. + * testsuite/libctf-lookup/enum-ctf.c: New CTF input. + * testsuite/libctf-lookup/enum.c: New lookup test. + * testsuite/libctf-lookup/ambiguous-struct*.c: New test. + * testsuite/libctf-lookup/lookup.exp: New. + +2021-01-05 Nick Alcock <nick.alcock@oracle.com> + * configure.ac (BFD_LIBADD): Remove. (BFD_DEPENDENCIES): Likewise. Remove associated cases. (SHARED_LIBADD): Rename to... diff --git a/libctf/Makefile.am b/libctf/Makefile.am index a66ccc1..3fe1994 100644 --- a/libctf/Makefile.am +++ b/libctf/Makefile.am @@ -19,7 +19,7 @@ ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd -AUTOMAKE_OPTIONS = foreign no-texinfo.tex +AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex # This is where we get zlib from. zlibdir is -L../zlib and zlibinc is # -I../zlib, unless we were configured with --with-system-zlib, in which @@ -54,3 +54,36 @@ libctf_la_LIBADD = ../bfd/libbfd.la $(libctf_nobfd_la_LIBADD) libctf_la_CPPFLAGS = $(AM_CPPFLAGS) -DNOBFD=0 libctf_la_LDFLAGS = $(libctf_nobfd_la_LDFLAGS) libctf_la_SOURCES = $(libctf_nobfd_la_SOURCES) ctf-open-bfd.c + +# Setup the testing framework, if you have one +EXPECT = expect +RUNTEST = runtest +RUNTESTFLAGS = + +CC_FOR_TARGET = ` \ + if [ -f $$r/../gcc/xgcc ] ; then \ + if [ -f $$r/../newlib/Makefile ] ; then \ + echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \ + else \ + echo $$r/../gcc/xgcc -B$$r/../gcc/; \ + fi; \ + else \ + if [ "@host@" = "@target@" ] ; then \ + echo $(CC); \ + else \ + echo gcc | sed '$(transform)'; \ + fi; \ + fi` + +check-DEJAGNU: site.exp + srcroot=`cd $(srcdir) && pwd`; export srcroot; \ + r=`pwd`; export r; \ + LC_ALL=C; export LC_ALL; \ + EXPECT=$(EXPECT); export EXPECT; \ + runtest=$(RUNTEST); \ + if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \ + CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS) -I$(INCDIR) -I$(srcdir) -I$(builddir) -I$(builddir)/../bfd $(ZLIBINC)" \ + CC_FOR_HOST="$(CC)" LIBS="$(LIBS)" $(RUNTESTFLAGS); \ + else echo "WARNING: could not find \`runtest'" 1>&2; :;\ + fi diff --git a/libctf/Makefile.in b/libctf/Makefile.in index 0ee67fc..c86ac7b 100644 --- a/libctf/Makefile.in +++ b/libctf/Makefile.in @@ -278,6 +278,8 @@ ETAGS = etags CTAGS = ctags CSCOPE = cscope AM_RECURSIVE_TARGETS = cscope +DEJATOOL = $(PACKAGE) +RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/../ar-lib $(top_srcdir)/../compile \ $(top_srcdir)/../config.guess $(top_srcdir)/../config.sub \ @@ -439,7 +441,7 @@ warn = @warn@ zlibdir = @zlibdir@ zlibinc = @zlibinc@ ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd -AUTOMAKE_OPTIONS = foreign no-texinfo.tex +AUTOMAKE_OPTIONS = dejagnu foreign no-texinfo.tex # This is where we get zlib from. zlibdir is -L../zlib and zlibinc is # -I../zlib, unless we were configured with --with-system-zlib, in which @@ -464,6 +466,26 @@ libctf_la_LIBADD = ../bfd/libbfd.la $(libctf_nobfd_la_LIBADD) libctf_la_CPPFLAGS = $(AM_CPPFLAGS) -DNOBFD=0 libctf_la_LDFLAGS = $(libctf_nobfd_la_LDFLAGS) libctf_la_SOURCES = $(libctf_nobfd_la_SOURCES) ctf-open-bfd.c + +# Setup the testing framework, if you have one +EXPECT = expect +RUNTEST = runtest +RUNTESTFLAGS = +CC_FOR_TARGET = ` \ + if [ -f $$r/../gcc/xgcc ] ; then \ + if [ -f $$r/../newlib/Makefile ] ; then \ + echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \ + else \ + echo $$r/../gcc/xgcc -B$$r/../gcc/; \ + fi; \ + else \ + if [ "@host@" = "@target@" ] ; then \ + echo $(CC); \ + else \ + echo gcc | sed '$(transform)'; \ + fi; \ + fi` + all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am @@ -966,6 +988,36 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files +site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG) + @echo 'Making a new site.exp file ...' + @echo '## these variables are automatically generated by make ##' >site.tmp + @echo '# Do not edit here. If you wish to override these values' >>site.tmp + @echo '# edit the last section' >>site.tmp + @echo 'set srcdir "$(srcdir)"' >>site.tmp + @echo "set objdir `pwd`" >>site.tmp + @echo 'set build_alias "$(build_alias)"' >>site.tmp + @echo 'set build_triplet $(build_triplet)' >>site.tmp + @echo 'set host_alias "$(host_alias)"' >>site.tmp + @echo 'set host_triplet $(host_triplet)' >>site.tmp + @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \ + echo "## Begin content included from file $$f. Do not modify. ##" \ + && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \ + && echo "## End content included from file $$f. ##" \ + || exit 1; \ + done >> site.tmp + @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp + @if test -f site.exp; then \ + sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \ + fi + @-rm -f site.bak + @test ! -f site.exp || mv site.exp site.bak + @mv site.tmp site.exp + +distclean-DEJAGNU: + -rm -f site.exp site.bak + -l='$(DEJATOOL)'; for tool in $$l; do \ + rm -f $$tool.sum $$tool.log; \ + done distdir: $(DISTFILES) $(am__remove_distdir) @@ -1131,6 +1183,7 @@ distcleancheck: distclean $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h installdirs: @@ -1176,8 +1229,9 @@ distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags +distclean-am: clean-am distclean-DEJAGNU distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags dvi: dvi-am @@ -1241,30 +1295,43 @@ ps-am: uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES -.MAKE: all install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ - clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \ - clean-noinstLTLIBRARIES cscope cscopelist-am ctags ctags-am \ - dist dist-all dist-bzip2 dist-gzip dist-lzip dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-includeHEADERS install-info \ - install-info-am install-libLTLIBRARIES install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES +.MAKE: all check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-DEJAGNU \ + check-am clean clean-cscope clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstLTLIBRARIES cscope cscopelist-am \ + ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \ + dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-DEJAGNU distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-includeHEADERS \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-includeHEADERS uninstall-libLTLIBRARIES .PRECIOUS: Makefile +check-DEJAGNU: site.exp + srcroot=`cd $(srcdir) && pwd`; export srcroot; \ + r=`pwd`; export r; \ + LC_ALL=C; export LC_ALL; \ + EXPECT=$(EXPECT); export EXPECT; \ + runtest=$(RUNTEST); \ + if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \ + CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS) -I$(INCDIR) -I$(srcdir) -I$(builddir) -I$(builddir)/../bfd $(ZLIBINC)" \ + CC_FOR_HOST="$(CC)" LIBS="$(LIBS)" $(RUNTESTFLAGS); \ + else echo "WARNING: could not find \`runtest'" 1>&2; :;\ + fi + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libctf/testsuite/config/default.exp b/libctf/testsuite/config/default.exp new file mode 100644 index 0000000..d14f660 --- /dev/null +++ b/libctf/testsuite/config/default.exp @@ -0,0 +1,59 @@ +# Basic expect script for libctf lookup tests +# Copyright (C) 1993-2021 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# +# Written by Jeffrey Wheat (cassidy@cygnus.com) +# + +if ![info exists ld] then { + set ld [findfile $base_dir/../ld/ld-new $base_dir/../ld/ld-new [transform ld]] +} + +if ![info exists as] then { + set as [findfile $base_dir/../gas/as-new $base_dir/../gas/as-new [transform as]] +} + +remote_exec host "mkdir -p tmpdir" + +# Make symlinks from tmpdir/libctf to the linker and assembler in the +# build tree, so that we can use a -B option to gcc to force it to use +# the newly built linker and assembler. +if {![file isdirectory tmpdir/libctf]} then { + catch "exec mkdir tmpdir/libctf" status + catch "exec ln -s ../../../ld/ld-new tmpdir/libctf/ld" status + catch "exec ln -s ld tmpdir/libctf/collect-ld" status + catch "exec ln -s ../../../gas/as-new tmpdir/libctf/as" status +} +set gcc_B_opt "-B[pwd]/tmpdir/libctf/" + +# The "make check" target in the Makefile passes in +# "CC=$(CC_FOR_TARGET)". But, if the user invokes runtest directly, +# these flags may not be set. +if {![info exists CC]} { + set CC [find_gcc] +} +if {![info exists CC_FOR_HOST]} { + set CC_FOR_HOST $CC +} +if {![info exists CFLAGS]} { + set CFLAGS "-g -O2" +} + +# load the utility procedures +load_lib ctf-lib.exp diff --git a/libctf/testsuite/lib/ctf-lib.exp b/libctf/testsuite/lib/ctf-lib.exp new file mode 100644 index 0000000..796342b --- /dev/null +++ b/libctf/testsuite/lib/ctf-lib.exp @@ -0,0 +1,409 @@ +# Support routines for libctf testsuite. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +proc load_common_lib { name } { + global srcdir + load_file $srcdir/../../binutils/testsuite/lib/$name +} + +load_common_lib binutils-common.exp + +proc run_native_host_cmd { command } { + global link_output + global ld + + verbose -log "$command" + set run_output "" + try { + set run_output [exec "sh" "-c" "$command" "2>@1"] + set status 0 + } trap CHILDSTATUS {results options} { + set status [lindex [dict get $options -errorcode] 2] + set run_output $results + } + regsub "\n$" $run_output "" run_output + if { [lindex $status 0] != 0 && [string match "" $run_output] } then { + append run_output "child process exited abnormally" + } + + if [string match "" $run_output] then { + return "" + } + + verbose -log "$run_output" + return "$run_output" +} + +proc run_host_cmd { prog command } { + global link_output + global gcc_B_opt + global gcc_ld_B_opt_tested + global ld + + if { ![is_remote host] && [which "$prog"] == 0 } then { + perror "$prog does not exist" + return 0 + } + + # If we are compiling with gcc, we want to add gcc_B_opt to flags. However, + # if $prog already has -B options, which might be the case when running gcc + # out of a build directory, we want our -B options to come first. + set gccexe $prog + set gccparm [string first " " $gccexe] + set gccflags "" + if { $gccparm > 0 } then { + set gccflags [string range $gccexe $gccparm end] + set gccexe [string range $gccexe 0 $gccparm] + set prog $gccexe + } + set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""] + if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then { + set gccflags "$gcc_B_opt $gccflags" + if {![info exists gcc_ld_B_opt_tested]} { + set gcc_ld_B_opt_tested 1 + set ld_version_message [run_host_cmd "$ld" "--version"] + set gcc_ld_version_message [run_host_cmd "$prog" "$gccflags -Wl,--version"] + if {[string first $ld_version_message $gcc_ld_version_message] < 0} { + perror "************************************************************************" + perror "Your compiler driver ignores -B when choosing ld." + perror "You will not be testing the new ld in many of the following tests." + set gcc_ld_version [run_host_cmd "$prog" "$gccflags --print-prog-name=ld"] + if {![string match "" $gcc_ld_version] && ![string match "ld" $gcc_ld_version]} { + perror "It seems you will be testing $gcc_ld_version instead." + } + perror "************************************************************************" + } + } + } + + verbose -log "$prog $gccflags $command" + set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "libctf.tmp"] + remote_upload host "libctf.tmp" + set run_output [file_contents "libctf.tmp"] + regsub "\n$" $run_output "" run_output + if { [lindex $status 0] != 0 && [string match "" $run_output] } then { + append run_output "child process exited abnormally" + } + remote_file build delete libctf.tmp + remote_file host delete libctf.tmp + + if [string match "" $run_output] then { + return "" + } + + verbose -log "$run_output" + return "$run_output" +} + +proc run_host_cmd_yesno { prog command } { + global exec_output + global errcnt warncnt + + set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]] + # Ignore error and warning. + set errcnt 0 + set warncnt 0 + if [string match "" $exec_output] then { + return 1; + } + return 0; +} + +# Return true if we can build a program with the compiler. +# On some targets, CC might be defined, but libraries and startup +# code might be missing or require special options that the ld test +# harness doesn't know about. + +proc check_compiler_available { } { + global compiler_available_saved + global CC + + if {![info exists compiler_available_saved]} { + if { [which $CC] == 0 } { + set compiler_available_saved 0 + return 0 + } + + set flags "" + if [board_info [target_info name] exists cflags] { + append flags " [board_info [target_info name] cflags]" + } + if [board_info [target_info name] exists ldflags] { + append flags " [board_info [target_info name] ldflags]" + } + + set basename "tmpdir/compiler[pid]" + set src ${basename}.c + set output ${basename}.out + set f [open $src "w"] + puts $f "int main (void)" + puts $f "{" + puts $f " return 0; " + puts $f "}" + close $f + if [is_remote host] { + set src [remote_download host $src] + } + set compiler_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"] + remote_file host delete $src + remote_file host delete $output + file delete $src + } + return $compiler_available_saved +} + +# Compile and link a C source file for execution on the host. +proc compile_link_one_host_cc { src output additional_args } { + global CC_FOR_HOST + global CFLAGS + + return [run_native_host_cmd "./libtool --quiet --tag=CC --mode=link $CC_FOR_HOST $CFLAGS $src -o $output $additional_args" ] +} + +# Compile a C source file, with the specified additional_flags. +proc compile_one_cc { src output additional_flags } { + global CC + global CFLAGS + + set flags "" + if [board_info [target_info name] exists cflags] { + append flags " [board_info [target_info name] cflags]" + } + if [board_info [target_info name] exists ldflags] { + append flags " [board_info [target_info name] ldflags]" + } + + if [is_remote host] { + set src [remote_download host $src] + } + return [run_host_cmd "$CC" "$flags $CFLAGS $additional_flags $src -o $output"] +} + +# run_lookup_test FILE +# +# Compile with the host compiler and link a .c file into a "lookup" binary, then +# compile and optionally link together a bunch of .s or .c files with CTF info +# and pass the name of the resulting binary to the "lookup" binary and check the +# output. (If none is specified, the binary is expected to generate its own CTF +# for testing purposes.) +# +# As with run_dump_test, this is all driven by a file (in this case, a .lk file) +# beginning with zero or more option lines, which specify the names of the +# lookup binary's source file, the source file(s) with CTF info to compile +# together, and whether to link them. The optional lines have the syntax: +# +# # OPTION: VALUE +# +# OPTION is the name of some option, like "name" or "lookup", and +# VALUE is OPTION's value. The valid options are described below. +# Whitespace is ignored everywhere, except within VALUE. The option +# list ends with the first line that doesn't match the above syntax. +# However, a line within the options that begins with a #, but doesn't +# have a recognizable option name followed by a colon, is considered a +# comment and entirely ignored. +# +# The interesting options are: +# +# name: TEST-NAME +# The name of this test, passed to DejaGNU's `pass' and `fail' +# commands. If omitted, this defaults to FILE, the root of the +# lookup .c file's name. +# +# lookup: SOURCE +# Compile the file SOURCE.c. If omitted, the lookup source defaults +# to FILE.c. +# +# source: SOURCE +# Assemble the file SOURCE.c and pass it to the LOOKUP program. +# +# link: +# If set, link the SOURCE together even if only one file is specified. +# +# link_flags: +# If set, extra flags to pass to the linker. +# +# xfail: GLOB|PROC ... +# This test is expected to fail on a specified list of targets. +# +# Each option may occur at most once unless otherwise mentioned. +# +# After the option lines come regexp lines. run_lookup_test calls +# regexp_diff to compare the output of the lookup program against the +# regexps in FILE.d. +# +proc run_lookup_test { name } { + global CC CFLAGS LIBS + global copyfile env runtests srcdir subdir verbose + + if ![runtest_file_p $runtests $name] then { + return + } + + if [string match "*/*" $name] { + set file $name + set name [file tail $name] + } else { + set file "$srcdir/$subdir/$name" + } + + set opt_array [slurp_options "${file}.lk"] + if { $opt_array == -1 } { + perror "error reading options from $file.lk" + unresolved $subdir/$name + return + } + set run_ld 0 + set opts(link) {} + set opts(link_flags) {} + set opts(lookup) {} + set opts(name) {} + set opts(source) {} + set opts(xfail) {} + + foreach i $opt_array { + set opt_name [lindex $i 0] + set opt_val [lindex $i 1] + if { $opt_name == "" } { + set in_extra 1 + continue + } + if ![info exists opts($opt_name)] { + perror "unknown option $opt_name in file $file.lk" + unresolved $subdir/$name + return + } + + set opts($opt_name) [concat $opts($opt_name) $opt_val] + } + + if { [llength $opts(lookup)] == 0 } { + set opts(lookup) "$file.c" + } else { + set opts(lookup) "[file dirname $file]/$opts(lookup)" + } + + if { [llength $opts(name)] == 0 } { + set opts(name) $opts(lookup) + } + + if { [llength $opts(link)] != 0 + || [llength $opts(source)] > 1 } { + set run_ld 1 + } + + set testname $opts(name) + if { $opts(name) == "" } { + set testname "$subdir/$name" + } + + # Compile and link the lookup program. + set comp_output [compile_link_one_host_cc $opts(lookup) "tmpdir/lookup" "libctf.la"] + + if { $comp_output != ""} { + send_log "compilation of lookup program $opts(lookup) failed with <$comp_output>" + perror "compilation of lookup program $opts(lookup) failed" + fail $testname + return 0 + } + + # Compile the inputs and posibly link them together. + + set lookup_output "" + if { [llength $opts(source)] > 0 } { + set lookup_flags "" + if { $run_ld } { + set lookup_output "tmpdir/out.so" + set lookup_flags "-gt -fPIC -shared $opts(link_flags)" + } else { + set lookup_output "tmpdir/out.o" + set lookup_flags "-gt -fPIC -c" + } + if [board_info [target_info name] exists cflags] { + append lookup_flags " [board_info [target_info name] cflags]" + } + if [board_info [target_info name] exists ldflags] { + append lookup_flags " [board_info [target_info name] ldflags]" + } + set src {} + foreach sfile $opts(source) { + if [is_remote host] { + lappend src [remote_download host [file join [file dirname $file] $sfile]] + } else { + lappend src [file join [file dirname $file] $sfile] + } + } + + set comp_output [run_host_cmd "$CC" "$CFLAGS $lookup_flags [concat $src] -o $lookup_output"] + + if { $comp_output != ""} { + send_log "compilation of CTF program [concat $src] failed with <$comp_output>" + fail $testname + return 0 + } + } + + # Time to setup xfailures. + foreach targ $opts(xfail) { + if [match_target $targ] { + setup_xfail "*-*-*" + break + } + } + + # Invoke the lookup program on the outputs. + + set results [run_host_cmd tmpdir/lookup $lookup_output] + + set f [open "tmpdir/lookup.out" "w"] + puts $f $results + close $f + + if { [regexp_diff "tmpdir/lookup.out" "${file}.lk"] } then { + fail $testname + if { $verbose == 2 } then { verbose "output is [file_contents tmpdir/lookup.out]" 2 } + return 0 + } + + pass $testname + return 0 +} + +# Returns true if the target compiler supports -gt +proc check_ctf_available { } { + global ctf_available_saved + + if {![info exists ctf_available_saved]} { + if { ![check_compiler_available] } { + set ctf_available_saved 0 + } else { + set basename "tmpdir/ctf_available[pid]" + set src ${basename}.c + set output ${basename}.o + set f [open $src "w"] + puts $f "int main() { return 0; }" + close $f + set ctf_available_saved [compile_one_cc $src $output "-gt -c"] + remote_file host delete $src + remote_file host delete $output + file delete $src + } + } + return $ctf_available_saved +} diff --git a/libctf/testsuite/libctf-lookup/ambiguous-struct-A.c b/libctf/testsuite/libctf-lookup/ambiguous-struct-A.c new file mode 100644 index 0000000..67047c4 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/ambiguous-struct-A.c @@ -0,0 +1,8 @@ +struct A; +struct B { struct A *a; }; +struct A { struct B b; long foo; long bar; struct B b2; }; + +typedef struct A a_array[50]; +a_array *foo __attribute__((__used__)); + +static struct A a __attribute ((__used__)); diff --git a/libctf/testsuite/libctf-lookup/ambiguous-struct-B.c b/libctf/testsuite/libctf-lookup/ambiguous-struct-B.c new file mode 100644 index 0000000..95a9346 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/ambiguous-struct-B.c @@ -0,0 +1,5 @@ +struct A; +struct B { struct A *a; }; +struct A { struct B b; int foo; struct B b2; }; + +static struct A a __attribute__((__used__)); diff --git a/libctf/testsuite/libctf-lookup/ambiguous-struct.c b/libctf/testsuite/libctf-lookup/ambiguous-struct.c new file mode 100644 index 0000000..05b471e --- /dev/null +++ b/libctf/testsuite/libctf-lookup/ambiguous-struct.c @@ -0,0 +1,51 @@ +/* Test ambiguous forward lookups post-deduplication. + + This also makes sure that deduplication succeeds in this case and does not + throw spurious errors. */ + +#include <ctf-api.h> +#include <stdio.h> +#include <stdlib.h> + +int +main (int argc, char *argv[]) +{ + ctf_dict_t *fp; + ctf_archive_t *ctf; + ctf_id_t type; + ctf_arinfo_t ar; + int err; + + if (argc != 2) + { + fprintf (stderr, "Syntax: %s PROGRAM\n", argv[0]); + exit(1); + } + + if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL) + goto open_err; + if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL) + goto open_err; + + /* Dig out the array type and resolve its element type. */ + + if ((type = ctf_lookup_by_name (fp, "a_array") ) == CTF_ERR) + goto err; + if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) + goto err; + if (ctf_array_info (fp, type, &ar) < 0) + goto err; + printf ("Kind of array element is %i\n", ctf_type_kind (fp, ar.ctr_contents)); + + ctf_dict_close (fp); + ctf_close (ctf); + + return 0; + + open_err: + fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err)); + return 1; + err: + fprintf (stderr, "Lookup failed: %s\n", ctf_errmsg (ctf_errno (fp))); + return 1; +} diff --git a/libctf/testsuite/libctf-lookup/ambiguous-struct.lk b/libctf/testsuite/libctf-lookup/ambiguous-struct.lk new file mode 100644 index 0000000..84f296d --- /dev/null +++ b/libctf/testsuite/libctf-lookup/ambiguous-struct.lk @@ -0,0 +1,4 @@ +# source: ambiguous-struct-A.c +# source: ambiguous-struct-B.c +# link: on +Kind of array element is 9 diff --git a/libctf/testsuite/libctf-lookup/enum-ctf.c b/libctf/testsuite/libctf-lookup/enum-ctf.c new file mode 100644 index 0000000..aa60d72 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/enum-ctf.c @@ -0,0 +1,8 @@ +/* Looked up item by item. */ +enum e { ENUMSAMPLE_1 = 0, ENUMSAMPLE_2 = 1 }; + +/* Looked up via both sorts of iterator in turn. */ +enum ie { IENUMSAMPLE_1 = -10, IENUMSAMPLE_2, IENUMSAMPLE_3 }; + +enum e foo; +enum ie bar; diff --git a/libctf/testsuite/libctf-lookup/enum.c b/libctf/testsuite/libctf-lookup/enum.c new file mode 100644 index 0000000..1804b23 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/enum.c @@ -0,0 +1,78 @@ +#include <ctf-api.h> +#include <stdio.h> +#include <stdlib.h> + +static int +print_enum (const char *name, int val, void *unused) +{ + printf ("iter test: %s has value %i\n", name, val); + return 0; +} + +int +main (int argc, char *argv[]) +{ + ctf_dict_t *fp; + ctf_archive_t *ctf; + ctf_id_t type; + const char *name; + ctf_next_t *i = NULL; + int val; + int err; + + if (argc != 2) + { + fprintf (stderr, "Syntax: %s PROGRAM\n", argv[0]); + exit(1); + } + + if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL) + goto open_err; + if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL) + goto open_err; + + /* Try getting some enum values by hand. */ + + if ((type = ctf_lookup_by_name (fp, "enum e") ) == CTF_ERR) + goto err; + if (ctf_enum_value (fp, type, "ENUMSAMPLE_1", &val) < 0) + goto err; + printf ("Enum e enumerand ENUMSAMPLE_1 has value %i\n", val); + + if ((name = ctf_enum_name (fp, type, 1)) == NULL) + goto err; + printf ("Enum e enumerand %s has value 1\n", name); + + /* Try getting some values using both sorts of iterator. */ + + if ((type = ctf_lookup_by_name (fp, "enum ie") ) == CTF_ERR) + goto err; + + if ((ctf_enum_iter (fp, type, print_enum, NULL)) < 0) + goto ierr; + + while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL) + { + printf ("next test: %s has value %i\n", name, val); + } + if (ctf_errno (fp) != ECTF_NEXT_END) + goto nerr; + + ctf_dict_close (fp); + ctf_close (ctf); + + return 0; + + open_err: + fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err)); + return 1; + err: + fprintf (stderr, "Lookup failed: %s\n", ctf_errmsg (ctf_errno (fp))); + return 1; + ierr: + fprintf (stderr, "_iter iteration failed: %s\n", ctf_errmsg (ctf_errno (fp))); + return 1; + nerr: + fprintf (stderr, "_next iteration failed: %s\n", ctf_errmsg (ctf_errno (fp))); + return 1; +} diff --git a/libctf/testsuite/libctf-lookup/enum.lk b/libctf/testsuite/libctf-lookup/enum.lk new file mode 100644 index 0000000..0b2b157 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/enum.lk @@ -0,0 +1,10 @@ +# source: enum-ctf.c +# link: on +Enum e enumerand ENUMSAMPLE_1 has value 0 +Enum e enumerand ENUMSAMPLE_2 has value 1 +iter test: IENUMSAMPLE_1 has value -10 +iter test: IENUMSAMPLE_2 has value -9 +iter test: IENUMSAMPLE_3 has value -8 +next test: IENUMSAMPLE_1 has value -10 +next test: IENUMSAMPLE_2 has value -9 +next test: IENUMSAMPLE_3 has value -8 diff --git a/libctf/testsuite/libctf-lookup/lookup.exp b/libctf/testsuite/libctf-lookup/lookup.exp new file mode 100644 index 0000000..51ad257 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/lookup.exp @@ -0,0 +1,43 @@ +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +if ![is_elf_format] { + unsupported "CTF needs bfd changes to be emitted on non-ELF" + return 0 +} + +if {[info exists env(LC_ALL)]} { + set old_lc_all $env(LC_ALL) +} +set env(LC_ALL) "C" + +set ctf_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.lk]] + +foreach ctf_test $ctf_test_list { + verbose [file rootname $ctf_test] + verbose running lookup test on $ctf_test + run_lookup_test [file rootname $ctf_test] +} + +if {[info exists old_lc_all]} { + set env(LC_ALL) $old_lc_all +} else { + unset env(LC_ALL) +} |