mirror of git://gcc.gnu.org/git/gcc.git
libbacktrace/:
* Initial implementation. ./: * MAINTAINERS (Various Maintainers): Add libbacktrace. * configure.ac (host_libs): Add libbacktrace. (target_libraries): Add libbacktrace. * Makefile.def (host_modules): Add libbacktrace. (target_modules): Likewise. * configure, Makefile.in: Rebuild. gcc/go: * config-lang.in (target_libs): Add target-libbacktrace. From-SVN: r191397
This commit is contained in:
parent
142c8954fd
commit
eff02e4f84
|
|
@ -1,3 +1,12 @@
|
||||||
|
2012-09-17 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
* MAINTAINERS (Various Maintainers): Add libbacktrace.
|
||||||
|
* configure.ac (host_libs): Add libbacktrace.
|
||||||
|
(target_libraries): Add libbacktrace.
|
||||||
|
* Makefile.def (host_modules): Add libbacktrace.
|
||||||
|
(target_modules): Likewise.
|
||||||
|
* configure, Makefile.in: Rebuild.
|
||||||
|
|
||||||
2012-09-14 David Edelsohn <dje.gcc@gmail.com>
|
2012-09-14 David Edelsohn <dje.gcc@gmail.com>
|
||||||
|
|
||||||
PR target/38607
|
PR target/38607
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ objective-c/c++ Stan Shebs stanshebs@earthlink.net
|
||||||
|
|
||||||
Various Maintainers
|
Various Maintainers
|
||||||
|
|
||||||
|
libbacktrace Ian Lance Taylor ian@airs.com
|
||||||
libcpp Per Bothner per@bothner.com
|
libcpp Per Bothner per@bothner.com
|
||||||
libcpp All C and C++ front end maintainers
|
libcpp All C and C++ front end maintainers
|
||||||
fp-bit Ian Lance Taylor ian@airs.com
|
fp-bit Ian Lance Taylor ian@airs.com
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ host_modules= { module= tcl;
|
||||||
missing=mostlyclean; };
|
missing=mostlyclean; };
|
||||||
host_modules= { module= itcl; };
|
host_modules= { module= itcl; };
|
||||||
host_modules= { module= ld; bootstrap=true; };
|
host_modules= { module= ld; bootstrap=true; };
|
||||||
|
host_modules= { module= libbacktrace; bootstrap=true; };
|
||||||
host_modules= { module= libcpp; bootstrap=true; };
|
host_modules= { module= libcpp; bootstrap=true; };
|
||||||
host_modules= { module= libdecnumber; bootstrap=true; };
|
host_modules= { module= libdecnumber; bootstrap=true; };
|
||||||
host_modules= { module= libgui; };
|
host_modules= { module= libgui; };
|
||||||
|
|
@ -121,6 +122,7 @@ target_modules = { module= libmudflap; lib_path=.libs; };
|
||||||
target_modules = { module= libssp; lib_path=.libs; };
|
target_modules = { module= libssp; lib_path=.libs; };
|
||||||
target_modules = { module= newlib; };
|
target_modules = { module= newlib; };
|
||||||
target_modules = { module= libgcc; bootstrap=true; no_check=true; };
|
target_modules = { module= libgcc; bootstrap=true; no_check=true; };
|
||||||
|
target_modules = { module= libbacktrace; };
|
||||||
target_modules = { module= libquadmath; };
|
target_modules = { module= libquadmath; };
|
||||||
target_modules = { module= libgfortran; };
|
target_modules = { module= libgfortran; };
|
||||||
target_modules = { module= libobjc; };
|
target_modules = { module= libobjc; };
|
||||||
|
|
|
||||||
1452
Makefile.in
1452
Makefile.in
File diff suppressed because it is too large
Load Diff
|
|
@ -2698,7 +2698,7 @@ build_tools="build-texinfo build-flex build-bison build-m4 build-fixincludes"
|
||||||
|
|
||||||
# these libraries are used by various programs built for the host environment
|
# these libraries are used by various programs built for the host environment
|
||||||
#
|
#
|
||||||
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
|
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktrace libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
|
||||||
|
|
||||||
# these tools are built for the host environment
|
# these tools are built for the host environment
|
||||||
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
|
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
|
||||||
|
|
@ -2717,6 +2717,7 @@ libgcj="target-libffi \
|
||||||
# the host libraries and the host tools (which may be a cross compiler)
|
# the host libraries and the host tools (which may be a cross compiler)
|
||||||
# Note that libiberty is not a target library.
|
# Note that libiberty is not a target library.
|
||||||
target_libraries="target-libgcc \
|
target_libraries="target-libgcc \
|
||||||
|
target-libbacktrace \
|
||||||
target-libgloss \
|
target-libgloss \
|
||||||
target-newlib \
|
target-newlib \
|
||||||
target-libgomp \
|
target-libgomp \
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ build_tools="build-texinfo build-flex build-bison build-m4 build-fixincludes"
|
||||||
|
|
||||||
# these libraries are used by various programs built for the host environment
|
# these libraries are used by various programs built for the host environment
|
||||||
#
|
#
|
||||||
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
|
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktrace libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
|
||||||
|
|
||||||
# these tools are built for the host environment
|
# these tools are built for the host environment
|
||||||
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
|
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
|
||||||
|
|
@ -152,6 +152,7 @@ libgcj="target-libffi \
|
||||||
# the host libraries and the host tools (which may be a cross compiler)
|
# the host libraries and the host tools (which may be a cross compiler)
|
||||||
# Note that libiberty is not a target library.
|
# Note that libiberty is not a target library.
|
||||||
target_libraries="target-libgcc \
|
target_libraries="target-libgcc \
|
||||||
|
target-libbacktrace \
|
||||||
target-libgloss \
|
target-libgloss \
|
||||||
target-newlib \
|
target-newlib \
|
||||||
target-libgomp \
|
target-libgomp \
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
2012-09-17 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
* config-lang.in (target_libs): Add target-libbacktrace.
|
||||||
|
|
||||||
2012-09-16 Ian Lance Taylor <iant@google.com>
|
2012-09-16 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* Make-lang.in (go/gogo.o): Depend on filenames.h.
|
* Make-lang.in (go/gogo.o): Depend on filenames.h.
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ language="go"
|
||||||
|
|
||||||
compilers="go1\$(exeext)"
|
compilers="go1\$(exeext)"
|
||||||
|
|
||||||
target_libs="target-libgo target-libffi"
|
target_libs="target-libgo target-libffi target-libbacktrace"
|
||||||
|
|
||||||
# The Go frontend is written in C++, so we need to build the C++
|
# The Go frontend is written in C++, so we need to build the C++
|
||||||
# compiler during stage 1.
|
# compiler during stage 1.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
2012-09-17 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
* Initial implementation.
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
# Makefile.am -- Backtrace Makefile.
|
||||||
|
# Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
|
||||||
|
# (1) Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
# (2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
|
||||||
|
# (3) The name of the author may not be used to
|
||||||
|
# endorse or promote products derived from this software without
|
||||||
|
# specific prior written permission.
|
||||||
|
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||||
|
|
||||||
|
AM_CFLAGS = $(WARN_FLAGS) $(PIC_FLAG) -I $(srcdir)/../include -I ../libgcc
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libbacktrace.la
|
||||||
|
|
||||||
|
libbacktrace_la_SOURCES = \
|
||||||
|
backtrace.h \
|
||||||
|
dwarf.c \
|
||||||
|
fileline.c \
|
||||||
|
internal.h \
|
||||||
|
posix.c \
|
||||||
|
print.c \
|
||||||
|
state.c
|
||||||
|
|
||||||
|
BACKTRACE_FILES = \
|
||||||
|
backtrace.c \
|
||||||
|
simple.c \
|
||||||
|
nounwind.c
|
||||||
|
|
||||||
|
FORMAT_FILES = \
|
||||||
|
elf.c \
|
||||||
|
unknown.c
|
||||||
|
|
||||||
|
VIEW_FILES = \
|
||||||
|
read.c \
|
||||||
|
mmapio.c
|
||||||
|
|
||||||
|
ALLOC_FILES = \
|
||||||
|
alloc.c \
|
||||||
|
mmap.c
|
||||||
|
|
||||||
|
EXTRA_libbacktrace_la_SOURCES = \
|
||||||
|
$(BACKTRACE_FILES) \
|
||||||
|
$(FORMAT_FILES) \
|
||||||
|
$(VIEW_FILES) \
|
||||||
|
$(ALLOC_FILES)
|
||||||
|
|
||||||
|
libbacktrace_la_LIBADD = \
|
||||||
|
$(BACKTRACE_FILE) \
|
||||||
|
$(FORMAT_FILE) \
|
||||||
|
$(VIEW_FILE) \
|
||||||
|
$(ALLOC_FILE)
|
||||||
|
|
||||||
|
libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
|
||||||
|
|
||||||
|
# Testsuite.
|
||||||
|
|
||||||
|
check_PROGRAMS =
|
||||||
|
|
||||||
|
TESTS = $(check_PROGRAMS)
|
||||||
|
|
||||||
|
if NATIVE
|
||||||
|
|
||||||
|
btest_SOURCES = btest.c
|
||||||
|
btest_CFLAGS = $(AM_CFLAGS) -g -O
|
||||||
|
btest_LDADD = libbacktrace.la
|
||||||
|
|
||||||
|
check_PROGRAMS += btest
|
||||||
|
|
||||||
|
endif NATIVE
|
||||||
|
|
@ -0,0 +1,740 @@
|
||||||
|
# Makefile.in generated by automake 1.11.1 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||||
|
# Inc.
|
||||||
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
# Makefile.am -- Backtrace Makefile.
|
||||||
|
# Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
|
||||||
|
# (1) Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
# (2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
|
||||||
|
# (3) The name of the author may not be used to
|
||||||
|
# endorse or promote products derived from this software without
|
||||||
|
# specific prior written permission.
|
||||||
|
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
VPATH = @srcdir@
|
||||||
|
pkgdatadir = $(datadir)/@PACKAGE@
|
||||||
|
pkgincludedir = $(includedir)/@PACKAGE@
|
||||||
|
pkglibdir = $(libdir)/@PACKAGE@
|
||||||
|
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||||
|
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||||
|
install_sh_DATA = $(install_sh) -c -m 644
|
||||||
|
install_sh_PROGRAM = $(install_sh) -c
|
||||||
|
install_sh_SCRIPT = $(install_sh) -c
|
||||||
|
INSTALL_HEADER = $(INSTALL_DATA)
|
||||||
|
transform = $(program_transform_name)
|
||||||
|
NORMAL_INSTALL = :
|
||||||
|
PRE_INSTALL = :
|
||||||
|
POST_INSTALL = :
|
||||||
|
NORMAL_UNINSTALL = :
|
||||||
|
PRE_UNINSTALL = :
|
||||||
|
POST_UNINSTALL = :
|
||||||
|
build_triplet = @build@
|
||||||
|
host_triplet = @host@
|
||||||
|
target_triplet = @target@
|
||||||
|
check_PROGRAMS = $(am__EXEEXT_1)
|
||||||
|
@NATIVE_TRUE@am__append_1 = btest
|
||||||
|
subdir = .
|
||||||
|
DIST_COMMON = README ChangeLog $(srcdir)/Makefile.in \
|
||||||
|
$(srcdir)/Makefile.am $(top_srcdir)/configure \
|
||||||
|
$(am__configure_deps) $(srcdir)/config.h.in \
|
||||||
|
$(srcdir)/../mkinstalldirs $(srcdir)/backtrace-supported.h.in \
|
||||||
|
$(srcdir)/../depcomp
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
|
||||||
|
$(top_srcdir)/../config/lead-dot.m4 \
|
||||||
|
$(top_srcdir)/../config/multi.m4 \
|
||||||
|
$(top_srcdir)/../config/override.m4 \
|
||||||
|
$(top_srcdir)/../config/unwind_ipinfo.m4 \
|
||||||
|
$(top_srcdir)/../config/warnings.m4 \
|
||||||
|
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
|
||||||
|
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
|
||||||
|
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||||
|
configure.lineno config.status.lineno
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
|
||||||
|
CONFIG_HEADER = config.h
|
||||||
|
CONFIG_CLEAN_FILES = backtrace-supported.h
|
||||||
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
|
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||||
|
am__DEPENDENCIES_1 =
|
||||||
|
am_libbacktrace_la_OBJECTS = dwarf.lo fileline.lo posix.lo print.lo \
|
||||||
|
state.lo
|
||||||
|
libbacktrace_la_OBJECTS = $(am_libbacktrace_la_OBJECTS)
|
||||||
|
@NATIVE_TRUE@am__EXEEXT_1 = btest$(EXEEXT)
|
||||||
|
@NATIVE_TRUE@am_btest_OBJECTS = btest-btest.$(OBJEXT)
|
||||||
|
btest_OBJECTS = $(am_btest_OBJECTS)
|
||||||
|
@NATIVE_TRUE@btest_DEPENDENCIES = libbacktrace.la
|
||||||
|
btest_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||||
|
--mode=link $(CCLD) $(btest_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||||
|
$(LDFLAGS) -o $@
|
||||||
|
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||||
|
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
||||||
|
am__depfiles_maybe = depfiles
|
||||||
|
am__mv = mv -f
|
||||||
|
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||||
|
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||||
|
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
|
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
CCLD = $(CC)
|
||||||
|
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||||
|
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||||
|
$(LDFLAGS) -o $@
|
||||||
|
SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \
|
||||||
|
$(btest_SOURCES)
|
||||||
|
MULTISRCTOP =
|
||||||
|
MULTIBUILDTOP =
|
||||||
|
MULTIDIRS =
|
||||||
|
MULTISUBDIR =
|
||||||
|
MULTIDO = true
|
||||||
|
MULTICLEAN = true
|
||||||
|
ETAGS = etags
|
||||||
|
CTAGS = ctags
|
||||||
|
am__tty_colors = \
|
||||||
|
red=; grn=; lgn=; blu=; std=
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
ALLOC_FILE = @ALLOC_FILE@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AR = @AR@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
BACKTRACE_FILE = @BACKTRACE_FILE@
|
||||||
|
BACKTRACE_SUPPORTED = @BACKTRACE_SUPPORTED@
|
||||||
|
BACKTRACE_SUPPORTS_THREADS = @BACKTRACE_SUPPORTS_THREADS@
|
||||||
|
BACKTRACE_USES_MALLOC = @BACKTRACE_USES_MALLOC@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
DSYMUTIL = @DSYMUTIL@
|
||||||
|
DUMPBIN = @DUMPBIN@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
FGREP = @FGREP@
|
||||||
|
FORMAT_FILE = @FORMAT_FILE@
|
||||||
|
GREP = @GREP@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LD = @LD@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBOBJS = @LIBOBJS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LIPO = @LIPO@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
NM = @NM@
|
||||||
|
NMEDIT = @NMEDIT@
|
||||||
|
OBJDUMP = @OBJDUMP@
|
||||||
|
OBJEXT = @OBJEXT@
|
||||||
|
OTOOL = @OTOOL@
|
||||||
|
OTOOL64 = @OTOOL64@
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||||
|
PACKAGE_NAME = @PACKAGE_NAME@
|
||||||
|
PACKAGE_STRING = @PACKAGE_STRING@
|
||||||
|
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||||
|
PACKAGE_URL = @PACKAGE_URL@
|
||||||
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
|
PIC_FLAG = @PIC_FLAG@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
SED = @SED@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
VIEW_FILE = @VIEW_FILE@
|
||||||
|
WARN_FLAGS = @WARN_FLAGS@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||||
|
am__include = @am__include@
|
||||||
|
am__leading_dot = @am__leading_dot@
|
||||||
|
am__quote = @am__quote@
|
||||||
|
am__tar = @am__tar@
|
||||||
|
am__untar = @am__untar@
|
||||||
|
bindir = @bindir@
|
||||||
|
build = @build@
|
||||||
|
build_alias = @build_alias@
|
||||||
|
build_cpu = @build_cpu@
|
||||||
|
build_os = @build_os@
|
||||||
|
build_vendor = @build_vendor@
|
||||||
|
builddir = @builddir@
|
||||||
|
datadir = @datadir@
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
docdir = @docdir@
|
||||||
|
dvidir = @dvidir@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
host = @host@
|
||||||
|
host_alias = @host_alias@
|
||||||
|
host_cpu = @host_cpu@
|
||||||
|
host_os = @host_os@
|
||||||
|
host_vendor = @host_vendor@
|
||||||
|
htmldir = @htmldir@
|
||||||
|
includedir = @includedir@
|
||||||
|
infodir = @infodir@
|
||||||
|
install_sh = @install_sh@
|
||||||
|
libdir = @libdir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
libtool_VERSION = @libtool_VERSION@
|
||||||
|
localedir = @localedir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
multi_basedir = @multi_basedir@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
target = @target@
|
||||||
|
target_alias = @target_alias@
|
||||||
|
target_cpu = @target_cpu@
|
||||||
|
target_os = @target_os@
|
||||||
|
target_vendor = @target_vendor@
|
||||||
|
top_build_prefix = @top_build_prefix@
|
||||||
|
top_builddir = @top_builddir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||||
|
AM_CFLAGS = $(WARN_FLAGS) $(PIC_FLAG) -I $(srcdir)/../include -I ../libgcc
|
||||||
|
noinst_LTLIBRARIES = libbacktrace.la
|
||||||
|
libbacktrace_la_SOURCES = \
|
||||||
|
backtrace.h \
|
||||||
|
dwarf.c \
|
||||||
|
fileline.c \
|
||||||
|
internal.h \
|
||||||
|
posix.c \
|
||||||
|
print.c \
|
||||||
|
state.c
|
||||||
|
|
||||||
|
BACKTRACE_FILES = \
|
||||||
|
backtrace.c \
|
||||||
|
simple.c \
|
||||||
|
nounwind.c
|
||||||
|
|
||||||
|
FORMAT_FILES = \
|
||||||
|
elf.c \
|
||||||
|
unknown.c
|
||||||
|
|
||||||
|
VIEW_FILES = \
|
||||||
|
read.c \
|
||||||
|
mmapio.c
|
||||||
|
|
||||||
|
ALLOC_FILES = \
|
||||||
|
alloc.c \
|
||||||
|
mmap.c
|
||||||
|
|
||||||
|
EXTRA_libbacktrace_la_SOURCES = \
|
||||||
|
$(BACKTRACE_FILES) \
|
||||||
|
$(FORMAT_FILES) \
|
||||||
|
$(VIEW_FILES) \
|
||||||
|
$(ALLOC_FILES)
|
||||||
|
|
||||||
|
libbacktrace_la_LIBADD = \
|
||||||
|
$(BACKTRACE_FILE) \
|
||||||
|
$(FORMAT_FILE) \
|
||||||
|
$(VIEW_FILE) \
|
||||||
|
$(ALLOC_FILE)
|
||||||
|
|
||||||
|
libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
|
||||||
|
TESTS = $(check_PROGRAMS)
|
||||||
|
@NATIVE_TRUE@btest_SOURCES = btest.c
|
||||||
|
@NATIVE_TRUE@btest_CFLAGS = $(AM_CFLAGS) -g -O
|
||||||
|
@NATIVE_TRUE@btest_LDADD = libbacktrace.la
|
||||||
|
all: config.h
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .lo .o .obj
|
||||||
|
am--refresh:
|
||||||
|
@:
|
||||||
|
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||||
|
@for dep in $?; do \
|
||||||
|
case '$(am__configure_deps)' in \
|
||||||
|
*$$dep*) \
|
||||||
|
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
|
||||||
|
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
|
||||||
|
&& exit 0; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||||
|
$(am__cd) $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --foreign Makefile
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
@case '$?' in \
|
||||||
|
*config.status*) \
|
||||||
|
echo ' $(SHELL) ./config.status'; \
|
||||||
|
$(SHELL) ./config.status;; \
|
||||||
|
*) \
|
||||||
|
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||||
|
esac;
|
||||||
|
|
||||||
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
$(SHELL) ./config.status --recheck
|
||||||
|
|
||||||
|
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||||
|
$(am__cd) $(srcdir) && $(AUTOCONF)
|
||||||
|
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||||
|
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||||
|
$(am__aclocal_m4_deps):
|
||||||
|
|
||||||
|
config.h: stamp-h1
|
||||||
|
@if test ! -f $@; then \
|
||||||
|
rm -f stamp-h1; \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
|
||||||
|
else :; fi
|
||||||
|
|
||||||
|
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||||
|
@rm -f stamp-h1
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||||
|
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||||
|
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
||||||
|
rm -f stamp-h1
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
distclean-hdr:
|
||||||
|
-rm -f config.h stamp-h1
|
||||||
|
backtrace-supported.h: $(top_builddir)/config.status $(srcdir)/backtrace-supported.h.in
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||||
|
|
||||||
|
clean-noinstLTLIBRARIES:
|
||||||
|
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
|
||||||
|
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
|
||||||
|
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||||
|
test "$$dir" != "$$p" || dir=.; \
|
||||||
|
echo "rm -f \"$${dir}/so_locations\""; \
|
||||||
|
rm -f "$${dir}/so_locations"; \
|
||||||
|
done
|
||||||
|
libbacktrace.la: $(libbacktrace_la_OBJECTS) $(libbacktrace_la_DEPENDENCIES)
|
||||||
|
$(LINK) $(libbacktrace_la_OBJECTS) $(libbacktrace_la_LIBADD) $(LIBS)
|
||||||
|
|
||||||
|
clean-checkPROGRAMS:
|
||||||
|
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||||
|
echo " rm -f" $$list; \
|
||||||
|
rm -f $$list || exit $$?; \
|
||||||
|
test -n "$(EXEEXT)" || exit 0; \
|
||||||
|
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||||
|
echo " rm -f" $$list; \
|
||||||
|
rm -f $$list
|
||||||
|
btest$(EXEEXT): $(btest_OBJECTS) $(btest_DEPENDENCIES)
|
||||||
|
@rm -f btest$(EXEEXT)
|
||||||
|
$(btest_LINK) $(btest_OBJECTS) $(btest_LDADD) $(LIBS)
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.$(OBJEXT)
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btest-btest.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileline.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmap.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmapio.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nounwind.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown.Plo@am__quote@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||||
|
|
||||||
|
.c.lo:
|
||||||
|
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||||
|
|
||||||
|
btest-btest.o: btest.c
|
||||||
|
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(btest_CFLAGS) $(CFLAGS) -MT btest-btest.o -MD -MP -MF $(DEPDIR)/btest-btest.Tpo -c -o btest-btest.o `test -f 'btest.c' || echo '$(srcdir)/'`btest.c
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/btest-btest.Tpo $(DEPDIR)/btest-btest.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='btest.c' object='btest-btest.o' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(btest_CFLAGS) $(CFLAGS) -c -o btest-btest.o `test -f 'btest.c' || echo '$(srcdir)/'`btest.c
|
||||||
|
|
||||||
|
btest-btest.obj: btest.c
|
||||||
|
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(btest_CFLAGS) $(CFLAGS) -MT btest-btest.obj -MD -MP -MF $(DEPDIR)/btest-btest.Tpo -c -o btest-btest.obj `if test -f 'btest.c'; then $(CYGPATH_W) 'btest.c'; else $(CYGPATH_W) '$(srcdir)/btest.c'; fi`
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/btest-btest.Tpo $(DEPDIR)/btest-btest.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='btest.c' object='btest-btest.obj' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(btest_CFLAGS) $(CFLAGS) -c -o btest-btest.obj `if test -f 'btest.c'; then $(CYGPATH_W) 'btest.c'; else $(CYGPATH_W) '$(srcdir)/btest.c'; fi`
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
|
||||||
|
distclean-libtool:
|
||||||
|
-rm -f libtool config.lt
|
||||||
|
|
||||||
|
# GNU Make needs to see an explicit $(MAKE) variable in the command it
|
||||||
|
# runs to enable its job server during parallel builds. Hence the
|
||||||
|
# comments below.
|
||||||
|
all-multi:
|
||||||
|
$(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
|
||||||
|
install-multi:
|
||||||
|
$(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)
|
||||||
|
|
||||||
|
mostlyclean-multi:
|
||||||
|
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)
|
||||||
|
clean-multi:
|
||||||
|
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)
|
||||||
|
distclean-multi:
|
||||||
|
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
|
||||||
|
maintainer-clean-multi:
|
||||||
|
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||||
|
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
set x; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||||
|
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||||
|
shift; \
|
||||||
|
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||||
|
test -n "$$unique" || unique=$$empty_fix; \
|
||||||
|
if test $$# -gt 0; then \
|
||||||
|
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
"$$@" $$unique; \
|
||||||
|
else \
|
||||||
|
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$unique; \
|
||||||
|
fi; \
|
||||||
|
fi
|
||||||
|
ctags: CTAGS
|
||||||
|
CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||||
|
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||||
|
test -z "$(CTAGS_ARGS)$$unique" \
|
||||||
|
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||||
|
$$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& $(am__cd) $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
|
check-TESTS: $(TESTS)
|
||||||
|
@failed=0; all=0; xfail=0; xpass=0; skip=0; \
|
||||||
|
srcdir=$(srcdir); export srcdir; \
|
||||||
|
list=' $(TESTS) '; \
|
||||||
|
$(am__tty_colors); \
|
||||||
|
if test -n "$$list"; then \
|
||||||
|
for tst in $$list; do \
|
||||||
|
if test -f ./$$tst; then dir=./; \
|
||||||
|
elif test -f $$tst; then dir=; \
|
||||||
|
else dir="$(srcdir)/"; fi; \
|
||||||
|
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
|
||||||
|
all=`expr $$all + 1`; \
|
||||||
|
case " $(XFAIL_TESTS) " in \
|
||||||
|
*[\ \ ]$$tst[\ \ ]*) \
|
||||||
|
xpass=`expr $$xpass + 1`; \
|
||||||
|
failed=`expr $$failed + 1`; \
|
||||||
|
col=$$red; res=XPASS; \
|
||||||
|
;; \
|
||||||
|
*) \
|
||||||
|
col=$$grn; res=PASS; \
|
||||||
|
;; \
|
||||||
|
esac; \
|
||||||
|
elif test $$? -ne 77; then \
|
||||||
|
all=`expr $$all + 1`; \
|
||||||
|
case " $(XFAIL_TESTS) " in \
|
||||||
|
*[\ \ ]$$tst[\ \ ]*) \
|
||||||
|
xfail=`expr $$xfail + 1`; \
|
||||||
|
col=$$lgn; res=XFAIL; \
|
||||||
|
;; \
|
||||||
|
*) \
|
||||||
|
failed=`expr $$failed + 1`; \
|
||||||
|
col=$$red; res=FAIL; \
|
||||||
|
;; \
|
||||||
|
esac; \
|
||||||
|
else \
|
||||||
|
skip=`expr $$skip + 1`; \
|
||||||
|
col=$$blu; res=SKIP; \
|
||||||
|
fi; \
|
||||||
|
echo "$${col}$$res$${std}: $$tst"; \
|
||||||
|
done; \
|
||||||
|
if test "$$all" -eq 1; then \
|
||||||
|
tests="test"; \
|
||||||
|
All=""; \
|
||||||
|
else \
|
||||||
|
tests="tests"; \
|
||||||
|
All="All "; \
|
||||||
|
fi; \
|
||||||
|
if test "$$failed" -eq 0; then \
|
||||||
|
if test "$$xfail" -eq 0; then \
|
||||||
|
banner="$$All$$all $$tests passed"; \
|
||||||
|
else \
|
||||||
|
if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
|
||||||
|
banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
|
||||||
|
fi; \
|
||||||
|
else \
|
||||||
|
if test "$$xpass" -eq 0; then \
|
||||||
|
banner="$$failed of $$all $$tests failed"; \
|
||||||
|
else \
|
||||||
|
if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
|
||||||
|
banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
|
||||||
|
fi; \
|
||||||
|
fi; \
|
||||||
|
dashes="$$banner"; \
|
||||||
|
skipped=""; \
|
||||||
|
if test "$$skip" -ne 0; then \
|
||||||
|
if test "$$skip" -eq 1; then \
|
||||||
|
skipped="($$skip test was not run)"; \
|
||||||
|
else \
|
||||||
|
skipped="($$skip tests were not run)"; \
|
||||||
|
fi; \
|
||||||
|
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
|
||||||
|
dashes="$$skipped"; \
|
||||||
|
fi; \
|
||||||
|
report=""; \
|
||||||
|
if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
|
||||||
|
report="Please report to $(PACKAGE_BUGREPORT)"; \
|
||||||
|
test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
|
||||||
|
dashes="$$report"; \
|
||||||
|
fi; \
|
||||||
|
dashes=`echo "$$dashes" | sed s/./=/g`; \
|
||||||
|
if test "$$failed" -eq 0; then \
|
||||||
|
echo "$$grn$$dashes"; \
|
||||||
|
else \
|
||||||
|
echo "$$red$$dashes"; \
|
||||||
|
fi; \
|
||||||
|
echo "$$banner"; \
|
||||||
|
test -z "$$skipped" || echo "$$skipped"; \
|
||||||
|
test -z "$$report" || echo "$$report"; \
|
||||||
|
echo "$$dashes$$std"; \
|
||||||
|
test "$$failed" -eq 0; \
|
||||||
|
else :; fi
|
||||||
|
check-am: all-am
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
|
||||||
|
check: check-am
|
||||||
|
all-am: Makefile $(LTLIBRARIES) all-multi config.h
|
||||||
|
installdirs:
|
||||||
|
install: install-am
|
||||||
|
install-exec: install-exec-am
|
||||||
|
install-data: install-data-am
|
||||||
|
uninstall: uninstall-am
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-am
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
`test -z '$(STRIP)' || \
|
||||||
|
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||||
|
mostlyclean-generic:
|
||||||
|
|
||||||
|
clean-generic:
|
||||||
|
|
||||||
|
distclean-generic:
|
||||||
|
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||||
|
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-am clean-multi
|
||||||
|
|
||||||
|
clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
|
||||||
|
clean-noinstLTLIBRARIES mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-am distclean-multi
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
-rm -f Makefile
|
||||||
|
distclean-am: clean-am distclean-compile distclean-generic \
|
||||||
|
distclean-hdr distclean-libtool distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-am
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
html: html-am
|
||||||
|
|
||||||
|
html-am:
|
||||||
|
|
||||||
|
info: info-am
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-dvi: install-dvi-am
|
||||||
|
|
||||||
|
install-dvi-am:
|
||||||
|
|
||||||
|
install-exec-am: install-multi
|
||||||
|
|
||||||
|
install-html: install-html-am
|
||||||
|
|
||||||
|
install-html-am:
|
||||||
|
|
||||||
|
install-info: install-info-am
|
||||||
|
|
||||||
|
install-info-am:
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
install-pdf: install-pdf-am
|
||||||
|
|
||||||
|
install-pdf-am:
|
||||||
|
|
||||||
|
install-ps: install-ps-am
|
||||||
|
|
||||||
|
install-ps-am:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-am maintainer-clean-multi
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -rf $(top_srcdir)/autom4te.cache
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
-rm -f Makefile
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-am mostlyclean-multi
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||||
|
mostlyclean-libtool
|
||||||
|
|
||||||
|
pdf: pdf-am
|
||||||
|
|
||||||
|
pdf-am:
|
||||||
|
|
||||||
|
ps: ps-am
|
||||||
|
|
||||||
|
ps-am:
|
||||||
|
|
||||||
|
uninstall-am:
|
||||||
|
|
||||||
|
.MAKE: all all-multi check-am clean-multi distclean-multi install-am \
|
||||||
|
install-multi install-strip maintainer-clean-multi \
|
||||||
|
mostlyclean-multi
|
||||||
|
|
||||||
|
.PHONY: CTAGS GTAGS all all-am all-multi am--refresh check check-TESTS \
|
||||||
|
check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
|
||||||
|
clean-multi clean-noinstLTLIBRARIES ctags distclean \
|
||||||
|
distclean-compile distclean-generic distclean-hdr \
|
||||||
|
distclean-libtool distclean-multi distclean-tags dvi dvi-am \
|
||||||
|
html html-am info info-am install install-am install-data \
|
||||||
|
install-data-am install-dvi install-dvi-am install-exec \
|
||||||
|
install-exec-am install-html install-html-am install-info \
|
||||||
|
install-info-am install-man install-multi install-pdf \
|
||||||
|
install-pdf-am install-ps install-ps-am install-strip \
|
||||||
|
installcheck installcheck-am installdirs maintainer-clean \
|
||||||
|
maintainer-clean-generic maintainer-clean-multi mostlyclean \
|
||||||
|
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||||
|
mostlyclean-multi pdf pdf-am ps ps-am tags uninstall \
|
||||||
|
uninstall-am
|
||||||
|
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
The libbacktrace library
|
||||||
|
Initially written by Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
The libbacktrace library may be linked into a program or library and
|
||||||
|
used to produce symbolic backtraces. Sample uses would be to print a
|
||||||
|
detailed backtrace when an error occurs or to gather detailed
|
||||||
|
profiling information.
|
||||||
|
|
||||||
|
The libbacktrace library is provided under a BSD license. See the
|
||||||
|
source files for the exact license text.
|
||||||
|
|
||||||
|
The public functions are declared and documented in the header file
|
||||||
|
backtrace.h, which should be #include'd by a user of the library.
|
||||||
|
|
||||||
|
Building libbacktrace will generate a file backtrace-supported.h,
|
||||||
|
which a user of the library may use to determine whether backtraces
|
||||||
|
will work. See the source file backtrace-supported.h.in for the
|
||||||
|
macros that it defines.
|
||||||
|
|
||||||
|
As of September 2012, libbacktrace only supports ELF executables with
|
||||||
|
DWARF debugging information. The library is written to make it
|
||||||
|
straightforward to add support for other object file and debugging
|
||||||
|
formats.
|
||||||
|
|
@ -0,0 +1,981 @@
|
||||||
|
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
|
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||||
|
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||||
|
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
|
||||||
|
[m4_warning([this file was generated for autoconf 2.64.
|
||||||
|
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||||
|
If you have problems, you may need to regenerate the build system entirely.
|
||||||
|
To do so, use the procedure documented by the package, typically `autoreconf'.])])
|
||||||
|
|
||||||
|
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# AM_AUTOMAKE_VERSION(VERSION)
|
||||||
|
# ----------------------------
|
||||||
|
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||||
|
# generated from the m4 files accompanying Automake X.Y.
|
||||||
|
# (This private macro should not be called outside this file.)
|
||||||
|
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||||
|
[am__api_version='1.11'
|
||||||
|
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||||
|
dnl require some minimum version. Point them to the right macro.
|
||||||
|
m4_if([$1], [1.11.1], [],
|
||||||
|
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
# _AM_AUTOCONF_VERSION(VERSION)
|
||||||
|
# -----------------------------
|
||||||
|
# aclocal traces this macro to find the Autoconf version.
|
||||||
|
# This is a private macro too. Using m4_define simplifies
|
||||||
|
# the logic in aclocal, which can simply ignore this definition.
|
||||||
|
m4_define([_AM_AUTOCONF_VERSION], [])
|
||||||
|
|
||||||
|
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||||
|
# -------------------------------
|
||||||
|
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||||
|
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||||
|
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||||
|
[AM_AUTOMAKE_VERSION([1.11.1])dnl
|
||||||
|
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||||
|
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||||
|
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||||
|
|
||||||
|
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||||
|
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||||
|
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||||
|
#
|
||||||
|
# Of course, Automake must honor this variable whenever it calls a
|
||||||
|
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||||
|
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||||
|
# depending on how configure is run. This is pretty annoying, since
|
||||||
|
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||||
|
# source directory, any form will work fine, but in subdirectories a
|
||||||
|
# relative path needs to be adjusted first.
|
||||||
|
#
|
||||||
|
# $ac_aux_dir/missing
|
||||||
|
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||||
|
# $top_srcdir/$ac_aux_dir/missing
|
||||||
|
# fails if $ac_aux_dir is absolute,
|
||||||
|
# fails when called from a subdirectory in a VPATH build with
|
||||||
|
# a relative $ac_aux_dir
|
||||||
|
#
|
||||||
|
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||||
|
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||||
|
# harmless because $srcdir is `.', but things will broke when you
|
||||||
|
# start a VPATH build or use an absolute $srcdir.
|
||||||
|
#
|
||||||
|
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||||
|
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||||
|
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||||
|
# and then we would define $MISSING as
|
||||||
|
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||||
|
# This will work as long as MISSING is not called from configure, because
|
||||||
|
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||||
|
# However there are other variables, like CC, which are often used in
|
||||||
|
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||||
|
#
|
||||||
|
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||||
|
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||||
|
# configured tree to be moved without reconfiguration.
|
||||||
|
|
||||||
|
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||||
|
[dnl Rely on autoconf to set up CDPATH properly.
|
||||||
|
AC_PREREQ([2.50])dnl
|
||||||
|
# expand $ac_aux_dir to an absolute path
|
||||||
|
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||||
|
])
|
||||||
|
|
||||||
|
# AM_CONDITIONAL -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 9
|
||||||
|
|
||||||
|
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||||
|
# -------------------------------------
|
||||||
|
# Define a conditional.
|
||||||
|
AC_DEFUN([AM_CONDITIONAL],
|
||||||
|
[AC_PREREQ(2.52)dnl
|
||||||
|
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||||
|
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||||
|
AC_SUBST([$1_TRUE])dnl
|
||||||
|
AC_SUBST([$1_FALSE])dnl
|
||||||
|
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||||
|
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||||
|
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||||
|
if $2; then
|
||||||
|
$1_TRUE=
|
||||||
|
$1_FALSE='#'
|
||||||
|
else
|
||||||
|
$1_TRUE='#'
|
||||||
|
$1_FALSE=
|
||||||
|
fi
|
||||||
|
AC_CONFIG_COMMANDS_PRE(
|
||||||
|
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||||
|
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||||
|
Usually this means the macro was only invoked conditionally.]])
|
||||||
|
fi])])
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 10
|
||||||
|
|
||||||
|
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
||||||
|
# written in clear, in which case automake, when reading aclocal.m4,
|
||||||
|
# will think it sees a *use*, and therefore will trigger all it's
|
||||||
|
# C support machinery. Also note that it means that autoscan, seeing
|
||||||
|
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
||||||
|
|
||||||
|
|
||||||
|
# _AM_DEPENDENCIES(NAME)
|
||||||
|
# ----------------------
|
||||||
|
# See how the compiler implements dependency checking.
|
||||||
|
# NAME is "CC", "CXX", "GCJ", or "OBJC".
|
||||||
|
# We try a few techniques and use that to set a single cache variable.
|
||||||
|
#
|
||||||
|
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
|
||||||
|
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
|
||||||
|
# dependency, and given that the user is not expected to run this macro,
|
||||||
|
# just rely on AC_PROG_CC.
|
||||||
|
AC_DEFUN([_AM_DEPENDENCIES],
|
||||||
|
[AC_REQUIRE([AM_SET_DEPDIR])dnl
|
||||||
|
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
|
||||||
|
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
|
||||||
|
AC_REQUIRE([AM_DEP_TRACK])dnl
|
||||||
|
|
||||||
|
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
|
||||||
|
[$1], CXX, [depcc="$CXX" am_compiler_list=],
|
||||||
|
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
|
||||||
|
[$1], UPC, [depcc="$UPC" am_compiler_list=],
|
||||||
|
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
||||||
|
[depcc="$$1" am_compiler_list=])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([dependency style of $depcc],
|
||||||
|
[am_cv_$1_dependencies_compiler_type],
|
||||||
|
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
|
||||||
|
# We make a subdir and do the tests there. Otherwise we can end up
|
||||||
|
# making bogus files that we don't know about and never remove. For
|
||||||
|
# instance it was reported that on HP-UX the gcc test will end up
|
||||||
|
# making a dummy file named `D' -- because `-MD' means `put the output
|
||||||
|
# in D'.
|
||||||
|
mkdir conftest.dir
|
||||||
|
# Copy depcomp to subdir because otherwise we won't find it if we're
|
||||||
|
# using a relative directory.
|
||||||
|
cp "$am_depcomp" conftest.dir
|
||||||
|
cd conftest.dir
|
||||||
|
# We will build objects and dependencies in a subdirectory because
|
||||||
|
# it helps to detect inapplicable dependency modes. For instance
|
||||||
|
# both Tru64's cc and ICC support -MD to output dependencies as a
|
||||||
|
# side effect of compilation, but ICC will put the dependencies in
|
||||||
|
# the current directory while Tru64 will put them in the object
|
||||||
|
# directory.
|
||||||
|
mkdir sub
|
||||||
|
|
||||||
|
am_cv_$1_dependencies_compiler_type=none
|
||||||
|
if test "$am_compiler_list" = ""; then
|
||||||
|
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
|
||||||
|
fi
|
||||||
|
am__universal=false
|
||||||
|
m4_case([$1], [CC],
|
||||||
|
[case " $depcc " in #(
|
||||||
|
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||||
|
esac],
|
||||||
|
[CXX],
|
||||||
|
[case " $depcc " in #(
|
||||||
|
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||||
|
esac])
|
||||||
|
|
||||||
|
for depmode in $am_compiler_list; do
|
||||||
|
# Setup a source with many dependencies, because some compilers
|
||||||
|
# like to wrap large dependency lists on column 80 (with \), and
|
||||||
|
# we should not choose a depcomp mode which is confused by this.
|
||||||
|
#
|
||||||
|
# We need to recreate these files for each test, as the compiler may
|
||||||
|
# overwrite some of them when testing with obscure command lines.
|
||||||
|
# This happens at least with the AIX C compiler.
|
||||||
|
: > sub/conftest.c
|
||||||
|
for i in 1 2 3 4 5 6; do
|
||||||
|
echo '#include "conftst'$i'.h"' >> sub/conftest.c
|
||||||
|
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
|
||||||
|
# Solaris 8's {/usr,}/bin/sh.
|
||||||
|
touch sub/conftst$i.h
|
||||||
|
done
|
||||||
|
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
|
||||||
|
|
||||||
|
# We check with `-c' and `-o' for the sake of the "dashmstdout"
|
||||||
|
# mode. It turns out that the SunPro C++ compiler does not properly
|
||||||
|
# handle `-M -o', and we need to detect this. Also, some Intel
|
||||||
|
# versions had trouble with output in subdirs
|
||||||
|
am__obj=sub/conftest.${OBJEXT-o}
|
||||||
|
am__minus_obj="-o $am__obj"
|
||||||
|
case $depmode in
|
||||||
|
gcc)
|
||||||
|
# This depmode causes a compiler race in universal mode.
|
||||||
|
test "$am__universal" = false || continue
|
||||||
|
;;
|
||||||
|
nosideeffect)
|
||||||
|
# after this tag, mechanisms are not by side-effect, so they'll
|
||||||
|
# only be used when explicitly requested
|
||||||
|
if test "x$enable_dependency_tracking" = xyes; then
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
msvisualcpp | msvcmsys)
|
||||||
|
# This compiler won't grok `-c -o', but also, the minuso test has
|
||||||
|
# not run yet. These depmodes are late enough in the game, and
|
||||||
|
# so weak that their functioning should not be impacted.
|
||||||
|
am__obj=conftest.${OBJEXT-o}
|
||||||
|
am__minus_obj=
|
||||||
|
;;
|
||||||
|
none) break ;;
|
||||||
|
esac
|
||||||
|
if depmode=$depmode \
|
||||||
|
source=sub/conftest.c object=$am__obj \
|
||||||
|
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
|
||||||
|
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
|
||||||
|
>/dev/null 2>conftest.err &&
|
||||||
|
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||||
|
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||||
|
grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
|
||||||
|
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
|
||||||
|
# icc doesn't choke on unknown options, it will just issue warnings
|
||||||
|
# or remarks (even with -Werror). So we grep stderr for any message
|
||||||
|
# that says an option was ignored or not supported.
|
||||||
|
# When given -MP, icc 7.0 and 7.1 complain thusly:
|
||||||
|
# icc: Command line warning: ignoring option '-M'; no argument required
|
||||||
|
# The diagnosis changed in icc 8.0:
|
||||||
|
# icc: Command line remark: option '-MP' not supported
|
||||||
|
if (grep 'ignoring option' conftest.err ||
|
||||||
|
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
|
||||||
|
am_cv_$1_dependencies_compiler_type=$depmode
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
rm -rf conftest.dir
|
||||||
|
else
|
||||||
|
am_cv_$1_dependencies_compiler_type=none
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
|
||||||
|
AM_CONDITIONAL([am__fastdep$1], [
|
||||||
|
test "x$enable_dependency_tracking" != xno \
|
||||||
|
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# AM_SET_DEPDIR
|
||||||
|
# -------------
|
||||||
|
# Choose a directory name for dependency files.
|
||||||
|
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
|
||||||
|
AC_DEFUN([AM_SET_DEPDIR],
|
||||||
|
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||||
|
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# AM_DEP_TRACK
|
||||||
|
# ------------
|
||||||
|
AC_DEFUN([AM_DEP_TRACK],
|
||||||
|
[AC_ARG_ENABLE(dependency-tracking,
|
||||||
|
[ --disable-dependency-tracking speeds up one-time build
|
||||||
|
--enable-dependency-tracking do not reject slow dependency extractors])
|
||||||
|
if test "x$enable_dependency_tracking" != xno; then
|
||||||
|
am_depcomp="$ac_aux_dir/depcomp"
|
||||||
|
AMDEPBACKSLASH='\'
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
||||||
|
AC_SUBST([AMDEPBACKSLASH])dnl
|
||||||
|
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
#serial 5
|
||||||
|
|
||||||
|
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||||
|
# ------------------------------
|
||||||
|
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||||
|
[{
|
||||||
|
# Autoconf 2.62 quotes --file arguments for eval, but not when files
|
||||||
|
# are listed without --file. Let's play safe and only enable the eval
|
||||||
|
# if we detect the quoting.
|
||||||
|
case $CONFIG_FILES in
|
||||||
|
*\'*) eval set x "$CONFIG_FILES" ;;
|
||||||
|
*) set x $CONFIG_FILES ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
for mf
|
||||||
|
do
|
||||||
|
# Strip MF so we end up with the name of the file.
|
||||||
|
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||||
|
# Check whether this is an Automake generated Makefile or not.
|
||||||
|
# We used to match only the files named `Makefile.in', but
|
||||||
|
# some people rename them; so instead we look at the file content.
|
||||||
|
# Grep'ing the first line is not enough: some people post-process
|
||||||
|
# each Makefile.in and add a new line on top of each file to say so.
|
||||||
|
# Grep'ing the whole file is not good either: AIX grep has a line
|
||||||
|
# limit of 2048, but all sed's we know have understand at least 4000.
|
||||||
|
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
|
||||||
|
dirpart=`AS_DIRNAME("$mf")`
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# Extract the definition of DEPDIR, am__include, and am__quote
|
||||||
|
# from the Makefile without running `make'.
|
||||||
|
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
||||||
|
test -z "$DEPDIR" && continue
|
||||||
|
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
||||||
|
test -z "am__include" && continue
|
||||||
|
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
||||||
|
# When using ansi2knr, U may be empty or an underscore; expand it
|
||||||
|
U=`sed -n 's/^U = //p' < "$mf"`
|
||||||
|
# Find all dependency output files, they are included files with
|
||||||
|
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
||||||
|
# simplest approach to changing $(DEPDIR) to its actual value in the
|
||||||
|
# expansion.
|
||||||
|
for file in `sed -n "
|
||||||
|
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
||||||
|
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
|
||||||
|
# Make sure the directory exists.
|
||||||
|
test -f "$dirpart/$file" && continue
|
||||||
|
fdir=`AS_DIRNAME(["$file"])`
|
||||||
|
AS_MKDIR_P([$dirpart/$fdir])
|
||||||
|
# echo "creating $dirpart/$file"
|
||||||
|
echo '# dummy' > "$dirpart/$file"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||||
|
|
||||||
|
|
||||||
|
# AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||||
|
# -----------------------------
|
||||||
|
# This macro should only be invoked once -- use via AC_REQUIRE.
|
||||||
|
#
|
||||||
|
# This code is only required when automatic dependency tracking
|
||||||
|
# is enabled. FIXME. This creates each `.P' file that we will
|
||||||
|
# need in order to bootstrap the dependency handling code.
|
||||||
|
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||||
|
[AC_CONFIG_COMMANDS([depfiles],
|
||||||
|
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||||
|
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
|
||||||
|
])
|
||||||
|
|
||||||
|
# Do all the work for Automake. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
|
# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 16
|
||||||
|
|
||||||
|
# This macro actually does too much. Some checks are only needed if
|
||||||
|
# your package does certain things. But this isn't really a big deal.
|
||||||
|
|
||||||
|
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||||
|
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||||
|
# -----------------------------------------------
|
||||||
|
# The call with PACKAGE and VERSION arguments is the old style
|
||||||
|
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||||
|
# and VERSION should now be passed to AC_INIT and removed from
|
||||||
|
# the call to AM_INIT_AUTOMAKE.
|
||||||
|
# We support both call styles for the transition. After
|
||||||
|
# the next Automake release, Autoconf can make the AC_INIT
|
||||||
|
# arguments mandatory, and then we can depend on a new Autoconf
|
||||||
|
# release and drop the old call support.
|
||||||
|
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||||
|
[AC_PREREQ([2.62])dnl
|
||||||
|
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||||
|
dnl the ones we care about.
|
||||||
|
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||||
|
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||||
|
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||||
|
if test "`cd $srcdir && pwd`" != "`pwd`"; then
|
||||||
|
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
|
||||||
|
# is not polluted with repeated "-I."
|
||||||
|
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
|
||||||
|
# test to see if srcdir already configured
|
||||||
|
if test -f $srcdir/config.status; then
|
||||||
|
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# test whether we have cygpath
|
||||||
|
if test -z "$CYGPATH_W"; then
|
||||||
|
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||||
|
CYGPATH_W='cygpath -w'
|
||||||
|
else
|
||||||
|
CYGPATH_W=echo
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AC_SUBST([CYGPATH_W])
|
||||||
|
|
||||||
|
# Define the identity of the package.
|
||||||
|
dnl Distinguish between old-style and new-style calls.
|
||||||
|
m4_ifval([$2],
|
||||||
|
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||||
|
AC_SUBST([PACKAGE], [$1])dnl
|
||||||
|
AC_SUBST([VERSION], [$2])],
|
||||||
|
[_AM_SET_OPTIONS([$1])dnl
|
||||||
|
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||||
|
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
|
||||||
|
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||||
|
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||||
|
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||||
|
|
||||||
|
_AM_IF_OPTION([no-define],,
|
||||||
|
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||||
|
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
|
||||||
|
|
||||||
|
# Some tools Automake needs.
|
||||||
|
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||||
|
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||||
|
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
|
||||||
|
AM_MISSING_PROG(AUTOCONF, autoconf)
|
||||||
|
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
|
||||||
|
AM_MISSING_PROG(AUTOHEADER, autoheader)
|
||||||
|
AM_MISSING_PROG(MAKEINFO, makeinfo)
|
||||||
|
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||||
|
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
|
||||||
|
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
|
||||||
|
# We need awk for the "check" target. The system "awk" is bad on
|
||||||
|
# some platforms.
|
||||||
|
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||||
|
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||||
|
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||||
|
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||||
|
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||||
|
[_AM_PROG_TAR([v7])])])
|
||||||
|
_AM_IF_OPTION([no-dependencies],,
|
||||||
|
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||||
|
[_AM_DEPENDENCIES(CC)],
|
||||||
|
[define([AC_PROG_CC],
|
||||||
|
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
|
||||||
|
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||||
|
[_AM_DEPENDENCIES(CXX)],
|
||||||
|
[define([AC_PROG_CXX],
|
||||||
|
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
|
||||||
|
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
|
||||||
|
[_AM_DEPENDENCIES(OBJC)],
|
||||||
|
[define([AC_PROG_OBJC],
|
||||||
|
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
|
||||||
|
])
|
||||||
|
_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
|
||||||
|
dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
|
||||||
|
dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
|
||||||
|
dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
|
||||||
|
AC_CONFIG_COMMANDS_PRE(dnl
|
||||||
|
[m4_provide_if([_AM_COMPILER_EXEEXT],
|
||||||
|
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
|
||||||
|
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
|
||||||
|
dnl mangled by Autoconf and run in a shell conditional statement.
|
||||||
|
m4_define([_AC_COMPILER_EXEEXT],
|
||||||
|
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
|
||||||
|
|
||||||
|
|
||||||
|
# When config.status generates a header, we must update the stamp-h file.
|
||||||
|
# This file resides in the same directory as the config header
|
||||||
|
# that is generated. The stamp files are numbered to have different names.
|
||||||
|
|
||||||
|
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||||
|
# loop where config.status creates the headers, so we can generate
|
||||||
|
# our stamp files there.
|
||||||
|
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||||
|
[# Compute $1's index in $config_headers.
|
||||||
|
_am_arg=$1
|
||||||
|
_am_stamp_count=1
|
||||||
|
for _am_header in $config_headers :; do
|
||||||
|
case $_am_header in
|
||||||
|
$_am_arg | $_am_arg:* )
|
||||||
|
break ;;
|
||||||
|
* )
|
||||||
|
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||||
|
|
||||||
|
# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# AM_PROG_INSTALL_SH
|
||||||
|
# ------------------
|
||||||
|
# Define $install_sh.
|
||||||
|
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||||
|
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||||
|
if test x"${install_sh}" != xset; then
|
||||||
|
case $am_aux_dir in
|
||||||
|
*\ * | *\ *)
|
||||||
|
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
|
||||||
|
*)
|
||||||
|
install_sh="\${SHELL} $am_aux_dir/install-sh"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
AC_SUBST(install_sh)])
|
||||||
|
|
||||||
|
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||||
|
# From Jim Meyering
|
||||||
|
|
||||||
|
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 5
|
||||||
|
|
||||||
|
# AM_MAINTAINER_MODE([DEFAULT-MODE])
|
||||||
|
# ----------------------------------
|
||||||
|
# Control maintainer-specific portions of Makefiles.
|
||||||
|
# Default is to disable them, unless `enable' is passed literally.
|
||||||
|
# For symmetry, `disable' may be passed as well. Anyway, the user
|
||||||
|
# can override the default with the --enable/--disable switch.
|
||||||
|
AC_DEFUN([AM_MAINTAINER_MODE],
|
||||||
|
[m4_case(m4_default([$1], [disable]),
|
||||||
|
[enable], [m4_define([am_maintainer_other], [disable])],
|
||||||
|
[disable], [m4_define([am_maintainer_other], [enable])],
|
||||||
|
[m4_define([am_maintainer_other], [enable])
|
||||||
|
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
|
||||||
|
AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
|
||||||
|
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
|
||||||
|
AC_ARG_ENABLE([maintainer-mode],
|
||||||
|
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
|
||||||
|
(and sometimes confusing) to the casual installer],
|
||||||
|
[USE_MAINTAINER_MODE=$enableval],
|
||||||
|
[USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
|
||||||
|
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
|
||||||
|
AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
|
||||||
|
MAINT=$MAINTAINER_MODE_TRUE
|
||||||
|
AC_SUBST([MAINT])dnl
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
|
||||||
|
|
||||||
|
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 4
|
||||||
|
|
||||||
|
# AM_MAKE_INCLUDE()
|
||||||
|
# -----------------
|
||||||
|
# Check to see how make treats includes.
|
||||||
|
AC_DEFUN([AM_MAKE_INCLUDE],
|
||||||
|
[am_make=${MAKE-make}
|
||||||
|
cat > confinc << 'END'
|
||||||
|
am__doit:
|
||||||
|
@echo this is the am__doit target
|
||||||
|
.PHONY: am__doit
|
||||||
|
END
|
||||||
|
# If we don't find an include directive, just comment out the code.
|
||||||
|
AC_MSG_CHECKING([for style of include used by $am_make])
|
||||||
|
am__include="#"
|
||||||
|
am__quote=
|
||||||
|
_am_result=none
|
||||||
|
# First try GNU make style include.
|
||||||
|
echo "include confinc" > confmf
|
||||||
|
# Ignore all kinds of additional output from `make'.
|
||||||
|
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||||
|
*the\ am__doit\ target*)
|
||||||
|
am__include=include
|
||||||
|
am__quote=
|
||||||
|
_am_result=GNU
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# Now try BSD make style include.
|
||||||
|
if test "$am__include" = "#"; then
|
||||||
|
echo '.include "confinc"' > confmf
|
||||||
|
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||||
|
*the\ am__doit\ target*)
|
||||||
|
am__include=.include
|
||||||
|
am__quote="\""
|
||||||
|
_am_result=BSD
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
AC_SUBST([am__include])
|
||||||
|
AC_SUBST([am__quote])
|
||||||
|
AC_MSG_RESULT([$_am_result])
|
||||||
|
rm -f confinc confmf
|
||||||
|
])
|
||||||
|
|
||||||
|
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 6
|
||||||
|
|
||||||
|
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||||
|
# ------------------------------
|
||||||
|
AC_DEFUN([AM_MISSING_PROG],
|
||||||
|
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||||
|
$1=${$1-"${am_missing_run}$2"}
|
||||||
|
AC_SUBST($1)])
|
||||||
|
|
||||||
|
|
||||||
|
# AM_MISSING_HAS_RUN
|
||||||
|
# ------------------
|
||||||
|
# Define MISSING if not defined so far and test if it supports --run.
|
||||||
|
# If it does, set am_missing_run to use it, otherwise, to nothing.
|
||||||
|
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||||
|
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||||
|
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||||
|
if test x"${MISSING+set}" != xset; then
|
||||||
|
case $am_aux_dir in
|
||||||
|
*\ * | *\ *)
|
||||||
|
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||||
|
*)
|
||||||
|
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
# Use eval to expand $SHELL
|
||||||
|
if eval "$MISSING --run true"; then
|
||||||
|
am_missing_run="$MISSING --run "
|
||||||
|
else
|
||||||
|
am_missing_run=
|
||||||
|
AC_MSG_WARN([`missing' script is too old or missing])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# AM_PROG_MKDIR_P
|
||||||
|
# ---------------
|
||||||
|
# Check for `mkdir -p'.
|
||||||
|
AC_DEFUN([AM_PROG_MKDIR_P],
|
||||||
|
[AC_PREREQ([2.60])dnl
|
||||||
|
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||||
|
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
|
||||||
|
dnl while keeping a definition of mkdir_p for backward compatibility.
|
||||||
|
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
|
||||||
|
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
|
||||||
|
dnl Makefile.ins that do not define MKDIR_P, so we do our own
|
||||||
|
dnl adjustment using top_builddir (which is defined more often than
|
||||||
|
dnl MKDIR_P).
|
||||||
|
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
|
||||||
|
case $mkdir_p in
|
||||||
|
[[\\/$]]* | ?:[[\\/]]*) ;;
|
||||||
|
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
# Helper functions for option handling. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 4
|
||||||
|
|
||||||
|
# _AM_MANGLE_OPTION(NAME)
|
||||||
|
# -----------------------
|
||||||
|
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||||
|
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||||
|
|
||||||
|
# _AM_SET_OPTION(NAME)
|
||||||
|
# ------------------------------
|
||||||
|
# Set option NAME. Presently that only means defining a flag for this option.
|
||||||
|
AC_DEFUN([_AM_SET_OPTION],
|
||||||
|
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
|
||||||
|
|
||||||
|
# _AM_SET_OPTIONS(OPTIONS)
|
||||||
|
# ----------------------------------
|
||||||
|
# OPTIONS is a space-separated list of Automake options.
|
||||||
|
AC_DEFUN([_AM_SET_OPTIONS],
|
||||||
|
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||||
|
|
||||||
|
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||||
|
# -------------------------------------------
|
||||||
|
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||||
|
AC_DEFUN([_AM_IF_OPTION],
|
||||||
|
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||||
|
|
||||||
|
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 5
|
||||||
|
|
||||||
|
# AM_SANITY_CHECK
|
||||||
|
# ---------------
|
||||||
|
AC_DEFUN([AM_SANITY_CHECK],
|
||||||
|
[AC_MSG_CHECKING([whether build environment is sane])
|
||||||
|
# Just in case
|
||||||
|
sleep 1
|
||||||
|
echo timestamp > conftest.file
|
||||||
|
# Reject unsafe characters in $srcdir or the absolute working directory
|
||||||
|
# name. Accept space and tab only in the latter.
|
||||||
|
am_lf='
|
||||||
|
'
|
||||||
|
case `pwd` in
|
||||||
|
*[[\\\"\#\$\&\'\`$am_lf]]*)
|
||||||
|
AC_MSG_ERROR([unsafe absolute working directory name]);;
|
||||||
|
esac
|
||||||
|
case $srcdir in
|
||||||
|
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
|
||||||
|
AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Do `set' in a subshell so we don't clobber the current shell's
|
||||||
|
# arguments. Must try -L first in case configure is actually a
|
||||||
|
# symlink; some systems play weird games with the mod time of symlinks
|
||||||
|
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||||
|
# directory).
|
||||||
|
if (
|
||||||
|
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
|
||||||
|
if test "$[*]" = "X"; then
|
||||||
|
# -L didn't work.
|
||||||
|
set X `ls -t "$srcdir/configure" conftest.file`
|
||||||
|
fi
|
||||||
|
rm -f conftest.file
|
||||||
|
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||||
|
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||||
|
|
||||||
|
# If neither matched, then we have a broken ls. This can happen
|
||||||
|
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||||
|
# broken ls alias from the environment. This has actually
|
||||||
|
# happened. Such a system could not be considered "sane".
|
||||||
|
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||||
|
alias in your environment])
|
||||||
|
fi
|
||||||
|
|
||||||
|
test "$[2]" = conftest.file
|
||||||
|
)
|
||||||
|
then
|
||||||
|
# Ok.
|
||||||
|
:
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||||
|
Check your system clock])
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT(yes)])
|
||||||
|
|
||||||
|
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# AM_PROG_INSTALL_STRIP
|
||||||
|
# ---------------------
|
||||||
|
# One issue with vendor `install' (even GNU) is that you can't
|
||||||
|
# specify the program used to strip binaries. This is especially
|
||||||
|
# annoying in cross-compiling environments, where the build's strip
|
||||||
|
# is unlikely to handle the host's binaries.
|
||||||
|
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||||
|
# always use install-sh in `make install-strip', and initialize
|
||||||
|
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||||
|
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||||
|
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||||
|
# Installed binaries are usually stripped using `strip' when the user
|
||||||
|
# run `make install-strip'. However `strip' might not be the right
|
||||||
|
# tool to use in cross-compilation environments, therefore Automake
|
||||||
|
# will honor the `STRIP' environment variable to overrule this program.
|
||||||
|
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
|
||||||
|
if test "$cross_compiling" != no; then
|
||||||
|
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||||
|
fi
|
||||||
|
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||||
|
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||||
|
|
||||||
|
# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 2
|
||||||
|
|
||||||
|
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||||
|
# ---------------------------
|
||||||
|
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||||
|
# This macro is traced by Automake.
|
||||||
|
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||||
|
|
||||||
|
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||||
|
# ---------------------------
|
||||||
|
# Public sister of _AM_SUBST_NOTMAKE.
|
||||||
|
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||||
|
|
||||||
|
# Check how to create a tarball. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 2
|
||||||
|
|
||||||
|
# _AM_PROG_TAR(FORMAT)
|
||||||
|
# --------------------
|
||||||
|
# Check how to create a tarball in format FORMAT.
|
||||||
|
# FORMAT should be one of `v7', `ustar', or `pax'.
|
||||||
|
#
|
||||||
|
# Substitute a variable $(am__tar) that is a command
|
||||||
|
# writing to stdout a FORMAT-tarball containing the directory
|
||||||
|
# $tardir.
|
||||||
|
# tardir=directory && $(am__tar) > result.tar
|
||||||
|
#
|
||||||
|
# Substitute a variable $(am__untar) that extract such
|
||||||
|
# a tarball read from stdin.
|
||||||
|
# $(am__untar) < result.tar
|
||||||
|
AC_DEFUN([_AM_PROG_TAR],
|
||||||
|
[# Always define AMTAR for backward compatibility.
|
||||||
|
AM_MISSING_PROG([AMTAR], [tar])
|
||||||
|
m4_if([$1], [v7],
|
||||||
|
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
|
||||||
|
[m4_case([$1], [ustar],, [pax],,
|
||||||
|
[m4_fatal([Unknown tar format])])
|
||||||
|
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||||
|
# Loop over all known methods to create a tar archive until one works.
|
||||||
|
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||||
|
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||||
|
# Do not fold the above two line into one, because Tru64 sh and
|
||||||
|
# Solaris sh will not grok spaces in the rhs of `-'.
|
||||||
|
for _am_tool in $_am_tools
|
||||||
|
do
|
||||||
|
case $_am_tool in
|
||||||
|
gnutar)
|
||||||
|
for _am_tar in tar gnutar gtar;
|
||||||
|
do
|
||||||
|
AM_RUN_LOG([$_am_tar --version]) && break
|
||||||
|
done
|
||||||
|
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||||
|
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||||
|
am__untar="$_am_tar -xf -"
|
||||||
|
;;
|
||||||
|
plaintar)
|
||||||
|
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||||
|
# ustar tarball either.
|
||||||
|
(tar --version) >/dev/null 2>&1 && continue
|
||||||
|
am__tar='tar chf - "$$tardir"'
|
||||||
|
am__tar_='tar chf - "$tardir"'
|
||||||
|
am__untar='tar xf -'
|
||||||
|
;;
|
||||||
|
pax)
|
||||||
|
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||||
|
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||||
|
am__untar='pax -r'
|
||||||
|
;;
|
||||||
|
cpio)
|
||||||
|
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||||
|
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||||
|
am__untar='cpio -i -H $1 -d'
|
||||||
|
;;
|
||||||
|
none)
|
||||||
|
am__tar=false
|
||||||
|
am__tar_=false
|
||||||
|
am__untar=false
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If the value was cached, stop now. We just wanted to have am__tar
|
||||||
|
# and am__untar set.
|
||||||
|
test -n "${am_cv_prog_tar_$1}" && break
|
||||||
|
|
||||||
|
# tar/untar a dummy directory, and stop if the command works
|
||||||
|
rm -rf conftest.dir
|
||||||
|
mkdir conftest.dir
|
||||||
|
echo GrepMe > conftest.dir/file
|
||||||
|
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||||
|
rm -rf conftest.dir
|
||||||
|
if test -s conftest.tar; then
|
||||||
|
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||||
|
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
rm -rf conftest.dir
|
||||||
|
|
||||||
|
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||||
|
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||||
|
AC_SUBST([am__tar])
|
||||||
|
AC_SUBST([am__untar])
|
||||||
|
]) # _AM_PROG_TAR
|
||||||
|
|
||||||
|
m4_include([../config/depstand.m4])
|
||||||
|
m4_include([../config/lead-dot.m4])
|
||||||
|
m4_include([../config/multi.m4])
|
||||||
|
m4_include([../config/override.m4])
|
||||||
|
m4_include([../config/unwind_ipinfo.m4])
|
||||||
|
m4_include([../config/warnings.m4])
|
||||||
|
m4_include([../libtool.m4])
|
||||||
|
m4_include([../ltoptions.m4])
|
||||||
|
m4_include([../ltsugar.m4])
|
||||||
|
m4_include([../ltversion.m4])
|
||||||
|
m4_include([../lt~obsolete.m4])
|
||||||
|
|
@ -0,0 +1,139 @@
|
||||||
|
/* alloc.c -- Memory allocation without mmap.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* Allocation routines to use on systems that do not support anonymous
|
||||||
|
mmap. This implementation just uses malloc, which means that the
|
||||||
|
backtrace functions may not be safely invoked from a signal
|
||||||
|
handler. */
|
||||||
|
|
||||||
|
/* Allocate memory like malloc. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
size_t size, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
ret = malloc (size);
|
||||||
|
if (ret == NULL)
|
||||||
|
error_callback (data, "malloc", errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free memory. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_free (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
void *p, size_t size ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||||
|
void *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grow VEC by SIZE bytes. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_vector_grow (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
size_t size, backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_vector *vec)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if (size > vec->alc)
|
||||||
|
{
|
||||||
|
size_t alc;
|
||||||
|
void *base;
|
||||||
|
|
||||||
|
if (vec->size == 0)
|
||||||
|
alc = 32 * size;
|
||||||
|
else if (vec->size >= 4096)
|
||||||
|
alc = vec->size + 4096;
|
||||||
|
else
|
||||||
|
alc = 2 * vec->size;
|
||||||
|
|
||||||
|
if (alc < vec->size + size)
|
||||||
|
alc = vec->size + size;
|
||||||
|
|
||||||
|
base = realloc (vec->base, alc);
|
||||||
|
if (base == NULL)
|
||||||
|
{
|
||||||
|
error_callback (data, "realloc", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->base = base;
|
||||||
|
vec->alc = alc - vec->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (char *) vec->base + vec->size;
|
||||||
|
vec->size += size;
|
||||||
|
vec->alc -= size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish the current allocation on VEC. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_vector_finish (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
struct backtrace_vector *vec)
|
||||||
|
{
|
||||||
|
vec->base = (char *) vec->base + vec->size;
|
||||||
|
vec->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release any extra space allocated for VEC. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_vector_release (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
vec->base = realloc (vec->base, vec->size);
|
||||||
|
if (vec->base == NULL)
|
||||||
|
{
|
||||||
|
error_callback (data, "realloc", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
vec->alc = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* backtrace-supported.h.in -- Whether stack backtrace is supported.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
/* The file backtrace-supported.h.in is used by configure to generate
|
||||||
|
the file backtrace-supported.h. The file backtrace-supported.h may
|
||||||
|
be #include'd to see whether the backtrace library will be able to
|
||||||
|
get a backtrace and produce symbolic information. */
|
||||||
|
|
||||||
|
|
||||||
|
/* BACKTRACE_SUPPORTED will be #define'd as 1 if the backtrace library
|
||||||
|
should work, 0 if it will not. Libraries may #include this to make
|
||||||
|
other arrangements. */
|
||||||
|
|
||||||
|
#define BACKTRACE_SUPPORTED @BACKTRACE_SUPPORTED@
|
||||||
|
|
||||||
|
/* BACKTRACE_USES_MALLOC will be #define'd as 1 if the backtrace
|
||||||
|
library will call malloc as it works, 0 if it will call mmap
|
||||||
|
instead. This may be used to determine whether it is safe to call
|
||||||
|
the backtrace functions from a signal handler. In general this
|
||||||
|
only applies to calls like backtrace and backtrace_pcinfo. It does
|
||||||
|
not apply to backtrace_simple, which never calls malloc. It does
|
||||||
|
not apply to backtrace_print, which always calls fprintf and
|
||||||
|
therefore malloc. */
|
||||||
|
|
||||||
|
#define BACKTRACE_USES_MALLOC @BACKTRACE_USES_MALLOC@
|
||||||
|
|
||||||
|
/* BACKTRACE_SUPPORTS_THREADS will be #define'd as 1 if the backtrace
|
||||||
|
library is configured with threading support, 0 if not. If this is
|
||||||
|
0, the threaded parameter to backtrace_create_state must be passed
|
||||||
|
as 0. */
|
||||||
|
|
||||||
|
#define BACKTRACE_SUPPORTS_THREADS @BACKTRACE_SUPPORTS_THREADS@
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* backtrace.c -- Entry point for stack backtrace library.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "unwind.h"
|
||||||
|
#include "backtrace.h"
|
||||||
|
|
||||||
|
/* The main backtrace_full routine. */
|
||||||
|
|
||||||
|
/* Data passed through _Unwind_Backtrace. */
|
||||||
|
|
||||||
|
struct backtrace_data
|
||||||
|
{
|
||||||
|
/* Number of frames to skip. */
|
||||||
|
int skip;
|
||||||
|
/* Library state. */
|
||||||
|
struct backtrace_state *state;
|
||||||
|
/* Callback routine. */
|
||||||
|
backtrace_full_callback callback;
|
||||||
|
/* Error callback routine. */
|
||||||
|
backtrace_error_callback error_callback;
|
||||||
|
/* Data to pass to callback routines. */
|
||||||
|
void *data;
|
||||||
|
/* Value to return from backtrace_full. */
|
||||||
|
int ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Unwind library callback routine. This is passed to
|
||||||
|
_Unwind_Backtrace. */
|
||||||
|
|
||||||
|
static _Unwind_Reason_Code
|
||||||
|
unwind (struct _Unwind_Context *context, void *vdata)
|
||||||
|
{
|
||||||
|
struct backtrace_data *bdata = (struct backtrace_data *) vdata;
|
||||||
|
uintptr_t pc;
|
||||||
|
int ip_before_insn = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_GETIPINFO
|
||||||
|
pc = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||||
|
#else
|
||||||
|
pc = _Unwind_GetIP (context);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (bdata->skip > 0)
|
||||||
|
{
|
||||||
|
--bdata->skip;
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ip_before_insn)
|
||||||
|
--pc;
|
||||||
|
|
||||||
|
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
|
||||||
|
bdata->error_callback, bdata->data);
|
||||||
|
if (bdata->ret != 0)
|
||||||
|
return _URC_END_OF_STACK;
|
||||||
|
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a stack backtrace. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_full (struct backtrace_state *state, int skip,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
struct backtrace_data bdata;
|
||||||
|
|
||||||
|
bdata.skip = skip + 1;
|
||||||
|
bdata.state = state;
|
||||||
|
bdata.callback = callback;
|
||||||
|
bdata.error_callback = error_callback;
|
||||||
|
bdata.data = data;
|
||||||
|
bdata.ret = 0;
|
||||||
|
_Unwind_Backtrace (unwind, &bdata);
|
||||||
|
return bdata.ret;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
/* backtrace.h -- Public header file for stack backtrace library.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#ifndef BACKTRACE_H
|
||||||
|
#define BACKTRACE_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The backtrace state. This struct is intentionally not defined in
|
||||||
|
the public interface. */
|
||||||
|
|
||||||
|
struct backtrace_state;
|
||||||
|
|
||||||
|
/* The type of the error callback argument to backtrace functions.
|
||||||
|
This function, if not NULL, will be called for certain error cases.
|
||||||
|
The DATA argument is passed to the function that calls this one.
|
||||||
|
The MSG argument is an error message. The ERRNUM argument, if
|
||||||
|
greater than 0, holds an errno value. The MSG buffer may become
|
||||||
|
invalid after this function returns.
|
||||||
|
|
||||||
|
As a special case, the ERRNUM argument will be passed as -1 if no
|
||||||
|
debug info can be found for the executable, but the function
|
||||||
|
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
|
||||||
|
MSG in this case will be something along the lines of "no debug
|
||||||
|
info". Similarly, ERRNUM will be passed as -1 if there is no
|
||||||
|
symbol table, but the function requires a symbol table (e.g.,
|
||||||
|
backtrace_syminfo). This may be used as a signal that some other
|
||||||
|
approach should be tried. */
|
||||||
|
|
||||||
|
typedef void (*backtrace_error_callback) (void *data, const char *msg,
|
||||||
|
int errnum);
|
||||||
|
|
||||||
|
/* Create state information for the backtrace routines. This must be
|
||||||
|
called before any of the other routines, and its return value must
|
||||||
|
be passed to all of the other routines. FILENAME is the path name
|
||||||
|
of the executable file; if it is NULL the library will try
|
||||||
|
system-specific path names. If not NULL, FILENAME must point to a
|
||||||
|
permanent buffer. If THREADED is non-zero the state may be
|
||||||
|
accessed by multiple threads simultaneously, and the library will
|
||||||
|
use appropriate locks (this requires that the library be configured
|
||||||
|
with --enable-backtrace-threads). If THREADED is zero the state
|
||||||
|
may only be accessed by one thread at a time. This returns a state
|
||||||
|
pointer on success, NULL on error. If an error occurs, this will
|
||||||
|
call the ERROR_CALLBACK routine. */
|
||||||
|
|
||||||
|
extern struct backtrace_state *backtrace_create_state (
|
||||||
|
const char *filename, int threaded,
|
||||||
|
backtrace_error_callback error_callback, void *data);
|
||||||
|
|
||||||
|
/* The type of the callback argument to the backtrace_full function.
|
||||||
|
DATA is the argument passed to backtrace_full. PC is the program
|
||||||
|
counter. FILENAME is the name of the file containing PC, or NULL
|
||||||
|
if not available. LINENO is the line number in FILENAME containing
|
||||||
|
PC, or 0 if not available. FUNCTION is the name of the function
|
||||||
|
containing PC, or NULL if not available. This should return 0 to
|
||||||
|
continuing tracing. The FILENAME and FUNCTION buffers may become
|
||||||
|
invalid after this function returns. */
|
||||||
|
|
||||||
|
typedef int (*backtrace_full_callback) (void *data, uintptr_t pc,
|
||||||
|
const char *filename, int lineno,
|
||||||
|
const char *function);
|
||||||
|
|
||||||
|
/* Get a full stack backtrace. SKIP is the number of frames to skip;
|
||||||
|
passing 0 will start the trace with the function calling
|
||||||
|
backtrace_full. DATA is passed to the callback routine. If any
|
||||||
|
call to CALLBACK returns a non-zero value, the stack backtrace
|
||||||
|
stops, and backtrace returns that value; this may be used to limit
|
||||||
|
the number of stack frames desired. If all calls to CALLBACK
|
||||||
|
return 0, backtrace returns 0. The backtrace_full function will
|
||||||
|
make at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||||
|
function requires debug info for the executable. */
|
||||||
|
|
||||||
|
extern int backtrace_full (struct backtrace_state *state, int skip,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* The type of the callback argument to the backtrace_simple function.
|
||||||
|
DATA is the argument passed to simple_backtrace. PC is the program
|
||||||
|
counter. This should return 0 to continue tracing. */
|
||||||
|
|
||||||
|
typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc);
|
||||||
|
|
||||||
|
/* Get a simple backtrace. SKIP is the number of frames to skip, as
|
||||||
|
in backtrace. DATA is passed to the callback routine. If any call
|
||||||
|
to CALLBACK returns a non-zero value, the stack backtrace stops,
|
||||||
|
and backtrace_simple returns that value. Otherwise
|
||||||
|
backtrace_simple returns 0. The backtrace_simple function will
|
||||||
|
make at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||||
|
function does not require any debug info for the executable. */
|
||||||
|
|
||||||
|
extern int backtrace_simple (struct backtrace_state *state, int skip,
|
||||||
|
backtrace_simple_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Print the current backtrace in a user readable format to a FILE.
|
||||||
|
SKIP is the number of frames to skip, as in backtrace_full. Any
|
||||||
|
error messages are printed to stderr. This function requires debug
|
||||||
|
info for the executable. */
|
||||||
|
|
||||||
|
extern void backtrace_print (struct backtrace_state *state, int skip, FILE *);
|
||||||
|
|
||||||
|
/* Given PC, a program counter in the current program, call the
|
||||||
|
callback function with filename, line number, and function name
|
||||||
|
information. This will normally call the callback function exactly
|
||||||
|
once. However, if the PC happens to describe an inlined call, and
|
||||||
|
the debugging information contains the necessary information, then
|
||||||
|
this may call the callback function multiple times. This will make
|
||||||
|
at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||||
|
returns the first non-zero value returned by CALLBACK, or 0. */
|
||||||
|
|
||||||
|
extern int backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* The type of the callback argument to backtrace_syminfo. DATA and
|
||||||
|
PC are the arguments passed to backtrace_syminfo. SYMNAME is the
|
||||||
|
name of the symbol for the corresponding code. SYMVAL is the
|
||||||
|
value. SYMNAME will be NULL if no error occurred but the symbol
|
||||||
|
could not be found. */
|
||||||
|
|
||||||
|
typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
|
||||||
|
const char *symname,
|
||||||
|
uintptr_t symval);
|
||||||
|
|
||||||
|
/* Given PC, a program counter in the current program, call the
|
||||||
|
callback information with the symbol name and value describing the
|
||||||
|
function in which PC may be found. This will call either CALLBACK
|
||||||
|
or ERROR_CALLBACK exactly once. This returns 1 on success, 0 on
|
||||||
|
failure. This function requires the symbol table but does not
|
||||||
|
require the debug info. Note that if the symbol table is present
|
||||||
|
but PC could not be found in the table, CALLBACK will be called
|
||||||
|
with a NULL SYMNAME argument. Returns 1 on success, 0 on
|
||||||
|
error. */
|
||||||
|
|
||||||
|
extern int backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* End extern "C". */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,629 @@
|
||||||
|
/* btest.c -- Test for libbacktrace library
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
/* This program tests the externally visible interfaces of the
|
||||||
|
libbacktrace library. */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "filenames.h"
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "backtrace-supported.h"
|
||||||
|
|
||||||
|
/* Portable attribute syntax. Actually some of these tests probably
|
||||||
|
won't work if the attributes are not recognized. */
|
||||||
|
|
||||||
|
#ifndef GCC_VERSION
|
||||||
|
# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GCC_VERSION < 2007)
|
||||||
|
# define __attribute__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_UNUSED
|
||||||
|
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Used to collect backtrace info. */
|
||||||
|
|
||||||
|
struct info
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
int lineno;
|
||||||
|
char *function;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Passed to backtrace callback function. */
|
||||||
|
|
||||||
|
struct bdata
|
||||||
|
{
|
||||||
|
struct info *all;
|
||||||
|
size_t index;
|
||||||
|
size_t max;
|
||||||
|
int failed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Passed to backtrace_simple callback function. */
|
||||||
|
|
||||||
|
struct sdata
|
||||||
|
{
|
||||||
|
uintptr_t *addrs;
|
||||||
|
size_t index;
|
||||||
|
size_t max;
|
||||||
|
int failed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Passed to backtrace_syminfo callback function. */
|
||||||
|
|
||||||
|
struct symdata
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
uintptr_t val;
|
||||||
|
int failed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The backtrace state. */
|
||||||
|
|
||||||
|
static void *state;
|
||||||
|
|
||||||
|
/* The number of failures. */
|
||||||
|
|
||||||
|
static int failures;
|
||||||
|
|
||||||
|
/* Return the base name in a path. */
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
base (const char *p)
|
||||||
|
{
|
||||||
|
const char *last;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
last = NULL;
|
||||||
|
for (s = p; *s != '\0'; ++s)
|
||||||
|
{
|
||||||
|
if (IS_DIR_SEPARATOR (*s))
|
||||||
|
last = s + 1;
|
||||||
|
}
|
||||||
|
return last != NULL ? last : p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check an entry in a struct info array. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
check (const char *name, int index, const struct info *all, int want_lineno,
|
||||||
|
const char *want_function, int *failed)
|
||||||
|
{
|
||||||
|
if (*failed)
|
||||||
|
return;
|
||||||
|
if (strcmp (base (all[index].filename), "btest.c") != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: [%d]: got %s expected test.c\n", name, index,
|
||||||
|
all[index].filename);
|
||||||
|
*failed = 1;
|
||||||
|
}
|
||||||
|
if (all[index].lineno != want_lineno)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: [%d]: got %d expected %d\n", name, index,
|
||||||
|
all[index].lineno, want_lineno);
|
||||||
|
*failed = 1;
|
||||||
|
}
|
||||||
|
if (strcmp (all[index].function, want_function) != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: [%d]: got %s expected %s\n", name, index,
|
||||||
|
all[index].function, want_function);
|
||||||
|
*failed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The backtrace callback function. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
callback_one (void *vdata, uintptr_t pc ATTRIBUTE_UNUSED,
|
||||||
|
const char *filename, int lineno, const char *function)
|
||||||
|
{
|
||||||
|
struct bdata *data = (struct bdata *) vdata;
|
||||||
|
struct info *p;
|
||||||
|
|
||||||
|
if (data->index >= data->max)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "callback_one: callback called too many times\n");
|
||||||
|
data->failed = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = &data->all[data->index];
|
||||||
|
if (filename == NULL)
|
||||||
|
p->filename = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->filename = strdup (filename);
|
||||||
|
assert (p->filename != NULL);
|
||||||
|
}
|
||||||
|
p->lineno = lineno;
|
||||||
|
if (function == NULL)
|
||||||
|
p->function = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->function = strdup (function);
|
||||||
|
assert (p->function != NULL);
|
||||||
|
}
|
||||||
|
++data->index;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An error callback passed to backtrace. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
error_callback_one (void *vdata, const char *msg, int errnum)
|
||||||
|
{
|
||||||
|
struct bdata *data = (struct bdata *) vdata;
|
||||||
|
|
||||||
|
fprintf (stderr, "%s", msg);
|
||||||
|
if (errnum > 0)
|
||||||
|
fprintf (stderr, ": %s", strerror (errnum));
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
data->failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The backtrace_simple callback function. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
callback_two (void *vdata, uintptr_t pc)
|
||||||
|
{
|
||||||
|
struct sdata *data = (struct sdata *) vdata;
|
||||||
|
|
||||||
|
if (data->index >= data->max)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "callback_two: callback called too many times\n");
|
||||||
|
data->failed = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->addrs[data->index] = pc;
|
||||||
|
++data->index;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An error callback passed to backtrace_simple. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
error_callback_two (void *vdata, const char *msg, int errnum)
|
||||||
|
{
|
||||||
|
struct sdata *data = (struct sdata *) vdata;
|
||||||
|
|
||||||
|
fprintf (stderr, "%s", msg);
|
||||||
|
if (errnum > 0)
|
||||||
|
fprintf (stderr, ": %s", strerror (errnum));
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
data->failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The backtrace_syminfo callback function. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
callback_three (void *vdata, uintptr_t pc ATTRIBUTE_UNUSED,
|
||||||
|
const char *symname, uintptr_t symval)
|
||||||
|
{
|
||||||
|
struct symdata *data = (struct symdata *) vdata;
|
||||||
|
|
||||||
|
if (symname == NULL)
|
||||||
|
data->name = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->name = strdup (symname);
|
||||||
|
assert (data->name != NULL);
|
||||||
|
}
|
||||||
|
data->val = symval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The backtrace_syminfo error callback function. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
error_callback_three (void *vdata, const char *msg, int errnum)
|
||||||
|
{
|
||||||
|
struct symdata *data = (struct symdata *) vdata;
|
||||||
|
|
||||||
|
fprintf (stderr, "%s", msg);
|
||||||
|
if (errnum > 0)
|
||||||
|
fprintf (stderr, ": %s", strerror (errnum));
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
data->failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test the backtrace function with non-inlined functions. */
|
||||||
|
|
||||||
|
static int test1 (void) __attribute__ ((noinline));
|
||||||
|
static int f2 (int) __attribute__ ((noinline));
|
||||||
|
static int f3 (int, int) __attribute__ ((noinline));
|
||||||
|
|
||||||
|
static int
|
||||||
|
test1 (void)
|
||||||
|
{
|
||||||
|
/* Returning a value here and elsewhere avoids a tailcall which
|
||||||
|
would mess up the backtrace. */
|
||||||
|
return f2 (__LINE__) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
f2 (int f1line)
|
||||||
|
{
|
||||||
|
return f3 (f1line, __LINE__) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
f3 (int f1line, int f2line)
|
||||||
|
{
|
||||||
|
struct info all[20];
|
||||||
|
struct bdata data;
|
||||||
|
int f3line;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data.all = &all[0];
|
||||||
|
data.index = 0;
|
||||||
|
data.max = 20;
|
||||||
|
data.failed = 0;
|
||||||
|
|
||||||
|
f3line = __LINE__ + 1;
|
||||||
|
i = backtrace_full (state, 0, callback_one, error_callback_one, &data);
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "test1: unexpected return value %d\n", i);
|
||||||
|
data.failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
check ("test1", 0, all, f3line, "f3", &data.failed);
|
||||||
|
check ("test1", 1, all, f2line, "f2", &data.failed);
|
||||||
|
check ("test1", 2, all, f1line, "test1", &data.failed);
|
||||||
|
|
||||||
|
printf ("%s: backtrace_full noinline\n", data.failed ? "FAIL" : "PASS");
|
||||||
|
|
||||||
|
if (data.failed)
|
||||||
|
++failures;
|
||||||
|
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test the backtrace function with inlined functions. */
|
||||||
|
|
||||||
|
static inline int test2 (void) __attribute__ ((always_inline));
|
||||||
|
static inline int f12 (int) __attribute__ ((always_inline));
|
||||||
|
static inline int f13 (int, int) __attribute__ ((always_inline));
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
test2 (void)
|
||||||
|
{
|
||||||
|
return f12 (__LINE__) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
f12 (int f1line)
|
||||||
|
{
|
||||||
|
return f13 (f1line, __LINE__) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
f13 (int f1line, int f2line)
|
||||||
|
{
|
||||||
|
struct info all[20];
|
||||||
|
struct bdata data;
|
||||||
|
int f3line;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data.all = &all[0];
|
||||||
|
data.index = 0;
|
||||||
|
data.max = 20;
|
||||||
|
data.failed = 0;
|
||||||
|
|
||||||
|
f3line = __LINE__ + 1;
|
||||||
|
i = backtrace_full (state, 0, callback_one, error_callback_one, &data);
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "test2: unexpected return value %d\n", i);
|
||||||
|
data.failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
check ("test2", 0, all, f3line, "f13", &data.failed);
|
||||||
|
check ("test2", 1, all, f2line, "f12", &data.failed);
|
||||||
|
check ("test2", 2, all, f1line, "test2", &data.failed);
|
||||||
|
|
||||||
|
printf ("%s: backtrace_full inline\n", data.failed ? "FAIL" : "PASS");
|
||||||
|
|
||||||
|
if (data.failed)
|
||||||
|
++failures;
|
||||||
|
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test the backtrace_simple function with non-inlined functions. */
|
||||||
|
|
||||||
|
static int test3 (void) __attribute__ ((noinline));
|
||||||
|
static int f22 (int) __attribute__ ((noinline));
|
||||||
|
static int f23 (int, int) __attribute__ ((noinline));
|
||||||
|
|
||||||
|
static int
|
||||||
|
test3 (void)
|
||||||
|
{
|
||||||
|
return f22 (__LINE__) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
f22 (int f1line)
|
||||||
|
{
|
||||||
|
return f23 (f1line, __LINE__) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
f23 (int f1line, int f2line)
|
||||||
|
{
|
||||||
|
uintptr_t addrs[20];
|
||||||
|
struct sdata data;
|
||||||
|
int f3line;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data.addrs = &addrs[0];
|
||||||
|
data.index = 0;
|
||||||
|
data.max = 20;
|
||||||
|
data.failed = 0;
|
||||||
|
|
||||||
|
f3line = __LINE__ + 1;
|
||||||
|
i = backtrace_simple (state, 0, callback_two, error_callback_two, &data);
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "test3: unexpected return value %d\n", i);
|
||||||
|
data.failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.failed)
|
||||||
|
{
|
||||||
|
struct info all[20];
|
||||||
|
struct bdata bdata;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
bdata.all = &all[0];
|
||||||
|
bdata.index = 0;
|
||||||
|
bdata.max = 20;
|
||||||
|
bdata.failed = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
i = backtrace_pcinfo (state, addrs[j], callback_one,
|
||||||
|
error_callback_one, &bdata);
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
("test3: unexpected return value "
|
||||||
|
"from backtrace_pcinfo %d\n"),
|
||||||
|
i);
|
||||||
|
bdata.failed = 1;
|
||||||
|
}
|
||||||
|
if (!bdata.failed && bdata.index != (size_t) (j + 1))
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
("wrong number of calls from backtrace_pcinfo "
|
||||||
|
"got %u expected %d\n"),
|
||||||
|
(unsigned int) bdata.index, j + 1);
|
||||||
|
bdata.failed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check ("test3", 0, all, f3line, "f23", &bdata.failed);
|
||||||
|
check ("test3", 1, all, f2line, "f22", &bdata.failed);
|
||||||
|
check ("test3", 2, all, f1line, "test3", &bdata.failed);
|
||||||
|
|
||||||
|
if (bdata.failed)
|
||||||
|
data.failed = 1;
|
||||||
|
|
||||||
|
for (j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
struct symdata symdata;
|
||||||
|
|
||||||
|
symdata.name = NULL;
|
||||||
|
symdata.val = 0;
|
||||||
|
symdata.failed = 0;
|
||||||
|
|
||||||
|
i = backtrace_syminfo (state, addrs[j], callback_three,
|
||||||
|
error_callback_three, &symdata);
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
("test3: [%d]: unexpected return value "
|
||||||
|
"from backtrace_syminfo %d\n"),
|
||||||
|
j, i);
|
||||||
|
symdata.failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!symdata.failed)
|
||||||
|
{
|
||||||
|
const char *expected;
|
||||||
|
|
||||||
|
switch (j)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
expected = "f23";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
expected = "f22";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
expected = "test3";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
assert (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (symdata.name == NULL)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "test3: [%d]: NULL syminfo name\n", j);
|
||||||
|
symdata.failed = 1;
|
||||||
|
}
|
||||||
|
/* Use strncmp, not strcmp, because GCC might create a
|
||||||
|
clone. */
|
||||||
|
else if (strncmp (symdata.name, expected, strlen (expected))
|
||||||
|
!= 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
("test3: [%d]: unexpected syminfo name "
|
||||||
|
"got %s expected %s\n"),
|
||||||
|
j, symdata.name, expected);
|
||||||
|
symdata.failed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (symdata.failed)
|
||||||
|
data.failed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("%s: backtrace_simple noinline\n", data.failed ? "FAIL" : "PASS");
|
||||||
|
|
||||||
|
if (data.failed)
|
||||||
|
++failures;
|
||||||
|
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test the backtrace_simple function with inlined functions. */
|
||||||
|
|
||||||
|
static inline int test4 (void) __attribute__ ((always_inline));
|
||||||
|
static inline int f32 (int) __attribute__ ((always_inline));
|
||||||
|
static inline int f33 (int, int) __attribute__ ((always_inline));
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
test4 (void)
|
||||||
|
{
|
||||||
|
return f32 (__LINE__) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
f32 (int f1line)
|
||||||
|
{
|
||||||
|
return f33 (f1line, __LINE__) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
f33 (int f1line, int f2line)
|
||||||
|
{
|
||||||
|
uintptr_t addrs[20];
|
||||||
|
struct sdata data;
|
||||||
|
int f3line;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data.addrs = &addrs[0];
|
||||||
|
data.index = 0;
|
||||||
|
data.max = 20;
|
||||||
|
data.failed = 0;
|
||||||
|
|
||||||
|
f3line = __LINE__ + 1;
|
||||||
|
i = backtrace_simple (state, 0, callback_two, error_callback_two, &data);
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "test3: unexpected return value %d\n", i);
|
||||||
|
data.failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.failed)
|
||||||
|
{
|
||||||
|
struct info all[20];
|
||||||
|
struct bdata bdata;
|
||||||
|
|
||||||
|
bdata.all = &all[0];
|
||||||
|
bdata.index = 0;
|
||||||
|
bdata.max = 20;
|
||||||
|
bdata.failed = 0;
|
||||||
|
|
||||||
|
i = backtrace_pcinfo (state, addrs[0], callback_one, error_callback_one,
|
||||||
|
&bdata);
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
("test4: unexpected return value "
|
||||||
|
"from backtrace_pcinfo %d\n"),
|
||||||
|
i);
|
||||||
|
bdata.failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
check ("test4", 0, all, f3line, "f33", &bdata.failed);
|
||||||
|
check ("test4", 1, all, f2line, "f32", &bdata.failed);
|
||||||
|
check ("test4", 2, all, f1line, "test4", &bdata.failed);
|
||||||
|
|
||||||
|
if (bdata.failed)
|
||||||
|
data.failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("%s: backtrace_simple inline\n", data.failed ? "FAIL" : "PASS");
|
||||||
|
|
||||||
|
if (data.failed)
|
||||||
|
++failures;
|
||||||
|
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
error_callback_create (void *data ATTRIBUTE_UNUSED, const char *msg,
|
||||||
|
int errnum)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s", msg);
|
||||||
|
if (errnum > 0)
|
||||||
|
fprintf (stderr, ": %s", strerror (errnum));
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run all the tests. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc ATTRIBUTE_UNUSED, char **argv)
|
||||||
|
{
|
||||||
|
state = backtrace_create_state (argv[0], BACKTRACE_SUPPORTS_THREADS,
|
||||||
|
error_callback_create, NULL);
|
||||||
|
|
||||||
|
#if BACKTRACE_SUPPORTED
|
||||||
|
test1 ();
|
||||||
|
test2 ();
|
||||||
|
test3 ();
|
||||||
|
test4 ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* ELF size: 32 or 64 */
|
||||||
|
#undef BACKTRACE_ELF_SIZE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#undef HAVE_DLFCN_H
|
||||||
|
|
||||||
|
/* Define if _Unwind_GetIPInfo is available. */
|
||||||
|
#undef HAVE_GETIPINFO
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the __sync functions */
|
||||||
|
#undef HAVE_SYNC_FUNCTIONS
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||||
|
#undef HAVE_SYS_MMAN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||||
|
*/
|
||||||
|
#undef LT_OBJDIR
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the home page for this package. */
|
||||||
|
#undef PACKAGE_URL
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,253 @@
|
||||||
|
# configure.ac -- Backtrace configure script.
|
||||||
|
# Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
|
||||||
|
# (1) Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
# (2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
|
||||||
|
# (3) The name of the author may not be used to
|
||||||
|
# endorse or promote products derived from this software without
|
||||||
|
# specific prior written permission.
|
||||||
|
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
AC_PREREQ(2.64)
|
||||||
|
AC_INIT(package-unused, version-unused,, libbacktrace)
|
||||||
|
AC_CONFIG_SRCDIR(backtrace.h)
|
||||||
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
AC_CANONICAL_SYSTEM
|
||||||
|
target_alias=${target_alias-$host_alias}
|
||||||
|
|
||||||
|
libtool_VERSION=1:0:0
|
||||||
|
AC_SUBST(libtool_VERSION)
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE([1.11.1 foreign no-dist no-define -Wall -Wno-portability])
|
||||||
|
|
||||||
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
|
AC_ARG_WITH(target-subdir,
|
||||||
|
[ --with-target-subdir=SUBDIR Configuring in a subdirectory for target])
|
||||||
|
|
||||||
|
# We must force CC to /not/ be precious variables; otherwise
|
||||||
|
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||||
|
# As a side effect, we have to subst CFLAGS ourselves.
|
||||||
|
m4_rename([_AC_ARG_VAR_PRECIOUS],[backtrace_PRECIOUS])
|
||||||
|
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||||
|
AC_PROG_CC
|
||||||
|
m4_rename_force([backtrace_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||||
|
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
|
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
|
||||||
|
AC_PROG_AWK
|
||||||
|
case "$AWK" in
|
||||||
|
"") AC_MSG_ERROR([can't build without awk]) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
LT_INIT([disable-shared])
|
||||||
|
AM_PROG_LIBTOOL
|
||||||
|
|
||||||
|
backtrace_supported=yes
|
||||||
|
|
||||||
|
if test -n "${with_target_subdir}"; then
|
||||||
|
# We are compiling a GCC library. We can assume that the unwind
|
||||||
|
# library exists.
|
||||||
|
AM_ENABLE_MULTILIB(, ..)
|
||||||
|
BACKTRACE_FILE="backtrace.lo simple.lo"
|
||||||
|
else
|
||||||
|
AC_CHECK_HEADER([unwind.h],
|
||||||
|
[AC_CHECK_FUNC([_Unwind_Backtrace],
|
||||||
|
[BACKTRACE_FILE="backtrace.lo simple.lo"],
|
||||||
|
[BACKTRACE_FILE="nounwind.lo"
|
||||||
|
backtrace_supported=no])],
|
||||||
|
[BACKTRACE_FILE="nounwind.lo"
|
||||||
|
backtrace_supported=no])
|
||||||
|
fi
|
||||||
|
AC_SUBST(BACKTRACE_FILE)
|
||||||
|
|
||||||
|
ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \
|
||||||
|
-Wmissing-prototypes -Wold-style-definition \
|
||||||
|
-Wmissing-format-attribute -Wcast-qual],
|
||||||
|
[WARN_FLAGS])
|
||||||
|
|
||||||
|
if test "x$GCC" = "xyes"; then
|
||||||
|
WARN_FLAGS="$WARN_FLAGS -Werror"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(WARN_FLAGS)
|
||||||
|
|
||||||
|
GCC_CHECK_UNWIND_GETIPINFO
|
||||||
|
|
||||||
|
# When building as a target library, shared libraries may want to link
|
||||||
|
# this in. We don't want to provide another shared library to
|
||||||
|
# complicate dependencies. Instead, we just compile with -fPIC.
|
||||||
|
PIC_FLAG=
|
||||||
|
if test -n "${with_target_subdir}"; then
|
||||||
|
PIC_FLAG=-fPIC
|
||||||
|
fi
|
||||||
|
AC_SUBST(PIC_FLAG)
|
||||||
|
|
||||||
|
# Test for __sync support.
|
||||||
|
AC_CACHE_CHECK([__sync extensions],
|
||||||
|
[libbacktrace_cv_sys_sync],
|
||||||
|
[if test -n "${with_target_subdir}"; then
|
||||||
|
libbacktrace_cv_sys_sync=yes
|
||||||
|
else
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([int i;],
|
||||||
|
[__sync_bool_compare_and_swap (&i, i, i);
|
||||||
|
__sync_lock_test_and_set (&i, 1);
|
||||||
|
__sync_lock_release (&i);])],
|
||||||
|
[libbacktrace_cv_sys_sync=yes],
|
||||||
|
[libbacktrace_cv_sys_sync=no])
|
||||||
|
fi])
|
||||||
|
BACKTRACE_SUPPORTS_THREADS=0
|
||||||
|
if test "$libbacktrace_cv_sys_sync" = "yes"; then
|
||||||
|
BACKTRACE_SUPPORTS_THREADS=1
|
||||||
|
AC_DEFINE([HAVE_SYNC_FUNCTIONS], 1,
|
||||||
|
[Define to 1 if you have the __sync functions])
|
||||||
|
fi
|
||||||
|
AC_SUBST(BACKTRACE_SUPPORTS_THREADS)
|
||||||
|
|
||||||
|
# The library needs to be able to read the executable itself. Compile
|
||||||
|
# a file to determine the executable format. The awk script
|
||||||
|
# filetype.awk prints out the file type.
|
||||||
|
AC_CACHE_CHECK([output filetype],
|
||||||
|
[libbacktrace_cv_sys_filetype],
|
||||||
|
[filetype=
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([int i;], [int j;])],
|
||||||
|
[filetype=`${AWK} -f $srcdir/filetype.awk conftest.$ac_objext`],
|
||||||
|
[AC_MSG_FAILURE([compiler failed])])
|
||||||
|
libbacktrace_cv_sys_filetype=$filetype])
|
||||||
|
|
||||||
|
# Match the file type to decide what files to compile.
|
||||||
|
FORMAT_FILE=
|
||||||
|
case "$libbacktrace_cv_sys_filetype" in
|
||||||
|
elf*) FORMAT_FILE="elf.lo" ;;
|
||||||
|
*) AC_MSG_WARN([could not determine output file type])
|
||||||
|
FORMAT_FILE="unknown.lo"
|
||||||
|
backtrace_supported=no
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_SUBST(FORMAT_FILE)
|
||||||
|
|
||||||
|
# ELF defines.
|
||||||
|
elfsize=
|
||||||
|
case "$libbacktrace_cv_sys_filetype" in
|
||||||
|
elf32) elfsize=32 ;;
|
||||||
|
elf64) elfsize=64 ;;
|
||||||
|
esac
|
||||||
|
AC_DEFINE_UNQUOTED([BACKTRACE_ELF_SIZE], [$elfsize], [ELF size: 32 or 64])
|
||||||
|
|
||||||
|
BACKTRACE_SUPPORTED=0
|
||||||
|
if test "$backtrace_supported" = "yes"; then
|
||||||
|
BACKTRACE_SUPPORTED=1
|
||||||
|
fi
|
||||||
|
AC_SUBST(BACKTRACE_SUPPORTED)
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS(sys/mman.h)
|
||||||
|
if test "$ac_cv_header_sys_mman_h" = "no"; then
|
||||||
|
have_mmap=no
|
||||||
|
else
|
||||||
|
if test -n "${with_target_subdir}"; then
|
||||||
|
# When built as a GCC target library, we can't do a link test. We
|
||||||
|
# simply assume that if we have mman.h, we have mmap.
|
||||||
|
have_mmap=yes
|
||||||
|
else
|
||||||
|
AC_CHECK_FUNC(mmap, [have_mmap=yes], [have_mmap=no])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test "$have_mmap" = "no"; then
|
||||||
|
VIEW_FILE=read.lo
|
||||||
|
ALLOC_FILE=alloc.lo
|
||||||
|
else
|
||||||
|
VIEW_FILE=mmapio.lo
|
||||||
|
AC_PREPROC_IFELSE([
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#if !defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
|
||||||
|
#error no MAP_ANONYMOUS
|
||||||
|
#endif
|
||||||
|
], [ALLOC_FILE=mmap.lo], [ALLOC_FILE=alloc.lo])
|
||||||
|
fi
|
||||||
|
AC_SUBST(VIEW_FILE)
|
||||||
|
AC_SUBST(ALLOC_FILE)
|
||||||
|
|
||||||
|
BACKTRACE_USES_MALLOC=0
|
||||||
|
if test "$ALLOC_FILE" = "alloc.lo"; then
|
||||||
|
BACKTRACE_USES_MALLOC=1
|
||||||
|
fi
|
||||||
|
AC_SUBST(BACKTRACE_USES_MALLOC)
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether tests can run],
|
||||||
|
[libbacktrace_cv_sys_native],
|
||||||
|
[AC_RUN_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
|
||||||
|
[libbacktrace_cv_sys_native=yes],
|
||||||
|
[libbacktrace_cv_sys_native=no],
|
||||||
|
[libbacktrace_cv_sys_native=no])])
|
||||||
|
AM_CONDITIONAL(NATIVE, test "$libbacktrace_cv_sys_native" = "yes")
|
||||||
|
|
||||||
|
if test "${multilib}" = "yes"; then
|
||||||
|
multilib_arg="--enable-multilib"
|
||||||
|
else
|
||||||
|
multilib_arg=
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CONFIG_FILES(Makefile backtrace-supported.h)
|
||||||
|
|
||||||
|
# We need multilib support, but only if configuring for the target.
|
||||||
|
AC_CONFIG_COMMANDS([default],
|
||||||
|
[if test -n "$CONFIG_FILES"; then
|
||||||
|
if test -n "${with_target_subdir}"; then
|
||||||
|
# Multilibs need MULTISUBDIR defined correctly in certain makefiles so
|
||||||
|
# that multilib installs will end up installed in the correct place.
|
||||||
|
# The testsuite needs it for multilib-aware ABI baseline files.
|
||||||
|
# To work around this not being passed down from config-ml.in ->
|
||||||
|
# srcdir/Makefile.am -> srcdir/{src,libsupc++,...}/Makefile.am, manually
|
||||||
|
# append it here. Only modify Makefiles that have just been created.
|
||||||
|
#
|
||||||
|
# Also, get rid of this simulated-VPATH thing that automake does.
|
||||||
|
cat > vpsed << \_EOF
|
||||||
|
s!`test -f '$<' || echo '$(srcdir)/'`!!
|
||||||
|
_EOF
|
||||||
|
for i in $SUBDIRS; do
|
||||||
|
case $CONFIG_FILES in
|
||||||
|
*${i}/Makefile*)
|
||||||
|
#echo "Adding MULTISUBDIR to $i/Makefile"
|
||||||
|
sed -f vpsed $i/Makefile > tmp
|
||||||
|
grep '^MULTISUBDIR =' Makefile >> tmp
|
||||||
|
mv tmp $i/Makefile
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
rm vpsed
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[
|
||||||
|
# Variables needed in config.status (file generation) which aren't already
|
||||||
|
# passed by autoconf.
|
||||||
|
SUBDIRS="$SUBDIRS"
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,688 @@
|
||||||
|
/* elf.c -- Get debug data from an ELF file for backtraces.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* The configure script must tell us whether we are 32-bit or 64-bit
|
||||||
|
ELF. We could make this code test and support either possibility,
|
||||||
|
but there is no point. This code only works for the currently
|
||||||
|
running executable, which means that we know the ELF mode at
|
||||||
|
configure mode. */
|
||||||
|
|
||||||
|
#if BACKTRACE_ELF_SIZE != 32 && BACKTRACE_ELF_SIZE != 64
|
||||||
|
#error "Unknown BACKTRACE_ELF_SIZE"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Basic types. */
|
||||||
|
|
||||||
|
typedef uint16_t Elf_Half;
|
||||||
|
typedef uint32_t Elf_Word;
|
||||||
|
typedef int32_t Elf_Sword;
|
||||||
|
|
||||||
|
#if BACKTRACE_ELF_SIZE == 32
|
||||||
|
|
||||||
|
typedef uint32_t Elf_Addr;
|
||||||
|
typedef uint32_t Elf_Off;
|
||||||
|
|
||||||
|
typedef uint32_t Elf_WXword;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef uint64_t Elf_Addr;
|
||||||
|
typedef uint64_t Elf_Off;
|
||||||
|
typedef uint64_t Elf_Xword;
|
||||||
|
typedef int64_t Elf_Sxword;
|
||||||
|
|
||||||
|
typedef uint64_t Elf_WXword;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Data structures and associated constants. */
|
||||||
|
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
|
||||||
|
Elf_Half e_type; /* Identifies object file type */
|
||||||
|
Elf_Half e_machine; /* Specifies required architecture */
|
||||||
|
Elf_Word e_version; /* Identifies object file version */
|
||||||
|
Elf_Addr e_entry; /* Entry point virtual address */
|
||||||
|
Elf_Off e_phoff; /* Program header table file offset */
|
||||||
|
Elf_Off e_shoff; /* Section header table file offset */
|
||||||
|
Elf_Word e_flags; /* Processor-specific flags */
|
||||||
|
Elf_Half e_ehsize; /* ELF header size in bytes */
|
||||||
|
Elf_Half e_phentsize; /* Program header table entry size */
|
||||||
|
Elf_Half e_phnum; /* Program header table entry count */
|
||||||
|
Elf_Half e_shentsize; /* Section header table entry size */
|
||||||
|
Elf_Half e_shnum; /* Section header table entry count */
|
||||||
|
Elf_Half e_shstrndx; /* Section header string table index */
|
||||||
|
} Elf_Ehdr;
|
||||||
|
|
||||||
|
#define EI_MAG0 0
|
||||||
|
#define EI_MAG1 1
|
||||||
|
#define EI_MAG2 2
|
||||||
|
#define EI_MAG3 3
|
||||||
|
#define EI_CLASS 4
|
||||||
|
#define EI_DATA 5
|
||||||
|
#define EI_VERSION 6
|
||||||
|
|
||||||
|
#define ELFMAG0 0x7f
|
||||||
|
#define ELFMAG1 'E'
|
||||||
|
#define ELFMAG2 'L'
|
||||||
|
#define ELFMAG3 'F'
|
||||||
|
|
||||||
|
#define ELFCLASS32 1
|
||||||
|
#define ELFCLASS64 2
|
||||||
|
|
||||||
|
#define ELFDATA2LSB 1
|
||||||
|
#define ELFDATA2MSB 2
|
||||||
|
|
||||||
|
#define EV_CURRENT 1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf_Word sh_name; /* Section name, index in string tbl */
|
||||||
|
Elf_Word sh_type; /* Type of section */
|
||||||
|
Elf_WXword sh_flags; /* Miscellaneous section attributes */
|
||||||
|
Elf_Addr sh_addr; /* Section virtual addr at execution */
|
||||||
|
Elf_Off sh_offset; /* Section file offset */
|
||||||
|
Elf_WXword sh_size; /* Size of section in bytes */
|
||||||
|
Elf_Word sh_link; /* Index of another section */
|
||||||
|
Elf_Word sh_info; /* Additional section information */
|
||||||
|
Elf_WXword sh_addralign; /* Section alignment */
|
||||||
|
Elf_WXword sh_entsize; /* Entry size if section holds table */
|
||||||
|
} Elf_Shdr;
|
||||||
|
|
||||||
|
#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
|
||||||
|
#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
|
||||||
|
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_DYNSYM 11
|
||||||
|
|
||||||
|
#if BACKTRACE_ELF_SIZE == 32
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Elf_Word st_name; /* Symbol name, index in string tbl */
|
||||||
|
Elf_Addr st_value; /* Symbol value */
|
||||||
|
Elf_Word st_size; /* Symbol size */
|
||||||
|
unsigned char st_info; /* Symbol binding and type */
|
||||||
|
unsigned char st_other; /* Visibility and other data */
|
||||||
|
Elf_Half st_shndx; /* Symbol section index */
|
||||||
|
} Elf_Sym;
|
||||||
|
|
||||||
|
#else /* BACKTRACE_ELF_SIZE != 32 */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Elf_Word st_name; /* Symbol name, index in string tbl */
|
||||||
|
unsigned char st_info; /* Symbol binding and type */
|
||||||
|
unsigned char st_other; /* Visibility and other data */
|
||||||
|
Elf_Half st_shndx; /* Symbol section index */
|
||||||
|
Elf_Addr st_value; /* Symbol value */
|
||||||
|
Elf_Xword st_size; /* Symbol size */
|
||||||
|
} Elf_Sym;
|
||||||
|
|
||||||
|
#endif /* BACKTRACE_ELF_SIZE != 32 */
|
||||||
|
|
||||||
|
#define STT_FUNC 2
|
||||||
|
|
||||||
|
/* An index of ELF sections we care about. */
|
||||||
|
|
||||||
|
enum debug_section
|
||||||
|
{
|
||||||
|
DEBUG_INFO,
|
||||||
|
DEBUG_LINE,
|
||||||
|
DEBUG_ABBREV,
|
||||||
|
DEBUG_RANGES,
|
||||||
|
DEBUG_STR,
|
||||||
|
DEBUG_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names of sections, indexed by enum elf_section. */
|
||||||
|
|
||||||
|
static const char * const debug_section_names[DEBUG_MAX] =
|
||||||
|
{
|
||||||
|
".debug_info",
|
||||||
|
".debug_line",
|
||||||
|
".debug_abbrev",
|
||||||
|
".debug_ranges",
|
||||||
|
".debug_str"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Information we gather for the sections we care about. */
|
||||||
|
|
||||||
|
struct debug_section_info
|
||||||
|
{
|
||||||
|
/* Section file offset. */
|
||||||
|
off_t offset;
|
||||||
|
/* Section size. */
|
||||||
|
size_t size;
|
||||||
|
/* Section contents, after read from file. */
|
||||||
|
const unsigned char *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Information we keep for an ELF symbol. */
|
||||||
|
|
||||||
|
struct elf_symbol
|
||||||
|
{
|
||||||
|
/* The name of the symbol. */
|
||||||
|
const char *name;
|
||||||
|
/* The address of the symbol. */
|
||||||
|
uintptr_t address;
|
||||||
|
/* The size of the symbol. */
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Information to pass to elf_syminfo. */
|
||||||
|
|
||||||
|
struct elf_syminfo_data
|
||||||
|
{
|
||||||
|
/* The ELF symbols, sorted by address. */
|
||||||
|
struct elf_symbol *symbols;
|
||||||
|
/* The number of symbols. */
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A dummy callback function used when we can't find any debug info. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
elf_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
uintptr_t pc ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_full_callback callback ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
error_callback (data, "no debug info in ELF executable", -1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A dummy callback function used when we can't find a symbol
|
||||||
|
table. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
elf_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
uintptr_t pc ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
error_callback (data, "no symbol table in ELF executable", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare struct elf_symbol for qsort. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
elf_symbol_compare (const void *v1, const void *v2)
|
||||||
|
{
|
||||||
|
const struct elf_symbol *e1 = (const struct elf_symbol *) v1;
|
||||||
|
const struct elf_symbol *e2 = (const struct elf_symbol *) v2;
|
||||||
|
|
||||||
|
if (e1->address < e2->address)
|
||||||
|
return -1;
|
||||||
|
else if (e1->address > e2->address)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare a PC against an elf_symbol for bsearch. We allocate one
|
||||||
|
extra entry in the array so that this can look safely at the next
|
||||||
|
entry. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
elf_symbol_search (const void *vkey, const void *ventry)
|
||||||
|
{
|
||||||
|
const uintptr_t *key = (const uintptr_t *) vkey;
|
||||||
|
const struct elf_symbol *entry = (const struct elf_symbol *) ventry;
|
||||||
|
uintptr_t pc;
|
||||||
|
|
||||||
|
pc = *key;
|
||||||
|
if (pc < entry->address)
|
||||||
|
return -1;
|
||||||
|
else if (pc >= entry->address + entry->size)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the symbol table info for elf_syminfo. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
elf_initialize_syminfo (struct backtrace_state *state,
|
||||||
|
const unsigned char *symtab_data, size_t symtab_size,
|
||||||
|
const unsigned char *strtab, size_t strtab_size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct elf_syminfo_data *sdata)
|
||||||
|
{
|
||||||
|
size_t sym_count;
|
||||||
|
const Elf_Sym *sym;
|
||||||
|
size_t elf_symbol_count;
|
||||||
|
size_t elf_symbol_size;
|
||||||
|
struct elf_symbol *elf_symbols;
|
||||||
|
size_t i;
|
||||||
|
unsigned int j;
|
||||||
|
|
||||||
|
sym_count = symtab_size / sizeof (Elf_Sym);
|
||||||
|
|
||||||
|
/* We only care about function symbols. Count them. */
|
||||||
|
sym = (const Elf_Sym *) symtab_data;
|
||||||
|
elf_symbol_count = 0;
|
||||||
|
for (i = 0; i < sym_count; ++i, ++sym)
|
||||||
|
{
|
||||||
|
if ((sym->st_info & 0xf) == STT_FUNC)
|
||||||
|
++elf_symbol_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
elf_symbol_size = elf_symbol_count * sizeof (struct elf_symbol);
|
||||||
|
elf_symbols = ((struct elf_symbol *)
|
||||||
|
backtrace_alloc (state, elf_symbol_size, error_callback,
|
||||||
|
data));
|
||||||
|
if (elf_symbols == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sym = (const Elf_Sym *) symtab_data;
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < sym_count; ++i, ++sym)
|
||||||
|
{
|
||||||
|
if ((sym->st_info & 0xf) != STT_FUNC)
|
||||||
|
continue;
|
||||||
|
if (sym->st_name >= strtab_size)
|
||||||
|
{
|
||||||
|
error_callback (data, "symbol string index out of range", 0);
|
||||||
|
backtrace_free (state, elf_symbols, elf_symbol_size, error_callback,
|
||||||
|
data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
elf_symbols[j].name = (const char *) strtab + sym->st_name;
|
||||||
|
elf_symbols[j].address = sym->st_value;
|
||||||
|
elf_symbols[j].size = sym->st_size;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort (elf_symbols, elf_symbol_count, sizeof (struct elf_symbol),
|
||||||
|
elf_symbol_compare);
|
||||||
|
|
||||||
|
sdata->symbols = elf_symbols;
|
||||||
|
sdata->count = elf_symbol_count;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the symbol name and value for a PC. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
elf_syminfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct elf_syminfo_data *edata;
|
||||||
|
struct elf_symbol *sym;
|
||||||
|
|
||||||
|
edata = (struct elf_syminfo_data *) state->syminfo_data;
|
||||||
|
sym = ((struct elf_symbol *)
|
||||||
|
bsearch (&pc, edata->symbols, edata->count,
|
||||||
|
sizeof (struct elf_symbol), elf_symbol_search));
|
||||||
|
if (sym == NULL)
|
||||||
|
callback (data, pc, NULL, 0);
|
||||||
|
else
|
||||||
|
callback (data, pc, sym->name, sym->address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the backtrace data we need from an ELF executable. At
|
||||||
|
the ELF level, all we need to do is find the debug info
|
||||||
|
sections. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_initialize (struct backtrace_state *state, int descriptor,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, fileline *fileline_fn)
|
||||||
|
{
|
||||||
|
struct backtrace_view ehdr_view;
|
||||||
|
Elf_Ehdr ehdr;
|
||||||
|
off_t shoff;
|
||||||
|
unsigned int shnum;
|
||||||
|
unsigned int shstrndx;
|
||||||
|
struct backtrace_view shdrs_view;
|
||||||
|
int shdrs_view_valid;
|
||||||
|
const Elf_Shdr *shdrs;
|
||||||
|
const Elf_Shdr *shstrhdr;
|
||||||
|
size_t shstr_size;
|
||||||
|
off_t shstr_off;
|
||||||
|
struct backtrace_view names_view;
|
||||||
|
int names_view_valid;
|
||||||
|
const char *names;
|
||||||
|
unsigned int symtab_shndx;
|
||||||
|
unsigned int dynsym_shndx;
|
||||||
|
unsigned int i;
|
||||||
|
struct debug_section_info sections[DEBUG_MAX];
|
||||||
|
struct backtrace_view symtab_view;
|
||||||
|
int symtab_view_valid;
|
||||||
|
struct backtrace_view strtab_view;
|
||||||
|
int strtab_view_valid;
|
||||||
|
off_t min_offset;
|
||||||
|
off_t max_offset;
|
||||||
|
struct backtrace_view debug_view;
|
||||||
|
int debug_view_valid;
|
||||||
|
|
||||||
|
shdrs_view_valid = 0;
|
||||||
|
names_view_valid = 0;
|
||||||
|
symtab_view_valid = 0;
|
||||||
|
strtab_view_valid = 0;
|
||||||
|
debug_view_valid = 0;
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
|
||||||
|
data, &ehdr_view))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
memcpy (&ehdr, ehdr_view.data, sizeof ehdr);
|
||||||
|
|
||||||
|
backtrace_release_view (state, &ehdr_view, error_callback, data);
|
||||||
|
|
||||||
|
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|
||||||
|
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||||
|
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||||
|
|| ehdr.e_ident[EI_MAG3] != ELFMAG3)
|
||||||
|
{
|
||||||
|
error_callback (data, "executable file is not ELF", 0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
|
||||||
|
{
|
||||||
|
error_callback (data, "executable file is unrecognized ELF version", 0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BACKTRACE_ELF_SIZE == 32
|
||||||
|
#define BACKTRACE_ELFCLASS ELFCLASS32
|
||||||
|
#else
|
||||||
|
#define BACKTRACE_ELFCLASS ELFCLASS64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ehdr.e_ident[EI_CLASS] != BACKTRACE_ELFCLASS)
|
||||||
|
{
|
||||||
|
error_callback (data, "executable file is unexpected ELF class", 0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB
|
||||||
|
&& ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
|
||||||
|
{
|
||||||
|
error_callback (data, "executable file has unknown endianness", 0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
shoff = ehdr.e_shoff;
|
||||||
|
shnum = ehdr.e_shnum;
|
||||||
|
shstrndx = ehdr.e_shstrndx;
|
||||||
|
|
||||||
|
if ((shnum == 0 || shstrndx == SHN_XINDEX)
|
||||||
|
&& shoff != 0)
|
||||||
|
{
|
||||||
|
struct backtrace_view shdr_view;
|
||||||
|
const Elf_Shdr *shdr;
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, shoff, sizeof shdr,
|
||||||
|
error_callback, data, &shdr_view))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
shdr = (const Elf_Shdr *) shdr_view.data;
|
||||||
|
|
||||||
|
if (shnum == 0)
|
||||||
|
shnum = shdr->sh_size;
|
||||||
|
|
||||||
|
if (shstrndx == SHN_XINDEX)
|
||||||
|
{
|
||||||
|
shstrndx = shdr->sh_link;
|
||||||
|
|
||||||
|
/* Versions of the GNU binutils between 2.12 and 2.18 did
|
||||||
|
not handle objects with more than SHN_LORESERVE sections
|
||||||
|
correctly. All large section indexes were offset by
|
||||||
|
0x100. There is more information at
|
||||||
|
http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
|
||||||
|
Fortunately these object files are easy to detect, as the
|
||||||
|
GNU binutils always put the section header string table
|
||||||
|
near the end of the list of sections. Thus if the
|
||||||
|
section header string table index is larger than the
|
||||||
|
number of sections, then we know we have to subtract
|
||||||
|
0x100 to get the real section index. */
|
||||||
|
if (shstrndx >= shnum && shstrndx >= SHN_LORESERVE + 0x100)
|
||||||
|
shstrndx -= 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
backtrace_release_view (state, &shdr_view, error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To translate PC to file/line when using DWARF, we need to find
|
||||||
|
the .debug_info and .debug_line sections. */
|
||||||
|
|
||||||
|
/* Read the section headers, skipping the first one. */
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, shoff + sizeof (Elf_Shdr),
|
||||||
|
(shnum - 1) * sizeof (Elf_Shdr),
|
||||||
|
error_callback, data, &shdrs_view))
|
||||||
|
goto fail;
|
||||||
|
shdrs_view_valid = 1;
|
||||||
|
shdrs = (const Elf_Shdr *) shdrs_view.data;
|
||||||
|
|
||||||
|
/* Read the section names. */
|
||||||
|
|
||||||
|
shstrhdr = &shdrs[shstrndx - 1];
|
||||||
|
shstr_size = shstrhdr->sh_size;
|
||||||
|
shstr_off = shstrhdr->sh_offset;
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, shstr_off, shstr_size,
|
||||||
|
error_callback, data, &names_view))
|
||||||
|
goto fail;
|
||||||
|
names_view_valid = 1;
|
||||||
|
names = (const char *) names_view.data;
|
||||||
|
|
||||||
|
symtab_shndx = 0;
|
||||||
|
dynsym_shndx = 0;
|
||||||
|
|
||||||
|
memset (sections, 0, sizeof sections);
|
||||||
|
for (i = 1; i < shnum; ++i)
|
||||||
|
{
|
||||||
|
const Elf_Shdr *shdr;
|
||||||
|
unsigned int sh_name;
|
||||||
|
const char *name;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
shdr = &shdrs[i - 1];
|
||||||
|
|
||||||
|
if (shdr->sh_type == SHT_SYMTAB)
|
||||||
|
symtab_shndx = i;
|
||||||
|
else if (shdr->sh_type == SHT_DYNSYM)
|
||||||
|
dynsym_shndx = i;
|
||||||
|
|
||||||
|
sh_name = shdr->sh_name;
|
||||||
|
if (sh_name >= shstr_size)
|
||||||
|
{
|
||||||
|
error_callback (data, "ELF section name out of range", 0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = names + sh_name;
|
||||||
|
|
||||||
|
for (j = 0; j < (int) DEBUG_MAX; ++j)
|
||||||
|
{
|
||||||
|
if (strcmp (name, debug_section_names[j]) == 0)
|
||||||
|
{
|
||||||
|
sections[j].offset = shdr->sh_offset;
|
||||||
|
sections[j].size = shdr->sh_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (symtab_shndx == 0)
|
||||||
|
symtab_shndx = dynsym_shndx;
|
||||||
|
if (symtab_shndx == 0)
|
||||||
|
{
|
||||||
|
state->syminfo_fn = elf_nosyms;
|
||||||
|
state->syminfo_data = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const Elf_Shdr *symtab_shdr;
|
||||||
|
unsigned int strtab_shndx;
|
||||||
|
const Elf_Shdr *strtab_shdr;
|
||||||
|
struct elf_syminfo_data *sdata;
|
||||||
|
|
||||||
|
symtab_shdr = &shdrs[symtab_shndx - 1];
|
||||||
|
strtab_shndx = symtab_shdr->sh_link;
|
||||||
|
if (strtab_shndx >= shnum)
|
||||||
|
{
|
||||||
|
error_callback (data,
|
||||||
|
"ELF symbol table strtab link out of range", 0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
strtab_shdr = &shdrs[strtab_shndx - 1];
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, symtab_shdr->sh_offset,
|
||||||
|
symtab_shdr->sh_size, error_callback, data,
|
||||||
|
&symtab_view))
|
||||||
|
goto fail;
|
||||||
|
symtab_view_valid = 1;
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, strtab_shdr->sh_offset,
|
||||||
|
strtab_shdr->sh_size, error_callback, data,
|
||||||
|
&strtab_view))
|
||||||
|
goto fail;
|
||||||
|
strtab_view_valid = 1;
|
||||||
|
|
||||||
|
sdata = ((struct elf_syminfo_data *)
|
||||||
|
backtrace_alloc (state, sizeof *sdata, error_callback, data));
|
||||||
|
if (sdata == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!elf_initialize_syminfo (state,
|
||||||
|
symtab_view.data, symtab_shdr->sh_size,
|
||||||
|
strtab_view.data, strtab_shdr->sh_size,
|
||||||
|
error_callback, data, sdata))
|
||||||
|
{
|
||||||
|
backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We no longer need the symbol table, but we hold on to the
|
||||||
|
string table permanently. */
|
||||||
|
backtrace_release_view (state, &symtab_view, error_callback, data);
|
||||||
|
|
||||||
|
state->syminfo_fn = elf_syminfo;
|
||||||
|
state->syminfo_data = sdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Need to handle compressed debug sections. */
|
||||||
|
|
||||||
|
backtrace_release_view (state, &shdrs_view, error_callback, data);
|
||||||
|
shdrs_view_valid = 0;
|
||||||
|
backtrace_release_view (state, &names_view, error_callback, data);
|
||||||
|
names_view_valid = 0;
|
||||||
|
|
||||||
|
/* Read all the debug sections in a single view, since they are
|
||||||
|
probably adjacent in the file. We never release this view. */
|
||||||
|
|
||||||
|
min_offset = 0;
|
||||||
|
max_offset = 0;
|
||||||
|
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
||||||
|
{
|
||||||
|
off_t end;
|
||||||
|
|
||||||
|
if (min_offset == 0 || sections[i].offset < min_offset)
|
||||||
|
min_offset = sections[i].offset;
|
||||||
|
end = sections[i].offset + sections[i].size;
|
||||||
|
if (end > max_offset)
|
||||||
|
max_offset = end;
|
||||||
|
}
|
||||||
|
if (min_offset == 0 || max_offset == 0)
|
||||||
|
{
|
||||||
|
if (!backtrace_close (descriptor, error_callback, data))
|
||||||
|
goto fail;
|
||||||
|
state->fileline_fn = elf_nodebug;
|
||||||
|
state->fileline_data = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, min_offset,
|
||||||
|
max_offset - min_offset,
|
||||||
|
error_callback, data, &debug_view))
|
||||||
|
goto fail;
|
||||||
|
debug_view_valid = 1;
|
||||||
|
|
||||||
|
/* We've read all we need from the executable. */
|
||||||
|
if (!backtrace_close (descriptor, error_callback, data))
|
||||||
|
goto fail;
|
||||||
|
descriptor = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
||||||
|
sections[i].data = ((const unsigned char *) debug_view.data
|
||||||
|
+ (sections[i].offset - min_offset));
|
||||||
|
|
||||||
|
if (!backtrace_dwarf_initialize (state,
|
||||||
|
sections[DEBUG_INFO].data,
|
||||||
|
sections[DEBUG_INFO].size,
|
||||||
|
sections[DEBUG_LINE].data,
|
||||||
|
sections[DEBUG_LINE].size,
|
||||||
|
sections[DEBUG_ABBREV].data,
|
||||||
|
sections[DEBUG_ABBREV].size,
|
||||||
|
sections[DEBUG_RANGES].data,
|
||||||
|
sections[DEBUG_RANGES].size,
|
||||||
|
sections[DEBUG_STR].data,
|
||||||
|
sections[DEBUG_STR].size,
|
||||||
|
ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
|
||||||
|
error_callback, data, fileline_fn))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (shdrs_view_valid)
|
||||||
|
backtrace_release_view (state, &shdrs_view, error_callback, data);
|
||||||
|
if (names_view_valid)
|
||||||
|
backtrace_release_view (state, &names_view, error_callback, data);
|
||||||
|
if (symtab_view_valid)
|
||||||
|
backtrace_release_view (state, &symtab_view, error_callback, data);
|
||||||
|
if (strtab_view_valid)
|
||||||
|
backtrace_release_view (state, &strtab_view, error_callback, data);
|
||||||
|
if (debug_view_valid)
|
||||||
|
backtrace_release_view (state, &debug_view, error_callback, data);
|
||||||
|
if (descriptor != -1)
|
||||||
|
backtrace_close (descriptor, error_callback, data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
/* fileline.c -- Get file and line number information in a backtrace.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* Initialize the fileline information from the executable. Returns 1
|
||||||
|
on success, 0 on failure. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
fileline_initialize (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
int failed;
|
||||||
|
fileline fileline_fn;
|
||||||
|
int descriptor;
|
||||||
|
|
||||||
|
failed = state->fileline_initialization_failed;
|
||||||
|
|
||||||
|
if (state->threaded)
|
||||||
|
{
|
||||||
|
/* Use __sync_bool_compare_and_swap to do an atomic load. */
|
||||||
|
while (!__sync_bool_compare_and_swap
|
||||||
|
(&state->fileline_initialization_failed, failed, failed))
|
||||||
|
failed = state->fileline_initialization_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
error_callback (data, "failed to read executable information", 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileline_fn = state->fileline_fn;
|
||||||
|
if (state->threaded)
|
||||||
|
{
|
||||||
|
while (!__sync_bool_compare_and_swap (&state->fileline_fn, fileline_fn,
|
||||||
|
fileline_fn))
|
||||||
|
fileline_fn = state->fileline_fn;
|
||||||
|
}
|
||||||
|
if (fileline_fn != NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* We have not initialized the information. Do it now. */
|
||||||
|
|
||||||
|
if (state->filename != NULL)
|
||||||
|
descriptor = backtrace_open (state->filename, error_callback, data);
|
||||||
|
else
|
||||||
|
descriptor = backtrace_open ("/proc/self/exe", error_callback, data);
|
||||||
|
if (descriptor < 0)
|
||||||
|
failed = 1;
|
||||||
|
|
||||||
|
if (!failed)
|
||||||
|
{
|
||||||
|
if (!backtrace_initialize (state, descriptor, error_callback, data,
|
||||||
|
&fileline_fn))
|
||||||
|
failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
if (!state->threaded)
|
||||||
|
state->fileline_initialization_failed = 1;
|
||||||
|
else
|
||||||
|
__sync_bool_compare_and_swap (&state->fileline_initialization_failed,
|
||||||
|
0, failed);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state->threaded)
|
||||||
|
state->fileline_fn = fileline_fn;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__sync_bool_compare_and_swap (&state->fileline_fn, NULL, fileline_fn);
|
||||||
|
|
||||||
|
/* At this point we know that state->fileline_fn is not NULL.
|
||||||
|
Either we stored our value, or some other thread stored its
|
||||||
|
value. If some other thread stored its value, we leak the
|
||||||
|
one we just initialized. Either way, state->fileline_fn is
|
||||||
|
initialized. The compare_and_swap is a full memory barrier,
|
||||||
|
so we should have full access to that value even if it was
|
||||||
|
created by another thread. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a PC, find the file name, line number, and function name. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
if (!fileline_initialize (state, error_callback, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (state->fileline_initialization_failed)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return state->fileline_fn (state, pc, callback, error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a PC, find the symbol for it, and its value. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
if (!fileline_initialize (state, error_callback, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (state->fileline_initialization_failed)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
state->syminfo_fn (state, pc, callback, error_callback, data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# An awk script to determine the type of a file.
|
||||||
|
/\177ELF\001/ { if (NR == 1) { print "elf32"; exit } }
|
||||||
|
/\177ELF\002/ { if (NR == 1) { print "elf64"; exit } }
|
||||||
|
|
@ -0,0 +1,235 @@
|
||||||
|
/* internal.h -- Internal header file for stack backtrace library.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#ifndef BACKTRACE_INTERNAL_H
|
||||||
|
#define BACKTRACE_INTERNAL_H
|
||||||
|
|
||||||
|
/* We assume that <sys/types.h> and "backtrace.h" have already been
|
||||||
|
included. */
|
||||||
|
|
||||||
|
#ifndef GCC_VERSION
|
||||||
|
# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GCC_VERSION < 2007)
|
||||||
|
# define __attribute__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_UNUSED
|
||||||
|
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_MALLOC
|
||||||
|
# if (GCC_VERSION >= 2096)
|
||||||
|
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_MALLOC
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SYNC_FUNCTIONS
|
||||||
|
|
||||||
|
/* Define out the sync functions. These should never be called if
|
||||||
|
they are not available. */
|
||||||
|
|
||||||
|
#define __sync_bool_compare_and_swap(A, B, C) (abort(), 1)
|
||||||
|
#define __sync_lock_test_and_set(A, B) (abort(), 0)
|
||||||
|
#define __sync_lock_release(A) abort()
|
||||||
|
|
||||||
|
#endif /* !defined(HAVE_SYNC_FUNCTIONS) */
|
||||||
|
|
||||||
|
/* The type of the function that collects file/line information. This
|
||||||
|
is like backtrace_pcinfo. */
|
||||||
|
|
||||||
|
typedef int (*fileline) (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data);
|
||||||
|
|
||||||
|
/* The type of the function that collects symbol information. This is
|
||||||
|
like backtrace_syminfo. */
|
||||||
|
|
||||||
|
typedef void (*syminfo) (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data);
|
||||||
|
|
||||||
|
/* What the backtrace state pointer points to. */
|
||||||
|
|
||||||
|
struct backtrace_state
|
||||||
|
{
|
||||||
|
/* The name of the executable. */
|
||||||
|
const char *filename;
|
||||||
|
/* Non-zero if threaded. */
|
||||||
|
int threaded;
|
||||||
|
/* The master lock for fileline_fn, fileline_data, syminfo_fn,
|
||||||
|
syminfo_data, fileline_initialization_failed and everything the
|
||||||
|
data pointers point to. */
|
||||||
|
void *lock;
|
||||||
|
/* The function that returns file/line information. */
|
||||||
|
fileline fileline_fn;
|
||||||
|
/* The data to pass to FILELINE_FN. */
|
||||||
|
void *fileline_data;
|
||||||
|
/* The function that returns symbol information. */
|
||||||
|
syminfo syminfo_fn;
|
||||||
|
/* The data to pass to SYMINFO_FN. */
|
||||||
|
void *syminfo_data;
|
||||||
|
/* Whether initializing the file/line information failed. */
|
||||||
|
int fileline_initialization_failed;
|
||||||
|
/* The lock for the freelist. */
|
||||||
|
int lock_alloc;
|
||||||
|
/* The freelist when using mmap. */
|
||||||
|
struct backtrace_freelist_struct *freelist;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Open a file for reading. Returns -1 on error. */
|
||||||
|
extern int backtrace_open (const char *filename,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* A view of the contents of a file. This supports mmap when
|
||||||
|
available. A view will remain in memory even after backtrace_close
|
||||||
|
is called on the file descriptor from which the view was
|
||||||
|
obtained. */
|
||||||
|
|
||||||
|
struct backtrace_view
|
||||||
|
{
|
||||||
|
/* The data that the caller requested. */
|
||||||
|
const void *data;
|
||||||
|
/* The base of the view. */
|
||||||
|
void *base;
|
||||||
|
/* The total length of the view. */
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. Store the
|
||||||
|
result in *VIEW. Returns 1 on success, 0 on error. */
|
||||||
|
extern int backtrace_get_view (struct backtrace_state *state, int descriptor,
|
||||||
|
off_t offset, size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_view *view);
|
||||||
|
|
||||||
|
/* Release a view created by backtrace_get_view. */
|
||||||
|
extern void backtrace_release_view (struct backtrace_state *state,
|
||||||
|
struct backtrace_view *view,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Close a file opened by backtrace_open. Returns 1 on success, 0 on
|
||||||
|
error. */
|
||||||
|
|
||||||
|
extern int backtrace_close (int descriptor,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Allocate memory. This is like malloc. */
|
||||||
|
|
||||||
|
extern void *backtrace_alloc (struct backtrace_state *state, size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data) ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
|
/* Free memory allocated by backtrace_alloc. */
|
||||||
|
|
||||||
|
extern void backtrace_free (struct backtrace_state *state, void *mem,
|
||||||
|
size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* A growable vector of some struct. This is used for more efficient
|
||||||
|
allocation when we don't know the final size of some group of data
|
||||||
|
that we want to represent as an array. */
|
||||||
|
|
||||||
|
struct backtrace_vector
|
||||||
|
{
|
||||||
|
/* The base of the vector. */
|
||||||
|
void *base;
|
||||||
|
/* The number of bytes in the vector. */
|
||||||
|
size_t size;
|
||||||
|
/* The number of bytes available at the current allocation. */
|
||||||
|
size_t alc;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Grow VEC by SIZE bytes. Return a pointer to the newly allocated
|
||||||
|
bytes. Note that this may move the entire vector to a new memory
|
||||||
|
location. Returns NULL on failure. */
|
||||||
|
|
||||||
|
extern void *backtrace_vector_grow (struct backtrace_state *state, size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
struct backtrace_vector *vec);
|
||||||
|
|
||||||
|
/* Finish the current allocation on VEC. Prepare to start a new
|
||||||
|
allocation. The finished allocation will never be freed. */
|
||||||
|
|
||||||
|
extern void backtrace_vector_finish (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec);
|
||||||
|
|
||||||
|
/* Release any extra space allocated for VEC. Returns 1 on success, 0
|
||||||
|
on failure. */
|
||||||
|
|
||||||
|
extern int backtrace_vector_release (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Read initial debug data from a descriptor, and set the
|
||||||
|
fileline_data, syminfo_fn, and syminfo_data fields of STATE.
|
||||||
|
Return the fileln_fn field in *FILELN_FN--this is done this way so
|
||||||
|
that the synchronization code is only implemented once. This is
|
||||||
|
called after the descriptor has first been opened. It will close
|
||||||
|
the descriptor if it is no longer needed. Returns 1 on success, 0
|
||||||
|
on error. There will be multiple implementations of this function,
|
||||||
|
for different file formats. Each system will compile the
|
||||||
|
appropriate one. */
|
||||||
|
|
||||||
|
extern int backtrace_initialize (struct backtrace_state *state,
|
||||||
|
int descriptor,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
fileline *fileline_fn);
|
||||||
|
|
||||||
|
/* Prepare to read file/line information from DWARF debug data. */
|
||||||
|
|
||||||
|
extern int backtrace_dwarf_initialize (struct backtrace_state *state,
|
||||||
|
const unsigned char* dwarf_info,
|
||||||
|
size_t dwarf_info_size,
|
||||||
|
const unsigned char *dwarf_line,
|
||||||
|
size_t dwarf_line_size,
|
||||||
|
const unsigned char *dwarf_abbrev,
|
||||||
|
size_t dwarf_abbrev_size,
|
||||||
|
const unsigned char *dwarf_ranges,
|
||||||
|
size_t dwarf_range_size,
|
||||||
|
const unsigned char *dwarf_str,
|
||||||
|
size_t dwarf_str_size,
|
||||||
|
int is_bigendian,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, fileline *fileline_fn);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,235 @@
|
||||||
|
/* mmap.c -- Memory allocation with mmap.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* Memory allocation on systems that provide anonymous mmap. This
|
||||||
|
permits the backtrace functions to be invoked from a signal
|
||||||
|
handler, assuming that mmap is async-signal safe. */
|
||||||
|
|
||||||
|
#ifndef MAP_ANONYMOUS
|
||||||
|
#define MAP_ANONYMOUS MAP_ANON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A list of free memory blocks. */
|
||||||
|
|
||||||
|
struct backtrace_freelist_struct
|
||||||
|
{
|
||||||
|
/* Next on list. */
|
||||||
|
struct backtrace_freelist_struct *next;
|
||||||
|
/* Size of this block, including this structure. */
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Free memory allocated by backtrace_alloc. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
backtrace_free_locked (struct backtrace_state *state, void *addr, size_t size)
|
||||||
|
{
|
||||||
|
/* Just leak small blocks. We don't have to be perfect. */
|
||||||
|
if (size >= sizeof (struct backtrace_freelist_struct))
|
||||||
|
{
|
||||||
|
struct backtrace_freelist_struct *p;
|
||||||
|
|
||||||
|
p = (struct backtrace_freelist_struct *) addr;
|
||||||
|
p->next = state->freelist;
|
||||||
|
p->size = size;
|
||||||
|
state->freelist = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory like malloc. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_alloc (struct backtrace_state *state,
|
||||||
|
size_t size, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
struct backtrace_freelist_struct **pp;
|
||||||
|
size_t pagesize;
|
||||||
|
size_t asksize;
|
||||||
|
void *page;
|
||||||
|
|
||||||
|
ret = NULL;
|
||||||
|
|
||||||
|
/* If we can acquire the lock, then see if there is space on the
|
||||||
|
free list. If we can't acquire the lock, drop straight into
|
||||||
|
using mmap. __sync_lock_test_and_set returns the old state of
|
||||||
|
the lock, so we have acquired it if it returns 0. */
|
||||||
|
|
||||||
|
if (!__sync_lock_test_and_set (&state->lock_alloc, 1))
|
||||||
|
{
|
||||||
|
for (pp = &state->freelist; *pp != NULL; pp = &(*pp)->next)
|
||||||
|
{
|
||||||
|
if ((*pp)->size >= size)
|
||||||
|
{
|
||||||
|
struct backtrace_freelist_struct *p;
|
||||||
|
|
||||||
|
p = *pp;
|
||||||
|
*pp = p->next;
|
||||||
|
|
||||||
|
/* Round for alignment; we assume that no type we care about
|
||||||
|
is more than 8 bytes. */
|
||||||
|
size = (size + 7) & ~ (size_t) 7;
|
||||||
|
if (size < p->size)
|
||||||
|
backtrace_free_locked (state, (char *) p + size,
|
||||||
|
p->size - size);
|
||||||
|
|
||||||
|
ret = (void *) p;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__sync_lock_release (&state->lock_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
/* Allocate a new page. */
|
||||||
|
|
||||||
|
pagesize = getpagesize ();
|
||||||
|
asksize = (size + pagesize - 1) & ~ (pagesize - 1);
|
||||||
|
page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (page == NULL)
|
||||||
|
error_callback (data, "mmap", errno);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = (size + 7) & ~ (size_t) 7;
|
||||||
|
if (size < asksize)
|
||||||
|
backtrace_free (state, (char *) page + size, asksize - size,
|
||||||
|
error_callback, data);
|
||||||
|
|
||||||
|
ret = page;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free memory allocated by backtrace_alloc. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_free (struct backtrace_state *state, void *addr, size_t size,
|
||||||
|
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||||
|
void *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
/* If we can acquire the lock, add the new space to the free list.
|
||||||
|
If we can't acquire the lock, just leak the memory.
|
||||||
|
__sync_lock_test_and_set returns the old state of the lock, so we
|
||||||
|
have acquired it if it returns 0. */
|
||||||
|
if (!__sync_lock_test_and_set (&state->lock_alloc, 1))
|
||||||
|
{
|
||||||
|
backtrace_free_locked (state, addr, size);
|
||||||
|
|
||||||
|
__sync_lock_release (&state->lock_alloc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grow VEC by SIZE bytes. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_vector_grow (struct backtrace_state *state,size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_vector *vec)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if (size > vec->alc)
|
||||||
|
{
|
||||||
|
size_t pagesize;
|
||||||
|
size_t alc;
|
||||||
|
void *base;
|
||||||
|
|
||||||
|
pagesize = getpagesize ();
|
||||||
|
alc = vec->size + size;
|
||||||
|
if (vec->size == 0)
|
||||||
|
alc = 16 * size;
|
||||||
|
else if (alc < pagesize)
|
||||||
|
{
|
||||||
|
alc *= 2;
|
||||||
|
if (alc > pagesize)
|
||||||
|
alc = pagesize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
alc = (alc + pagesize - 1) & ~ (pagesize - 1);
|
||||||
|
base = backtrace_alloc (state, alc, error_callback, data);
|
||||||
|
if (base == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (vec->base != NULL)
|
||||||
|
{
|
||||||
|
memcpy (base, vec->base, vec->size);
|
||||||
|
backtrace_free (state, vec->base, vec->alc, error_callback, data);
|
||||||
|
}
|
||||||
|
vec->base = base;
|
||||||
|
vec->alc = alc - vec->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (char *) vec->base + vec->size;
|
||||||
|
vec->size += size;
|
||||||
|
vec->alc -= size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish the current allocation on VEC. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_vector_finish (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
struct backtrace_vector *vec)
|
||||||
|
{
|
||||||
|
vec->base = (char *) vec->base + vec->size;
|
||||||
|
vec->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release any extra space allocated for VEC. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_vector_release (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
backtrace_free (state, (char *) vec->base + vec->size, vec->alc,
|
||||||
|
error_callback, data);
|
||||||
|
vec->alc = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* mmapio.c -- File views using mmap.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* This file implements file views and memory allocation when mmap is
|
||||||
|
available. */
|
||||||
|
|
||||||
|
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_get_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
int descriptor, off_t offset, size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_view *view)
|
||||||
|
{
|
||||||
|
size_t pagesize;
|
||||||
|
unsigned int inpage;
|
||||||
|
off_t pageoff;
|
||||||
|
void *map;
|
||||||
|
|
||||||
|
pagesize = getpagesize ();
|
||||||
|
inpage = offset % pagesize;
|
||||||
|
pageoff = offset - inpage;
|
||||||
|
|
||||||
|
size += inpage;
|
||||||
|
size = (size + (pagesize - 1)) & ~ (pagesize - 1);
|
||||||
|
|
||||||
|
map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, descriptor, pageoff);
|
||||||
|
if (map == MAP_FAILED)
|
||||||
|
{
|
||||||
|
error_callback (data, "mmap", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
view->data = (char *) map + inpage;
|
||||||
|
view->base = map;
|
||||||
|
view->len = size;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release a view read by backtrace_get_view. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_release_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
struct backtrace_view *view,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
const void *cv;
|
||||||
|
void *v;
|
||||||
|
} const_cast;
|
||||||
|
|
||||||
|
const_cast.cv = view->base;
|
||||||
|
if (munmap (const_cast.v, view->len) < 0)
|
||||||
|
error_callback (data, "munmap", errno);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* backtrace.c -- Entry point for stack backtrace library.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* This source file is compiled if the unwind library is not
|
||||||
|
available. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace (int skip ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_full_callback callback ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
error_callback (data,
|
||||||
|
"no stack trace because unwind library not available",
|
||||||
|
0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_simple (int skip ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_simple_callback callback ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
error_callback (data,
|
||||||
|
"no stack trace because unwind library not available",
|
||||||
|
0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* posix.c -- POSIX file I/O routines for the backtrace library.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Open a file for reading. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_open (const char *filename, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int descriptor;
|
||||||
|
|
||||||
|
descriptor = open (filename, O_RDONLY | O_CLOEXEC);
|
||||||
|
if (descriptor < 0)
|
||||||
|
{
|
||||||
|
error_callback (data, filename, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set FD_CLOEXEC just in case the kernel does not support
|
||||||
|
O_CLOEXEC. It doesn't matter if this fails for some reason.
|
||||||
|
FIXME: At some point it should be safe to only do this if
|
||||||
|
O_CLOEXEC == 0. */
|
||||||
|
fcntl (descriptor, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close DESCRIPTOR. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_close (int descriptor, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
if (close (descriptor) < 0)
|
||||||
|
{
|
||||||
|
error_callback (data, "close", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
/* print.c -- Print the current backtrace.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* Passed to callbacks. */
|
||||||
|
|
||||||
|
struct print_data
|
||||||
|
{
|
||||||
|
struct backtrace_state *state;
|
||||||
|
FILE *f;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Print one level of a backtrace. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_callback (void *data, uintptr_t pc, const char *filename, int lineno,
|
||||||
|
const char *function)
|
||||||
|
{
|
||||||
|
struct print_data *pdata = (struct print_data *) data;
|
||||||
|
|
||||||
|
fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n",
|
||||||
|
(unsigned long) pc,
|
||||||
|
function == NULL ? "???" : function,
|
||||||
|
filename == NULL ? "???" : filename,
|
||||||
|
lineno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print errors to stderr. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
error_callback (void *data, const char *msg, int errnum)
|
||||||
|
{
|
||||||
|
struct print_data *pdata = (struct print_data *) data;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = pdata->state->filename;
|
||||||
|
if (name == NULL)
|
||||||
|
name = "/proc/self/exe";
|
||||||
|
fprintf (stderr, "%s: libbacktrace: %s", name, msg);
|
||||||
|
if (errnum > 0)
|
||||||
|
fprintf (stderr, ": %s", strerror (errnum));
|
||||||
|
fputc ('\n', stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a backtrace. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_print (struct backtrace_state *state, int skip, FILE *f)
|
||||||
|
{
|
||||||
|
struct print_data data;
|
||||||
|
|
||||||
|
data.state = state;
|
||||||
|
data.f = f;
|
||||||
|
backtrace_full (state, skip + 1, print_callback, error_callback,
|
||||||
|
(void *) &data);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/* read.c -- File views without mmap.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* This file implements file views when mmap is not available. */
|
||||||
|
|
||||||
|
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_get_view (struct backtrace_state *state, int descriptor,
|
||||||
|
off_t offset, size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_view *view)
|
||||||
|
{
|
||||||
|
ssize_t got;
|
||||||
|
|
||||||
|
if (lseek (descriptor, offset, SEEK_SET) < 0)
|
||||||
|
{
|
||||||
|
error_callback (data, "lseek", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
view->base = backtrace_alloc (state, size, error_callback, data);
|
||||||
|
if (view->base == NULL)
|
||||||
|
return 0;
|
||||||
|
view->data = view->base;
|
||||||
|
view->len = size;
|
||||||
|
|
||||||
|
got = read (descriptor, view->base, size);
|
||||||
|
if (got < 0)
|
||||||
|
{
|
||||||
|
error_callback (data, "read", errno);
|
||||||
|
free (view->base);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size_t) got < size)
|
||||||
|
{
|
||||||
|
error_callback (data, "file too short", 0);
|
||||||
|
free (view->base);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release a view read by backtrace_get_view. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_release_view (struct backtrace_state *state,
|
||||||
|
struct backtrace_view *view,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
backtrace_free (state, view->base, view->len, error_callback, data);
|
||||||
|
view->data = NULL;
|
||||||
|
view->base = NULL;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* simple.c -- The backtrace_simple function.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "unwind.h"
|
||||||
|
#include "backtrace.h"
|
||||||
|
|
||||||
|
/* The simple_backtrace routine. */
|
||||||
|
|
||||||
|
/* Data passed through _Unwind_Backtrace. */
|
||||||
|
|
||||||
|
struct backtrace_simple_data
|
||||||
|
{
|
||||||
|
/* Number of frames to skip. */
|
||||||
|
int skip;
|
||||||
|
/* Library state. */
|
||||||
|
struct backtrace_state *state;
|
||||||
|
/* Callback routine. */
|
||||||
|
backtrace_simple_callback callback;
|
||||||
|
/* Error callback routine. */
|
||||||
|
backtrace_error_callback error_callback;
|
||||||
|
/* Data to pass to callback routine. */
|
||||||
|
void *data;
|
||||||
|
/* Value to return from backtrace. */
|
||||||
|
int ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Unwind library callback routine. This is passd to
|
||||||
|
_Unwind_Backtrace. */
|
||||||
|
|
||||||
|
static _Unwind_Reason_Code
|
||||||
|
simple_unwind (struct _Unwind_Context *context, void *vdata)
|
||||||
|
{
|
||||||
|
struct backtrace_simple_data *bdata = (struct backtrace_simple_data *) vdata;
|
||||||
|
uintptr_t pc;
|
||||||
|
int ip_before_insn = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_GETIPINFO
|
||||||
|
pc = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||||
|
#else
|
||||||
|
pc = _Unwind_GetIP (context);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (bdata->skip > 0)
|
||||||
|
{
|
||||||
|
--bdata->skip;
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ip_before_insn)
|
||||||
|
--pc;
|
||||||
|
|
||||||
|
bdata->ret = bdata->callback (bdata->data, pc);
|
||||||
|
|
||||||
|
if (bdata->ret != 0)
|
||||||
|
return _URC_END_OF_STACK;
|
||||||
|
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a simple stack backtrace. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_simple (struct backtrace_state *state, int skip,
|
||||||
|
backtrace_simple_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
struct backtrace_simple_data bdata;
|
||||||
|
|
||||||
|
bdata.skip = skip + 1;
|
||||||
|
bdata.state = state;
|
||||||
|
bdata.callback = callback;
|
||||||
|
bdata.error_callback = error_callback;
|
||||||
|
bdata.data = data;
|
||||||
|
bdata.ret = 0;
|
||||||
|
_Unwind_Backtrace (simple_unwind, &bdata);
|
||||||
|
return bdata.ret;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* state.c -- Create the backtrace state.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "backtrace-supported.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* Create the backtrace state. This will then be passed to all the
|
||||||
|
other routines. */
|
||||||
|
|
||||||
|
struct backtrace_state *
|
||||||
|
backtrace_create_state (const char *filename, int threaded,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct backtrace_state init_state;
|
||||||
|
struct backtrace_state *state;
|
||||||
|
|
||||||
|
#ifndef HAVE_SYNC_FUNCTIONS
|
||||||
|
if (threaded)
|
||||||
|
{
|
||||||
|
error_callback (data, "backtrace library does not support threads", 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset (&init_state, 0, sizeof init_state);
|
||||||
|
init_state.filename = filename;
|
||||||
|
init_state.threaded = threaded;
|
||||||
|
|
||||||
|
state = ((struct backtrace_state *)
|
||||||
|
backtrace_alloc (&init_state, sizeof *state, error_callback, data));
|
||||||
|
if (state == NULL)
|
||||||
|
return NULL;
|
||||||
|
*state = init_state;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* unknown.c -- used when backtrace configury does not know file format.
|
||||||
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/* A trivial routine that always fails to find fileline data. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
unknown_fileline (void *fileline_data ATTRIBUTE_UNUSED,
|
||||||
|
uintptr_t pc, backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback ATTRIBUTE_UNUSED,
|
||||||
|
void *data)
|
||||||
|
|
||||||
|
{
|
||||||
|
return callback (data, pc, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the backtrace data when we don't know how to read the
|
||||||
|
debug info. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_initialize (int descriptor ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||||
|
void *data ATTRIBUTE_UNUSED, fileline *fileline_fn,
|
||||||
|
void **fileline_data)
|
||||||
|
{
|
||||||
|
*fileline_fn = unknown_fileline;
|
||||||
|
*fileline_data = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue