Compare commits

...

16 Commits

Author SHA1 Message Date
Indu Bhagat
28ce839819 testsuite: libsframest: more renames
and fixing some formatting issues.

ChangeLog:
	* include/sframe-stacktrace-api.h
	* sframe-stacktrace.c
	* sframe-state.c
	* sframe-state.h
2025-03-23 12:04:06 -07:00
Indu Bhagat
828794e2f2 testsuite: libsframest: create new sframest_sfinfo_init
ChangeLog:
	* sframe-state.c
	* sframe-state.h
2025-03-23 12:04:06 -07:00
Indu Bhagat
b8dae559ae testsuite: libsframest: define a new function sframest_sfinfo_addr_range_p
Use this function consistently and remove unnecessary API
sframest_update_sfinfo.

ChangeLog:
	* sframe-stacktrace.c
	* sframe-state.c
	* sframe-state.h
2025-03-23 12:04:06 -07:00
Indu Bhagat
ef0c1ae194 more renames for readability
ChangeLog:
	* sframe-stacktrace.c
	* sframe-state.c
	* sframe-state.h
2025-03-23 12:04:06 -07:00
Indu Bhagat
cd1a49b3c2 testsuite: libsframest: rename for readability
Some struct names and member names were long and unintuitive.  Reduce
the technical debt and make the code hopefully easier to maintain.

libsframe/testsuite/
	* libsframe.stacktrace/libsframest/sframe-stacktrace.c
	* libsframe.stacktrace/libsframest/sframe-state.c
	* libsframe.stacktrace/libsframest/sframe-state.h
2025-03-23 12:04:06 -07:00
Indu Bhagat
1d65150c46 testsuite: libsframest: use shorter version in conditionals
libsframe/testsuite/

	* libsframe.stacktrace/libsframest/sframe-stacktrace.c
	* libsframe.stacktrace/libsframest/sframe-state.c
2025-03-23 12:04:06 -07:00
Indu Bhagat
e2ee611cd0 libsframest: use access API instead of direct access using FRE info
libsframe/testsuite/

            * libsframe.stacktrace/libsframest/sframe-backtrace.c
2025-03-23 12:04:06 -07:00
Indu Bhagat
1b88cb4a5e lisbframest: remove unnecessary arch-specific code
ChangeLog:
	* libsframe/testsuite/libsframe.stacktrace/libsframest
	/sframe-stacktrace.c (sframe_unwind): Remove unnecessary guards
	and arch-specific handling.
2025-03-23 12:04:06 -07:00
Indu Bhagat
8b9d48ef52 testsuite: minor housekeeping
Fix some code formatting nits.

libsframe/testsuite/

        * libsframe.stacktrace/libsframest/sframe-stacktrace-err.c:
        * libsframe.stacktrace/libsframest/sframe-stacktrace.c:
        * libsframe.stacktrace/libsframest/sframe-state.c:
        * libsframe.stacktrace/libsframest/sframe-state.h:
        * libsframe.stacktrace/stacktrace-inline-2.c:
2025-03-23 12:04:06 -07:00
Indu Bhagat
fafb1fafdb testsuite: libsframest: use as, ld, collect-ld from build dir
instead of host's as and ld.  Also disable libsframest build if cross
compiling.  The testsuite will consequently also be skipped.

Override the check-am make target and first execute setup.sh to bring in
the as-new / ld-new and use -B<path> to ensure these are picked up for
building:
  - libsframest
  - libsframe.stacktrace testsuite

Remove the configure time variable HAVE_SFRAME_AS as it is now
unnecessary.

TBD:
  - Get review on whether the whole setup.sh way of doing this is OK.
    But it seems there is no other way ?
  - Check the portability of the setup.sh script.

ChangeLog:
	* libsframe/Makefile.am: Override check-am to first run setup.sh
	before invoking make.  This ensures libsframest is built with
	the newly setup tmpdir/libsframe.
	* libsframe/Makefile.in: Regenerate.
	* libsframe/acinclude.m4: Delete.
	* libsframe/aclocal.m4: Remove include for acinclude.m4.
	* libsframe/configure: Regenerate.
	* libsframe/configure.ac: Remove HAVE_SFRAME_AS.  Add a new
	AM_CONDITIONAL for CROSS_COMPILE.
	* libsframe/setup.sh: New file.
	* libsframe/testsuite/config/default.exp: Remove the creation
	and setup of tmpdir/lisframe.
	* libsframe/testsuite/lib/sframe-lib.exp: Use -B<path> to use
	the as/ld from build tree.
	* libsframe/testsuite/libsframe.stacktrace/libsframest/local.mk:
	Use -B<path> and use the as/ld from build tree.
	* libsframe/testsuite/libsframe.stacktrace/stacktrace.exp: Skip
	testing if cross build.
2025-03-23 12:04:01 -07:00
Indu Bhagat
d327bb48a8 libsframest: use as a test tool instead
Add a configure time check for dl_iterate_phdr and run
libsframe.stacktrace testsuite using libsframest.  libsframest is the
library for stack tracing using the SFrame stack trace format.

libsframest is not installed anymore but used in the testsuite only.

TBD:
  - More renamings are in order.
  - Cleanup the .exp files.
  - Disable (libsframest based) stack tracer tests in a cross build
2025-03-23 11:42:06 -07:00
Indu Bhagat
22781a16ab testsuite: sframebt: Add backtrace-1 which uses -O2 always
Keep a testcase with an explicit -O2 for testing purposes.
2025-03-23 11:42:06 -07:00
Weimin Pan
e73921d00f testsuite: sframebt: Use -fno-optimize-sibling-calls
With -O2 and above, the compiler performs a sibling call optimization as
main () and it's callee have compatible stack usage.  As for generating
stack traces though, there is nothing that any stack trace or unwind
format can do here.  Use -fno-optimize-sibling-calls to at least ensure
the testcase checkes for the complete stack trace.

ChangeLog:

	* libsframe/testsuite/libsframe.unwind/backtrace-fp-attr-1.lk:
	Use -fno-optimize-sibling-calls.
	* libsframe/testsuite/libsframe.unwind/backtrace-fp-attr-2.lk:
	Likewise.
2025-03-23 11:42:06 -07:00
Weimin Pan
e409b5efef sframebt: Factor register access code into a header file
ChangeLog:

	* libsframe/sframe-backtrace-regs.h: New file.
	* libsframe/sframe-backtrace.c: Use the new abstractions.
2025-03-23 11:42:06 -07:00
Weimin Pan
bb188a0619 unwinder: Add SFrame unwinder tests
[Changes in V4]
  - Addressed Mike's review comments.
    - Be careful with the use of # and dnl in configure.ac
    - Add AC_CANONICAL_TARGET as we check for target.
    - Remove the LC_ALL=C bits.
  - Minor code fixups in the testcases
    - Removed unnecessary unistd.h.
    - use ATTRIBUTE_NOCLONE consistently.
    - Other minor cleanups.
[End of changes in V4]

[Changes in V3]
  - Added two new tests with attributes -f(no-)omit-frame-pointer.
  - Minor adjustments due to buildsystem changes in libsframe.
[End of changes in V3]

[Changes in V2]
  - minor changes in filenames in the testsuite.
[End of changes in V2]

Add tests for backtracing using SFrame section.

ChangeLog:

	* libsframe/Makefile.in: Regenerated.
	* libsframe/configure: Regenerated.
	* libsframe/configure.ac: Check for cross compilation.
	* libsframe/testsuite/Makefile.in: Regenerated.
	* libsframe/testsuite/config/default.exp: Load
	  sframe-lib.exp.
	* libsframe/testsuite/libsframe.decode/Makefile.in:
	  Regenerated.
	* libsframe/testsuite/libsframe.encode/Makefile.in:
	  Regenerated.
	* libsframe/testsuite/lib/sframe-lib.exp: New file.  Add
	  procedures for handling unwinder tests.
	* libsframe/testsuite/libsframe.unwind/backtrace.c: New test.
	* libsframe/testsuite/libsframe.unwind/backtrace.lk: New test.
	* libsframe/testsuite/libsframe.unwind/inline-cmds.c: New test.
	* libsframe/testsuite/libsframe.unwind/inline-cmds.lk: New test.
	* libsframe/testsuite/libsframe.unwind/inline.c: New test.
	* libsframe/testsuite/libsframe.unwind/inline.lk: New test.
	* libsframe/testsuite/libsframe.unwind/solib-lib1.c: New test.
	* libsframe/testsuite/libsframe.unwind/solib-lib2.c: New test.
	* libsframe/testsuite/libsframe.unwind/solib-main.c: New test.
	* libsframe/testsuite/libsframe.unwind/solib-main.d: New test.
	* libsframe/testsuite/libsframe.unwind/solib.exp: New file.
	* libsframe/testsuite/libsframe.unwind/solib-lib1.h: New test.
	* libsframe/testsuite/libsframe.unwind/solib-lib2.h: New test.
	* libsframe/testsuite/libsframe.unwind/tailcall.c: New test.
	* libsframe/testsuite/libsframe.unwind/tailcall.lk: New test.
	* libsframe/testsuite/libsframe.unwind/ttest.c: New test.
	* libsframe/testsuite/libsframe.unwind/ttest.lk: New test.
	* libsframe/testsuite/libsframe.unwind/unwind.exp: New file.
	* libsframe/testsuite/libsframe.unwind/backtrace-fp-attr-1.c:
	  Likewise.
	* libsframe/testsuite/libsframe.unwind/backtrace-fp-attr-1.lk:
	  Likewise.
	* libsframe/testsuite/libsframe.unwind/backtrace-fp-attr-2.c:
	  Likewise.
	* libsframe/testsuite/libsframe.unwind/backtrace-fp-attr-2.lk:
	  Likewise.
2025-03-23 11:42:04 -07:00
Weimin Pan
5abc6d9265 unwinder: generate backtrace using SFrame format
[Changes in V4]
  - Renamed ESFRAME_* enum error code names to SFRAME_ERR_*.
  - Addressed review comments by Mike.
    - Use AC_CACHE_CHECK macro in sframe.m4
    - Delete config/sframe.m4. Add into libsframe/acinclude.m4.
    - Code fixups.
[End of changes in V4]

[Changes in V3]
  - Use the updated APIs from libsframe.
  - Use sframe_decoder_get_fixed_ra_offset on AMD64 instead of magic
    number -8.
[End of changes in V3]

[Changes in V2]
  - Minor formatting fixes.
[End of changes in V2]

A simple unwinder based on SFrame format.

The unwinder is made available via libsframebt library.

Buildsystem changes have been made to build libsframebt only when
--gsframe support is available in the assembler. These buildsystem
changes are necessary because the SFrame based unwinder the SFrame
unwind info for itself to work.

include/ChangeLog:

	* sframe-backtrace-api.h: New file.

ChangeLog:

	* libsframe/acinclude.m4: New file.
	* libsframe/Makefile.am: Build backtrace functionality in its
	own library.  Install libsframebt conditionally.
	* libsframe/Makefile.in: Regenerate.
	* libsframe/aclocal.m4: Regenerate.
	* libsframe/configure: Regenerate.
	* libsframe/configure.ac: Check if gas supports --gsframe
	command line option.
	* libsframe/sframe-backtrace-err.c: New file.
	* libsframe/sframe-backtrace.c: New file.
2025-03-23 11:32:25 -07:00
42 changed files with 2688 additions and 33 deletions

View File

@@ -55,6 +55,10 @@ libsframe_la_LDFLAGS = $(libsframe_version_info) $(libsframe_version_script)
EXTRA_DIST = libtool-version libsframe.ver
diststuff: $(EXTRA_DIST) info
check-am: all-am setup.sh
$(SHELL) $(srcdir)/setup.sh
$(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
include doc/local.mk

View File

@@ -119,6 +119,9 @@ check_PROGRAMS = $(am__EXEEXT_1)
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.find/findfre-1 \
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.find/findfunc-1 \
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.find/plt-findfre-1
# Build libsframest only when not cross-building
@CROSS_COMPILE_FALSE@@HAVE_DL_ITERATE_PHDR_TRUE@am__append_5 = testsuite/libsframe.stacktrace/libsframest/libsframest.la
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \
@@ -187,6 +190,21 @@ libsframe_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(libsframe_la_LDFLAGS) $(LDFLAGS) -o $@
@INSTALL_LIBBFD_FALSE@am_libsframe_la_rpath =
@INSTALL_LIBBFD_TRUE@am_libsframe_la_rpath = -rpath $(libdir)
testsuite_libsframe_stacktrace_libsframest_libsframest_la_DEPENDENCIES = \
${top_builddir}/libsframe.la
am__dirstamp = $(am__leading_dot)dirstamp
am_testsuite_libsframe_stacktrace_libsframest_libsframest_la_OBJECTS = testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.lo \
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.lo \
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.lo
testsuite_libsframe_stacktrace_libsframest_libsframest_la_OBJECTS = $(am_testsuite_libsframe_stacktrace_libsframest_libsframest_la_OBJECTS)
testsuite_libsframe_stacktrace_libsframest_libsframest_la_LINK = \
$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS) \
$(CFLAGS) \
$(testsuite_libsframe_stacktrace_libsframest_libsframest_la_LDFLAGS) \
$(LDFLAGS) -o $@
@CROSS_COMPILE_FALSE@@HAVE_DL_ITERATE_PHDR_TRUE@am_testsuite_libsframe_stacktrace_libsframest_libsframest_la_rpath =
@HAVE_COMPAT_DEJAGNU_TRUE@am__EXEEXT_1 = testsuite/libsframe.decode/be-flipping$(EXEEXT) \
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.decode/frecnt-1$(EXEEXT) \
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.decode/frecnt-2$(EXEEXT) \
@@ -194,7 +212,6 @@ libsframe_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.find/findfre-1$(EXEEXT) \
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.find/findfunc-1$(EXEEXT) \
@HAVE_COMPAT_DEJAGNU_TRUE@ testsuite/libsframe.find/plt-findfre-1$(EXEEXT)
am__dirstamp = $(am__leading_dot)dirstamp
am_testsuite_libsframe_decode_be_flipping_OBJECTS = testsuite/libsframe.decode/testsuite_libsframe_decode_be_flipping-be-flipping.$(OBJEXT)
testsuite_libsframe_decode_be_flipping_OBJECTS = \
$(am_testsuite_libsframe_decode_be_flipping_OBJECTS)
@@ -265,6 +282,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libsframe_la_SOURCES) \
$(testsuite_libsframe_stacktrace_libsframest_libsframest_la_SOURCES) \
$(testsuite_libsframe_decode_be_flipping_SOURCES) \
$(testsuite_libsframe_decode_frecnt_1_SOURCES) \
$(testsuite_libsframe_decode_frecnt_2_SOURCES) \
@@ -273,6 +291,7 @@ SOURCES = $(libsframe_la_SOURCES) \
$(testsuite_libsframe_find_findfunc_1_SOURCES) \
$(testsuite_libsframe_find_plt_findfre_1_SOURCES)
DIST_SOURCES = $(libsframe_la_SOURCES) \
$(testsuite_libsframe_stacktrace_libsframest_libsframest_la_SOURCES) \
$(testsuite_libsframe_decode_be_flipping_SOURCES) \
$(testsuite_libsframe_decode_frecnt_1_SOURCES) \
$(testsuite_libsframe_decode_frecnt_2_SOURCES) \
@@ -356,6 +375,8 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(srcdir)/testsuite/libsframe.decode/local.mk \
$(srcdir)/testsuite/libsframe.encode/local.mk \
$(srcdir)/testsuite/libsframe.find/local.mk \
$(srcdir)/testsuite/libsframe.stacktrace/libsframest/local.mk \
$(srcdir)/testsuite/libsframe.stacktrace/local.mk \
$(srcdir)/testsuite/local.mk $(top_srcdir)/../ar-lib \
$(top_srcdir)/../compile $(top_srcdir)/../config.guess \
$(top_srcdir)/../config.sub $(top_srcdir)/../depcomp \
@@ -392,6 +413,7 @@ CFLAGS = @CFLAGS@
COMPAT_DEJAGNU = @COMPAT_DEJAGNU@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CROSS_COMPILE = @CROSS_COMPILE@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -569,6 +591,21 @@ testsuite_libsframe_find_findfunc_1_CPPFLAGS = -I${top_srcdir}/../include -Wall
testsuite_libsframe_find_plt_findfre_1_SOURCES = testsuite/libsframe.find/plt-findfre-1.c
testsuite_libsframe_find_plt_findfre_1_LDADD = ${top_builddir}/libsframe.la
testsuite_libsframe_find_plt_findfre_1_CPPFLAGS = -I${top_srcdir}/../include -Wall
check_LTLIBRARIES = $(am__append_5)
testsuite_libsframe_stacktrace_libsframest_libsframest_la_SOURCES = testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c \
testsuite/libsframe.stacktrace/libsframest/sframe-state.c \
testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-err.c
testsuite_libsframe_stacktrace_libsframest_libsframest_la_LIBADD = ${top_builddir}/libsframe.la
testsuite_libsframe_stacktrace_libsframest_libsframest_la_CPPFLAGS = -I${top_srcdir}/../include \
-I${top_srcdir}/testsuite/libsframe.stacktrace/libsframest/include \
-B${top_builddir}/tmpdir/libsframe \
-Wall -Wno-unused-but-set-variable
testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS = -B${top_builddir}/tmpdir/libsframe \
-Wa,--gsframe
testsuite_libsframe_stacktrace_libsframest_libsframest_la_LDFLAGS = -B${top_builddir}/tmpdir/libsframe
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -576,7 +613,7 @@ all: config.h
.SUFFIXES: .c .dvi .lo .o .obj .ps
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/doc/local.mk $(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(srcdir)/testsuite/libsframe.find/local.mk $(am__configure_deps)
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/doc/local.mk $(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(srcdir)/testsuite/libsframe.find/local.mk $(srcdir)/testsuite/libsframe.stacktrace/local.mk $(srcdir)/testsuite/libsframe.stacktrace/libsframest/local.mk $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -598,7 +635,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(srcdir)/doc/local.mk $(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(srcdir)/testsuite/libsframe.find/local.mk $(am__empty):
$(srcdir)/doc/local.mk $(srcdir)/testsuite/local.mk $(srcdir)/testsuite/libsframe.decode/local.mk $(srcdir)/testsuite/libsframe.encode/local.mk $(srcdir)/testsuite/libsframe.find/local.mk $(srcdir)/testsuite/libsframe.stacktrace/local.mk $(srcdir)/testsuite/libsframe.stacktrace/libsframest/local.mk $(am__empty):
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
@@ -624,6 +661,17 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
distclean-hdr:
-rm -f config.h stamp-h1
clean-checkLTLIBRARIES:
-test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
@list='$(check_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
@@ -672,6 +720,24 @@ clean-noinstLTLIBRARIES:
libsframe.la: $(libsframe_la_OBJECTS) $(libsframe_la_DEPENDENCIES) $(EXTRA_libsframe_la_DEPENDENCIES)
$(AM_V_CCLD)$(libsframe_la_LINK) $(am_libsframe_la_rpath) $(libsframe_la_OBJECTS) $(libsframe_la_LIBADD) $(LIBS)
testsuite/libsframe.stacktrace/libsframest/$(am__dirstamp):
@$(MKDIR_P) testsuite/libsframe.stacktrace/libsframest
@: > testsuite/libsframe.stacktrace/libsframest/$(am__dirstamp)
testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)
@: > testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/$(am__dirstamp)
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.lo: \
testsuite/libsframe.stacktrace/libsframest/$(am__dirstamp) \
testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/$(am__dirstamp)
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.lo: \
testsuite/libsframe.stacktrace/libsframest/$(am__dirstamp) \
testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/$(am__dirstamp)
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.lo: \
testsuite/libsframe.stacktrace/libsframest/$(am__dirstamp) \
testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/$(am__dirstamp)
testsuite/libsframe.stacktrace/libsframest/libsframest.la: $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_OBJECTS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_DEPENDENCIES) $(EXTRA_testsuite_libsframe_stacktrace_libsframest_libsframest_la_DEPENDENCIES) testsuite/libsframe.stacktrace/libsframest/$(am__dirstamp)
$(AM_V_CCLD)$(testsuite_libsframe_stacktrace_libsframest_libsframest_la_LINK) $(am_testsuite_libsframe_stacktrace_libsframest_libsframest_la_rpath) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_OBJECTS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_LIBADD) $(LIBS)
clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
@@ -754,6 +820,8 @@ mostlyclean-compile:
-rm -f testsuite/libsframe.decode/*.$(OBJEXT)
-rm -f testsuite/libsframe.encode/*.$(OBJEXT)
-rm -f testsuite/libsframe.find/*.$(OBJEXT)
-rm -f testsuite/libsframe.stacktrace/libsframest/*.$(OBJEXT)
-rm -f testsuite/libsframe.stacktrace/libsframest/*.lo
distclean-compile:
-rm -f *.tab.c
@@ -768,6 +836,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.find/$(DEPDIR)/testsuite_libsframe_find_findfre_1-findfre-1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.find/$(DEPDIR)/testsuite_libsframe_find_findfunc_1-findfunc-1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.find/$(DEPDIR)/testsuite_libsframe_find_plt_findfre_1-plt-findfre-1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -814,6 +885,27 @@ libsframe_la-sframe-error.lo: sframe-error.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsframe_la-sframe-error.lo `test -f 'sframe-error.c' || echo '$(srcdir)/'`sframe-error.c
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.lo: testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CPPFLAGS) $(CPPFLAGS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS) $(CFLAGS) -MT testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.lo -MD -MP -MF testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.Tpo -c -o testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.lo `test -f 'testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c' || echo '$(srcdir)/'`testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.Tpo testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c' object='testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CPPFLAGS) $(CPPFLAGS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS) $(CFLAGS) -c -o testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace.lo `test -f 'testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c' || echo '$(srcdir)/'`testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.lo: testsuite/libsframe.stacktrace/libsframest/sframe-state.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CPPFLAGS) $(CPPFLAGS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS) $(CFLAGS) -MT testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.lo -MD -MP -MF testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.Tpo -c -o testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.lo `test -f 'testsuite/libsframe.stacktrace/libsframest/sframe-state.c' || echo '$(srcdir)/'`testsuite/libsframe.stacktrace/libsframest/sframe-state.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.Tpo testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testsuite/libsframe.stacktrace/libsframest/sframe-state.c' object='testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CPPFLAGS) $(CPPFLAGS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS) $(CFLAGS) -c -o testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-state.lo `test -f 'testsuite/libsframe.stacktrace/libsframest/sframe-state.c' || echo '$(srcdir)/'`testsuite/libsframe.stacktrace/libsframest/sframe-state.c
testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.lo: testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-err.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CPPFLAGS) $(CPPFLAGS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS) $(CFLAGS) -MT testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.lo -MD -MP -MF testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.Tpo -c -o testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.lo `test -f 'testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-err.c' || echo '$(srcdir)/'`testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-err.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.Tpo testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-err.c' object='testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CPPFLAGS) $(CPPFLAGS) $(testsuite_libsframe_stacktrace_libsframest_libsframest_la_CFLAGS) $(CFLAGS) -c -o testsuite/libsframe.stacktrace/libsframest/testsuite_libsframe_stacktrace_libsframest_libsframest_la-sframe-stacktrace-err.lo `test -f 'testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-err.c' || echo '$(srcdir)/'`testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-err.c
testsuite/libsframe.decode/testsuite_libsframe_decode_be_flipping-be-flipping.o: testsuite/libsframe.decode/be-flipping.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testsuite_libsframe_decode_be_flipping_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testsuite/libsframe.decode/testsuite_libsframe_decode_be_flipping-be-flipping.o -MD -MP -MF testsuite/libsframe.decode/$(DEPDIR)/testsuite_libsframe_decode_be_flipping-be-flipping.Tpo -c -o testsuite/libsframe.decode/testsuite_libsframe_decode_be_flipping-be-flipping.o `test -f 'testsuite/libsframe.decode/be-flipping.c' || echo '$(srcdir)/'`testsuite/libsframe.decode/be-flipping.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) testsuite/libsframe.decode/$(DEPDIR)/testsuite_libsframe_decode_be_flipping-be-flipping.Tpo testsuite/libsframe.decode/$(DEPDIR)/testsuite_libsframe_decode_be_flipping-be-flipping.Po
@@ -920,6 +1012,7 @@ clean-libtool:
-rm -rf testsuite/libsframe.decode/.libs testsuite/libsframe.decode/_libs
-rm -rf testsuite/libsframe.encode/.libs testsuite/libsframe.encode/_libs
-rm -rf testsuite/libsframe.find/.libs testsuite/libsframe.find/_libs
-rm -rf testsuite/libsframe.stacktrace/libsframest/.libs testsuite/libsframe.stacktrace/libsframest/_libs
distclean-libtool:
-rm -f libtool config.lt
@@ -1342,7 +1435,7 @@ distcleancheck: distclean
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
check: check-am
all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(HEADERS) config.h
@@ -1383,6 +1476,8 @@ distclean-generic:
-rm -f testsuite/libsframe.encode/$(am__dirstamp)
-rm -f testsuite/libsframe.find/$(DEPDIR)/$(am__dirstamp)
-rm -f testsuite/libsframe.find/$(am__dirstamp)
-rm -f testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)/$(am__dirstamp)
-rm -f testsuite/libsframe.stacktrace/libsframest/$(am__dirstamp)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@@ -1392,13 +1487,13 @@ maintainer-clean-generic:
@BUILD_INFO_FALSE@html-local:
clean: clean-am
clean-am: clean-aminfo clean-checkPROGRAMS clean-generic \
clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
clean-am: clean-aminfo clean-checkLTLIBRARIES clean-checkPROGRAMS \
clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf ./$(DEPDIR) testsuite/libsframe.decode/$(DEPDIR) testsuite/libsframe.encode/$(DEPDIR) testsuite/libsframe.find/$(DEPDIR)
-rm -rf ./$(DEPDIR) testsuite/libsframe.decode/$(DEPDIR) testsuite/libsframe.encode/$(DEPDIR) testsuite/libsframe.find/$(DEPDIR) testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-DEJAGNU distclean-compile \
distclean-generic distclean-hdr distclean-libtool \
@@ -1538,7 +1633,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -rf ./$(DEPDIR) testsuite/libsframe.decode/$(DEPDIR) testsuite/libsframe.encode/$(DEPDIR) testsuite/libsframe.find/$(DEPDIR)
-rm -rf ./$(DEPDIR) testsuite/libsframe.decode/$(DEPDIR) testsuite/libsframe.encode/$(DEPDIR) testsuite/libsframe.find/$(DEPDIR) testsuite/libsframe.stacktrace/libsframest/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
maintainer-clean-generic
@@ -1563,15 +1658,16 @@ uninstall-am: uninstall-dvi-am uninstall-html-am \
.MAKE: all check-am install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-DEJAGNU \
check-am clean clean-aminfo clean-checkPROGRAMS clean-cscope \
clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstLTLIBRARIES cscope cscopelist-am ctags ctags-am \
dist dist-all dist-bzip2 dist-gzip dist-info 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 html-local \
info info-am install install-am install-data install-data-am \
check-am clean clean-aminfo clean-checkLTLIBRARIES \
clean-checkPROGRAMS clean-cscope clean-generic \
clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
dist-gzip dist-info 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 html-local 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 \
@@ -1588,6 +1684,10 @@ uninstall-am: uninstall-dvi-am uninstall-html-am \
.PRECIOUS: Makefile
diststuff: $(EXTRA_DIST) info
check-am: all-am setup.sh
$(SHELL) $(srcdir)/setup.sh
$(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
@BUILD_INFO_TRUE@html-local: doc/sframe-spec/index.html
@BUILD_INFO_TRUE@doc/sframe-spec/index.html: doc/sframe-spec.texi doc/$(am__dirstamp)
@@ -1609,12 +1709,13 @@ check-DEJAGNU: site.exp
CC="$(CC)" \
CROSS_COMPILE="$(CROSS_COMPILE)" \
COMPAT_DEJAGNU="$(COMPAT_DEJAGNU)" \
CFLAGS="$(CFLAGS) -I$(top_srcdir)/../include -I$(top_srcdir) -I$(top_builddir)" \
HAVE_DL_ITERATE_PHDR="$(HAVE_DL_ITERATE_PHDR)" \
CFLAGS="$(CFLAGS) -I$(top_srcdir)/../include -I$(top_srcdir) -I$(top_srcdir)/testsuite/libsframe.stacktrace/libsframest/include -I$(top_builddir)" \
$(RUNTESTFLAGS); \
else echo "WARNING: could not find \`runtest'" 1>&2; :;\
fi
# libsframe encoder/decoder/find testsuite
# libsframe encoder/decoder/stacktracer testsuite
# 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.

View File

@@ -3,6 +3,9 @@
/* Define to 1 if you have the <byteswap.h> header file. */
#undef HAVE_BYTESWAP_H
/* Define to 1 if you have the declaration of `', and to 0 if you don't. */
#undef HAVE_DECL_
/* Define to 1 if you have the declaration of `bswap_16', and to 0 if you
don't. */
#undef HAVE_DECL_BSWAP_16
@@ -18,6 +21,9 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if dl_iterate_phdr is available. */
#undef HAVE_DL_ITERATE_PHDR
/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
@@ -27,6 +33,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <link.h> header file. */
#undef HAVE_LINK_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

97
libsframe/configure vendored
View File

@@ -634,6 +634,8 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
HAVE_DL_ITERATE_PHDR_FALSE
HAVE_DL_ITERATE_PHDR_TRUE
bfdincludedir
bfdlibdir
target_noncanonical
@@ -643,6 +645,9 @@ INSTALL_LIBBFD_TRUE
MAINT
MAINTAINER_MODE_FALSE
MAINTAINER_MODE_TRUE
CROSS_COMPILE_FALSE
CROSS_COMPILE_TRUE
CROSS_COMPILE
HAVE_LD_VERSION_SCRIPT_FALSE
HAVE_LD_VERSION_SCRIPT_TRUE
HAVE_SOLARIS_LD_FALSE
@@ -2417,6 +2422,7 @@ test -n "$target_alias" &&
NONENONEs,x,x, &&
program_prefix=${target_alias}-
# Expand $ac_aux_dir to an absolute path.
am_aux_dir=`cd "$ac_aux_dir" && pwd`
@@ -11563,7 +11569,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 11566 "configure"
#line 11572 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11669,7 +11675,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 11672 "configure"
#line 11678 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12464,6 +12470,24 @@ fi
is_cross_compiler=
if test x"${host}" = x"${target}" ; then
is_cross_compiler=no
else
is_cross_compiler=yes
fi
CROSS_COMPILE=$is_cross_compiler
if test "is_cross_compiler" = "yes"; then
CROSS_COMPILE_TRUE=
CROSS_COMPILE_FALSE='#'
else
CROSS_COMPILE_TRUE='#'
CROSS_COMPILE_FALSE=
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
# Check whether --enable-maintainer-mode was given.
@@ -12798,6 +12822,67 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
for ac_header in link.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "link.h" "ac_cv_header_link_h" "$ac_includes_default"
if test "x$ac_cv_header_link_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LINK_H 1
_ACEOF
fi
done
if test "$ac_cv_header_link_h" = "no"; then
have_dl_iterate_phdr=no
else
ac_fn_c_check_func "$LINENO" "dl_iterate_phdr" "ac_cv_func_dl_iterate_phdr"
if test "x$ac_cv_func_dl_iterate_phdr" = xyes; then :
have_dl_iterate_phdr=yes
else
have_dl_iterate_phdr=no
fi
fi
if test "$have_dl_iterate_phdr" = "yes"; then
$as_echo "#define HAVE_DL_ITERATE_PHDR 1" >>confdefs.h
fi
if test "x$have_dl_iterate_phdr" = "xyes"; then
HAVE_DL_ITERATE_PHDR_TRUE=
HAVE_DL_ITERATE_PHDR_FALSE='#'
else
HAVE_DL_ITERATE_PHDR_TRUE='#'
HAVE_DL_ITERATE_PHDR_FALSE=
fi
for ac_header in link.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "link.h" "ac_cv_header_link_h" "$ac_includes_default"
if test "x$ac_cv_header_link_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LINK_H 1
_ACEOF
fi
done
ac_fn_c_check_decl "$LINENO" "" "ac_cv_have_decl_" "$ac_includes_default"
if test "x$ac_cv_have_decl_" = xyes; then :
ac_have_decl=1
else
ac_have_decl=0
fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_ $ac_have_decl
_ACEOF
ac_config_files="$ac_config_files Makefile"
ac_config_headers="$ac_config_headers config.h"
@@ -12951,6 +13036,10 @@ if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT
as_fn_error $? "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${CROSS_COMPILE_TRUE}" && test -z "${CROSS_COMPILE_FALSE}"; then
as_fn_error $? "conditional \"CROSS_COMPILE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -12959,6 +13048,10 @@ if test -z "${INSTALL_LIBBFD_TRUE}" && test -z "${INSTALL_LIBBFD_FALSE}"; then
as_fn_error $? "conditional \"INSTALL_LIBBFD\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${HAVE_DL_ITERATE_PHDR_TRUE}" && test -z "${HAVE_DL_ITERATE_PHDR_FALSE}"; then
as_fn_error $? "conditional \"HAVE_DL_ITERATE_PHDR\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0

View File

@@ -22,6 +22,7 @@ AC_INIT([libsframe], [BFD_VERSION])
AC_CONFIG_SRCDIR(sframe.c)
AC_CANONICAL_TARGET
AC_CANONICAL_HOST
AC_USE_SYSTEM_EXTENSIONS
AM_INIT_AUTOMAKE
@@ -112,6 +113,18 @@ else
fi
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
dnl Determine if we are cross compiling
is_cross_compiler=
if test x"${host}" = x"${target}" ; then
is_cross_compiler=no
else
is_cross_compiler=yes
fi
CROSS_COMPILE=$is_cross_compiler
AC_SUBST([CROSS_COMPILE])
AM_CONDITIONAL(CROSS_COMPILE, test "is_cross_compiler" = "yes")
AM_MAINTAINER_MODE
AM_INSTALL_LIBBFD
@@ -121,6 +134,25 @@ AC_CHECK_HEADERS(byteswap.h endian.h)
dnl Check for bswap_{16,32,64}
AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64], [], [], [[#include <byteswap.h>]])
dnl Check for dl_iterate_phdr. Used in the libsframe.stacktrace testsuite.
dnl The stacktrace testsuite is NOT built and run for build != target.
AC_CHECK_HEADERS(link.h)
if test "$ac_cv_header_link_h" = "no"; then
have_dl_iterate_phdr=no
else
AC_CHECK_FUNC([dl_iterate_phdr],
[have_dl_iterate_phdr=yes],
[have_dl_iterate_phdr=no])
fi
if test "$have_dl_iterate_phdr" = "yes"; then
AC_DEFINE(HAVE_DL_ITERATE_PHDR, 1, [Define if dl_iterate_phdr is available.])
fi
AM_CONDITIONAL([HAVE_DL_ITERATE_PHDR], [test "x$have_dl_iterate_phdr" = "xyes"])
dnl Check for dl_iterate_phdr
AC_CHECK_HEADERS(link.h)
AC_CHECK_DECLS
AC_CONFIG_FILES(Makefile)
AC_CONFIG_HEADERS(config.h)
AC_OUTPUT

23
libsframe/setup.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/sh
# Make symlinks from tmpdir/libsframe 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.
#
# The libsframest library (used in the testsuite) needs to be built with
# SFrame info.
DIRECTORY="tmpdir/libsframe"
if [ ! -d "$DIRECTORY" ]; then
mkdir -p $DIRECTORY
fi
if [ ! -L "$DIRECTORY/ld" ]; then
ln -s ../../../ld/ld-new $DIRECTORY/ld
fi
if [ ! -L "$DIRECTORY/collect-ld" ]; then
ln -s ld $DIRECTORY/collect-ld
fi
if [ ! -L "$DIRECTORY/as" ]; then
ln -s ../../../gas/as-new $DIRECTORY/as
fi

View File

@@ -31,15 +31,6 @@ if ![info exists as] then {
remote_exec host "mkdir -p tmpdir"
# Make symlinks from tmpdir/libsframe 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/libsframe]} then {
catch "exec mkdir tmpdir/libsframe" status
catch "exec ln -s ../../../ld/ld-new tmpdir/libsframe/ld" status
catch "exec ln -s ld tmpdir/libsframe/collect-ld" status
catch "exec ln -s ../../../gas/as-new tmpdir/libsframe/as" status
}
set gcc_B_opt "-B[pwd]/tmpdir/libsframe/"
set ld_L_opt ""
@@ -52,3 +43,6 @@ if {![info exists CFLAGS]} {
if {![info exists CFLAGS_FOR_TARGET]} {
set CFLAGS_FOR_TARGET $CFLAGS
}
# load the utility procedures
load_lib sframe-lib.exp

View File

@@ -0,0 +1,180 @@
# Support routines for libsframe testsuite.
# Copyright (C) 2022 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.
load_file $srcdir/../../ld/testsuite/lib/ld-lib.exp
set unwind_test_file_name ""
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"
}
# Compile and link a C source file for execution on the host.
proc compile_link_one_host_cc { src output additional_args } {
global CC
global CFLAGS
return [run_native_host_cmd "./libtool --quiet --tag=CC --mode=link $CC -B./tmpdir/libsframe $CFLAGS $src -o $output $additional_args" ]
}
proc make_unwind_parallel_path { args } {
global objdir
set joiner [list "file" "join" $objdir]
set joiner [concat $joiner $args]
return [eval $joiner]
}
proc standard_output_file {basename} {
global objdir subdir unwind_test_file_name
set dir [make_unwind_parallel_path outputs $subdir $unwind_test_file_name]
file mkdir $dir
return [file join $dir $basename]
}
proc standard_testfile {args} {
global unwind_test_file_name
global subdir
global unwind_test_file_last_vars
# Outputs.
global testfile binfile
set testfile $unwind_test_file_name
set binfile [standard_output_file ${testfile}]
if {[llength $args] == 0} {
set args .c
}
# Unset our previous output variables.
# This can help catch hidden bugs.
if {[info exists unwind_test_file_last_vars]} {
foreach varname $unwind_test_file_last_vars {
global $varname
catch {unset $varname}
}
}
# 'executable' is often set by tests.
set unwind_test_file_last_vars {executable}
set suffix ""
foreach arg $args {
set varname srcfile$suffix
global $varname
# Handle an extension.
if {$arg == ""} {
set arg $testfile.c
} else {
set first [string range $arg 0 0]
if { $first == "." || $first == "-" } {
set arg $testfile$arg
}
}
set $varname $arg
lappend unwind_test_file_last_vars $varname
if {$suffix == ""} {
set suffix 2
} else {
incr suffix
}
}
}
# Build a shared object DEST from SOURCES.
proc unwind_compile_so {sources dest} {
global CFLAGS
set obj_options $CFLAGS
lappend obj_options "additional_flags=-fPIC -Wa,--gsframe"
set outdir [file dirname $dest]
set objects ""
foreach source $sources {
set sourcebase [file tail $source]
set object ${outdir}/${sourcebase}.o
if {[target_compile $source $object object \
$obj_options] != ""} {
return -1
}
lappend objects $object
}
set link_options "additional_flags=-shared"
set destbase [file tail $dest]
lappend link_options "additional_flags=-Wl,-soname,$destbase"
if {[target_compile "${objects}" "${dest}" executable $link_options] != ""} {
catch "exec rm ${objects}" status
return -1
}
catch "exec rm ${objects}" status
return ""
}
# Build a binary of TYPE from SOURCE at path DEST.
proc unwind_compile {source dest type options} {
set new_options ""
foreach opt $options {
if {[regexp {^shlib=(.*)} $opt dummy_var shlib_name]
&& $type == "executable"} {
lappend source "-Wl,$shlib_name"
} else {
lappend new_options $opt
}
}
set options $new_options
verbose "options are $options"
verbose "source is $source $dest $type $options"
lappend options "additional_flags=-rdynamic -Wa,--gsframe ./.libs/libsframebt.a ./.libs/libsframe.a"
set result [target_compile $source $dest $type $options]
return $result
}

View File

@@ -0,0 +1,7 @@
libsframest
===========
libsframest is the SFrame stack tracer library.
The current usecase libsframest fulfills here is: aid testing stack
tracing in libsframe testsuite.

View File

@@ -0,0 +1,67 @@
/* Public API to SFrame stacktracer.
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of libsframest.
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, see <http://www.gnu.org/licenses/>. */
#ifndef _SFRAME_STACKTRACE_API_H
#define _SFRAME_STACKTRACE_API_H
#ifdef __cplusplus
extern "C"
{
#endif
enum sframe_bt_errcode
{
SFRAME_BT_OK,
SFRAME_BT_ERR_BAD_SFSTATE,
SFRAME_BT_ERR_ARG,
SFRAME_BT_ERR_MALLOC,
SFRAME_BT_ERR_REALLOC,
SFRAME_BT_ERR_OPEN,
SFRAME_BT_ERR_READLINK,
SFRAME_BT_ERR_LSEEK,
SFRAME_BT_ERR_READ,
SFRAME_BT_ERR_GETCONTEXT,
SFRAME_BT_ERR_DECODE,
SFRAME_BT_ERR_CFA_OFFSET,
SFRAME_BT_ERR_FRE_INVAL,
};
#define SFRAME_BT_ERR ((int) -1)
#define NUM_OF_DSOS 32 /* Number of DSOs. */
#define ENUM_ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
/* Get the stacktrace of the calling program by storing return addresses
in BUFFER. The SIZE argument specifies the maximum number of addresses
that can be stored in the buffer. Return the number of return addresses
collected or -1 if there is any error. */
extern int sframe_stacktrace (void **buffer, int size, int *errp);
extern const char *sframe_bt_errmsg (enum sframe_bt_errcode ecode);
extern int sframe_bt_ret_set_errno (int *errp, int error);
extern int sframe_bt_errno (const int *errp);
#ifdef __cplusplus
}
#endif
#endif /* _SFRAME_STACKTRACE_API_H */

View File

@@ -0,0 +1,20 @@
check_LTLIBRARIES =
if HAVE_DL_ITERATE_PHDR
# Build libsframest only when not cross-building
if !CROSS_COMPILE
check_LTLIBRARIES += %D%/libsframest.la
endif
endif
%C%_libsframest_la_SOURCES = %D%/sframe-stacktrace.c \
%D%/sframe-state.c \
%D%/sframe-stacktrace-err.c
%C%_libsframest_la_LIBADD = ${top_builddir}/libsframe.la
%C%_libsframest_la_CPPFLAGS = -I${top_srcdir}/../include \
-I${top_srcdir}/%D%/include \
-B${top_builddir}/tmpdir/libsframe \
-Wall -Wno-unused-but-set-variable
%C%_libsframest_la_CFLAGS = -B${top_builddir}/tmpdir/libsframe \
-Wa,--gsframe
%C%_libsframest_la_LDFLAGS = -B${top_builddir}/tmpdir/libsframe

View File

@@ -0,0 +1,70 @@
/* sframe-stacktrace-err.c - SFrame Stacktrace Error table.
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of libsframest.
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, see <http://www.gnu.org/licenses/>. */
#include "config.h"
#include "sframe-stacktrace-api.h"
/* SFrame stacktrace error messages. */
static const char *const sframe_bt_errlist[] =
{
"",
"Failed to setup SFrame state for stack tracing",
"Bad arguments; Unhealthy SFrame state possible",
"Failed to malloc memory space",
"Failed to realloc memory space",
"Failed to open file",
"Failed on resolve canonical file name",
"Failed to reposition file offset",
"Failed to read from a file descriptor",
"Failed to get the user context",
"Failed to set up decode data",
"Illegal CFA offset",
"Corrupt FRE"
};
/* Return the error message associated with the error code. */
const char *
sframe_bt_errmsg (enum sframe_bt_errcode ecode)
{
if ((unsigned int)ecode >= ENUM_ARRAY_SIZE (sframe_bt_errlist))
return "Unknown error";
return sframe_bt_errlist[ecode];
}
/* Check if there is error code in ERRP. */
int
sframe_bt_errno (const int *errp)
{
if (!errp)
return 0;
return (*errp != SFRAME_BT_OK);
}
int
sframe_bt_ret_set_errno (int *errp, int error)
{
if (errp)
*errp = error;
return error;
}

View File

@@ -0,0 +1,82 @@
/* The SFrame stacktracer - accessing target registers.
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of libsframest.
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, see <http://www.gnu.org/licenses/>. */
#include <stdint.h>
#include <ucontext.h>
#ifndef SFRAME_STACKTRACE_REGS_H
#define SFRAME_STACKTRACE_REGS_H
#if defined (__x86_64__)
static inline uint64_t
get_context_pc (ucontext_t *cp)
{
return cp->uc_mcontext.gregs[REG_RIP];
}
static inline uint64_t
get_context_rsp (ucontext_t *cp)
{
return cp->uc_mcontext.gregs[REG_RSP];
}
static inline uint64_t
get_context_rfp (ucontext_t *cp)
{
return cp->uc_mcontext.gregs[REG_RBP];
}
static inline uint64_t
get_context_ra (ucontext_t *cp)
{
return 0; /* SFRAME_CFA_FIXED_RA_INVALID */
}
#elif defined (__aarch64__)
static inline uint64_t
get_context_pc (ucontext_t *cp)
{
return cp->uc_mcontext.pc;
}
static inline uint64_t
get_context_rsp (ucontext_t *cp)
{
return cp->uc_mcontext.sp;
}
static inline uint64_t
get_context_rfp (ucontext_t *cp)
{
#define UNWIND_AARCH64_X29 29 /* 64-bit frame pointer. */
return cp->uc_mcontext.regs[UNWIND_AARCH64_X29];
}
static inline uint64_t
get_context_ra (ucontext_t *cp)
{
#define UNWIND_AARCH64_X30 30 /* 64-bit link pointer. */
return cp->uc_mcontext.regs[UNWIND_AARCH64_X30];
}
#endif
#endif /* SFRAME_STACKTRACE_REGS_H. */

View File

@@ -0,0 +1,224 @@
/* sframe-stacktrace.c - The SFrame stacktracer.
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of libsframest.
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, see <http://www.gnu.org/licenses/>. */
#include "config.h"
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <execinfo.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ucontext.h>
#include <stdarg.h>
#include "ansidecl.h"
#include "sframe-api.h"
#include "sframe-stacktrace-api.h"
#include "sframe-stacktrace-regs.h"
#include "sframe-state.h"
#define STACK_ELEM_SIZE sizeof(uint64_t)
/* Get the 8 bytes at ADDR from file descriptor FD. */
static int
get_contents_8b (int fd, uint64_t addr, uint64_t *data)
{
size_t sz = 0;
int err = 0;
if (!data)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_ARG);
if (lseek (fd, addr, SEEK_SET) == -1)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_LSEEK);
sz = read (fd, data, STACK_ELEM_SIZE);
if (sz != STACK_ELEM_SIZE)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_READ);
return SFRAME_BT_OK;
}
/* Check if ADDR is valid in SF.
The address is considered invalid, with regards to SFrame, if it's not in
any address range of the main module or any of its DSO's.
Return 1 if valid, 0 otherwise. */
static bool
sframe_valid_addr_p (struct sframest_ctx *sf, uint64_t addr)
{
struct sframest_info *sfinfo;
if (!sf)
return 0;
sfinfo = sframe_find_context (sf, addr);
return sfinfo ? 1 : 0;
}
/* Unwind the stack and collect the stacktrace given SFrame unwind info SF.
If successful, store the return addresses in RA_LST. The RA_SIZE argument
specifies the maximum number of return addresses that can be stored in
RA_LST and contains the number of the addresses collected. */
static int
sframe_unwind (struct sframest_ctx *sf, void **ra_lst, int *ra_size)
{
uint64_t cfa, return_addr, ra_stack_loc, rfp_stack_loc;
struct sframest_info *sfinfo;
sframe_decoder_ctx *dctx;
int cfa_offset, rfp_offset, ra_offset, errnum, i, count;
sframe_frame_row_entry fred, *frep = &fred;
uint64_t pc, rfp, rsp, ra, sframe_vma;
ucontext_t context, *cp = &context;
int err = 0;
if (!sf || !ra_lst || !ra_size)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_ARG);
/* Get the user context for its registers. */
if (getcontext (cp))
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_GETCONTEXT);
pc = get_context_pc (cp);
rsp = get_context_rsp (cp);
rfp = get_context_rfp (cp);
ra = get_context_ra (cp);
return_addr = ra;
/* Load and set up the SFrame stack trace info for pc. */
sfinfo = sframest_get_sfinfo (sf, pc);
if (!sfinfo || !sfinfo->dctx)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_DECODE);
count = *ra_size;
for (i = 0; i < count; ++i)
{
dctx = sfinfo->dctx;
sframe_vma = sfinfo->sframe_vma;
pc -= sframe_vma;
errnum = sframe_find_fre (dctx, pc, frep);
if (!errnum)
{
cfa_offset = sframe_fre_get_cfa_offset (dctx, frep, &errnum);
if (errnum == SFRAME_ERR_FREOFFSET_NOPRESENT)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_CFA_OFFSET);
cfa = ((sframe_fre_get_base_reg_id (frep, &errnum)
== SFRAME_BASE_REG_SP) ? rsp : rfp) + cfa_offset;
ra_offset = sframe_fre_get_ra_offset (dctx, frep, &errnum);
if (!errnum)
{
ra_stack_loc = cfa + ra_offset;
errnum = get_contents_8b (sf->fd, ra_stack_loc, &return_addr);
if (sframe_bt_errno (&errnum))
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_FRE_INVAL);
}
/* Validate and add return address to the list. */
if (!sframe_valid_addr_p (sf, return_addr))
{
i -= 1;
goto find_fre_ra_err;
}
if (i != 0) /* exclude self. */
ra_lst[i-1] = (void *)return_addr;
/* Set up for the next frame. */
rfp_offset = sframe_fre_get_fp_offset (dctx, frep, &errnum);
if (!errnum)
{
rfp_stack_loc = cfa + rfp_offset;
errnum = get_contents_8b (sf->fd, rfp_stack_loc, &rfp);
if (sframe_bt_errno (&errnum))
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_FRE_INVAL);
}
rsp = cfa;
pc = return_addr;
/* Check if need to update the SFrame stack trace info for the return
addr. */
if (!sframest_sfinfo_addr_range_p (sfinfo, return_addr))
{
sfinfo = sframest_get_sfinfo (sf, pc);
if (!sfinfo || !sfinfo->dctx)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_DECODE);
}
}
else
{
i -= 1;
goto find_fre_ra_err;
}
}
find_fre_ra_err:
*ra_size = i;
return SFRAME_BT_OK;
}
/* Main API that user program calls to get a stacktrace.
The BUFFER argument provides space for the list of the return addresses
and the SIZE argument specifies the maximum number of addresses that
can be stored in the buffer.
Returns the number of return addresses collected or -1 if there is any
error. ERRP is set with the error code if any. */
int
sframe_stacktrace (void **buffer, int size, int *errp)
{
struct sframest_ctx sf_ctx;
sframe_unwind_init_debug ();
memset (&sf_ctx, 0, sizeof (struct sframest_ctx));
/* Find the .sframe sections and setup the SFrame state for generating stack
traces. */
(void) dl_iterate_phdr (sframe_callback, (void *)&sf_ctx);
if (!sf_ctx.fd)
{
sframe_bt_ret_set_errno (errp, SFRAME_BT_ERR_BAD_SFSTATE);
return -1;
}
/* Do the stack unwinding. */
*errp = sframe_unwind (&sf_ctx, buffer, &size);
if (sframe_bt_errno (errp))
size = -1;
sframest_ctx_free (&sf_ctx);
return size;
}

View File

@@ -0,0 +1,324 @@
/* sframe-state.c - The SFrame state for stacktracing.
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of libsframest.
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, see <http://www.gnu.org/licenses/>. */
#include "config.h"
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <execinfo.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ucontext.h>
#include <stdarg.h>
#include "ansidecl.h"
#include "sframe-api.h"
#include "sframe-stacktrace-api.h"
#include "sframe-stacktrace-regs.h"
#include "sframe-state.h"
#define _sf_printflike_(string_index, first_to_check) ATTRIBUTE_PRINTF (1, 2)
static bool _sframe_unwind_debug; /* Control for printing out debug info. */
static const int no_of_entries = NUM_OF_DSOS;
void
sframe_unwind_init_debug (void)
{
static int inited;
if (!inited)
{
_sframe_unwind_debug = getenv ("SFRAME_UNWIND_DEBUG") != NULL;
inited = 1;
}
}
_sf_printflike_ (1, 2)
static void
debug_printf (const char *format, ...)
{
if (_sframe_unwind_debug == true)
{
va_list args;
va_start (args, format);
__builtin_vprintf (format, args);
va_end (args);
}
}
#if 0
/* sframe_bt_set_errno - Store the specified error code ERROR into ERRP if
it is non-NULL. */
static void
sframe_bt_set_errno (int *errp, int error)
{
if (errp != NULL)
*errp = error;
}
#endif
static void
sframest_sfinfo_init (struct sframest_info *sfinfo, const char *buf,
int64_t buflen, uint64_t sframe_vma,
uint64_t text_vma, int64_t text_size)
{
if (!sfinfo)
return;
sfinfo->buf = buf;
sfinfo->buflen = buflen;
sfinfo->sframe_vma = sframe_vma;
sfinfo->text_vma = text_vma;
sfinfo->text_size = text_size;
}
/* Return whether the given SFrame stack trace info object SFINFO has (stack
trace) information corresponding to addr. */
bool
sframest_sfinfo_addr_range_p (struct sframest_info *sfinfo, uint64_t addr)
{
if (!sfinfo || !addr)
return false;
return (sfinfo->text_vma <= addr
&& sfinfo->text_vma + sfinfo->text_size > addr);
}
/* Add .sframe info in D_DATA, which is associated with
a dynamic shared object, to D_LIST. */
static int
sframe_add_dso (struct sframest_info_list *d_list,
struct sframest_info d_data)
{
int err = 0;
if (!d_list->alloced)
{
d_list->entry = malloc (no_of_entries * sizeof (struct sframest_info));
if (!d_list->entry)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_MALLOC);
memset (d_list->entry, 0,
no_of_entries * sizeof (struct sframest_info));
d_list->alloced = no_of_entries;
}
else if (d_list->used == d_list->alloced)
{
d_list->entry = realloc (d_list->entry,
((d_list->alloced + no_of_entries)
* sizeof (struct sframest_info)));
if (!d_list->entry)
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_REALLOC);
memset (&d_list->entry[d_list->alloced], 0,
no_of_entries * sizeof (struct sframest_info));
d_list->alloced += no_of_entries;
}
sframe_bt_ret_set_errno (&err, SFRAME_BT_OK);
d_list->entry[d_list->used++] = d_data;
return SFRAME_BT_OK;
}
/* Free up space allocated SFrame stack trace context object SFCTX. */
void
sframest_ctx_free (struct sframest_ctx *sfctx)
{
struct sframest_info_list *d_list;
int i;
if (!sfctx)
return;
// free (sf->sui_ctx.sfdd_data);
sframe_decoder_free (&sfctx->prog_sfinfo.dctx);
close (sfctx->fd);
d_list = &sfctx->dsos_sfinfo;
if (!d_list->alloced)
return;
for (i = 0; i < d_list->used; ++i)
{
// free (d_list->entry[i].sfdd_data);
sframe_decoder_free (&d_list->entry[i].dctx);
}
free (d_list->entry);
}
/* Find the decode data that contains ADDR from SFCTX.
Return the pointer to the decode data or NULL. */
struct sframest_info *
sframe_find_context (struct sframest_ctx *sfctx, uint64_t addr)
{
struct sframest_info_list *d_list;
struct sframest_info sfinfo;
int i;
if (!sfctx)
return NULL;
if (sframest_sfinfo_addr_range_p (&sfctx->prog_sfinfo, addr))
return &sfctx->prog_sfinfo;
d_list = &sfctx->dsos_sfinfo;
for (i = 0; i < sfctx->dsos_sfinfo.used; ++i)
{
sfinfo = d_list->entry[i];
if (sframest_sfinfo_addr_range_p (&sfinfo, addr))
return &d_list->entry[i];
}
return NULL;
}
/* Call decoder to create and set up the SFrame info for either the main module
or one of the DSOs from SFCTX, based on the input RADDR argument.
Return the newly created decode context or NULL. */
struct sframest_info *
sframest_get_sfinfo (struct sframest_ctx *sfctx, uint64_t raddr)
{
struct sframest_info *sfinfo = NULL;
int err = 0;
if (!sfctx)
return NULL;
sfinfo = sframe_find_context (sfctx, raddr);
if (!sfinfo)
return NULL;
/* Decode the SFrame section the first time. */
if (!sfinfo->dctx)
sfinfo->dctx = sframe_decode (sfinfo->buf, sfinfo->buflen, &err);
return sfinfo;
}
/* Open /proc image associated with the process id and return the file
descriptor. */
static int
get_proc_mem_fd (int *errp)
{
int fd;
if ((fd = open ("/proc/self/mem", O_CLOEXEC)) == -1)
{
sframe_bt_ret_set_errno (errp, SFRAME_BT_ERR_OPEN);
return -1;
}
return fd;
}
/* The callback from dl_iterate_phdr with header info in INFO.
Return SFrame info for either the main module or a DSO in DATA. */
int
sframe_callback (struct dl_phdr_info *info,
size_t size ATTRIBUTE_UNUSED,
void *data)
{
struct sframest_ctx *sfctx = (struct sframest_ctx *) data;
int p_type, i, fd, sframe_err;
uint64_t text_vma = 0;
uint64_t text_size = 0;
if (!data || !info)
return 1;
debug_printf ("-- name: %s %14p\n", info->dlpi_name, (void *)info->dlpi_addr);
for (i = 0; i < info->dlpi_phnum; i++)
{
debug_printf (" %2d: [%" PRIu64 "; memsz %" PRIu64 "] flags: 0x%x; \n", i,
(uint64_t) info->dlpi_phdr[i].p_vaddr,
(uint64_t) info->dlpi_phdr[i].p_memsz,
info->dlpi_phdr[i].p_flags);
p_type = info->dlpi_phdr[i].p_type;
if (p_type == PT_LOAD && info->dlpi_phdr[i].p_flags & PF_X)
{
text_vma = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr;
text_size = info->dlpi_phdr[i].p_memsz;
continue;
}
if (p_type != PT_SFRAME)
continue;
if (info->dlpi_name[0] == '\0')
{
/* the main module. */
fd = get_proc_mem_fd (&sframe_err);
if (fd == -1)
return 1;
assert (text_vma);
sframest_sfinfo_init (&sfctx->prog_sfinfo,
(char *)(info->dlpi_addr
+ info->dlpi_phdr[i].p_vaddr),
info->dlpi_phdr[i].p_memsz,
info->dlpi_addr + info->dlpi_phdr[i].p_vaddr,
text_vma, text_size);
sfctx->fd = fd;
text_vma = 0;
return 0;
}
else
{
/* a dynamic shared object. */
struct sframest_info sfinfo;
memset (&sfinfo, 0, sizeof (struct sframest_info));
assert (sfctx->fd);
assert (text_vma);
sframest_sfinfo_init (&sfinfo,
(char *)(info->dlpi_addr
+ info->dlpi_phdr[i].p_vaddr),
info->dlpi_phdr[i].p_memsz,
info->dlpi_addr + info->dlpi_phdr[i].p_vaddr,
text_vma, text_size);
text_vma = 0;
sframe_err = sframe_add_dso (&sfctx->dsos_sfinfo, sfinfo);
// FIXME TODO
if (sframe_err != SFRAME_BT_OK)
return 1;
return 0;
}
}
return 0;
}

View File

@@ -0,0 +1,107 @@
/* sframe-state.h - The SFrame state for stacktracing.
Copyright (C) 2023 Free Software Foundation, Inc.
This file is part of libsframest.
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, see <http://www.gnu.org/licenses/>. */
#ifndef SFRAME_STATE_H
#define SFRAME_STATE_H
#include "config.h"
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <execinfo.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ucontext.h>
#include <stdarg.h>
#include "ansidecl.h"
#include "sframe-api.h"
#include "sframe-stacktrace-api.h"
#include "sframe-stacktrace-regs.h"
/* glibc's elf.h will bring this in future. */
#ifndef PT_SFRAME
#define PT_SFRAME 0x6474e554
#endif
/* SFrame stacktrace data. */
struct sframest_info
{
/* Reference to the SFrame section in process memory. */
const char *buf;
/* Length in bytes of the SFrame section in memory. */
uint64_t buflen;
/* Text segment's virtual address. */
uint64_t text_vma;
/* Text segment's length in bytes. */
uint64_t text_size;
/* SFrame segment's virtual address. */
uint64_t sframe_vma;
/* SFrame decoder context. For access to decoded SFrame information. */
sframe_decoder_ctx *dctx;
};
/* List of SFrame stacktrace info objects.
Typically used to represent SFrame stacktrace info for set of shared
libraries of a program. */
struct sframest_info_list
{
/* Number of entries allocated. */
int alloced;
/* Number of entries used. */
int used;
/* (Array) List of SFrame stacktrace info objects. */
struct sframest_info *entry;
};
/* SFrame stacktracing context. */
struct sframest_ctx
{
/* File descriptor for the process memory. */
int fd;
/* SFrame stacktrace info for program. */
struct sframest_info prog_sfinfo;
/* SFrame stacktrace info for its DSOs. */
struct sframest_info_list dsos_sfinfo;
};
void sframe_unwind_init_debug (void);
int sframe_callback (struct dl_phdr_info *info,
size_t size ATTRIBUTE_UNUSED,
void *data);
bool sframest_sfinfo_addr_range_p (struct sframest_info *sfinfo,
uint64_t addr);
struct sframest_info *sframest_get_sfinfo (struct sframest_ctx *sfctx,
uint64_t raddr);
struct sframest_info *sframe_find_context (struct sframest_ctx *sfctx,
uint64_t addr);
void sframest_ctx_free (struct sframest_ctx *sfctx);
#endif /* SFRAME_STATE_H. */

View File

@@ -0,0 +1 @@
include %D%/libsframest/local.mk

View File

@@ -0,0 +1,8 @@
#include "solib-lib1.h"
unsigned int
adder(unsigned int a, unsigned int b, int (*call)(int))
{
(void)(*call)(a+b);
return (a+b);
}

View File

@@ -0,0 +1,3 @@
#include<stdio.h>
extern unsigned int adder(unsigned int a, unsigned int b, int (*call)(int));

View File

@@ -0,0 +1,55 @@
#include <execinfo.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#include "solib-lib2.h"
#define BT_BUF_SIZE 100
/* funclist for running "ttest.x 3". */
static const char *const bt_list[] =
{
"adder2",
"bar",
"adder",
"main"
};
unsigned int
adder2 (unsigned int a, unsigned int b, int (*call)(int))
{
void *buffer[BT_BUF_SIZE];
int i, nptrs, err;
char **strings;
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (err)
{
printf ("SFrame error: %s\n", sframe_bt_errmsg (err));
return (-1);
}
if (nptrs != 4)
{
printf ("sframe_stacktrace failed: %d %d\n", nptrs, err);
return (-1);
}
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL)
{
printf ("Error in backtrace_symbols");
return (-1);
}
/* Verify the results. */
for (i = 0; i < nptrs; i++)
if (!strstr (strings[i], bt_list[i]))
break;
free (strings);
printf ("%s: unwind solib test\n", i == nptrs ? "PASS" : "FAIL");
(void)(*call) (a+b);
return (a+b);
}

View File

@@ -0,0 +1,3 @@
#include<stdio.h>
extern unsigned int adder2(unsigned int a, unsigned int b, int (*call)(int));

View File

@@ -0,0 +1,46 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include "sframe-stacktrace-api.h"
#include "solib-lib1.h"
#include "solib-lib2.h"
#define BT_BUF_SIZE 100
int foo (int x)
{
return ++x;
}
int bar (int x)
{
x = adder2 (x, x+1, foo);
return ++x;
}
int main (void)
{
unsigned int a = 1;
unsigned int b = 2;
unsigned int result = 0;
result = adder (a,b, bar);
return 0;
}

View File

@@ -0,0 +1,3 @@
# source: solib-main.c
# link: on
PASS: unwind solib test

View File

@@ -0,0 +1,70 @@
# Copyright 2022 Free Software Foundation, Inc.
# 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, see <http://www.gnu.org/licenses/>.
# Run the test only if sframebt library exists.
if [catch "exec ls $objdir/.libs/libsframebt.la" status] then {
return;
}
set experimental ""
# Shared object files.
set libname1 "solib-lib1"
set srcfile_lib1 ${srcdir}/${subdir}/${libname1}.c
set binfile_lib1 ${objdir}/${libname1}.so
set libname2 "solib-lib2"
set srcfile_lib2 ${srcdir}/${subdir}/${libname2}.c
set binfile_lib2 ${objdir}/${libname2}.so
# Binary file.
set testfile "solib-main"
set srcfile ${srcdir}/${subdir}/${testfile}.c
set binfile [standard_output_file ${testfile}]
set bin_flags [list debug shlib=${binfile_lib1} shlib=${binfile_lib2}]
if { [unwind_compile_so ${srcfile_lib1} ${binfile_lib1}] != ""
|| [unwind_compile_so ${srcfile_lib2} ${binfile_lib2}] != ""
|| [unwind_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
untested "failed to compile"
return -1
}
if {[info exists env(LD_LIBRARY_PATH)]} {
set old_ld_lib $env(LD_LIBRARY_PATH)
}
set env(LD_LIBRARY_PATH) "${objdir}"
set solib_output "${binfile} ${binfile_lib1} ${binfile_lib2}"
set results [run_host_cmd ${binfile} $solib_output]
set f [open "tmpdir/solib.out" "w"]
puts $f $results
close $f
if { [regexp_diff "tmpdir/solib.out" "${srcdir}/${subdir}/${testfile}.d"] } then {
fail "$test_name"
} else {
pass "$test_name"
}
catch "exec rm ${binfile_lib1}" status
catch "exec rm ${binfile_lib2}" status
catch "exec rm tmpdir/solib.out" status
if {[info exists old_ld_lib]} {
set env(LD_LIBRARY_PATH) $old_ld_lib
} else {
unset env(LD_LIBRARY_PATH)
}

View File

@@ -0,0 +1,111 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
/* This is a revised version of gdb/testsuite/gdb.base/backtrace.c. */
#ifdef __has_attribute
# if !__has_attribute (noclone)
# define ATTRIBUTE_NOCLONE
# endif
#endif
#ifndef ATTRIBUTE_NOCLONE
# define ATTRIBUTE_NOCLONE __attribute__((noclone))
#endif
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#define BT_BUF_SIZE 100
#define BT_EXPECTED_NPTRS 3
/* Expected funclist. */
static const char *const func_list[] =
{
"show_bt",
"bar",
"main"
};
void __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
show_bt ()
{
void *buffer[BT_BUF_SIZE];
int j, nptrs, err = 0;
char **strings;
/* Call the unwinder to get an array of return addresses. */
// nptrs = backtrace (buffer, BT_BUF_SIZE);
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (err)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL) {
printf ("Error in backtrace_symbols");
return;
}
// for (j = 0; j < nptrs; j++)
// printf (" %s \n", strings[j]);
if (nptrs != BT_EXPECTED_NPTRS)
{
printf ("Backtace nptrs mismatch: expected = %d, generated = %d \n",
BT_EXPECTED_NPTRS, nptrs);
return;
}
/* Verify the results. */
for (j = 0; j < nptrs; j++)
if (!strstr (strings[j], func_list[j]))
break;
free(strings);
printf ("%s: stacktrace-1\n", (j == nptrs) ? "PASS" : "FAIL");
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
bar ()
{
show_bt ();
return 0;
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
main ()
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* The following call to sframe_stacktrace () also prevents sibling call
optimization in main (). */
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return -1;
}
return bar ();
}

View File

@@ -0,0 +1,4 @@
# source: stacktrace-1.c
# cflags: -O2
# link: on
PASS: stacktrace-1

View File

@@ -0,0 +1,144 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
/* This is a revised version of gdb/testsuite/gdb.base/backtrace.c. */
#ifdef __has_attribute
# if !__has_attribute (noclone)
# define ATTRIBUTE_NOCLONE
# endif
#endif
#ifndef ATTRIBUTE_NOCLONE
# define ATTRIBUTE_NOCLONE __attribute__((noclone))
#endif
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#define BT_BUF_SIZE 100
/* Expected funclist. */
static const char *const func_list[] =
{
"show_bt",
"baz",
"bar",
"foo",
"main"
};
void __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
show_bt ()
{
void *buffer[BT_BUF_SIZE];
int j, nptrs, err;
char **strings;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs != 5)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL) {
printf ("Error in backtrace_symbols");
return;
}
/* Verify the results. */
for (j = 0; j < nptrs; j++)
if (!strstr (strings[j], func_list[j]))
break;
free(strings);
printf ("%s: stacktrace-2\n", (j == nptrs) ? "PASS" : "FAIL");
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
baz ()
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return -1;
}
show_bt ();
return 0;
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
bar ()
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return -1;
}
return baz ();
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
foo ()
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return -1;
}
return bar ();
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
main ()
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return -1;
}
return foo ();
}

View File

@@ -0,0 +1,3 @@
# source: stacktrace-2.c
# link: on
PASS: stacktrace-2

View File

@@ -0,0 +1,127 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
/* This is the revised version of the example in "man backtrace". */
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#ifdef __has_attribute
# if !__has_attribute (noclone)
# define ATTRIBUTE_NOCLONE
# endif
#endif
#ifndef ATTRIBUTE_NOCLONE
# define ATTRIBUTE_NOCLONE __attribute__((noclone))
#endif
#define BT_BUF_SIZE 100
/* funclist */
static const char *const func_list[] =
{
"myfunc3",
"()",
"myfunc",
"myfunc",
"myfunc",
"main"
};
void myfunc3 (void)
{
void *buffer[BT_BUF_SIZE];
int j, nptrs, err;
char **strings;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1 || nptrs != 6)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL) {
printf ("Error in backtrace_symbols");
return;
}
/* Verify the results. */
for (j = 0; j < nptrs; j++)
if (!strstr (strings[j], func_list[j]))
break;
free(strings);
printf ("%s: stacktrace with static function\n",
(j == nptrs) ? "PASS" : "FAIL");
}
static void __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
/* "static" means don't export the symbol. */
myfunc2 (void)
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
myfunc3 ();
}
void __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
myfunc (int ncalls)
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
if (ncalls > 1)
myfunc (ncalls - 1);
else
myfunc2 ();
}
int
main (int argc, char *argv[])
{
int cnt;
if (argc != 2) {
cnt = 3;
}
else
cnt = atoi(argv[1]);
myfunc (cnt);
exit (EXIT_SUCCESS);
}

View File

@@ -0,0 +1,3 @@
# source: stacktrace-3.c
# link: on
PASS: stacktrace with static function

View File

@@ -0,0 +1,108 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
/* This is a revised version of gdb/testsuite/gdb.base/backtrace.c. */
#ifdef __has_attribute
# if !__has_attribute (noclone)
# define ATTRIBUTE_NOCLONE
# endif
#endif
#ifndef ATTRIBUTE_NOCLONE
# define ATTRIBUTE_NOCLONE __attribute__((noclone))
#endif
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#define BT_BUF_SIZE 100
#define BT_EXPECTED_NPTRS 5
/* Expected funclist. */
static const char *const func_list[] =
{
"show_bt",
"baz",
"bar",
"foo",
"main"
};
void __attribute__((__noinline__,__optimize__("omit-frame-pointer"))) ATTRIBUTE_NOCLONE
show_bt ()
{
void *buffer[BT_BUF_SIZE];
int j, nptrs, err;
char **strings;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (err)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
if (nptrs != BT_EXPECTED_NPTRS)
{
printf ("Backtace nptrs mismatch: expected = %d, generated = %d \n",
BT_EXPECTED_NPTRS, nptrs);
return;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL) {
printf ("Error in backtrace_symbols");
return;
}
/* Verify the results. */
for (j = 0; j < nptrs; j++)
if (!strstr (strings[j], func_list[j]))
break;
free(strings);
printf ("%s: stacktrace with omit-frame-pointer attr\n",
(j == nptrs) ? "PASS" : "FAIL");
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
baz ()
{
show_bt ();
return 0;
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
bar ()
{
return baz ();
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
foo ()
{
return bar ();
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
main ()
{
return foo ();
}

View File

@@ -0,0 +1,4 @@
# source: stacktrace-fp-attr-1.c
# cflags: -fno-omit-frame-pointer -fno-optimize-sibling-calls
# link: on
PASS: stacktrace with omit-frame-pointer attr

View File

@@ -0,0 +1,109 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
/* This is a revised version of gdb/testsuite/gdb.base/backtrace.c. */
#ifdef __has_attribute
# if !__has_attribute (noclone)
# define ATTRIBUTE_NOCLONE
# endif
#endif
#ifndef ATTRIBUTE_NOCLONE
# define ATTRIBUTE_NOCLONE __attribute__((noclone))
#endif
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#define BT_BUF_SIZE 100
#define BT_EXPECTED_NPTRS 5
/* Expected funclist. */
static const char *const func_list[] =
{
"show_bt",
"baz",
"bar",
"foo",
"main"
};
void __attribute__((__noinline__,__optimize__("no-omit-frame-pointer"))) ATTRIBUTE_NOCLONE
show_bt ()
{
void *buffer[BT_BUF_SIZE];
int j, nptrs, err;
char **strings;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (err)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
if (nptrs != BT_EXPECTED_NPTRS)
{
printf ("Backtace nptrs mismatch: expected = %d, generated = %d \n",
BT_EXPECTED_NPTRS, nptrs);
return;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL) {
printf ("Error in backtrace_symbols");
return;
}
/* Verify the results. */
for (j = 0; j < nptrs; j++)
if (!strstr (strings[j], func_list[j]))
break;
free(strings);
printf ("%s: stacktrace with no-omit-frame-pointer attr\n",
(j == nptrs) ? "PASS" : "FAIL");
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
baz ()
{
show_bt ();
return 0;
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
bar ()
{
return baz ();
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
foo ()
{
return bar ();
}
int __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
main ()
{
return foo ();
}

View File

@@ -0,0 +1,4 @@
# source: stacktrace-fp-attr-2.c
# cflags: -fomit-frame-pointer -fno-optimize-sibling-calls
# link: on
PASS: stacktrace with no-omit-frame-pointer attr

View File

@@ -0,0 +1,96 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
/* This is a revised version of gdb/testsuite/gdb.opt/inline-bt.c. */
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#define ALWAYS_INLINE __attribute__((always_inline))
#define BT_BUF_SIZE 32
int x, y;
volatile int z = 0;
volatile int result;
/* funclist. */
const char *const flist[] =
{
"main"
};
void bar(void)
{
x += y;
}
inline ALWAYS_INLINE int func1(void)
{
bar ();
return x * y;
}
inline ALWAYS_INLINE int func2(void)
{
void *buffer[BT_BUF_SIZE];
int ok = 0, nptrs, err;
char **strings;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s\n", sframe_bt_errmsg (err));
return -1;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL) {
printf ("Error in backtrace_symbols");
return -1;
}
/* Verify the results. */
if (nptrs == 1 && strstr (strings[0], flist[0]))
ok = 1;
free(strings);
printf ("%s: stacktrace with inlined function\n", ok == 1 ? "PASS" : "FAIL");
return x * func1 ();
}
int main (void)
{
int val;
x = 7;
y = 8;
bar ();
val = func1 ();
result = val;
val = func2 ();
result = val;
return 0;
}

View File

@@ -0,0 +1,3 @@
# source: stacktrace-inline-1.c
# link: on
PASS: stacktrace with inlined function

View File

@@ -0,0 +1,107 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
/* This is a revised version of gdb/testsuite/gdb.opt/inline-cmds.c. */
/* This is only ever run if it is compiled with a new-enough GCC, but
we don't want the compilation to fail if compiled by some other
compiler. */
#ifdef __GNUC__
#define ATTR __attribute__((always_inline))
#else
#define ATTR
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <execinfo.h>
#include "sframe-stacktrace-api.h"
#define BT_BUF_SIZE 10
int x, y;
volatile int z = 0;
volatile int result;
void noinline(void);
inline ATTR void outer_inline1(void)
{
noinline ();
}
inline ATTR void outer_inline2(void)
{
outer_inline1 ();
}
int main (void)
{ /* start of main */
int val;
x = 7;
y = 8;
outer_inline2 ();
return 0;
}
/* funclist for inline-cmds. */
const char *const func_list[] =
{
"noinline",
"main"
};
inline ATTR void inlined_fn(void)
{
x += y + z;
void *buffer[BT_BUF_SIZE];
char **strings;
/* Call the unwinder to get an array of return addresses. */
int j, err;
int nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1 || nptrs != 2)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL)
{
printf ("Error in backtrace_symbols");
return;
}
/* Verify the results. */
for (j = 0; j < nptrs; j++)
if (!strstr (strings[j], func_list[j]))
break;
free(strings);
printf ("%s: stacktrace with inlined function test 2\n",
(j == nptrs) ? "PASS" : "FAIL");
}
void noinline(void)
{
inlined_fn (); /* inlined */
}

View File

@@ -0,0 +1,3 @@
# source: stacktrace-inline-2.c
# link: on
PASS: stacktrace with inlined function test 2

View File

@@ -0,0 +1,102 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>. */
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sframe-stacktrace-api.h"
#ifdef __has_attribute
# if !__has_attribute (noclone)
# define ATTRIBUTE_NOCLONE
# endif
#endif
#ifndef ATTRIBUTE_NOCLONE
# define ATTRIBUTE_NOCLONE __attribute__((noclone))
#endif
#define BT_BUF_SIZE 16
/* funclist for running tailcall. */
const char *const func_list[] =
{
"show_bt",
"dec",
"dec",
"main"
};
void show_bt ()
{
void *buffer[BT_BUF_SIZE];
int j, nptrs, err;
char **strings;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1 || nptrs != 4)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
/* Get these addresses symbolically. */
strings = backtrace_symbols (buffer, nptrs);
if (strings == NULL) {
printf ("Error in backtrace_symbols");
return;
}
/* Verify the results. */
for (j = 0; j < nptrs; j++)
if (!strstr (strings[j], func_list[j]))
break;
free(strings);
printf ("%s: stacktrace tailcall test\n", j == nptrs ? "PASS" : "FAIL");
}
/* An example of tail recursive function. */
void __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
dec (int n)
{
void *buffer[BT_BUF_SIZE];
int nptrs, err;
/* Call the unwinder to get an array of return addresses. */
nptrs = sframe_stacktrace (buffer, BT_BUF_SIZE, &err);
if (nptrs == -1)
{
printf ("SFrame error: %s (%d)\n", sframe_bt_errmsg (err), nptrs);
return;
}
if (n < 0)
return;
if (n == 2)
show_bt ();
/* The last executed statement is recursive call. */
dec (n-1);
}
int
main (void)
{
dec (3);
}

View File

@@ -0,0 +1,3 @@
# source: stacktrace-tailcall-1.c
# link: on
PASS: stacktrace tailcall test

View File

@@ -0,0 +1,196 @@
# Copyright (C) 2022 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.
#
# Run the tests only if libsframest library exists.
if [catch "exec ls $objdir/testsuite/libsframe.stacktrace/libsframest/.libs/libsframest.la" status] then {
verbose -log \
"$objdir/testsuite/libsframe.stacktrace/libsframest/.libs/libsframest.la not found.";
verbose -log "Skipping SFrame stacktrace tests";
return;
}
proc run_unwind_test { name } {
global CC
global CFLAGS
global CROSS_COMPILE
global copyfile env runtests srcdir subdir verbose
# Append additional flags for unwinder to work properly
set unwind_cflags "-Wa,--gsframe -rdynamic "
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 shared "-shared"
set opts(cflags) {}
set opts(link) {}
set opts(link_flags) {}
set opts(nonshared) {}
set opts(unwind) {}
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 { "$CROSS_COMPILE" eq "yes" } {
untested "$subdir/$name not tested when cross-compiling"
return
}
if { [llength $opts(unwind)] == 0 } {
set opts(unwind) "$file.c"
} else {
set opts(unwind) "[file dirname $file]/$opts(unwind)"
}
if { [llength $opts(name)] == 0 } {
set opts(name) $opts(unwind)
}
if { [llength $opts(cflags)] != 0 } {
append unwind_cflags $opts(cflags)
}
if { [llength $opts(link)] != 0
|| [llength $opts(source)] > 1 } {
set run_ld 1
}
if { [llength $opts(nonshared)] != 0 } {
set shared ""
}
set testname $opts(name)
if { $opts(name) == "" } {
set testname "$subdir/$name"
}
# Compile and link the unwind program.
set comp_output [compile_link_one_host_cc $opts(unwind) "tmpdir/test_x" "./testsuite/libsframe.stacktrace/libsframest/.libs/libsframest.la ./.libs/libsframe.la"]
if { $comp_output != ""} {
send_log "compilation of unwind program $opts(unwind) failed with <$comp_output>"
perror "compilation of unwind program $opts(unwind) failed"
fail $testname
return 0
}
# Compile the inputs and posibly link them together.
set unwind ""
if { [llength $opts(source)] > 0 } {
set unwind ""
if { $run_ld } {
set unwind_output "tmpdir/test_x ./testsuite/libsframe.stacktrace/libsframest/.libs/libsframest.a ./.libs/libsframe.a"
# set unwind_output "tmpdir/out.so"
# set unwind_flags "-fPIC $shared $opts(link_flags)"
} else {
set unwind_output "tmpdir/out.o"
# set unwind_flags "-fPIC -c"
}
if [board_info [target_info name] exists cflags] {
append unwind_flags " [board_info [target_info name] cflags]"
}
if [board_info [target_info name] exists ldflags] {
append unwind_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 $unwind_cflags [concat $src] -o $unwind_output"]
if { $comp_output != ""} {
send_log "compilation of SFrame test 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 unwind program on the outputs.
verbose -log "$srcdir"
set results [run_host_cmd tmpdir/test_x $unwind_output]
set f [open "tmpdir/test_x.out" "w"]
puts $f $results
close $f
if { [regexp_diff "tmpdir/test_x.out" "${file}.lk"] } then {
fail $testname
if { $verbose == 2 } then { verbose "output is [file_contents tmpdir/test_x.out]" 2 }
return 0
}
pass $testname
return 0
}
set sframe_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.lk]]
foreach sframe_test $sframe_test_list {
verbose [file rootname $sframe_test]
verbose running unwind test on $sframe_test
run_unwind_test [file rootname $sframe_test]
}

View File

@@ -14,12 +14,14 @@ check-DEJAGNU: site.exp
CC="$(CC)" \
CROSS_COMPILE="$(CROSS_COMPILE)" \
COMPAT_DEJAGNU="$(COMPAT_DEJAGNU)" \
CFLAGS="$(CFLAGS) -I$(top_srcdir)/../include -I$(top_srcdir) -I$(top_builddir)" \
HAVE_DL_ITERATE_PHDR="$(HAVE_DL_ITERATE_PHDR)" \
CFLAGS="$(CFLAGS) -I$(top_srcdir)/../include -I$(top_srcdir) -I$(top_srcdir)/testsuite/libsframe.stacktrace/libsframest/include -I$(top_builddir)" \
$(RUNTESTFLAGS); \
else echo "WARNING: could not find \`runtest'" 1>&2; :;\
fi
# libsframe encoder/decoder/find testsuite
# libsframe encoder/decoder/stacktracer testsuite
include %D%/libsframe.decode/local.mk
include %D%/libsframe.encode/local.mk
include %D%/libsframe.find/local.mk
include %D%/libsframe.stacktrace/local.mk