Merge ../libunwind-v0.98
diff --git a/ChangeLog b/ChangeLog
index 81eede6..dfa24b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,8 @@
***********************************************************
- Discontinued. See bitkeeper log instead at
+ Discontinued. See git log instead at
- http://unwind.bkbits.net/
+ http://www.kernel.org/git/gitweb.cgi?p=libs/libunwind/libunwind.git;a=log
***********************************************************
diff --git a/ChangeSet b/ChangeSet
deleted file mode 100644
index e69de29..0000000
--- a/ChangeSet
+++ /dev/null
diff --git a/src/hppa/Gget_reg.c b/LICENSE
similarity index 68%
copy from src/hppa/Gget_reg.c
copy to LICENSE
index 4553f65..c9b44cb 100644
--- a/src/hppa/Gget_reg.c
+++ b/LICENSE
@@ -1,9 +1,3 @@
-/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
-
-This file is part of libunwind.
-
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -21,14 +15,4 @@
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "unwind_i.h"
-
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Makefile.am b/Makefile.am
index 8a2c2a6..6b4e1d8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,6 +9,14 @@
else
if ARCH_X86_64
include_HEADERS_tdep = include/libunwind-x86_64.h
+else
+if ARCH_PPC32
+include_HEADERS_tdep = include/libunwind-ppc32.h
+else
+if ARCH_PPC64
+include_HEADERS_tdep = include/libunwind-ppc64.h
+endif # ARCH_PPC64
+endif # ARCH_PPC32
endif # ARCH_X86_64
endif # ARCH_X86
endif # ARCH_HPPA
@@ -28,16 +36,21 @@
SUBDIRS = src tests doc
-EXTRA_DIST = include/dwarf.h include/dwarf_i.h \
- include/internal.h include/mempool.h \
+EXTRA_DIST = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \
+ include/libunwind_i.h include/mempool.h \
include/remote.h \
include/libunwind-common.h.in \
- include/libunwind-ia64.h include/tdep-ia64.h \
- include/ia64/jmpbuf.h include/ia64/rse.h include/ia64/script.h \
- include/libunwind-hppa.h include/tdep-hppa.h \
- include/libunwind-x86.h include/tdep-x86.h \
- include/x86/jmpbuf.h include/x86/dwarf-config.h \
- include/libunwind-x86_64.h include/tdep-x86_64.h \
- include/x86_64/jmpbuf.h include/x86_64/dwarf-config.h
+ include/libunwind-ia64.h include/tdep-ia64/libunwind_i.h \
+ include/tdep-ia64/jmpbuf.h include/tdep-ia64/rse.h \
+ include/tdep-ia64/script.h \
+ include/libunwind-hppa.h include/tdep-hppa/libunwind_i.h \
+ include/tdep-hppa/jmpbuf.h include/tdep-hppa/dwarf-config.h \
+ include/libunwind-x86.h include/tdep-x86/libunwind_i.h \
+ include/tdep-x86/jmpbuf.h include/tdep-x86/dwarf-config.h \
+ include/libunwind-x86_64.h include/tdep-x86_64/libunwind_i.h \
+ include/tdep-x86_64/jmpbuf.h include/tdep-x86_64/dwarf-config.h \
+ include/libunwind-ppc64.h include/tdep-ppc64/dwarf-config.h \
+ include/tdep-ppc32/jmpbuf.h include/tdep-ppc32/libunwind_i.h \
+ include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h
-DISTCLEANFILES = include/libunwind.h include/tdep.h
+DISTCLEANFILES = include/libunwind.h include/tdep
diff --git a/Makefile.in b/Makefile.in
index bcc03ea..09c1df1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -55,7 +55,7 @@
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES = include/libunwind-common.h include/libunwind.h \
- include/tdep.h
+ include/tdep
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
@@ -64,7 +64,8 @@
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
-am__include_HEADERS_DIST = include/libunwind-x86_64.h \
+am__include_HEADERS_DIST = include/libunwind-ppc64.h \
+ include/libunwind-ppc32.h include/libunwind-x86_64.h \
include/libunwind-x86.h include/libunwind-hppa.h \
include/libunwind-ia64.h include/libunwind-dynamic.h \
include/libunwind-ptrace.h include/libunwind.h \
@@ -103,6 +104,10 @@
ARCH_HPPA_TRUE = @ARCH_HPPA_TRUE@
ARCH_IA64_FALSE = @ARCH_IA64_FALSE@
ARCH_IA64_TRUE = @ARCH_IA64_TRUE@
+ARCH_PPC32_FALSE = @ARCH_PPC32_FALSE@
+ARCH_PPC32_TRUE = @ARCH_PPC32_TRUE@
+ARCH_PPC64_FALSE = @ARCH_PPC64_FALSE@
+ARCH_PPC64_TRUE = @ARCH_PPC64_TRUE@
ARCH_X86_64_FALSE = @ARCH_X86_64_FALSE@
ARCH_X86_64_TRUE = @ARCH_X86_64_TRUE@
ARCH_X86_FALSE = @ARCH_X86_FALSE@
@@ -172,6 +177,8 @@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+USE_ALTIVEC_FALSE = @USE_ALTIVEC_FALSE@
+USE_ALTIVEC_TRUE = @USE_ALTIVEC_TRUE@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
@@ -226,6 +233,8 @@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@include_HEADERS_tdep = include/libunwind-ppc64.h
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@include_HEADERS_tdep = include/libunwind-ppc32.h
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@include_HEADERS_tdep = include/libunwind-x86_64.h
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@include_HEADERS_tdep = include/libunwind-x86.h
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@include_HEADERS_tdep = include/libunwind-hppa.h
@@ -239,19 +248,24 @@
@REMOTE_ONLY_TRUE@include_HEADERS = $(include_HEADERS_common)
nodist_include_HEADERS = include/libunwind-common.h
SUBDIRS = src tests doc
-EXTRA_DIST = include/dwarf.h include/dwarf_i.h \
- include/internal.h include/mempool.h \
+EXTRA_DIST = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \
+ include/libunwind_i.h include/mempool.h \
include/remote.h \
include/libunwind-common.h.in \
- include/libunwind-ia64.h include/tdep-ia64.h \
- include/ia64/jmpbuf.h include/ia64/rse.h include/ia64/script.h \
- include/libunwind-hppa.h include/tdep-hppa.h \
- include/libunwind-x86.h include/tdep-x86.h \
- include/x86/jmpbuf.h include/x86/dwarf-config.h \
- include/libunwind-x86_64.h include/tdep-x86_64.h \
- include/x86_64/jmpbuf.h include/x86_64/dwarf-config.h
+ include/libunwind-ia64.h include/tdep-ia64/libunwind_i.h \
+ include/tdep-ia64/jmpbuf.h include/tdep-ia64/rse.h \
+ include/tdep-ia64/script.h \
+ include/libunwind-hppa.h include/tdep-hppa/libunwind_i.h \
+ include/tdep-hppa/jmpbuf.h include/tdep-hppa/dwarf-config.h \
+ include/libunwind-x86.h include/tdep-x86/libunwind_i.h \
+ include/tdep-x86/jmpbuf.h include/tdep-x86/dwarf-config.h \
+ include/libunwind-x86_64.h include/tdep-x86_64/libunwind_i.h \
+ include/tdep-x86_64/jmpbuf.h include/tdep-x86_64/dwarf-config.h \
+ include/libunwind-ppc64.h include/tdep-ppc64/dwarf-config.h \
+ include/tdep-ppc32/jmpbuf.h include/tdep-ppc32/libunwind_i.h \
+ include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h
-DISTCLEANFILES = include/libunwind.h include/tdep.h
+DISTCLEANFILES = include/libunwind.h include/tdep
all: all-recursive
.SUFFIXES:
@@ -487,7 +501,7 @@
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
- $(mkdir_p) $(distdir)/config $(distdir)/doc $(distdir)/include $(distdir)/include/ia64 $(distdir)/include/x86 $(distdir)/include/x86_64 $(distdir)/tests
+ $(mkdir_p) $(distdir)/config $(distdir)/doc $(distdir)/include $(distdir)/include/tdep-hppa $(distdir)/include/tdep-ia64 $(distdir)/include/tdep-ppc32 $(distdir)/include/tdep-ppc64 $(distdir)/include/tdep-x86 $(distdir)/include/tdep-x86_64 $(distdir)/tests
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
diff --git a/NEWS b/NEWS
index f788ce1..83ac810 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
-*-Mode: outline-*-
+* News for v0.99:
+
+** Greatly improved x86-64 support thanks to Arun Sharma.
+** Support for PPC64 added by Jose Flavio Aguilar Paulino.
+
* News for v0.98.6:
** Fix address-leak triggered by invalid byte-order. Fixed by Andreas Schwab.
diff --git a/README b/README
index 2282181..180edd2 100644
--- a/README
+++ b/README
@@ -1,21 +1,15 @@
-*- mode: Outline -*-
-This is version 0.97 of the unwind library. At the moment, only the
-IA-64 Linux (IPF Linux) platform is fully supported. Some basic
-support for x86 and HP-UX/IPF exists also. However, the x86 support
-is based mostly on the frame-chain and does not reliably use unwind
-information yet, so its utility is limited. Similarly, the HP-UX/IPF
-support is incomplete, though it is sufficient to do a basic
-backtrace. unw_resume() is not supported, however.
+This is version 0.99 of the unwind library. This library supports
+several architecture/operating-system combinations:
-* Important GCC v3.4.[012] Caveat
+ Linux/IA-64: Fully tested and supported.
+ Linux/x86-64: Works well.
+ Linux/x86: Works well, but C library is missing some unwind-info.
+ Linux/PARISC: Works well, but C library missing unwind-info.
+ HP-UX/IA-64: Mostly works but known to have some serious limitations.
+ Linux/PPC64: Newly added.
-GCC v3.4.[012] break C++ ABI compatibility and because of that,
-libunwind cannot easily be used as the unwinder. The GCC developers
-are aware of the problem [1] and the the problem has been fixed for
-GCC v3.4.3.
-
-[1] http://gcc.gnu.org/ml/gcc/2004-04/msg00989.html
* General Build Instructions
@@ -43,22 +37,6 @@
$ ./configure CC=icc CFLAGS="-g -O3 -ip" CXX=icc CCAS=gcc CCASFLAGS=-g \
LDFLAGS="-L$PWD/src/.libs"
-** Version 7
-
-To build libunwind with the Intel Electron compiler (ECC), it is
-recommended to run configure like this:
-
- $ ./configure CC=ecc CXX=ecc CCAS=gcc CCASFLAGS=-g \
- LDFLAGS="-L$PWD/src/.libs"
-
-The reason for this is that ECC uses the Intel assembler, which
-doesn't grok some of the IA-64 assembly code in the "tests" directory.
-
-For an ECC-built version of libunwind to work properly, you also need
-to ensure that /usr/include/asm/fpu.h contains a "long double" member
-called "__dummy" in the declaration of "struct ia64_fpreg". Without
-that member, variables of type unw_context_t won't be aligned
-properly.
* Building on HP-UX
@@ -83,6 +61,25 @@
GCC v3.3.2 or later have been fixed and do not require this
workaround.
+* Building for PowerPC64 / Linux
+
+For building for power64 you should use:
+
+ $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64"
+
+If your power support altivec registers:
+ $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec"
+
+To check if your processor has support for vector registers (altivec):
+ cat /proc/cpuinfo | grep altivec
+and should have something like this:
+ cpu : PPC970, altivec supported
+
+If libunwind seems to not work (backtracing failing), try to compile
+it with -O0, without optimizations. There are some compiler problems
+depending on the version of your gcc.
+
+
* Regression Testing
After building the library, you can run a set of regression tests with:
@@ -114,10 +111,47 @@
The following tests are expected to fail on x86 Linux:
- test-proc-info (x86 unwinder doesn't use unwind-info yet)
- Gtest-exc (unw_resume() not implmented yet)
- Ltest-exc (unw_resume() not implmented yet)
- test-setjmp (unw_resume() not implmented yet)
+ Gtest-resume-sig (fails to get SIGUSR2)
+ Ltest-resume-sig (likewise)
+ Gtest-dyn1 (no dynamic unwind info support yet)
+ Ltest-dyn1 (no dynamic unwind info support yet)
+ test-setjmp (longjmp() not implemented yet)
+ run-check-namespace (no _Ux86_getcontext yet)
+ test-ptrace
+
+** Expected results on x86-64 Linux
+
+The following tests are expected to fail on x86-64 Linux:
+
+ Gtest-dyn1 (no dynamic unwind info support yet)
+ Ltest-dyn1 (no dynamic unwind info support yet)
+ Gtest-init (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18743)
+ Ltest-init (likewise)
+ test-async-sig (crashes due to bad unwind-info?)
+ test-setjmp (longjmp() not implemented yet)
+ run-check-namespace (no _Ux86_64_getcontext yet)
+ run-ptrace-mapper (??? investigate)
+ run-ptrace-misc (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18748
+ and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18749)
+
+** Expected results on PARISC Linux
+
+Caveat: GCC v3.4 or newer is needed on PA-RISC Linux. Earlier
+versions of the compiler failed to generate the exception-handling
+program header (GNU_EH_FRAME) needed for unwinding.
+
+The following tests are expected to fail on x86-64 Linux:
+
+ Gtest-bt (backtrace truncated at kill() due to lack of unwind-info)
+ Ltest-bt (likewise)
+ Gtest-resume-sig (Gresume.c:my_rt_sigreturn() is wrong somehow)
+ Ltest-resume-sig (likewise)
+ Gtest-init (likewise)
+ Ltest-init (likewise)
+ Gtest-dyn1 (no dynamic unwind info support yet)
+ Ltest-dyn1 (no dynamic unwind info support yet)
+ test-setjmp (longjmp() not implemented yet)
+ run-check-namespace (toolchain doesn't support HIDDEN yet)
** Expected results on HP-UX
@@ -134,6 +168,11 @@
tests/Gtest-resume-sig
tests/Ltest-resume-sig
+** Expected results on PPC64 Linux
+
+"make check" should run with no more than 10 out of 24 tests failed.
+
+
* Performance Testing
This distribution includes a few simple performance tests which give
diff --git a/configure b/configure
index c00664f..0156c45 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for libunwind 0.98.6.
+# Generated by GNU Autoconf 2.61 for libunwind 0.99-alpha.
#
# Report bugs to <libunwind-devel@nongnu.org>.
#
@@ -728,8 +728,8 @@
# Identity of this package.
PACKAGE_NAME='libunwind'
PACKAGE_TARNAME='libunwind'
-PACKAGE_VERSION='0.98.6'
-PACKAGE_STRING='libunwind 0.98.6'
+PACKAGE_VERSION='0.99-alpha'
+PACKAGE_STRING='libunwind 0.99-alpha'
PACKAGE_BUGREPORT='libunwind-devel@nongnu.org'
ac_unique_file="src/mi/backtrace.c"
@@ -879,6 +879,8 @@
CCAS
CCASFLAGS
LIBOBJS
+USE_ALTIVEC_TRUE
+USE_ALTIVEC_FALSE
REMOTE_ONLY_TRUE
REMOTE_ONLY_FALSE
ARCH_IA64_TRUE
@@ -889,6 +891,10 @@
ARCH_X86_FALSE
ARCH_X86_64_TRUE
ARCH_X86_64_FALSE
+ARCH_PPC32_TRUE
+ARCH_PPC32_FALSE
+ARCH_PPC64_TRUE
+ARCH_PPC64_FALSE
OS_LINUX_TRUE
OS_LINUX_FALSE
OS_HPUX_TRUE
@@ -1423,7 +1429,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libunwind 0.98.6 to adapt to many kinds of systems.
+\`configure' configures libunwind 0.99-alpha to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1494,7 +1500,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libunwind 0.98.6:";;
+ short | recursive ) echo "Configuration of libunwind 0.99-alpha:";;
esac
cat <<\_ACEOF
@@ -1601,7 +1607,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libunwind configure 0.98.6
+libunwind configure 0.99-alpha
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1615,7 +1621,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libunwind $as_me 0.98.6, which was
+It was created by libunwind $as_me 0.99-alpha, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -2412,7 +2418,7 @@
# Define the identity of the package.
PACKAGE='libunwind'
- VERSION='0.98.6'
+ VERSION='0.99-alpha'
cat >>confdefs.h <<_ACEOF
@@ -4974,7 +4980,7 @@
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 4977 "configure"' > conftest.$ac_ext
+ echo '#line 4983 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -7233,11 +7239,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7236: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7242: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7240: \$? = $ac_status" >&5
+ echo "$as_me:7246: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7501,11 +7507,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7504: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7510: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7508: \$? = $ac_status" >&5
+ echo "$as_me:7514: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7605,11 +7611,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7608: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7614: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7612: \$? = $ac_status" >&5
+ echo "$as_me:7618: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -9902,7 +9908,7 @@
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9905 "configure"
+#line 9911 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10002,7 +10008,7 @@
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10005 "configure"
+#line 10011 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12338,11 +12344,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12341: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12347: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:12345: \$? = $ac_status" >&5
+ echo "$as_me:12351: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -12442,11 +12448,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12445: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12451: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:12449: \$? = $ac_status" >&5
+ echo "$as_me:12455: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -14003,11 +14009,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14006: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14012: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:14010: \$? = $ac_status" >&5
+ echo "$as_me:14016: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -14107,11 +14113,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14110: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14116: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:14114: \$? = $ac_status" >&5
+ echo "$as_me:14120: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -16294,11 +16300,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16297: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16303: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16301: \$? = $ac_status" >&5
+ echo "$as_me:16307: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16562,11 +16568,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16565: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16571: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16569: \$? = $ac_status" >&5
+ echo "$as_me:16575: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16666,11 +16672,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16669: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16675: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:16673: \$? = $ac_status" >&5
+ echo "$as_me:16679: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -20723,11 +20729,37 @@
fi
done
+is_gcc_m64() {
+ if test `echo $CFLAGS | grep "\-m64" -c` -eq 1 ; then echo ppc64;
+ else
+ if test `echo $CC | grep "\-m64" -c` -eq 1 ; then echo ppc64; else echo ppc32; fi;
+ fi;
+}
+
+is_gcc_altivec() {
+ if test `echo $CFLAGS | grep "\-maltivec" -c` -eq 1 ; then echo has_altivec;
+ else
+ if test `echo $CC | grep "\-maltivec" -c` -eq 1 ; then echo has_altivec; else echo no_altivec; fi;
+ fi;
+}
+
+use_altivec=`is_gcc_altivec`
+
+
+if test x$use_altivec = xhas_altivec; then
+ USE_ALTIVEC_TRUE=
+ USE_ALTIVEC_FALSE='#'
+else
+ USE_ALTIVEC_TRUE='#'
+ USE_ALTIVEC_FALSE=
+fi
+
get_arch() {
case "$1" in
i?86) echo x86;;
hppa*) echo hppa;;
+ powerpc64) is_gcc_m64;;
*) echo $1;;
esac
}
@@ -20787,6 +20819,26 @@
+if test x$target_arch = xppc32; then
+ ARCH_PPC32_TRUE=
+ ARCH_PPC32_FALSE='#'
+else
+ ARCH_PPC32_TRUE='#'
+ ARCH_PPC32_FALSE=
+fi
+
+
+
+if test x$target_arch = xppc64; then
+ ARCH_PPC64_TRUE=
+ ARCH_PPC64_FALSE='#'
+else
+ ARCH_PPC64_TRUE='#'
+ ARCH_PPC64_FALSE=
+fi
+
+
+
if expr x$target_os : xlinux >/dev/null; then
OS_LINUX_TRUE=
OS_LINUX_FALSE='#'
@@ -20806,10 +20858,17 @@
fi
+if test x$target_arch = xppc64; then
+ libdir='${exec_prefix}/lib64'
+ { echo "$as_me:$LINENO: PowerPC64 detected, lib will be installed ${libdir}" >&5
+echo "$as_me: PowerPC64 detected, lib will be installed ${libdir}" >&6;};
+
+fi
+
if test x$target_arch != x$build_arch; then
CPPFLAGS="${CPPFLAGS} -DUNW_REMOTE_ONLY"
fi
-ac_config_links="$ac_config_links include/libunwind.h:include/libunwind-$target_arch.h include/tdep.h:include/tdep-$target_arch.h"
+ac_config_links="$ac_config_links include/libunwind.h:include/libunwind-$target_arch.h include/tdep:include/tdep-$target_arch"
# Check whether --enable-debug was given.
@@ -20947,7 +21006,7 @@
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test x$GCC = xyes -a x$intel_compiler != xyes; then
- CFLAGS="${CFLAGS} -Wall -Wsign-compare"
+ CFLAGS="${CFLAGS} -fexceptions -Wall -Wsign-compare"
LIBCRTS="-lgcc"
fi
@@ -20957,8 +21016,8 @@
ARCH=`echo $target_arch | tr a-z A-Z`
PKG_MAJOR=0
-PKG_MINOR=98
-PKG_EXTRA=.6
+PKG_MINOR=99
+PKG_EXTRA=-alpha
PKG_MAINTAINER=libunwind-devel@nongnu.org
@@ -21098,6 +21157,13 @@
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${USE_ALTIVEC_TRUE}" && test -z "${USE_ALTIVEC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_ALTIVEC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_ALTIVEC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${REMOTE_ONLY_TRUE}" && test -z "${REMOTE_ONLY_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"REMOTE_ONLY\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -21133,6 +21199,20 @@
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${ARCH_PPC32_TRUE}" && test -z "${ARCH_PPC32_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"ARCH_PPC32\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"ARCH_PPC32\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${ARCH_PPC64_TRUE}" && test -z "${ARCH_PPC64_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"ARCH_PPC64\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"ARCH_PPC64\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${OS_LINUX_TRUE}" && test -z "${OS_LINUX_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"OS_LINUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -21447,7 +21527,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libunwind $as_me 0.98.6, which was
+This file was extended by libunwind $as_me 0.99-alpha, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -21504,7 +21584,7 @@
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-libunwind config.status 0.98.6
+libunwind config.status 0.99-alpha
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -21620,7 +21700,7 @@
"include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;;
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"include/libunwind.h") CONFIG_LINKS="$CONFIG_LINKS include/libunwind.h:include/libunwind-$target_arch.h" ;;
- "include/tdep.h") CONFIG_LINKS="$CONFIG_LINKS include/tdep.h:include/tdep-$target_arch.h" ;;
+ "include/tdep") CONFIG_LINKS="$CONFIG_LINKS include/tdep:include/tdep-$target_arch" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
@@ -21842,6 +21922,8 @@
CCAS!$CCAS$ac_delim
CCASFLAGS!$CCASFLAGS$ac_delim
LIBOBJS!$LIBOBJS$ac_delim
+USE_ALTIVEC_TRUE!$USE_ALTIVEC_TRUE$ac_delim
+USE_ALTIVEC_FALSE!$USE_ALTIVEC_FALSE$ac_delim
REMOTE_ONLY_TRUE!$REMOTE_ONLY_TRUE$ac_delim
REMOTE_ONLY_FALSE!$REMOTE_ONLY_FALSE$ac_delim
ARCH_IA64_TRUE!$ARCH_IA64_TRUE$ac_delim
@@ -21852,6 +21934,10 @@
ARCH_X86_FALSE!$ARCH_X86_FALSE$ac_delim
ARCH_X86_64_TRUE!$ARCH_X86_64_TRUE$ac_delim
ARCH_X86_64_FALSE!$ARCH_X86_64_FALSE$ac_delim
+ARCH_PPC32_TRUE!$ARCH_PPC32_TRUE$ac_delim
+ARCH_PPC32_FALSE!$ARCH_PPC32_FALSE$ac_delim
+ARCH_PPC64_TRUE!$ARCH_PPC64_TRUE$ac_delim
+ARCH_PPC64_FALSE!$ARCH_PPC64_FALSE$ac_delim
OS_LINUX_TRUE!$OS_LINUX_TRUE$ac_delim
OS_LINUX_FALSE!$OS_LINUX_FALSE$ac_delim
OS_HPUX_TRUE!$OS_HPUX_TRUE$ac_delim
@@ -21868,7 +21954,7 @@
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 37; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 43; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 7021333..bf44eaa 100644
--- a/configure.in
+++ b/configure.in
@@ -1,6 +1,6 @@
define(pkg_major, 0)
-define(pkg_minor, 98)
-define(pkg_extra, .6)
+define(pkg_minor, 99)
+define(pkg_extra, -alpha)
define(pkg_maintainer, libunwind-devel@nongnu.org)
define(mkvers, $1.$2$3)
dnl Process this file with autoconf to produce a configure script.
@@ -56,11 +56,28 @@
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \
ttrace)
+is_gcc_m64() {
+ if test `echo $CFLAGS | grep "\-m64" -c` -eq 1 ; then echo ppc64;
+ else
+ if test `echo $CC | grep "\-m64" -c` -eq 1 ; then echo ppc64; else echo ppc32; fi;
+ fi;
+}
+
+is_gcc_altivec() {
+ if test `echo $CFLAGS | grep "\-maltivec" -c` -eq 1 ; then echo has_altivec;
+ else
+ if test `echo $CC | grep "\-maltivec" -c` -eq 1 ; then echo has_altivec; else echo no_altivec; fi;
+ fi;
+}
+
+use_altivec=`is_gcc_altivec`
+AM_CONDITIONAL(USE_ALTIVEC, test x$use_altivec = xhas_altivec)
get_arch() {
case "$1" in
i?86) echo x86;;
hppa*) echo hppa;;
+ powerpc64) is_gcc_m64;;
*) echo $1;;
esac
}
@@ -73,14 +90,22 @@
AM_CONDITIONAL(ARCH_HPPA, test x$target_arch = xhppa)
AM_CONDITIONAL(ARCH_X86, test x$target_arch = xx86)
AM_CONDITIONAL(ARCH_X86_64, test x$target_arch = xx86_64)
+AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32)
+AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64)
AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null)
AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null)
+if test x$target_arch = xppc64; then
+ libdir='${exec_prefix}/lib64'
+ AC_MSG_NOTICE([PowerPC64 detected, lib will be installed ${libdir}]);
+ AC_SUBST([libdir])
+fi
+
if test x$target_arch != x$build_arch; then
CPPFLAGS="${CPPFLAGS} -DUNW_REMOTE_ONLY"
fi
AC_CONFIG_LINKS(include/libunwind.h:include/libunwind-$target_arch.h
- include/tdep.h:include/tdep-$target_arch.h)
+ include/tdep:include/tdep-$target_arch)
AC_ARG_ENABLE(debug,
[ --enable-debug turn on debug support (slows down execution)],
@@ -101,7 +126,7 @@
#endif], [intel_compiler=yes])
if test x$GCC = xyes -a x$intel_compiler != xyes; then
- CFLAGS="${CFLAGS} -Wall -Wsign-compare"
+ CFLAGS="${CFLAGS} -fexceptions -Wall -Wsign-compare"
LIBCRTS="-lgcc"
fi
diff --git a/doc/Makefile.am b/doc/Makefile.am
index b76f1da..b414568 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -54,13 +54,12 @@
.tex.man:
$(L2M_CMD) $< $@
- -bk get -e $(srcdir)/$@
-cp $@ $(srcdir)/$@
html:
for n in $(man3_MANS); do \
page=`basename $$n .man`; \
- $(L2H_CMD) $(srcdir)/$$page.tex "$$page(3).php"; \
+ $(L2H_CMD) $(srcdir)/$$page.tex "$$page(3).raw"; \
done
pdf:
diff --git a/doc/Makefile.in b/doc/Makefile.in
index a8dfd8e..26cb508 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -64,6 +64,10 @@
ARCH_HPPA_TRUE = @ARCH_HPPA_TRUE@
ARCH_IA64_FALSE = @ARCH_IA64_FALSE@
ARCH_IA64_TRUE = @ARCH_IA64_TRUE@
+ARCH_PPC32_FALSE = @ARCH_PPC32_FALSE@
+ARCH_PPC32_TRUE = @ARCH_PPC32_TRUE@
+ARCH_PPC64_FALSE = @ARCH_PPC64_FALSE@
+ARCH_PPC64_TRUE = @ARCH_PPC64_TRUE@
ARCH_X86_64_FALSE = @ARCH_X86_64_FALSE@
ARCH_X86_64_TRUE = @ARCH_X86_64_TRUE@
ARCH_X86_FALSE = @ARCH_X86_FALSE@
@@ -133,6 +137,8 @@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+USE_ALTIVEC_FALSE = @USE_ALTIVEC_FALSE@
+USE_ALTIVEC_TRUE = @USE_ALTIVEC_TRUE@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
@@ -454,13 +460,12 @@
.tex.man:
$(L2M_CMD) $< $@
- -bk get -e $(srcdir)/$@
-cp $@ $(srcdir)/$@
html:
for n in $(man3_MANS); do \
page=`basename $$n .man`; \
- $(L2H_CMD) $(srcdir)/$$page.tex "$$page(3).php"; \
+ $(L2H_CMD) $(srcdir)/$$page.tex "$$page(3).raw"; \
done
pdf:
diff --git a/doc/_U_dyn_cancel.man b/doc/_U_dyn_cancel.man
index ed08a2a..a420a6d 100644
--- a/doc/_U_dyn_cancel.man
+++ b/doc/_U_dyn_cancel.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Tue Dec 9 16:32:40 PST 2003
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "\\_U\\_DYN\\_CANCEL" "3" "09 December 2003" "Programming Library " "Programming Library "
+.TH "\\_U\\_DYN\\_CANCEL" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
_U_dyn_cancel
\-\- cancel unwind\-info for dynamically generated code
@@ -59,12 +59,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/_U_dyn_cancel.tex b/doc/_U_dyn_cancel.tex
index 8f00a8f..ca5a12a 100644
--- a/doc/_U_dyn_cancel.tex
+++ b/doc/_U_dyn_cancel.tex
@@ -39,10 +39,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/_U_dyn_register.man b/doc/_U_dyn_register.man
index 0ecd55b..107e5fd 100644
--- a/doc/_U_dyn_register.man
+++ b/doc/_U_dyn_register.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Tue Dec 9 16:32:06 PST 2003
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "\\_U\\_DYN\\_REGISTER" "3" "09 December 2003" "Programming Library " "Programming Library "
+.TH "\\_U\\_DYN\\_REGISTER" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
_U_dyn_register
\-\- register unwind\-info for dynamically generated code
@@ -61,12 +61,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/_U_dyn_register.tex b/doc/_U_dyn_register.tex
index 0dd4527..ab23b5c 100644
--- a/doc/_U_dyn_register.tex
+++ b/doc/_U_dyn_register.tex
@@ -40,10 +40,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/libunwind-dynamic.man b/doc/libunwind-dynamic.man
index f8a4941..7c7507c 100644
--- a/doc/libunwind-dynamic.man
+++ b/doc/libunwind-dynamic.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "LIBUNWIND\-DYNAMIC" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "LIBUNWIND\-DYNAMIC" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
libunwind\-dynamic
\-\- libunwind\-support for runtime\-generated code
@@ -531,12 +531,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/libunwind-dynamic.tex b/doc/libunwind-dynamic.tex
index 43c8632..21e895a 100644
--- a/doc/libunwind-dynamic.tex
+++ b/doc/libunwind-dynamic.tex
@@ -394,10 +394,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/libunwind-ia64.man b/doc/libunwind-ia64.man
index a8bce6a..06b141e 100644
--- a/doc/libunwind-ia64.man
+++ b/doc/libunwind-ia64.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "LIBUNWIND\-IA64" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "LIBUNWIND\-IA64" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
libunwind\-ia64
\-\- IA\-64\-specific support in libunwind
@@ -118,14 +118,15 @@
.TP
UNW_IA64_SP:
Contains the (memory) stack\-pointer
-value (SP). This frame\-register is read\-only.
+value (SP).
.TP
UNW_IA64_BSP:
Contains the register backing\-store
-pointer (BSP). This frame\-register is read\-only. \fBNote:\fP
-the value in this register is equal to the contents of register
-ar.bsp
-at the time the instruction at UNW_IA64_IP
+pointer (BSP). \fBNote:\fP
+the value in this register is equal
+to the contents of register ar.bsp
+at the time the
+instruction at UNW_IA64_IP
was about to begin execution.
.PP
.SS NORMAL REGISTER MACROS
@@ -207,9 +208,13 @@
This 64\-bit wide register contains registers p0
through
p63
-in the ``broad\-side\&'' format (i.e., p0
-corresponds to bit 0, p1
-to bit 1, and so on).
+in the ``broad\-side\&'' format. Just like with the
+``move predicates\&'' instruction, the registers are mapped as if
+CFM.rrb.pr
+were set to 0. Thus, in general the value of
+predicate register pN
+with N>=16 can be found
+in bit 16 + ((N\-16)+CFM.rrb.pr) % 48\&.
.TP
UNW_IA64_CFM:
Contains the current\-frame\-mask
@@ -302,12 +307,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/libunwind-ia64.tex b/doc/libunwind-ia64.tex
index b3dd45d..c08946d 100644
--- a/doc/libunwind-ia64.tex
+++ b/doc/libunwind-ia64.tex
@@ -92,12 +92,11 @@
the slot number is usually zero, but can be non-zero, e.g., in the
stack-frame of a signal-handler trampoline.
\item[\Const{UNW\_IA64\_SP}:] Contains the (memory) stack-pointer
- value (SP). This frame-register is read-only.
+ value (SP).
\item[\Const{UNW\_IA64\_BSP}:] Contains the register backing-store
- pointer (BSP). This frame-register is read-only. \textbf{Note:}
- the value in this register is equal to the contents of register
- \texttt{ar.bsp} at the time the instruction at \Const{UNW\_IA64\_IP}
- was about to begin execution.
+ pointer (BSP). \textbf{Note:} the value in this register is equal
+ to the contents of register \texttt{ar.bsp} at the time the
+ instruction at \Const{UNW\_IA64\_IP} was about to begin execution.
\end{Description}
@@ -145,8 +144,11 @@
\Const{UNW\_IA64\_BR}\texttt{+6} should be used.
\item[\Const{UNW\_IA64\_PR}:] Contains the set of predicate registers.
This 64-bit wide register contains registers \texttt{p0} through
- \texttt{p63} in the ``broad-side'' format (i.e., \texttt{p0}
- corresponds to bit 0, \texttt{p1} to bit 1, and so on).
+ \texttt{p63} in the ``broad-side'' format. Just like with the
+ ``move predicates'' instruction, the registers are mapped as if
+ \texttt{CFM.rrb.pr} were set to 0. Thus, in general the value of
+ predicate register \texttt{p}$N$ with $N$>=16 can be found
+ in bit \texttt{16 + (($N$-16)+CFM.rrb.pr) \% 48}.
\item[\Const{UNW\_IA64\_CFM}:] Contains the current-frame-mask
register.
\end{Description}
@@ -207,10 +209,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/libunwind-ptrace.man b/doc/libunwind-ptrace.man
index f117640..985fcae 100644
--- a/doc/libunwind-ptrace.man
+++ b/doc/libunwind-ptrace.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:20:31 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "LIBUNWIND\-PTRACE" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "LIBUNWIND\-PTRACE" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
libunwind\-ptrace
\-\- ptrace() support in libunwind
@@ -213,12 +213,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/libunwind-ptrace.tex b/doc/libunwind-ptrace.tex
index 2e2c758..fe074d8 100644
--- a/doc/libunwind-ptrace.tex
+++ b/doc/libunwind-ptrace.tex
@@ -127,10 +127,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/libunwind-setjmp.man b/doc/libunwind-setjmp.man
index d7f65a5..e8b9de8 100644
--- a/doc/libunwind-setjmp.man
+++ b/doc/libunwind-setjmp.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "LIBUNWIND\-SETJMP" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "LIBUNWIND\-SETJMP" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
libunwind\-setjmp
\-\- libunwind\-based non\-local gotos
@@ -125,12 +125,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/libunwind-setjmp.tex b/doc/libunwind-setjmp.tex
index c5f6af7..b31ee9e 100644
--- a/doc/libunwind-setjmp.tex
+++ b/doc/libunwind-setjmp.tex
@@ -80,10 +80,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/libunwind.man b/doc/libunwind.man
index 5729d45..c6046e2 100644
--- a/doc/libunwind.man
+++ b/doc/libunwind.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:47:33 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:43 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "LIBUNWIND" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "LIBUNWIND" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
libunwind
\-\- a (mostly) platform\-independent unwind API
@@ -485,6 +485,7 @@
unw_set_fpreg(3),
unw_set_reg(3),
unw_step(3),
+unw_strerror(3),
_U_dyn_register(3),
_U_dyn_cancel(3)
.PP
@@ -492,12 +493,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/libunwind.tex b/doc/libunwind.tex
index cef6fbb..534bd4d 100644
--- a/doc/libunwind.tex
+++ b/doc/libunwind.tex
@@ -340,6 +340,7 @@
\SeeAlso{unw\_set\_fpreg(3)},
\SeeAlso{unw\_set\_reg(3)},
\SeeAlso{unw\_step(3)},
+\SeeAlso{unw\_strerror(3)},
\SeeAlso{\_U\_dyn\_register(3)},
\SeeAlso{\_U\_dyn\_cancel(3)}
@@ -347,10 +348,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/libunwind.trans b/doc/libunwind.trans
index f68158d..a514e5a 100644
--- a/doc/libunwind.trans
+++ b/doc/libunwind.trans
@@ -27,7 +27,7 @@
$manMacro1b{'SeeAlso'} = $manMacro1b{File};
# special handling of SeeAlso in latex2man, so that argument gets doubled:
$htmlMacro2a{'SeeAlso'} = "<a href=\"";
- $htmlMacro2b{'SeeAlso'} = ".php\">$htmlMacro1a{File}";
+ $htmlMacro2b{'SeeAlso'} = ".html\">$htmlMacro1a{File}";
$htmlMacro2c{'SeeAlso'} = "$htmlMacro1b{File}</a>";
$texiMacro1a{'SeeAlso'} = $texiMacro1a{File};
$texiMacro1b{'SeeAlso'} = $texiMacro1b{File};
diff --git a/doc/unw_create_addr_space.man b/doc/unw_create_addr_space.man
index 3c5d62c..4aca13e 100644
--- a/doc/unw_create_addr_space.man
+++ b/doc/unw_create_addr_space.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Wed Apr 20 14:03:33 PDT 2005
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_CREATE\\_ADDR\\_SPACE" "3" "20 April 2005" "Programming Library " "Programming Library "
+.TH "UNW\\_CREATE\\_ADDR\\_SPACE" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_create_addr_space
\-\- create address space for remote unwinding
@@ -450,12 +450,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_create_addr_space.tex b/doc/unw_create_addr_space.tex
index 3dce780..8de0691 100644
--- a/doc/unw_create_addr_space.tex
+++ b/doc/unw_create_addr_space.tex
@@ -258,10 +258,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_destroy_addr_space.man b/doc/unw_destroy_addr_space.man
index 4eb4792..90c9777 100644
--- a/doc/unw_destroy_addr_space.man
+++ b/doc/unw_destroy_addr_space.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:20:31 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_DESTROY\\_ADDR\\_SPACE" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_DESTROY\\_ADDR\\_SPACE" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_destroy_addr_space
\-\- destroy unwind address space
@@ -50,12 +50,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_destroy_addr_space.tex b/doc/unw_destroy_addr_space.tex
index 9c393a4..a66b10b 100644
--- a/doc/unw_destroy_addr_space.tex
+++ b/doc/unw_destroy_addr_space.tex
@@ -33,10 +33,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_flush_cache.man b/doc/unw_flush_cache.man
index bda9b6d..2c05bc2 100644
--- a/doc/unw_flush_cache.man
+++ b/doc/unw_flush_cache.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_FLUSH\\_CACHE" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_FLUSH\\_CACHE" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_flush_cache
\-\- flush cached info
@@ -85,12 +85,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_flush_cache.tex b/doc/unw_flush_cache.tex
index 818488a..9b61dfc 100644
--- a/doc/unw_flush_cache.tex
+++ b/doc/unw_flush_cache.tex
@@ -50,10 +50,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_get_accessors.man b/doc/unw_get_accessors.man
index f8de861..83fe4fc 100644
--- a/doc/unw_get_accessors.man
+++ b/doc/unw_get_accessors.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_GET\\_ACCESSORS" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_GET\\_ACCESSORS" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_get_accessors
\-\- get pointer to accessor call\-backs
@@ -72,12 +72,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_get_accessors.tex b/doc/unw_get_accessors.tex
index 865c6fe..bf344a3 100644
--- a/doc/unw_get_accessors.tex
+++ b/doc/unw_get_accessors.tex
@@ -48,10 +48,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_get_fpreg.man b/doc/unw_get_fpreg.man
index 572a316..5e54ca1 100644
--- a/doc/unw_get_fpreg.man
+++ b/doc/unw_get_fpreg.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_GET\\_FPREG" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_GET\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_get_fpreg
\-\- get contents of floating\-point register
@@ -104,12 +104,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_get_fpreg.tex b/doc/unw_get_fpreg.tex
index 18544cd..dd679ad 100644
--- a/doc/unw_get_fpreg.tex
+++ b/doc/unw_get_fpreg.tex
@@ -70,10 +70,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_get_proc_info.man b/doc/unw_get_proc_info.man
index 31bda2b..09eadee 100644
--- a/doc/unw_get_proc_info.man
+++ b/doc/unw_get_proc_info.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:20:31 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_GET\\_PROC\\_INFO" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_GET\\_PROC\\_INFO" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_get_proc_info
\-\- get info on current procedure
@@ -46,7 +46,7 @@
instruction of the procedure. If this address cannot be determined
(e.g., due to lack of unwind information), the start_ip
member is cleared to 0.
-.br
+.br
.TP
unw_word_t end_ip
The address of the first
@@ -55,14 +55,14 @@
cannot be determined (e.g., due to lack of unwind information),
the end_ip
member is cleared to 0.
-.br
+.br
.TP
unw_word_t lsda
The address of the
language\-specific data\-area (LSDA). This area normally contains
language\-specific information needed during exception handling. If
the procedure has no such area, this member is cleared to 0.
-.br
+.br
.TP
unw_word_t handler
The address of the exception
@@ -70,7 +70,7 @@
routine. If the procedure does not define
a personality routine, the handler
member is cleared to 0.
-.br
+.br
.TP
unw_word_t gp
The global\-pointer of the
@@ -79,7 +79,7 @@
must be set either to the correct global\-pointer value of the
procedure or to 0 if the proper global\-pointer cannot be
obtained for some reason.
-.br
+.br
.TP
unw_word_t flags
A set of flags. There are
@@ -87,7 +87,7 @@
flag UNW_PI_FLAG_IA64_RBS_SWITCH
is set if the
procedure may switch the register\-backing store.
-.br
+.br
.TP
int format
The format of the unwind\-info for this
@@ -107,7 +107,7 @@
unw_get_proc_info()
routine
may return an undefined value in this member.
-.br
+.br
.TP
int unwind_info_size
The size of the unwind\-info
@@ -119,7 +119,7 @@
unw_get_proc_info()
routine
may return an undefined value in this member.
-.br
+.br
.TP
void *unwind_info
The pointer to the unwind\-info.
@@ -133,7 +133,7 @@
unw_get_proc_info()
routine
may return an undefined value in this member.
-.br
+.br
.PP
Note that for the purposes of libunwind,
the code of a
@@ -196,12 +196,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_get_proc_info.tex b/doc/unw_get_proc_info.tex
index fdf2766..72621f1 100644
--- a/doc/unw_get_proc_info.tex
+++ b/doc/unw_get_proc_info.tex
@@ -116,10 +116,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_get_proc_info_by_ip.man b/doc/unw_get_proc_info_by_ip.man
index a6a2208..a347a1d 100644
--- a/doc/unw_get_proc_info_by_ip.man
+++ b/doc/unw_get_proc_info_by_ip.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_GET\\_PROC\\_INFO\\_BY\\_IP" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_GET\\_PROC\\_INFO\\_BY\\_IP" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_get_proc_info_by_ip
\-\- get procedure info by IP
@@ -127,12 +127,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_get_proc_info_by_ip.tex b/doc/unw_get_proc_info_by_ip.tex
index ddfcf63..5e1d5d2 100644
--- a/doc/unw_get_proc_info_by_ip.tex
+++ b/doc/unw_get_proc_info_by_ip.tex
@@ -84,10 +84,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_get_proc_name.man b/doc/unw_get_proc_name.man
index ea6e27c..bbf350f 100644
--- a/doc/unw_get_proc_name.man
+++ b/doc/unw_get_proc_name.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_GET\\_PROC\\_NAME" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_GET\\_PROC\\_NAME" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_get_proc_name
\-\- get name of current procedure
@@ -116,12 +116,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_get_proc_name.tex b/doc/unw_get_proc_name.tex
index c9c52b6..4a9b585 100644
--- a/doc/unw_get_proc_name.tex
+++ b/doc/unw_get_proc_name.tex
@@ -75,10 +75,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_get_reg.man b/doc/unw_get_reg.man
index c60788d..83e8bb4 100644
--- a/doc/unw_get_reg.man
+++ b/doc/unw_get_reg.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_GET\\_REG" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_GET\\_REG" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_get_reg
\-\- get register contents
@@ -105,12 +105,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_get_reg.tex b/doc/unw_get_reg.tex
index 26c2555..b66e8c0 100644
--- a/doc/unw_get_reg.tex
+++ b/doc/unw_get_reg.tex
@@ -70,10 +70,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_getcontext.man b/doc/unw_getcontext.man
index c13860b..13725df 100644
--- a/doc/unw_getcontext.man
+++ b/doc/unw_getcontext.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Tue Mar 30 16:50:17 PST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_GETCONTEXT" "3" "30 March 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_GETCONTEXT" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_getcontext
\-\- get initial machine\-state
@@ -86,12 +86,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_getcontext.tex b/doc/unw_getcontext.tex
index 823fcba..fa3eb81 100644
--- a/doc/unw_getcontext.tex
+++ b/doc/unw_getcontext.tex
@@ -56,10 +56,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_init_local.man b/doc/unw_init_local.man
index 08060d9..73b7988 100644
--- a/doc/unw_init_local.man
+++ b/doc/unw_init_local.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_INIT\\_LOCAL" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_INIT\\_LOCAL" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_init_local
\-\- initialize cursor for local unwinding
@@ -112,12 +112,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_init_local.tex b/doc/unw_init_local.tex
index d32821e..5cea673 100644
--- a/doc/unw_init_local.tex
+++ b/doc/unw_init_local.tex
@@ -74,10 +74,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_init_remote.man b/doc/unw_init_remote.man
index d90ab7d..0acdac9 100644
--- a/doc/unw_init_remote.man
+++ b/doc/unw_init_remote.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_INIT\\_REMOTE" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_INIT\\_REMOTE" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_init_remote
\-\- initialize cursor for remote unwinding
@@ -116,12 +116,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_init_remote.tex b/doc/unw_init_remote.tex
index fe7280f..9b4dc79 100644
--- a/doc/unw_init_remote.tex
+++ b/doc/unw_init_remote.tex
@@ -72,10 +72,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_is_fpreg.man b/doc/unw_is_fpreg.man
index 382e79b..0c26ec1 100644
--- a/doc/unw_is_fpreg.man
+++ b/doc/unw_is_fpreg.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Tue Jan 20 16:44:37 PST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_IS\\_FPREG" "3" "20 January 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_IS\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_is_fpreg
\-\- check if a register is a floating\-point register
@@ -66,12 +66,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_is_fpreg.tex b/doc/unw_is_fpreg.tex
index b729adf..c28cdc9 100644
--- a/doc/unw_is_fpreg.tex
+++ b/doc/unw_is_fpreg.tex
@@ -45,10 +45,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_is_signal_frame.man b/doc/unw_is_signal_frame.man
index 9863e57..d9a7cda 100644
--- a/doc/unw_is_signal_frame.man
+++ b/doc/unw_is_signal_frame.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:51 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_IS\\_SIGNAL\\_FRAME" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_IS\\_SIGNAL\\_FRAME" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_is_signal_frame
\-\- check if current frame is a signal frame
@@ -81,12 +81,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_is_signal_frame.tex b/doc/unw_is_signal_frame.tex
index 38fabbb..f262e56 100644
--- a/doc/unw_is_signal_frame.tex
+++ b/doc/unw_is_signal_frame.tex
@@ -60,10 +60,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_regname.man b/doc/unw_regname.man
index 1c5b0ac..1e3e2db 100644
--- a/doc/unw_regname.man
+++ b/doc/unw_regname.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Mon Mar 31 14:18:03 PST 2003
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_REGNAME" "3" "31 March 2003" "Programming Library " "Programming Library "
+.TH "UNW\\_REGNAME" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_regname
\-\- get register name
@@ -61,12 +61,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_regname.tex b/doc/unw_regname.tex
index 2563556..94b6434 100644
--- a/doc/unw_regname.tex
+++ b/doc/unw_regname.tex
@@ -40,10 +40,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_resume.man b/doc/unw_resume.man
index aee1049..1bf3832 100644
--- a/doc/unw_resume.man
+++ b/doc/unw_resume.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:52 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_RESUME" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_RESUME" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_resume
\-\- resume execution in a particular stack frame
@@ -139,12 +139,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_resume.tex b/doc/unw_resume.tex
index 4250b8b..38b1824 100644
--- a/doc/unw_resume.tex
+++ b/doc/unw_resume.tex
@@ -92,10 +92,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_set_caching_policy.man b/doc/unw_set_caching_policy.man
index 57b3bcd..a21d84a 100644
--- a/doc/unw_set_caching_policy.man
+++ b/doc/unw_set_caching_policy.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:20:31 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_SET\\_CACHING\\_POLICY" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_SET\\_CACHING\\_POLICY" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_set_caching_policy
\-\- set unwind caching policy
@@ -111,12 +111,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_set_caching_policy.tex b/doc/unw_set_caching_policy.tex
index 465fddc..a84e020 100644
--- a/doc/unw_set_caching_policy.tex
+++ b/doc/unw_set_caching_policy.tex
@@ -73,10 +73,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_set_fpreg.man b/doc/unw_set_fpreg.man
index 77f0a36..6cefa54 100644
--- a/doc/unw_set_fpreg.man
+++ b/doc/unw_set_fpreg.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:52 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_SET\\_FPREG" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_SET\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_set_fpreg
\-\- set contents of floating\-point register
@@ -110,12 +110,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_set_fpreg.tex b/doc/unw_set_fpreg.tex
index 15b8231..aaf7fb2 100644
--- a/doc/unw_set_fpreg.tex
+++ b/doc/unw_set_fpreg.tex
@@ -72,10 +72,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_set_reg.man b/doc/unw_set_reg.man
index 80705d5..5d57045 100644
--- a/doc/unw_set_reg.man
+++ b/doc/unw_set_reg.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:52 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_SET\\_REG" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_SET\\_REG" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_set_reg
\-\- set register contents
@@ -110,12 +110,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_set_reg.tex b/doc/unw_set_reg.tex
index 1dea1e3..2421846 100644
--- a/doc/unw_set_reg.tex
+++ b/doc/unw_set_reg.tex
@@ -72,10 +72,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/doc/unw_step.man b/doc/unw_step.man
index 79c62bc..54da1b2 100644
--- a/doc/unw_step.man
+++ b/doc/unw_step.man
@@ -1,5 +1,5 @@
'\" t
-.\" Manual page created with latex2man on Thu Aug 5 10:00:52 CEST 2004
+.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
.\" NOTE: This file is generated, DO NOT EDIT.
.de Vb
.ft CW
@@ -10,7 +10,7 @@
.fi
..
-.TH "UNW\\_STEP" "3" "05 August 2004" "Programming Library " "Programming Library "
+.TH "UNW\\_STEP" "3" "16 August 2007" "Programming Library " "Programming Library "
.SH NAME
unw_step
\-\- advance to next stack frame
@@ -99,12 +99,8 @@
.PP
David Mosberger\-Tang
-.br
-Hewlett\-Packard Labs
-.br
-Palo\-Alto, CA 94304
-.br
-Email: \fBdavidm@hpl.hp.com\fP
.br
-WWW: \fBhttp://www.hpl.hp.com/research/linux/libunwind/\fP\&.
+Email: \fBdmosberger@gmail.com\fP
+.br
+WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
.\" NOTE: This file is generated, DO NOT EDIT.
diff --git a/doc/unw_step.tex b/doc/unw_step.tex
index 1bfc735..106bd9b 100644
--- a/doc/unw_step.tex
+++ b/doc/unw_step.tex
@@ -61,10 +61,8 @@
\noindent
David Mosberger-Tang\\
-Hewlett-Packard Labs\\
-Palo-Alto, CA 94304\\
-Email: \Email{davidm@hpl.hp.com}\\
-WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}.
+Email: \Email{dmosberger@gmail.com}\\
+WWW: \URL{http://www.nongnu.org/libunwind/}.
\LatexManEnd
\end{document}
diff --git a/src/dwarf/dwarf-eh.h b/include/dwarf-eh.h
similarity index 100%
rename from src/dwarf/dwarf-eh.h
rename to include/dwarf-eh.h
diff --git a/include/dwarf.h b/include/dwarf.h
index 8b5eb38..3dbf520 100644
--- a/include/dwarf.h
+++ b/include/dwarf.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -26,8 +26,15 @@
#ifndef dwarf_h
#define dwarf_h
-#include "internal.h"
-#include "mempool.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_ATOMIC_OPS_H
+# include <atomic_ops.h>
+#endif
+
+#include <libunwind.h>
struct dwarf_cursor; /* forward-declaration */
@@ -145,7 +152,7 @@
DW_CFA_def_cfa_register = 0x0d,
DW_CFA_def_cfa_offset = 0x0e,
DW_CFA_def_cfa_expression = 0x0f,
- DW_CFA_CFA_expression = 0x10,
+ DW_CFA_expression = 0x10,
DW_CFA_offset_extended_sf = 0x11,
DW_CFA_def_cfa_sf = 0x12,
DW_CFA_def_cfa_offset_sf = 0x13,
@@ -199,6 +206,7 @@
#define DW_EH_PE_aligned 0x50 /* aligned pointer */
extern struct mempool dwarf_reg_state_pool;
+extern struct mempool dwarf_cie_info_pool;
typedef enum
{
@@ -234,9 +242,33 @@
{
struct dwarf_reg_state *next; /* for rs_stack */
dwarf_save_loc_t reg[DWARF_NUM_PRESERVED_REGS + 2];
+ unw_word_t ip; /* ip this rs is for */
+ unw_word_t ret_addr_column; /* indicates which column in the rule table represents return address */
+ unsigned short lru_chain; /* used for least-recently-used chain */
+ unsigned short coll_chain; /* used for hash collisions */
+ unsigned short hint; /* hint for next rs to try (or -1) */
}
dwarf_reg_state_t;
+typedef struct dwarf_cie_info
+ {
+ unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */
+ unw_word_t cie_instr_end; /* end addr. of CIE "initial_instructions" */
+ unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */
+ unw_word_t fde_instr_end; /* end addr. of FDE "instructions" */
+ unw_word_t code_align; /* code-alignment factor */
+ unw_word_t data_align; /* data-alignment factor */
+ unw_word_t ret_addr_column; /* column of return-address register */
+ unw_word_t handler; /* address of personality-routine */
+ uint16_t abi;
+ uint16_t tag;
+ uint8_t fde_encoding;
+ uint8_t lsda_encoding;
+ unsigned int sized_augmentation : 1;
+ unsigned int have_abi_marker : 1;
+ }
+dwarf_cie_info_t;
+
typedef struct dwarf_state_record
{
unsigned char fde_encoding;
@@ -256,16 +288,47 @@
unw_word_t ip; /* instruction pointer */
unw_word_t args_size; /* size of arguments */
unw_word_t ret_addr_column; /* column for return-address */
+ unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS];
+ unsigned int eh_valid_mask;
dwarf_loc_t loc[DWARF_NUM_PRESERVED_REGS];
unsigned int pi_valid :1; /* is proc_info valid? */
unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */
- unsigned int cfa_is_sp :1; /* TRUE if stack-pointer is CFA */
unw_proc_info_t pi; /* info about current procedure */
+
+ short hint; /* faster lookup of the rs cache */
+ short prev_rs;
}
dwarf_cursor_t;
+#define DWARF_LOG_UNW_CACHE_SIZE 7
+#define DWARF_UNW_CACHE_SIZE (1 << DWARF_LOG_UNW_CACHE_SIZE)
+
+#define DWARF_LOG_UNW_HASH_SIZE (DWARF_LOG_UNW_CACHE_SIZE + 1)
+#define DWARF_UNW_HASH_SIZE (1 << DWARF_LOG_UNW_HASH_SIZE)
+
+typedef unsigned char unw_hash_index_t;
+
+struct dwarf_rs_cache
+ {
+#ifdef HAVE_ATOMIC_OPS_H
+ AO_TS_t busy; /* is the rs-cache busy? */
+#else
+ pthread_mutex_t lock;
+#endif
+ unsigned short lru_head; /* index of lead-recently used rs */
+ unsigned short lru_tail; /* index of most-recently used rs */
+
+ /* hash table that maps instruction pointer to rs index: */
+ unsigned short hash[DWARF_UNW_HASH_SIZE];
+
+ uint32_t generation; /* generation number */
+
+ /* rs cache: */
+ dwarf_reg_state_t buckets[DWARF_UNW_CACHE_SIZE];
+ };
+
/* Convenience macros: */
#define dwarf_init UNW_ARCH_OBJ (dwarf_init)
#define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info)
@@ -273,7 +336,8 @@
#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
#define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr)
-#define dwarf_parse_fde UNW_OBJ (dwarf_parse_fde)
+#define dwarf_extract_proc_info_from_fde \
+ UNW_OBJ (dwarf_extract_proc_info_from_fde)
#define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs)
#define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record)
#define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info)
@@ -294,9 +358,12 @@
extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr,
unw_word_t len, unw_word_t *valp,
int *is_register);
-extern int dwarf_parse_fde (unw_addr_space_t as, unw_accessors_t *a,
- unw_word_t *addr, unw_proc_info_t *pi,
- unw_dyn_dwarf_fde_info_t *dfi, void *arg);
+extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as,
+ unw_accessors_t *a,
+ unw_word_t *fde_addr,
+ unw_proc_info_t *pi,
+ int need_unwind_info,
+ void *arg);
extern int dwarf_find_save_locs (struct dwarf_cursor *c);
extern int dwarf_create_state_record (struct dwarf_cursor *c,
dwarf_state_record_t *sr);
@@ -305,7 +372,7 @@
unw_accessors_t *a,
unw_word_t *addr,
unsigned char encoding,
- unw_proc_info_t *pi,
+ const unw_proc_info_t *pi,
unw_word_t *valp, void *arg);
extern int dwarf_step (struct dwarf_cursor *c);
diff --git a/include/dwarf_i.h b/include/dwarf_i.h
index 55320c2..5b78dc0 100644
--- a/include/dwarf_i.h
+++ b/include/dwarf_i.h
@@ -7,19 +7,15 @@
files are compiled with inlining disabled. */
#include "dwarf.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map)
extern uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH];
-static inline unw_regnum_t
-dwarf_to_unw_regnum (unw_word_t regnum)
-{
- if (regnum <= DWARF_REGNUM_MAP_LENGTH)
- return dwarf_to_unw_regnum_map[regnum];
- return 0;
-}
+/* REG is evaluated multiple times; it better be side-effects free! */
+#define dwarf_to_unw_regnum(reg) \
+ (((reg) <= DWARF_REGNUM_MAP_LENGTH) ? dwarf_to_unw_regnum_map[reg] : 0)
#ifdef UNW_LOCAL_ONLY
@@ -340,4 +336,139 @@
return 0;
}
+static ALWAYS_INLINE int
+dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
+ unw_word_t *addr, unsigned char encoding,
+ const unw_proc_info_t *pi,
+ unw_word_t *valp, void *arg)
+{
+ unw_word_t val, initial_addr = *addr;
+ uint16_t uval16;
+ uint32_t uval32;
+ uint64_t uval64;
+ int16_t sval16;
+ int32_t sval32;
+ int64_t sval64;
+ int ret;
+
+ /* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal
+ format/application encoding. Handle them first. */
+ if (encoding == DW_EH_PE_omit)
+ {
+ *valp = 0;
+ return 0;
+ }
+ else if (encoding == DW_EH_PE_aligned)
+ {
+ *addr = (initial_addr + sizeof (unw_word_t) - 1) & -sizeof (unw_word_t);
+ return dwarf_readw (as, a, addr, valp, arg);
+ }
+
+ switch (encoding & DW_EH_PE_FORMAT_MASK)
+ {
+ case DW_EH_PE_ptr:
+ if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
+ return ret;
+ break;
+
+ case DW_EH_PE_uleb128:
+ if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
+ return ret;
+ break;
+
+ case DW_EH_PE_udata2:
+ if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
+ return ret;
+ val = uval16;
+ break;
+
+ case DW_EH_PE_udata4:
+ if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
+ return ret;
+ val = uval32;
+ break;
+
+ case DW_EH_PE_udata8:
+ if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
+ return ret;
+ val = uval64;
+ break;
+
+ case DW_EH_PE_sleb128:
+ if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
+ return ret;
+ break;
+
+ case DW_EH_PE_sdata2:
+ if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
+ return ret;
+ val = sval16;
+ break;
+
+ case DW_EH_PE_sdata4:
+ if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
+ return ret;
+ val = sval32;
+ break;
+
+ case DW_EH_PE_sdata8:
+ if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
+ return ret;
+ val = sval64;
+ break;
+
+ default:
+ Debug (1, "unexpected encoding format 0x%x\n",
+ encoding & DW_EH_PE_FORMAT_MASK);
+ return -UNW_EINVAL;
+ }
+
+ if (val == 0)
+ {
+ /* 0 is a special value and always absolute. */
+ *valp = 0;
+ return 0;
+ }
+
+ switch (encoding & DW_EH_PE_APPL_MASK)
+ {
+ case DW_EH_PE_absptr:
+ break;
+
+ case DW_EH_PE_pcrel:
+ val += initial_addr;
+ break;
+
+ case DW_EH_PE_datarel:
+ /* XXX For now, assume that data-relative addresses are relative
+ to the global pointer. */
+ val += pi->gp;
+ break;
+
+ case DW_EH_PE_funcrel:
+ val += pi->start_ip;
+ break;
+
+ case DW_EH_PE_textrel:
+ /* XXX For now we don't support text-rel values. If there is a
+ platform which needs this, we probably would have to add a
+ "segbase" member to unw_proc_info_t. */
+ default:
+ Debug (1, "unexpected application type 0x%x\n",
+ encoding & DW_EH_PE_APPL_MASK);
+ return -UNW_EINVAL;
+ }
+
+ if (encoding & DW_EH_PE_indirect)
+ {
+ unw_word_t indirect_addr = val;
+
+ if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
+ return ret;
+ }
+
+ *valp = val;
+ return 0;
+}
+
#endif /* DWARF_I_H */
diff --git a/include/libunwind-dynamic.h b/include/libunwind-dynamic.h
index dbfba47..8f6041f 100644
--- a/include/libunwind-dynamic.h
+++ b/include/libunwind-dynamic.h
@@ -76,7 +76,6 @@
UNW_INFO_FORMAT_DYNAMIC, /* unw_dyn_proc_info_t */
UNW_INFO_FORMAT_TABLE, /* unw_dyn_table_t */
UNW_INFO_FORMAT_REMOTE_TABLE, /* unw_dyn_remote_table_t */
- UNW_INFO_FORMAT_DWARF_FDE /* unw_dyn_dwarf_fde_t */
}
unw_dyn_info_format_t;
@@ -127,26 +126,6 @@
}
unw_dyn_remote_table_info_t;
-/* The flags member encodes the pointer-encoding used in the FDE, the
- pointer-encoding used for the LSDA, and a bit flag that is set if
- the FDE's augmentation body starts with a length. */
-#define UNW_DYN_DFI_FLAG_FDE_PE_MASK 0x0ff
-#define UNW_DYN_DFI_FLAG_AUGMENTATION_HAS_SIZE 0x100
-
-typedef struct unw_dyn_dwarf_fde_info
- {
- unw_word_t name_ptr; /* addr. of table name (e.g., library name) */
- unw_word_t flags; /* see UNW_DYN_DFI_FLAG */
- unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */
- unw_word_t cie_instr_end; /* start addr. of CIE "initial_instructions" */
- unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */
- unw_word_t fde_instr_end; /* start addr. of FDE "instructions" */
- unw_word_t code_align; /* code-alignment factor */
- unw_word_t data_align; /* data-alignment factor */
- unw_word_t ret_addr_column; /* column of return-address register */
- }
-unw_dyn_dwarf_fde_info_t;
-
typedef struct unw_dyn_info
{
/* doubly-linked list of dyn-info structures: */
@@ -162,7 +141,6 @@
unw_dyn_proc_info_t pi;
unw_dyn_table_info_t ti;
unw_dyn_remote_table_info_t rti;
- unw_dyn_dwarf_fde_info_t dfi;
}
u;
}
diff --git a/include/libunwind-hppa.h b/include/libunwind-hppa.h
index 75fb14c..74ea70d 100644
--- a/include/libunwind-hppa.h
+++ b/include/libunwind-hppa.h
@@ -1,6 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by Scott Marovitch
+ Copyright (C) 2003-2004 Hewlett-Packard Co
This file is part of libunwind.
@@ -36,28 +35,34 @@
#define UNW_TARGET hppa
#define UNW_TARGET_HPPA 1
+#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
+
/* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will
require recompiling all users of this library. Stack allocation is
relatively cheap and unwind-state copying is relatively rare, so we
want to err on making it rather too big than too small. */
-#define UNW_TDEP_CURSOR_LEN 127
+#define UNW_TDEP_CURSOR_LEN 511
-typedef uint64_t unw_word_t;
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
-typedef struct
+typedef union
{
- /* no PA-RISC-specific auxiliary proc-info */
+ struct { unw_word_t bits[2]; } raw;
+ double val;
}
-unw_tdep_proc_info_t;
+unw_tdep_fpreg_t;
typedef enum
{
- /* Note: general registers are excepted to start with index 0.
+ /* Note: general registers are expected to start with index 0.
This convention facilitates architecture-independent
implementation of the C++ exception handling ABI. See
_Unwind_SetGR() and _Unwind_GetGR() for details. */
UNW_HPPA_GR = 0,
+ UNW_HPPA_RP = 2, /* return pointer */
+ UNW_HPPA_FP = 3, /* frame pointer */
UNW_HPPA_SP = UNW_HPPA_GR + 30,
UNW_HPPA_FR = UNW_HPPA_GR + 32,
@@ -66,13 +71,29 @@
/* other "preserved" registers (fpsr etc.)... */
+ /* PA-RISC has 4 exception-argument registers but they're not
+ contiguous. To deal with this, we define 4 pseudo
+ exception-handling registers which we then alias to the actual
+ physical register. */
+
+ UNW_HPPA_EH0 = UNW_HPPA_IP + 1, /* alias for UNW_HPPA_GR + 20 */
+ UNW_HPPA_EH1 = UNW_HPPA_EH0 + 1, /* alias for UNW_HPPA_GR + 21 */
+ UNW_HPPA_EH2 = UNW_HPPA_EH1 + 1, /* alias for UNW_HPPA_GR + 22 */
+ UNW_HPPA_EH3 = UNW_HPPA_EH2 + 1, /* alias for UNW_HPPA_GR + 31 */
+
+ /* frame info (read-only) */
+ UNW_HPPA_CFA,
+
UNW_TDEP_LAST_REG = UNW_HPPA_IP,
UNW_TDEP_IP = UNW_HPPA_IP,
- UNW_TDEP_SP = UNW_HPPA_SP
+ UNW_TDEP_SP = UNW_HPPA_SP,
+ UNW_TDEP_EH = UNW_HPPA_EH0
}
hppa_regnum_t;
+#define UNW_TDEP_NUM_EH_REGS 4
+
typedef struct unw_tdep_save_loc
{
/* Additional target-dependent info on a save location. */
@@ -82,18 +103,21 @@
/* On PA-RISC, we can directly use ucontext_t as the unwind context. */
typedef ucontext_t unw_tdep_context_t;
-/* XXX this is not ideal: an application should not be prevented from
- using the "getcontext" name just because it's using libunwind. We
- can't just use __getcontext() either, because that isn't exported
- by glibc... */
-#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
-
-/* XXX fixme: */
-#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 128)
+#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 32)
#include "libunwind-dynamic.h"
+
+typedef struct
+ {
+ /* no PA-RISC-specific auxiliary proc-info */
+ }
+unw_tdep_proc_info_t;
+
#include "libunwind-common.h"
+#define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext)
+extern int unw_tdep_getcontext (unw_tdep_context_t *);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/include/libunwind-ia64.h b/include/libunwind-ia64.h
index 073826d..fb2fbfe 100644
--- a/include/libunwind-ia64.h
+++ b/include/libunwind-ia64.h
@@ -67,6 +67,7 @@
#define UNW_PI_FLAG_IA64_RBS_SWITCH (1 << UNW_PI_FLAG_IA64_RBS_SWITCH_BIT)
typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
/* On IA-64, we want to access the contents of floating-point
registers as a pair of "words", but to ensure 16-byte alignment, we
@@ -119,7 +120,7 @@
UNW_IA64_PR = UNW_IA64_BR + 8, /* predicate registers (p0..p63) */
UNW_IA64_CFM,
- /* frame info (read-only): */
+ /* frame info: */
UNW_IA64_BSP,
UNW_IA64_IP,
UNW_IA64_SP,
diff --git a/include/libunwind-ppc32.h b/include/libunwind-ppc32.h
new file mode 100644
index 0000000..b40a84e
--- /dev/null
+++ b/include/libunwind-ppc32.h
@@ -0,0 +1,207 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <ucontext.h>
+
+#define UNW_TARGET ppc32
+#define UNW_TARGET_PPC32 1
+
+#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
+
+/*
+ * This needs to be big enough to accommodate "struct cursor", while
+ * leaving some slack for future expansion. Changing this value will
+ * require recompiling all users of this library. Stack allocation is
+ * relatively cheap and unwind-state copying is relatively rare, so we want
+ * to err on making it rather too big than too small.
+ *
+ * To simplify this whole process, we are at least initially taking the
+ * tack that UNW_PPC32_* map straight across to the .eh_frame column register
+ * numbers. These register numbers come from gcc's source in
+ * gcc/config/rs6000/rs6000.h
+ *
+ * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size. Since we have 115
+ * elements in the loc array, each sized 2 * unw_word_t, plus the rest of
+ * the cursor struct, this puts us at about 2 * 115 + 40 = 270. Let's
+ * round that up to 280.
+ */
+
+#define UNW_TDEP_CURSOR_LEN 200
+
+#if __WORDSIZE==32
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+#else
+typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
+#endif
+
+typedef long double unw_tdep_fpreg_t;
+
+typedef enum
+ {
+ UNW_PPC32_R0,
+ UNW_PPC32_R1, /* called STACK_POINTER in gcc */
+ UNW_PPC32_R2,
+ UNW_PPC32_R3,
+ UNW_PPC32_R4,
+ UNW_PPC32_R5,
+ UNW_PPC32_R6,
+ UNW_PPC32_R7,
+ UNW_PPC32_R8,
+ UNW_PPC32_R9,
+ UNW_PPC32_R10,
+ UNW_PPC32_R11, /* called STATIC_CHAIN in gcc */
+ UNW_PPC32_R12,
+ UNW_PPC32_R13,
+ UNW_PPC32_R14,
+ UNW_PPC32_R15,
+ UNW_PPC32_R16,
+ UNW_PPC32_R17,
+ UNW_PPC32_R18,
+ UNW_PPC32_R19,
+ UNW_PPC32_R20,
+ UNW_PPC32_R21,
+ UNW_PPC32_R22,
+ UNW_PPC32_R23,
+ UNW_PPC32_R24,
+ UNW_PPC32_R25,
+ UNW_PPC32_R26,
+ UNW_PPC32_R27,
+ UNW_PPC32_R28,
+ UNW_PPC32_R29,
+ UNW_PPC32_R30,
+ UNW_PPC32_R31, /* called HARD_FRAME_POINTER in gcc */
+
+ /* Count Register */
+ UNW_PPC32_CTR = 32,
+ /* Fixed-Point Status and Control Register */
+ UNW_PPC32_XER = 33,
+ /* Condition Register */
+ UNW_PPC32_CCR = 34,
+ /* Machine State Register */
+ //UNW_PPC32_MSR = 35,
+ /* MQ or SPR0, not part of generic Power, part of MPC601 */
+ //UNW_PPC32_MQ = 36,
+ /* Link Register */
+ UNW_PPC32_LR = 36,
+ /* Floating Pointer Status and Control Register */
+ UNW_PPC32_FPSCR = 37,
+
+ UNW_PPC32_F0 = 48,
+ UNW_PPC32_F1,
+ UNW_PPC32_F2,
+ UNW_PPC32_F3,
+ UNW_PPC32_F4,
+ UNW_PPC32_F5,
+ UNW_PPC32_F6,
+ UNW_PPC32_F7,
+ UNW_PPC32_F8,
+ UNW_PPC32_F9,
+ UNW_PPC32_F10,
+ UNW_PPC32_F11,
+ UNW_PPC32_F12,
+ UNW_PPC32_F13,
+ UNW_PPC32_F14,
+ UNW_PPC32_F15,
+ UNW_PPC32_F16,
+ UNW_PPC32_F17,
+ UNW_PPC32_F18,
+ UNW_PPC32_F19,
+ UNW_PPC32_F20,
+ UNW_PPC32_F21,
+ UNW_PPC32_F22,
+ UNW_PPC32_F23,
+ UNW_PPC32_F24,
+ UNW_PPC32_F25,
+ UNW_PPC32_F26,
+ UNW_PPC32_F27,
+ UNW_PPC32_F28,
+ UNW_PPC32_F29,
+ UNW_PPC32_F30,
+ UNW_PPC32_F31,
+
+ UNW_TDEP_LAST_REG = UNW_PPC32_F31,
+
+ UNW_TDEP_IP = UNW_PPC32_LR,
+ UNW_TDEP_SP = UNW_PPC32_R1,
+ UNW_TDEP_EH = UNW_PPC32_R12
+ }
+ppc32_regnum_t;
+
+/*
+ * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for
+ * passing parameters to exception handlers.
+ */
+
+#define UNW_TDEP_NUM_EH_REGS 4
+
+typedef struct unw_tdep_save_loc
+ {
+ /* Additional target-dependent info on a save location. */
+ }
+unw_tdep_save_loc_t;
+
+/* On ppc, we can directly use ucontext_t as the unwind context. */
+typedef ucontext_t unw_tdep_context_t;
+
+/* XXX this is not ideal: an application should not be prevented from
+ using the "getcontext" name just because it's using libunwind. We
+ can't just use __getcontext() either, because that isn't exported
+ by glibc... */
+#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+ {
+ /* no ppc32-specific auxiliary proc-info */
+ }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/include/libunwind-ppc64.h b/include/libunwind-ppc64.h
new file mode 100644
index 0000000..66420b3
--- /dev/null
+++ b/include/libunwind-ppc64.h
@@ -0,0 +1,264 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef LIBUNWIND_H
+#define LIBUNWIND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <ucontext.h>
+
+#define UNW_TARGET ppc64
+#define UNW_TARGET_PPC64 1
+
+#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
+
+/*
+ * This needs to be big enough to accommodate "struct cursor", while
+ * leaving some slack for future expansion. Changing this value will
+ * require recompiling all users of this library. Stack allocation is
+ * relatively cheap and unwind-state copying is relatively rare, so we want
+ * to err on making it rather too big than too small.
+ *
+ * To simplify this whole process, we are at least initially taking the
+ * tack that UNW_PPC64_* map straight across to the .eh_frame column register
+ * numbers. These register numbers come from gcc's source in
+ * gcc/config/rs6000/rs6000.h
+ *
+ * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size. Since we have 115
+ * elements in the loc array, each sized 2 * unw_word_t, plus the rest of
+ * the cursor struct, this puts us at about 2 * 115 + 40 = 270. Let's
+ * round that up to 280.
+ */
+
+#define UNW_TDEP_CURSOR_LEN 280
+
+#if __WORDSIZE==32
+typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
+#else
+typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
+#endif
+
+typedef long double unw_tdep_fpreg_t;
+
+/*
+ * Vector register (in PowerPC64 used for AltiVec registers)
+ */
+typedef struct {
+ uint64_t halves[2];
+} unw_tdep_vreg_t;
+
+typedef enum
+ {
+ UNW_PPC64_R0,
+ UNW_PPC64_R1, /* called STACK_POINTER in gcc */
+ UNW_PPC64_R2,
+ UNW_PPC64_R3,
+ UNW_PPC64_R4,
+ UNW_PPC64_R5,
+ UNW_PPC64_R6,
+ UNW_PPC64_R7,
+ UNW_PPC64_R8,
+ UNW_PPC64_R9,
+ UNW_PPC64_R10,
+ UNW_PPC64_R11, /* called STATIC_CHAIN in gcc */
+ UNW_PPC64_R12,
+ UNW_PPC64_R13,
+ UNW_PPC64_R14,
+ UNW_PPC64_R15,
+ UNW_PPC64_R16,
+ UNW_PPC64_R17,
+ UNW_PPC64_R18,
+ UNW_PPC64_R19,
+ UNW_PPC64_R20,
+ UNW_PPC64_R21,
+ UNW_PPC64_R22,
+ UNW_PPC64_R23,
+ UNW_PPC64_R24,
+ UNW_PPC64_R25,
+ UNW_PPC64_R26,
+ UNW_PPC64_R27,
+ UNW_PPC64_R28,
+ UNW_PPC64_R29,
+ UNW_PPC64_R30,
+ UNW_PPC64_R31, /* called HARD_FRAME_POINTER in gcc */
+
+ UNW_PPC64_F0 = 32,
+ UNW_PPC64_F1,
+ UNW_PPC64_F2,
+ UNW_PPC64_F3,
+ UNW_PPC64_F4,
+ UNW_PPC64_F5,
+ UNW_PPC64_F6,
+ UNW_PPC64_F7,
+ UNW_PPC64_F8,
+ UNW_PPC64_F9,
+ UNW_PPC64_F10,
+ UNW_PPC64_F11,
+ UNW_PPC64_F12,
+ UNW_PPC64_F13,
+ UNW_PPC64_F14,
+ UNW_PPC64_F15,
+ UNW_PPC64_F16,
+ UNW_PPC64_F17,
+ UNW_PPC64_F18,
+ UNW_PPC64_F19,
+ UNW_PPC64_F20,
+ UNW_PPC64_F21,
+ UNW_PPC64_F22,
+ UNW_PPC64_F23,
+ UNW_PPC64_F24,
+ UNW_PPC64_F25,
+ UNW_PPC64_F26,
+ UNW_PPC64_F27,
+ UNW_PPC64_F28,
+ UNW_PPC64_F29,
+ UNW_PPC64_F30,
+ UNW_PPC64_F31,
+ /* Note that there doesn't appear to be an .eh_frame register column
+ for the FPSCR register. I don't know why this is. Since .eh_frame
+ info is what this implementation uses for unwinding, we have no way
+ to unwind this register, and so we will not expose an FPSCR register
+ number in the libunwind API.
+ */
+
+ UNW_PPC64_LR = 65,
+ UNW_PPC64_CTR = 66,
+ UNW_PPC64_ARG_POINTER = 67,
+
+ UNW_PPC64_CR0 = 68,
+ UNW_PPC64_CR1,
+ UNW_PPC64_CR2,
+ UNW_PPC64_CR3,
+ UNW_PPC64_CR4,
+ /* CR5 .. CR7 are currently unused */
+ UNW_PPC64_CR5,
+ UNW_PPC64_CR6,
+ UNW_PPC64_CR7,
+
+ UNW_PPC64_XER = 76,
+
+ UNW_PPC64_V0 = 77,
+ UNW_PPC64_V1,
+ UNW_PPC64_V2,
+ UNW_PPC64_V3,
+ UNW_PPC64_V4,
+ UNW_PPC64_V5,
+ UNW_PPC64_V6,
+ UNW_PPC64_V7,
+ UNW_PPC64_V8,
+ UNW_PPC64_V9,
+ UNW_PPC64_V10,
+ UNW_PPC64_V11,
+ UNW_PPC64_V12,
+ UNW_PPC64_V13,
+ UNW_PPC64_V14,
+ UNW_PPC64_V15,
+ UNW_PPC64_V16,
+ UNW_PPC64_V17,
+ UNW_PPC64_V18,
+ UNW_PPC64_V19,
+ UNW_PPC64_V20,
+ UNW_PPC64_V21,
+ UNW_PPC64_V22,
+ UNW_PPC64_V23,
+ UNW_PPC64_V24,
+ UNW_PPC64_V25,
+ UNW_PPC64_V26,
+ UNW_PPC64_V27,
+ UNW_PPC64_V28,
+ UNW_PPC64_V29,
+ UNW_PPC64_V30,
+ UNW_PPC64_V31,
+
+ UNW_PPC64_VRSAVE = 109,
+ UNW_PPC64_VSCR = 110,
+ UNW_PPC64_SPE_ACC = 111,
+ UNW_PPC64_SPEFSCR = 112,
+
+ /* frame info (read-only) */
+ UNW_PPC64_FRAME_POINTER,
+ UNW_PPC64_NIP,
+
+
+ UNW_TDEP_LAST_REG = UNW_PPC64_NIP,
+
+ UNW_TDEP_IP = UNW_PPC64_NIP,
+ UNW_TDEP_SP = UNW_PPC64_R1,
+ UNW_TDEP_EH = UNW_PPC64_R12
+ }
+ppc64_regnum_t;
+
+/*
+ * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for
+ * passing parameters to exception handlers.
+ */
+
+#define UNW_TDEP_NUM_EH_REGS 4
+
+typedef struct unw_tdep_save_loc
+ {
+ /* Additional target-dependent info on a save location. */
+ }
+unw_tdep_save_loc_t;
+
+/* On ppc64, we can directly use ucontext_t as the unwind context. */
+typedef ucontext_t unw_tdep_context_t;
+
+/* XXX this is not ideal: an application should not be prevented from
+ using the "getcontext" name just because it's using libunwind. We
+ can't just use __getcontext() either, because that isn't exported
+ by glibc... */
+#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
+
+#include "libunwind-dynamic.h"
+
+typedef struct
+ {
+ /* no ppc64-specific auxiliary proc-info */
+ }
+unw_tdep_proc_info_t;
+
+#include "libunwind-common.h"
+
+#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
+extern int unw_tdep_is_fpreg (int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* LIBUNWIND_H */
diff --git a/include/libunwind-x86.h b/include/libunwind-x86.h
index 8dba027..38664f9 100644
--- a/include/libunwind-x86.h
+++ b/include/libunwind-x86.h
@@ -46,6 +46,7 @@
#define UNW_TDEP_CURSOR_LEN 127
typedef uint32_t unw_word_t;
+typedef int32_t unw_sword_t;
typedef long double unw_tdep_fpreg_t;
@@ -68,7 +69,7 @@
wouldn't be with the DWARF numbering. */
UNW_X86_EAX, /* scratch (exception argument 1) */
UNW_X86_EDX, /* scratch (exception argument 2) */
- UNW_X86_ECX, /* preserved */
+ UNW_X86_ECX, /* scratch */
UNW_X86_EBX, /* preserved */
UNW_X86_ESI, /* preserved */
UNW_X86_EDI, /* preserved */
@@ -159,7 +160,7 @@
typedef struct
{
- unw_dyn_dwarf_fde_info_t dwarf_info;
+ /* no x86-specific auxiliary proc-info */
}
unw_tdep_proc_info_t;
diff --git a/include/libunwind-x86_64.h b/include/libunwind-x86_64.h
index bc8caea..a87b57e 100644
--- a/include/libunwind-x86_64.h
+++ b/include/libunwind-x86_64.h
@@ -48,6 +48,7 @@
#define UNW_TDEP_CURSOR_LEN 127
typedef uint64_t unw_word_t;
+typedef int64_t unw_sword_t;
typedef long double unw_tdep_fpreg_t;
@@ -106,7 +107,7 @@
typedef struct
{
- unw_dyn_dwarf_fde_info_t dwarf_info;
+ /* no x86-64-specific auxiliary proc-info */
}
unw_tdep_proc_info_t;
diff --git a/include/internal.h b/include/libunwind_i.h
similarity index 78%
rename from include/internal.h
rename to include/libunwind_i.h
index 73a1191..17b3cf8 100644
--- a/include/internal.h
+++ b/include/libunwind_i.h
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2001-2005 Hewlett-Packard Co
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -23,8 +24,12 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef internal_h
-#define internal_h
+/* This files contains libunwind-internal definitions which are
+ subject to frequent change and are not to be exposed to
+ libunwind-users. */
+
+#ifndef libunwind_i_h
+#define libunwind_i_h
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -45,6 +50,7 @@
#include <libunwind.h>
#include <pthread.h>
#include <signal.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -65,7 +71,7 @@
# define NORETURN __attribute__((noreturn))
# define ALIAS(name) __attribute__((alias (#name)))
# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-# define ALWAYS_INLINE __attribute__((always_inline))
+# define ALWAYS_INLINE inline __attribute__((always_inline))
# define HIDDEN __attribute__((visibility ("hidden")))
# define PROTECTED __attribute__((visibility ("protected")))
# else
@@ -97,7 +103,7 @@
# define UNW_DEBUG 0
#endif
-#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
/* Make it easy to write thread-safe code which may or may not be
linked against libpthread. The macros below can be used
@@ -157,13 +163,45 @@
# define HAVE_FETCH_AND_ADD1
# endif
#endif
+#define atomic_read(ptr) (*(ptr))
#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
-#define unwi_full_sigmask UNWI_ARCH_OBJ(full_sigmask)
+#define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
-extern sigset_t unwi_full_sigmask;
+/* Type of a mask that can be used to inhibit preemption. At the
+ userlevel, preemption is caused by signals and hence sigset_t is
+ appropriate. In constrast, the Linux kernel uses "unsigned long"
+ to hold the processor "flags" instead. */
+typedef sigset_t intrmask_t;
+
+extern intrmask_t unwi_full_mask;
+
+#define define_lock(name) \
+ pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
+#define lock_init(l) mutex_init (l)
+#define lock_acquire(l,m) \
+do { \
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &(m)); \
+ mutex_lock (l); \
+} while (0)
+#define lock_release(l,m) \
+do { \
+ mutex_unlock (l); \
+ sigprocmask (SIG_SETMASK, &(m), NULL); \
+} while (0)
+
+#define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */
+
+#define GET_MEMORY(mem, size_in_bytes) \
+do { \
+ /* Hopefully, mmap() goes straight through to a system call stub... */ \
+ mem = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, \
+ -1, 0); \
+ if (mem == MAP_FAILED) \
+ mem = NULL; \
+} while (0)
#define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info)
#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info)
@@ -208,7 +246,7 @@
# include <stdio.h>
# define Debug(level,format...) \
do { \
- if (unwi_debug_level > level) \
+ if (unwi_debug_level >= level) \
{ \
int _n = level; \
if (_n > 16) \
@@ -227,7 +265,7 @@
# define dprintf(format...)
#endif
-static inline ALWAYS_INLINE void
+static ALWAYS_INLINE void
print_error (const char *string)
{
write (2, string, strlen (string));
@@ -246,4 +284,10 @@
size_t size; /* (file-) size of the image */
};
-#endif /* internal_h */
+#include "tdep/libunwind_i.h"
+
+#ifndef tdep_get_func_addr
+# define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0)
+#endif
+
+#endif /* libunwind_i_h */
diff --git a/include/mempool.h b/include/mempool.h
index 7d65070..4b55974 100644
--- a/include/mempool.h
+++ b/include/mempool.h
@@ -49,7 +49,7 @@
#include <sys/types.h>
-#include "internal.h"
+#include "libunwind_i.h"
#define sos_alloc(s) UNWI_ARCH_OBJ(_sos_alloc)(s)
#define mempool_init(p,s,r) UNWI_ARCH_OBJ(_mempool_init)(p,s,r)
diff --git a/include/tdep-hppa.h b/include/tdep-hppa.h
deleted file mode 100644
index 0b3d5da..0000000
--- a/include/tdep-hppa.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* libunwind - a platform-independent unwind library
- Copyright (C) 2003-2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-
-This file is part of libunwind.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#ifndef TDEP_HPPA_H
-#define TDEP_HPPA_H
-
-/* Target-dependent definitions that are internal to libunwind but need
- to be shared with target-independent code. */
-
-#include <stdlib.h>
-#include <libunwind.h>
-
-enum hppa_pregnum
- {
- HPPA_NUM_PREGS
- };
-
-struct hppa_loc
- {
- unw_word_t val;
-#ifndef UNW_LOCAL_ONLY
- unw_word_t type; /* see HPPA_LOC_TYPE_* macros. */
-#endif
- };
-
-struct unw_addr_space
- {
- struct unw_accessors acc;
- unw_caching_policy_t caching_policy;
- uint32_t cache_generation;
- unw_word_t dyn_generation; /* see dyn-common.h */
- unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
- };
-
-struct cursor
- {
- unw_addr_space_t as;
- void *as_arg;
-
- /* IP & SP cache: */
- unw_word_t ip;
- unw_word_t sp;
-
- struct hppa_loc ip_loc;
- struct hppa_loc sp_loc;
- };
-
-/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
- tdep_search_unwind_table. */
-#define tdep_search_unwind_table UNW_ARCH_OBJ(search_unwind_table)
-#define tdep_find_proc_info UNW_ARCH_OBJ(find_proc_info)
-#define tdep_put_unwind_info UNW_ARCH_OBJ(put_unwind_info)
-#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
-
-extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
- unw_dyn_info_t *di, unw_proc_info_t *pi,
- int need_unwind_info, void *arg);
-extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
- unw_proc_info_t *pi, int need_unwind_info,
- void *arg);
-extern void tdep_put_unwind_info (unw_addr_space_t as,
- unw_proc_info_t *pi, void *arg);
-extern void *tdep_uc_addr (ucontext_t *uc, int reg);
-
-#endif /* TDEP_HPPA_H */
diff --git a/include/x86_64/dwarf-config.h b/include/tdep-hppa/dwarf-config.h
similarity index 78%
copy from include/x86_64/dwarf-config.h
copy to include/tdep-hppa/dwarf-config.h
index 1eb1e73..29f9eee 100644
--- a/include/x86_64/dwarf-config.h
+++ b/include/tdep-hppa/dwarf-config.h
@@ -1,9 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
- Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
-
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
@@ -25,19 +23,20 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/* copy of include/x86/dwarf-config.h, modified slightly for x86-64
- some consolidation is possible here */
-
#ifndef dwarf_config_h
#define dwarf_config_h
-/* XXX need to verify if this value is correct */
-#define DWARF_NUM_PRESERVED_REGS 17
+/* See DWARF_FRAME_REGNUM() macro in gcc/config/pa/pa32-regs.h: */
+#define dwarf_to_unw_regnum(reg) \
+ (((reg) < DWARF_NUM_PRESERVED_REGS) ? (reg) : 0)
-#define DWARF_REGNUM_MAP_LENGTH 17
+/* This matches the value used by GCC (see
+ gcc/config/pa/pa32-regs.h:FIRST_PSEUDO_REGISTER), which leaves
+ plenty of room for expansion. */
+#define DWARF_NUM_PRESERVED_REGS 89
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
-#define dwarf_is_big_endian(addr_space) 0
+#define dwarf_is_big_endian(addr_space) 1
/* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */
diff --git a/src/hppa/Gget_reg.c b/include/tdep-hppa/jmpbuf.h
similarity index 80%
copy from src/hppa/Gget_reg.c
copy to include/tdep-hppa/jmpbuf.h
index 4553f65..6735b21 100644
--- a/src/hppa/Gget_reg.c
+++ b/include/tdep-hppa/jmpbuf.h
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,12 +23,11 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+/* Use glibc's jump-buffer indices; NPTL peeks at SP: */
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#ifndef JB_SP
+# define JB_SP 19
+#endif
+#define JB_RP 20
+#define JB_MASK_SAVED 21
+#define JB_MASK 22
diff --git a/include/tdep-x86.h b/include/tdep-hppa/libunwind_i.h
similarity index 95%
rename from include/tdep-x86.h
rename to include/tdep-hppa/libunwind_i.h
index ee2ac5c..52cfc56 100644
--- a/include/tdep-x86.h
+++ b/include/tdep-hppa/libunwind_i.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,8 +23,8 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef TDEP_X86_H
-#define TDEP_X86_H
+#ifndef HPPA_LIBUNWIND_I_H
+#define HPPA_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
@@ -56,9 +56,8 @@
stored: */
enum
{
- X86_SCF_NONE, /* no signal frame encountered */
- X86_SCF_LINUX_SIGFRAME, /* classic x86 sigcontext */
- X86_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
+ HPPA_SCF_NONE, /* no signal frame encountered */
+ HPPA_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
}
sigcontext_format;
unw_word_t sigcontext_addr;
@@ -70,6 +69,7 @@
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
+# define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
@@ -241,7 +241,7 @@
#define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip)
-#define tdep_big_endian(as) 0
+#define tdep_big_endian(as) 1
extern int tdep_needs_initialization;
@@ -257,4 +257,4 @@
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
-#endif /* TDEP_X86_H */
+#endif /* HPPA_LIBUNWIND_I_H */
diff --git a/include/ia64/jmpbuf.h b/include/tdep-ia64/jmpbuf.h
similarity index 100%
rename from include/ia64/jmpbuf.h
rename to include/tdep-ia64/jmpbuf.h
diff --git a/include/tdep-ia64.h b/include/tdep-ia64/libunwind_i.h
similarity index 94%
rename from include/tdep-ia64.h
rename to include/tdep-ia64/libunwind_i.h
index 0a3bec7..552c949 100644
--- a/include/tdep-ia64.h
+++ b/include/tdep-ia64/libunwind_i.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
+ Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,14 +23,12 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef TDEP_IA64_H
-#define TDEP_IA64_H
+#ifndef IA64_LIBUNWIND_I_H
+#define IA64_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
-#include <libunwind.h>
-
#include "elf64.h"
#include "mempool.h"
@@ -77,7 +75,7 @@
#endif /* !UNW_LOCAL_ONLY */
-#include "ia64/script.h"
+#include "script.h"
#define ABI_UNKNOWN 0
#define ABI_LINUX 1
@@ -132,6 +130,7 @@
unw_word_t sp; /* stack pointer value */
unw_word_t psp; /* previous sp value */
ia64_loc_t cfm_loc; /* cfm save location (or NULL) */
+ ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */
ia64_loc_t loc[IA64_NUM_PREGS];
unw_word_t eh_args[4]; /* exception handler arguments */
@@ -253,4 +252,10 @@
extern struct ia64_global_unwind_state unw;
-#endif /* TDEP_IA64_H */
+/* In user-level, we have no reasonable way of determining the base of
+ an arbitrary backing-store. We default to half the
+ address-space. */
+#define rbs_get_base(c,bspstore,rbs_basep) \
+ (*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0)
+
+#endif /* IA64_LIBUNWIND_I_H */
diff --git a/include/ia64/rse.h b/include/tdep-ia64/rse.h
similarity index 65%
rename from include/ia64/rse.h
rename to include/tdep-ia64/rse.h
index 928f1a6..c5fe4b5 100644
--- a/include/ia64/rse.h
+++ b/include/tdep-ia64/rse.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1998, 1999, 2002, 2003 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* Register stack engine related helper functions. This file may be
@@ -10,12 +10,10 @@
#ifndef RSE_H
#define RSE_H
-#include "internal.h"
-
-#include <inttypes.h>
+#include <libunwind.h>
static inline uint64_t
-ia64_rse_slot_num (uint64_t addr)
+rse_slot_num (uint64_t addr)
{
return (addr >> 3) & 0x3f;
}
@@ -24,9 +22,9 @@
* Return TRUE if ADDR is the address of an RNAT slot.
*/
static inline uint64_t
-ia64_rse_is_rnat_slot (uint64_t addr)
+rse_is_rnat_slot (uint64_t addr)
{
- return ia64_rse_slot_num (addr) == 0x3f;
+ return rse_slot_num (addr) == 0x3f;
}
/*
@@ -34,22 +32,22 @@
* address SLOT_ADDR.
*/
static inline uint64_t
-ia64_rse_rnat_addr (uint64_t slot_addr)
+rse_rnat_addr (uint64_t slot_addr)
{
return slot_addr | (0x3f << 3);
}
/*
- * Calcuate the number of registers in the dirty partition starting at
+ * Calculate the number of registers in the dirty partition starting at
* BSPSTORE and ending at BSP. This isn't simply (BSP-BSPSTORE)/8
* because every 64th slot stores ar.rnat.
*/
static inline uint64_t
-ia64_rse_num_regs (uint64_t bspstore, uint64_t bsp)
+rse_num_regs (uint64_t bspstore, uint64_t bsp)
{
uint64_t slots = (bsp - bspstore) >> 3;
- return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40;
+ return slots - (rse_slot_num(bspstore) + slots)/0x40;
}
/*
@@ -57,9 +55,9 @@
* registers, calculate ar.bsp.
*/
static inline uint64_t
-ia64_rse_skip_regs (uint64_t addr, long num_regs)
+rse_skip_regs (uint64_t addr, long num_regs)
{
- long delta = ia64_rse_slot_num(addr) + num_regs;
+ long delta = rse_slot_num(addr) + num_regs;
if (num_regs < 0)
delta -= 0x3e;
diff --git a/include/ia64/script.h b/include/tdep-ia64/script.h
similarity index 94%
rename from include/ia64/script.h
rename to include/tdep-ia64/script.h
index 646ca1a..48a9fe5 100644
--- a/include/ia64/script.h
+++ b/include/tdep-ia64/script.h
@@ -76,8 +76,10 @@
struct ia64_script buckets[IA64_UNW_CACHE_SIZE];
};
-#define ia64_get_cached_proc_info UNW_OBJ(ia64_get_cached_proc_info)
+#define ia64_cache_proc_info UNW_OBJ(cache_proc_info)
+#define ia64_get_cached_proc_info UNW_OBJ(get_cached_proc_info)
struct cursor; /* forward declaration */
+extern int ia64_cache_proc_info (struct cursor *c);
extern int ia64_get_cached_proc_info (struct cursor *c);
diff --git a/include/x86_64/dwarf-config.h b/include/tdep-ppc32/dwarf-config.h
similarity index 74%
copy from include/x86_64/dwarf-config.h
copy to include/tdep-ppc32/dwarf-config.h
index 1eb1e73..e2676a8 100644
--- a/include/x86_64/dwarf-config.h
+++ b/include/tdep-ppc32/dwarf-config.h
@@ -1,8 +1,12 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
- Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
This file is part of libunwind.
@@ -25,19 +29,16 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/* copy of include/x86/dwarf-config.h, modified slightly for x86-64
- some consolidation is possible here */
-
#ifndef dwarf_config_h
#define dwarf_config_h
-/* XXX need to verify if this value is correct */
-#define DWARF_NUM_PRESERVED_REGS 17
+/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */
+#define DWARF_NUM_PRESERVED_REGS 115
-#define DWARF_REGNUM_MAP_LENGTH 17
+#define DWARF_REGNUM_MAP_LENGTH 115
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
-#define dwarf_is_big_endian(addr_space) 0
+#define dwarf_is_big_endian(addr_space) 1
/* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */
diff --git a/src/hppa/Gget_reg.c b/include/tdep-ppc32/jmpbuf.h
similarity index 68%
copy from src/hppa/Gget_reg.c
copy to include/tdep-ppc32/jmpbuf.h
index 4553f65..3780d5b 100644
--- a/src/hppa/Gget_reg.c
+++ b/include/tdep-ppc32/jmpbuf.h
@@ -1,6 +1,12 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
This file is part of libunwind.
@@ -23,12 +29,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+/* Use glibc's jump-buffer indices; NPTL peeks at SP: */
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#define JB_SP 6
+#define JB_RP 7
+#define JB_MASK_SAVED 8
+#define JB_MASK 9
diff --git a/include/tdep-x86.h b/include/tdep-ppc32/libunwind_i.h
similarity index 61%
copy from include/tdep-x86.h
copy to include/tdep-ppc32/libunwind_i.h
index ee2ac5c..2a9f9c1 100644
--- a/include/tdep-x86.h
+++ b/include/tdep-ppc32/libunwind_i.h
@@ -1,6 +1,12 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
This file is part of libunwind.
@@ -23,8 +29,8 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef TDEP_X86_H
-#define TDEP_X86_H
+#ifndef PPC32_LIBUNWIND_I_H
+#define PPC32_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
@@ -33,36 +39,38 @@
#include <libunwind.h>
#include "elf32.h"
+#include "mempool.h"
#include "dwarf.h"
struct unw_addr_space
- {
- struct unw_accessors acc;
- unw_caching_policy_t caching_policy;
+{
+ struct unw_accessors acc;
+ unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
- AO_t cache_generation;
+ AO_t cache_generation;
#else
- uint32_t cache_generation;
+ uint32_t cache_generation;
#endif
- unw_word_t dyn_generation; /* see dyn-common.h */
- unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
- };
+ unw_word_t dyn_generation; /* see dyn-common.h */
+ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
+ struct dwarf_rs_cache global_cache;
+ int validate;
+};
struct cursor
- {
- struct dwarf_cursor dwarf; /* must be first */
+{
+ struct dwarf_cursor dwarf; /* must be first */
- /* Format of sigcontext structure and address at which it is
- stored: */
- enum
- {
- X86_SCF_NONE, /* no signal frame encountered */
- X86_SCF_LINUX_SIGFRAME, /* classic x86 sigcontext */
- X86_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
- }
- sigcontext_format;
- unw_word_t sigcontext_addr;
- };
+ /* Format of sigcontext structure and address at which it is
+ stored: */
+ enum
+ {
+ PPC_SCF_NONE, /* no signal frame encountered */
+ PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
+ }
+ sigcontext_format;
+ unw_word_t sigcontext_addr;
+};
#define DWARF_GET_LOC(l) ((l).val)
@@ -70,110 +78,132 @@
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
+# define DWARF_IS_REG_LOC(l) 0
+# define DWARF_IS_FP_LOC(l) 0
+# define DWARF_IS_V_LOC(l) 0
+# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
-# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
-
-static inline int
-dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val;
- return 0;
-}
-
-static inline int
-dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *val = *(unw_word_t *) DWARF_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *(unw_word_t *) DWARF_GET_LOC (loc) = val;
- return 0;
-}
-
+# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
+ tdep_uc_addr((c)->as_arg, (r)), 0))
#else /* !UNW_LOCAL_ONLY */
+
# define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1)
+# define DWARF_LOC_TYPE_V (1 << 2)
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
-# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
+# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
+# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP))
+# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
+ | DWARF_LOC_TYPE_V))
+
+#endif /* !UNW_LOCAL_ONLY */
static inline int
-dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
+dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
{
- char *valp = (char *) &val;
+ unw_word_t *valp = (unw_word_t *) val;
unw_word_t addr;
int ret;
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
+ assert (DWARF_IS_V_LOC (loc));
+ assert (!DWARF_IS_FP_LOC (loc));
+
+ if (DWARF_IS_REG_LOC (loc))
+ return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
+ val, 0, c->as_arg);
+
+ addr = DWARF_GET_LOC (loc);
+
+ if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
+ 0, c->as_arg)) < 0)
+ return ret;
+
+ return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg);
+}
+
+static inline int
+dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
+{
+ unw_word_t *valp = (unw_word_t *) & val;
+ unw_word_t addr;
+ int ret;
+
+ if (DWARF_IS_NULL_LOC (loc))
+ return -UNW_EBADREG;
+
+ assert (DWARF_IS_V_LOC (loc));
+ assert (!DWARF_IS_FP_LOC (loc));
+
+ if (DWARF_IS_REG_LOC (loc))
+ return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
+ &val, 1, c->as_arg);
+
+ addr = DWARF_GET_LOC (loc);
+ if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
+ 1, c->as_arg)) < 0)
+ return ret;
+
+ return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg);
+}
+
+static inline int
+dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
+{
+ unw_word_t *valp = (unw_word_t *) val;
+ unw_word_t addr;
+
+ if (DWARF_IS_NULL_LOC (loc))
+ return -UNW_EBADREG;
+
+ assert (DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
+
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc);
- if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
- 0, c->as_arg)) < 0)
- return ret;
+ return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg);
- return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
- c->as_arg);
}
static inline int
dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
{
- char *valp = (char *) &val;
+ unw_word_t *valp = (unw_word_t *) & val;
unw_word_t addr;
- int ret;
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
+ assert (DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
+
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc);
- if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
- 1, c->as_arg)) < 0)
- return ret;
- return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
- 1, c->as_arg);
+ return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg);
}
static inline int
-dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
+dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val)
{
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
@@ -183,6 +213,7 @@
suppose it could happen with MMX registers, but does it really
happen? */
assert (!DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
@@ -203,6 +234,7 @@
suppose it could happen with MMX registers, but does it really
happen? */
assert (!DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
@@ -212,7 +244,7 @@
1, c->as_arg);
}
-#endif /* !UNW_LOCAL_ONLY */
+
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
#define tdep_init UNW_OBJ(init)
@@ -223,38 +255,45 @@
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg)
+#define tdep_get_func_addr UNW_OBJ(get_func_addr)
#ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- dwarf_put_unwind_info((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ dwarf_put_unwind_info((as), (pi), (arg))
#else
# define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif
+extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip,
+ int need_unwind_info);
+
#define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip)
-#define tdep_big_endian(as) 0
+#define tdep_big_endian(as) 1
extern int tdep_needs_initialization;
extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
- unw_dyn_info_t *di, unw_proc_info_t *pi,
+ unw_dyn_info_t * di,
+ unw_proc_info_t * pi,
int need_unwind_info, void *arg);
-extern void *tdep_uc_addr (ucontext_t *uc, int reg);
+extern void *tdep_uc_addr (ucontext_t * uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
- unw_word_t *valp, int write);
+ unw_word_t * valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
- unw_fpreg_t *valp, int write);
+ unw_fpreg_t * valp, int write);
+extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr,
+ unw_word_t *entry_point);
-#endif /* TDEP_X86_H */
+#endif /* PPC64_LIBUNWIND_I_H */
diff --git a/include/x86_64/dwarf-config.h b/include/tdep-ppc64/dwarf-config.h
similarity index 74%
copy from include/x86_64/dwarf-config.h
copy to include/tdep-ppc64/dwarf-config.h
index 1eb1e73..e2676a8 100644
--- a/include/x86_64/dwarf-config.h
+++ b/include/tdep-ppc64/dwarf-config.h
@@ -1,8 +1,12 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
- Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
This file is part of libunwind.
@@ -25,19 +29,16 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/* copy of include/x86/dwarf-config.h, modified slightly for x86-64
- some consolidation is possible here */
-
#ifndef dwarf_config_h
#define dwarf_config_h
-/* XXX need to verify if this value is correct */
-#define DWARF_NUM_PRESERVED_REGS 17
+/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */
+#define DWARF_NUM_PRESERVED_REGS 115
-#define DWARF_REGNUM_MAP_LENGTH 17
+#define DWARF_REGNUM_MAP_LENGTH 115
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
-#define dwarf_is_big_endian(addr_space) 0
+#define dwarf_is_big_endian(addr_space) 1
/* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */
diff --git a/src/hppa/Gget_reg.c b/include/tdep-ppc64/jmpbuf.h
similarity index 68%
copy from src/hppa/Gget_reg.c
copy to include/tdep-ppc64/jmpbuf.h
index 4553f65..3780d5b 100644
--- a/src/hppa/Gget_reg.c
+++ b/include/tdep-ppc64/jmpbuf.h
@@ -1,6 +1,12 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
This file is part of libunwind.
@@ -23,12 +29,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+/* Use glibc's jump-buffer indices; NPTL peeks at SP: */
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#define JB_SP 6
+#define JB_RP 7
+#define JB_MASK_SAVED 8
+#define JB_MASK 9
diff --git a/include/tdep-x86.h b/include/tdep-ppc64/libunwind_i.h
similarity index 61%
copy from include/tdep-x86.h
copy to include/tdep-ppc64/libunwind_i.h
index ee2ac5c..8b5c4de 100644
--- a/include/tdep-x86.h
+++ b/include/tdep-ppc64/libunwind_i.h
@@ -1,6 +1,12 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+ Copied from libunwind-x86_64.h, modified slightly for building
+ frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+ Will be replaced when libunwind is ready on ppc64 platform.
This file is part of libunwind.
@@ -23,8 +29,8 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef TDEP_X86_H
-#define TDEP_X86_H
+#ifndef PPC64_LIBUNWIND_I_H
+#define PPC64_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
@@ -32,37 +38,39 @@
#include <stdlib.h>
#include <libunwind.h>
-#include "elf32.h"
+#include "elf64.h"
+#include "mempool.h"
#include "dwarf.h"
struct unw_addr_space
- {
- struct unw_accessors acc;
- unw_caching_policy_t caching_policy;
+{
+ struct unw_accessors acc;
+ unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
- AO_t cache_generation;
+ AO_t cache_generation;
#else
- uint32_t cache_generation;
+ uint32_t cache_generation;
#endif
- unw_word_t dyn_generation; /* see dyn-common.h */
- unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
- };
+ unw_word_t dyn_generation; /* see dyn-common.h */
+ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
+ struct dwarf_rs_cache global_cache;
+ int validate;
+};
struct cursor
- {
- struct dwarf_cursor dwarf; /* must be first */
+{
+ struct dwarf_cursor dwarf; /* must be first */
- /* Format of sigcontext structure and address at which it is
- stored: */
- enum
- {
- X86_SCF_NONE, /* no signal frame encountered */
- X86_SCF_LINUX_SIGFRAME, /* classic x86 sigcontext */
- X86_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
- }
- sigcontext_format;
- unw_word_t sigcontext_addr;
- };
+ /* Format of sigcontext structure and address at which it is
+ stored: */
+ enum
+ {
+ PPC_SCF_NONE, /* no signal frame encountered */
+ PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
+ }
+ sigcontext_format;
+ unw_word_t sigcontext_addr;
+};
#define DWARF_GET_LOC(l) ((l).val)
@@ -70,110 +78,132 @@
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
+# define DWARF_IS_REG_LOC(l) 0
+# define DWARF_IS_FP_LOC(l) 0
+# define DWARF_IS_V_LOC(l) 0
+# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
-# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
-
-static inline int
-dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val;
- return 0;
-}
-
-static inline int
-dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *val = *(unw_word_t *) DWARF_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *(unw_word_t *) DWARF_GET_LOC (loc) = val;
- return 0;
-}
-
+# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
+ tdep_uc_addr((c)->as_arg, (r)), 0))
#else /* !UNW_LOCAL_ONLY */
+
# define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1)
+# define DWARF_LOC_TYPE_V (1 << 2)
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
-# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
+# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
+# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP))
+# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
+ | DWARF_LOC_TYPE_V))
+
+#endif /* !UNW_LOCAL_ONLY */
static inline int
-dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
+dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
{
- char *valp = (char *) &val;
+ unw_word_t *valp = (unw_word_t *) val;
unw_word_t addr;
int ret;
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
+ assert (DWARF_IS_V_LOC (loc));
+ assert (!DWARF_IS_FP_LOC (loc));
+
+ if (DWARF_IS_REG_LOC (loc))
+ return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
+ val, 0, c->as_arg);
+
+ addr = DWARF_GET_LOC (loc);
+
+ if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
+ 0, c->as_arg)) < 0)
+ return ret;
+
+ return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg);
+}
+
+static inline int
+dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
+{
+ unw_word_t *valp = (unw_word_t *) & val;
+ unw_word_t addr;
+ int ret;
+
+ if (DWARF_IS_NULL_LOC (loc))
+ return -UNW_EBADREG;
+
+ assert (DWARF_IS_V_LOC (loc));
+ assert (!DWARF_IS_FP_LOC (loc));
+
+ if (DWARF_IS_REG_LOC (loc))
+ return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
+ &val, 1, c->as_arg);
+
+ addr = DWARF_GET_LOC (loc);
+ if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
+ 1, c->as_arg)) < 0)
+ return ret;
+
+ return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg);
+}
+
+static inline int
+dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
+{
+ unw_word_t *valp = (unw_word_t *) val;
+ unw_word_t addr;
+
+ if (DWARF_IS_NULL_LOC (loc))
+ return -UNW_EBADREG;
+
+ assert (DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
+
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc);
- if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
- 0, c->as_arg)) < 0)
- return ret;
+ return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg);
- return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
- c->as_arg);
}
static inline int
dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
{
- char *valp = (char *) &val;
+ unw_word_t *valp = (unw_word_t *) & val;
unw_word_t addr;
- int ret;
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
+ assert (DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
+
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc);
- if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
- 1, c->as_arg)) < 0)
- return ret;
- return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
- 1, c->as_arg);
+ return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg);
}
static inline int
-dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
+dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val)
{
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
@@ -183,6 +213,7 @@
suppose it could happen with MMX registers, but does it really
happen? */
assert (!DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
@@ -203,6 +234,7 @@
suppose it could happen with MMX registers, but does it really
happen? */
assert (!DWARF_IS_FP_LOC (loc));
+ assert (!DWARF_IS_V_LOC (loc));
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
@@ -212,7 +244,7 @@
1, c->as_arg);
}
-#endif /* !UNW_LOCAL_ONLY */
+
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
#define tdep_init UNW_OBJ(init)
@@ -223,38 +255,45 @@
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg)
+#define tdep_get_func_addr UNW_OBJ(get_func_addr)
#ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- dwarf_put_unwind_info((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ dwarf_put_unwind_info((as), (pi), (arg))
#else
# define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif
+extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip,
+ int need_unwind_info);
+
#define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip)
-#define tdep_big_endian(as) 0
+#define tdep_big_endian(as) 1
extern int tdep_needs_initialization;
extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
- unw_dyn_info_t *di, unw_proc_info_t *pi,
+ unw_dyn_info_t * di,
+ unw_proc_info_t * pi,
int need_unwind_info, void *arg);
-extern void *tdep_uc_addr (ucontext_t *uc, int reg);
+extern void *tdep_uc_addr (ucontext_t * uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
- unw_word_t *valp, int write);
+ unw_word_t * valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
- unw_fpreg_t *valp, int write);
+ unw_fpreg_t * valp, int write);
+extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr,
+ unw_word_t *entry_point);
-#endif /* TDEP_X86_H */
+#endif /* PPC64_LIBUNWIND_I_H */
diff --git a/include/x86/dwarf-config.h b/include/tdep-x86/dwarf-config.h
similarity index 92%
rename from include/x86/dwarf-config.h
rename to include/tdep-x86/dwarf-config.h
index b428bc9..898ab79 100644
--- a/include/x86/dwarf-config.h
+++ b/include/tdep-x86/dwarf-config.h
@@ -26,8 +26,9 @@
#ifndef dwarf_config_h
#define dwarf_config_h
-/* This matches the value used by GCC, which leaves plenty of room for
- expansion. */
+/* This matches the value used by GCC (see
+ gcc/config/i386.h:DWARF_FRAME_REGISTERS), which leaves plenty of
+ room for expansion. */
#define DWARF_NUM_PRESERVED_REGS 17
#define DWARF_REGNUM_MAP_LENGTH 19
diff --git a/src/hppa/Gget_reg.c b/include/tdep-x86/jmpbuf.h
similarity index 80%
copy from src/hppa/Gget_reg.c
copy to include/tdep-x86/jmpbuf.h
index 4553f65..a0eb072 100644
--- a/src/hppa/Gget_reg.c
+++ b/include/tdep-x86/jmpbuf.h
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,12 +23,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+/* Use glibc's jump-buffer indices; NPTL peeks at SP: */
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#define JB_SP 4
+#define JB_RP 5
+#define JB_MASK_SAVED 6
+#define JB_MASK 7
diff --git a/include/tdep-x86.h b/include/tdep-x86/libunwind_i.h
similarity index 94%
copy from include/tdep-x86.h
copy to include/tdep-x86/libunwind_i.h
index ee2ac5c..1a43882 100644
--- a/include/tdep-x86.h
+++ b/include/tdep-x86/libunwind_i.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,8 +23,8 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef TDEP_X86_H
-#define TDEP_X86_H
+#ifndef X86_LIBUNWIND_I_H
+#define X86_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
@@ -33,6 +33,7 @@
#include <libunwind.h>
#include "elf32.h"
+#include "mempool.h"
#include "dwarf.h"
struct unw_addr_space
@@ -46,6 +47,7 @@
#endif
unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
+ struct dwarf_rs_cache global_cache;
};
struct cursor
@@ -70,6 +72,7 @@
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
+# define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
@@ -228,14 +231,14 @@
# define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- dwarf_put_unwind_info((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ dwarf_put_unwind_info((as), (pi), (arg))
#else
# define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif
#define tdep_get_as(c) ((c)->dwarf.as)
@@ -257,4 +260,4 @@
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
-#endif /* TDEP_X86_H */
+#endif /* X86_LIBUNWIND_I_H */
diff --git a/include/x86_64/dwarf-config.h b/include/tdep-x86_64/dwarf-config.h
similarity index 92%
rename from include/x86_64/dwarf-config.h
rename to include/tdep-x86_64/dwarf-config.h
index 1eb1e73..8023f36 100644
--- a/include/x86_64/dwarf-config.h
+++ b/include/tdep-x86_64/dwarf-config.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@@ -25,7 +25,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/* copy of include/x86/dwarf-config.h, modified slightly for x86-64
+/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64
some consolidation is possible here */
#ifndef dwarf_config_h
diff --git a/src/hppa/Gget_reg.c b/include/tdep-x86_64/jmpbuf.h
similarity index 80%
rename from src/hppa/Gget_reg.c
rename to include/tdep-x86_64/jmpbuf.h
index 4553f65..9220068 100644
--- a/src/hppa/Gget_reg.c
+++ b/include/tdep-x86_64/jmpbuf.h
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,12 +23,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+/* Use glibc's jump-buffer indices; NPTL peeks at SP: */
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#define JB_SP 6
+#define JB_RP 7
+#define JB_MASK_SAVED 8
+#define JB_MASK 9
diff --git a/include/tdep-x86_64.h b/include/tdep-x86_64/libunwind_i.h
similarity index 81%
rename from include/tdep-x86_64.h
rename to include/tdep-x86_64/libunwind_i.h
index e7a3b0b..04a3c37 100644
--- a/include/tdep-x86_64.h
+++ b/include/tdep-x86_64/libunwind_i.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@@ -25,8 +25,8 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef TDEP_X86_64_H
-#define TDEP_X86_64_H
+#ifndef X86_64_LIBUNWIND_I_H
+#define X86_64_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
@@ -35,15 +35,22 @@
#include <libunwind.h>
#include "elf64.h"
+#include "mempool.h"
#include "dwarf.h"
struct unw_addr_space
{
struct unw_accessors acc;
unw_caching_policy_t caching_policy;
+#ifdef HAVE_ATOMIC_OPS_H
+ AO_t cache_generation;
+#else
uint32_t cache_generation;
+#endif
unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
+ struct dwarf_rs_cache global_cache;
+ int validate;
};
struct cursor
@@ -67,49 +74,14 @@
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
+# define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
-
-static inline int
-dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val;
- return 0;
-}
-
-static inline int
-dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *val = *(unw_word_t *) DWARF_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
-{
- if (!DWARF_GET_LOC (loc))
- return -1;
- *(unw_word_t *) DWARF_GET_LOC (loc) = val;
- return 0;
-}
-
#else /* !UNW_LOCAL_ONLY */
+
# define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
@@ -123,13 +95,14 @@
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP))
+#endif /* !UNW_LOCAL_ONLY */
+
static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
{
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
-//# warning fix me
abort ();
}
@@ -139,7 +112,6 @@
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
-//# warning fix me
abort ();
}
@@ -149,10 +121,6 @@
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
- if (DWARF_IS_FP_LOC (loc))
-//# warning fix me
- abort ();
-
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg);
@@ -167,10 +135,6 @@
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
- if (DWARF_IS_FP_LOC (loc))
-//# warning fix me
- abort ();
-
if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg);
@@ -179,8 +143,6 @@
1, c->as_arg);
}
-#endif /* !UNW_LOCAL_ONLY */
-
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
#define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
@@ -195,14 +157,14 @@
# define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- dwarf_put_unwind_info((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ dwarf_put_unwind_info((as), (pi), (arg))
#else
# define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg)
-# define tdep_put_unwind_info(c,pi) \
- (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg)
+# define tdep_put_unwind_info(as,pi,arg) \
+ (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif
#define tdep_get_as(c) ((c)->dwarf.as)
@@ -224,4 +186,4 @@
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
-#endif /* TDEP_X86_64_H */
+#endif /* X86_64_LIBUNWIND_I_H */
diff --git a/scripts/kernel-diff.sh b/scripts/kernel-diff.sh
new file mode 100755
index 0000000..459194e
--- /dev/null
+++ b/scripts/kernel-diff.sh
@@ -0,0 +1,10 @@
+kdir=${1:-../kernel}
+scriptdir=$(dirname $0)
+udir=$(dirname $scriptdir)
+cat $scriptdir/kernel-files.txt | \
+(while read l r; do
+ left=$(eval echo $l)
+ right=$(eval echo $r)
+# echo $left $right
+ diff -up $left $right
+done)
diff --git a/scripts/kernel-files.txt b/scripts/kernel-files.txt
new file mode 100644
index 0000000..d79e453
--- /dev/null
+++ b/scripts/kernel-files.txt
@@ -0,0 +1,19 @@
+$udir/include/tdep-ia64/rse.h $kdir/arch/ia64/unwind/rse.h
+$udir/src/ia64/Ginit_local.c $kdir/arch/ia64/unwind/init_local.c
+$udir/src/ia64/Gis_signal_frame.c $kdir/arch/ia64/unwind/is_signal_frame.c
+$udir/src/ia64/Gparser.c $kdir/arch/ia64/unwind/parser.c
+$udir/src/ia64/Grbs.c $kdir/arch/ia64/unwind/rbs.c
+$udir/src/ia64/Gregs.c $kdir/arch/ia64/unwind/regs.c
+$udir/src/ia64/Gscript.c $kdir/arch/ia64/unwind/script.c
+$udir/src/ia64/Gstep.c $kdir/arch/ia64/unwind/step.c
+$udir/src/ia64/init.h $kdir/arch/ia64/unwind/init.h
+$udir/src/ia64/offsets.h $kdir/arch/ia64/unwind/offsets.h
+$udir/src/ia64/regname.c $kdir/arch/ia64/unwind/regname.c
+$udir/src/ia64/regs.h $kdir/arch/ia64/unwind/regs.h
+$udir/src/ia64/unwind_decoder.h $kdir/arch/ia64/unwind/unwind_decoder.h
+$udir/src/mi/Gget_fpreg.c $kdir/unwind/get_fpreg.c
+$udir/src/mi/Gget_reg.c $kdir/unwind/get_reg.c
+$udir/src/mi/Gset_fpreg.c $kdir/unwind/set_fpreg.c
+$udir/src/mi/Gset_reg.c $kdir/unwind/set_reg.c
+$udir/src/mi/flush_cache.c $kdir/unwind/flush_cache.c
+$udir/src/mi/mempool.c $kdir/unwind/mempool.c
diff --git a/scripts/make-L-files b/scripts/make-L-files
old mode 100644
new mode 100755
diff --git a/src/Makefile.am b/src/Makefile.am
index 1b7203d..88bb20b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,12 +1,9 @@
SOVERSION=7:0:0 # See comments at end of file.
SETJMP_SO_VERSION=0:0:0
#
-# Don't link with standard libraries, because those may mention
-# libunwind already.
+# Don't link with start-files since we don't use any constructors/destructors:
#
-COMMON_SO_LDFLAGS = -XCClinker -nostartfiles \
- -XCClinker -nostdlib \
- $(LDFLAGS_STATIC_LIBCXA)
+COMMON_SO_LDFLAGS = -XCClinker -nostartfiles
if REMOTE_ONLY
LIBRARIES_cdep =
@@ -20,6 +17,7 @@
### libunwind-ptrace:
libunwind_ptrace_a_SOURCES = \
+ ptrace/_UPT_elf.c \
ptrace/_UPT_internal.h \
ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c \
ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c \
@@ -32,14 +30,16 @@
libunwind_setjmp_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \
-version-info $(SETJMP_SO_VERSION)
libunwind_setjmp_la_LIBADD = libunwind-$(arch).la -lc
-libunwind_setjmp_la_SOURCES_common = longjmp.c siglongjmp.c
+libunwind_setjmp_la_SOURCES_common = setjmp/setjmp_i.h \
+ setjmp/longjmp.c \
+ setjmp/siglongjmp.c
libunwind_setjmp_la_SOURCES_ia64 = ia64/setjmp.S ia64/sigsetjmp.S \
ia64/longjmp.S ia64/siglongjmp.S
-libunwind_setjmp_la_SOURCES_hppa = setjmp.c sigsetjmp.c \
- hppa/siglongjmp.S
-libunwind_setjmp_la_SOURCES_x86 = setjmp.c sigsetjmp.c x86/siglongjmp.S
-libunwind_setjmp_la_SOURCES_x86_64 = setjmp.c sigsetjmp.c \
- x86_64/siglongjmp.S
+libunwind_setjmp_la_SOURCES_hppa = hppa/siglongjmp.S
+libunwind_setjmp_la_SOURCES_x86 = x86/longjmp.S x86/siglongjmp.S
+libunwind_setjmp_la_SOURCES_x86_64 = x86_64/longjmp.S x86_64/siglongjmp.S
+libunwind_setjmp_la_SOURCES_ppc64 = ppc/longjmp.S ppc/siglongjmp.S
+libunwind_setjmp_la_SOURCES_ppc32 = ppc/longjmp.S ppc/siglongjmp.S
### libunwind:
@@ -86,7 +86,6 @@
libunwind_la_SOURCES_os_hpux = os-hpux.c
dwarf_SOURCES_common = \
- dwarf/dwarf-eh.h \
dwarf/global.c
dwarf_SOURCES_local = \
@@ -97,6 +96,7 @@
# The list of files that go both into libunwind and libunwind-ia64:
libunwind_la_SOURCES_ia64_common = $(libunwind_la_SOURCES_common) \
+ elf64.c elf64.h \
ia64/init.h ia64/offsets.h ia64/regs.h \
ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h \
ia64/regname.c
@@ -105,8 +105,6 @@
libunwind_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \
$(libunwind_la_SOURCES_local) \
\
- elf64.c elf64.h \
- \
ia64/dyn_info_list.S ia64/getcontext.S \
\
ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \
@@ -124,26 +122,44 @@
ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c ia64/Gstep.c \
ia64/Gtables.c
-libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_common) \
- hppa/global.c hppa/tables.c \
- hppa/init.h hppa/unwind_i.h \
- \
- hppa/Gget_reg.c hppa/Gget_proc_name.c hppa/Ginit.c hppa/Ginit_local.c \
- hppa/Gget_proc_info.c hppa/Gregs.c hppa/Gstep.c \
- \
- hppa/Lget_reg.c hppa/Lget_proc_name.c hppa/Linit.c hppa/Linit_local.c \
- hppa/Lget_proc_info.c hppa/Lregs.c hppa/Lstep.c
+# The list of files that go both into libunwind and libunwind-hppa:
+libunwind_la_SOURCES_hppa_common = $(libunwind_la_SOURCES_common) \
+ $(dwarf_SOURCES_common) \
+ elf32.c elf32.h \
+ hppa/init.h hppa/offsets.h hppa/unwind_i.h \
+ hppa/regname.c
+
+# The list of files that go into libunwind:
+libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \
+ $(libunwind_la_SOURCES_local) \
+ hppa/getcontext.S hppa/setcontext.S \
+ $(dwarf_SOURCES_local) \
+ dwarf/Lfind_proc_info-lsb.c \
+ hppa/Lcreate_addr_space.c hppa/Lget_save_loc.c hppa/Lglobal.c \
+ hppa/Linit.c hppa/Linit_local.c hppa/Linit_remote.c \
+ hppa/Lis_signal_frame.c hppa/Lget_proc_info.c hppa/Lregs.c \
+ hppa/Lresume.c hppa/Lstep.c
+
+# The list of files that go into libunwind-hppa:
+libunwind_hppa_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \
+ $(libunwind_la_SOURCES_generic) \
+ $(dwarf_SOURCES_generic) \
+ dwarf/Gfind_proc_info-lsb.c \
+ hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \
+ hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \
+ hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \
+ hppa/Gresume.c hppa/Gstep.c
# The list of files that go both into libunwind and libunwind-x86:
libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \
$(dwarf_SOURCES_common) \
+ elf32.c elf32.h \
x86/init.h x86/offsets.h x86/unwind_i.h \
x86/is_fpreg.c x86/regname.c
# The list of files that go into libunwind:
libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \
$(libunwind_la_SOURCES_local) \
- elf32.c elf32.h \
$(dwarf_SOURCES_local) \
dwarf/Lfind_proc_info-lsb.c \
x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \
@@ -164,21 +180,22 @@
# The list of files that go both into libunwind and libunwind-x86_64:
libunwind_la_SOURCES_x86_64_common = $(libunwind_la_SOURCES_common) \
$(dwarf_SOURCES_common) \
+ elf64.c elf64.h \
x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h \
- x86_64/is_fpreg.c x86_64/regname.c
+ x86_64/is_fpreg.c x86_64/regname.c x86_64/offsets.h
# The list of files that go into libunwind:
libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \
$(libunwind_la_SOURCES_local) \
- elf64.c elf64.h \
$(dwarf_SOURCES_local) \
dwarf/Lfind_proc_info-lsb.c \
+ x86_64/setcontext.S \
x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \
x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \
x86_64/Lis_signal_frame.c x86_64/Lget_proc_info.c x86_64/Lregs.c \
x86_64/Lresume.c x86_64/Lstep.c
-# The list of files that go into libunwind:
+# The list of files that go into libunwind-x86_64:
libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \
$(libunwind_la_SOURCES_generic) \
$(dwarf_SOURCES_generic) \
@@ -188,6 +205,66 @@
x86_64/Gis_signal_frame.c x86_64/Gget_proc_info.c x86_64/Gregs.c \
x86_64/Gresume.c x86_64/Gstep.c
+# The list of local files that go to Power 64 and 32:
+libunwind_la_SOURCES_ppc = ppc/Lcreate_addr_space.c \
+ ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \
+ ppc/Linit_remote.c ppc/Lis_signal_frame.c
+
+# The list of generic files that go to Power 64 and 32:
+libunwind_ppc_la_SOURCES_ppc_generic = ppc/Gcreate_addr_space.c \
+ ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \
+ ppc/Ginit_remote.c ppc/Gis_signal_frame.c
+
+# The list of files that go both into libunwind and libunwind-ppc32:
+libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \
+ $(dwarf_SOURCES_common) \
+ elf32.c elf32.h \
+ ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h \
+ ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c
+
+# The list of files that go into libunwind:
+libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \
+ $(libunwind_la_SOURCES_local) \
+ $(dwarf_SOURCES_local) \
+ $(libunwind_la_SOURCES_ppc) \
+ dwarf/Lfind_proc_info-lsb.c \
+ ppc32/Lglobal.c ppc32/Linit.c \
+ ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c
+
+# The list of files that go into libunwind-ppc32:
+libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \
+ $(libunwind_la_SOURCES_generic) \
+ $(dwarf_SOURCES_generic) \
+ $(libunwind_ppc_la_SOURCES_ppc_generic) \
+ dwarf/Gfind_proc_info-lsb.c \
+ ppc32/Gglobal.c ppc32/Ginit.c \
+ ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c
+
+# The list of files that go both into libunwind and libunwind-ppc64:
+libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \
+ $(dwarf_SOURCES_common) \
+ elf64.c elf64.h \
+ ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h \
+ ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c
+
+# The list of files that go into libunwind:
+libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \
+ $(libunwind_la_SOURCES_local) \
+ $(dwarf_SOURCES_local) \
+ $(libunwind_la_SOURCES_ppc) \
+ dwarf/Lfind_proc_info-lsb.c \
+ ppc64/Lglobal.c ppc64/Linit.c \
+ ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c
+
+# The list of files that go into libunwind-ppc64:
+libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \
+ $(libunwind_la_SOURCES_generic) \
+ $(dwarf_SOURCES_generic) \
+ $(libunwind_ppc_la_SOURCES_ppc_generic) \
+ dwarf/Gfind_proc_info-lsb.c \
+ ppc64/Gglobal.c ppc64/Ginit.c \
+ ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c
+
if REMOTE_ONLY
install-exec-hook:
# Nothing to do here....
@@ -263,19 +340,49 @@
endif
libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
$(libunwind_setjmp_la_SOURCES_x86_64)
+else
+if ARCH_PPC32
+ lib_LTLIBRARIES_arch = libunwind-ppc32.la
+ libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32)
+ libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32)
+ libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
+if !REMOTE_ONLY
+ libunwind_ppc32_la_LIBADD = libunwind.la -lc
+endif
+ libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
+ $(libunwind_setjmp_la_SOURCES_ppc32)
+else
+if ARCH_PPC64
+ lib_LTLIBRARIES_arch = libunwind-ppc64.la
+ libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64)
+ libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64)
+ libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
+if !REMOTE_ONLY
+ libunwind_ppc64_la_LIBADD = libunwind.la -lc
+endif
+ libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
+ $(libunwind_setjmp_la_SOURCES_ppc64)
+
+endif # ARCH_PPC64
+endif # ARCH_PPC32
endif # ARCH_X86_64
endif # ARCH_X86
endif # ARCH_HPPA
endif # ARCH_IA64
-libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
+#
+# Don't link with standard libraries, because those may mention
+# libunwind already.
+#
+libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \
+ $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION)
libunwind_la_LIBADD = -lc $(LIBCRTS)
lib_LIBRARIES = $(LIBRARIES_cdep)
lib_LTLIBRARIES = $(lib_LTLIBRARIES_cdep) $(lib_LTLIBRARIES_arch) \
$(lib_LTLIBRARIES_cdep_setjmp)
-AM_CPPFLAGS = -I$(top_srcdir)/include/$(arch) -I$(top_srcdir)/include -I.
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I.
AM_CCASFLAGS = $(AM_CPPFLAGS)
EXTRA_DIST = elfxx.h elfxx.c unwind/unwind-internal.h \
@@ -296,7 +403,10 @@
$(libunwind_setjmp_la_SOURCES_hppa) \
$(libunwind_setjmp_la_SOURCES_ia64) \
$(libunwind_setjmp_la_SOURCES_x86) \
- $(libunwind_setjmp_la_SOURCES_x86_64)
+ $(libunwind_setjmp_la_SOURCES_x86_64) \
+ $(libunwind_setjmp_la_SOURCES_ppc32) \
+ $(libunwind_setjmp_la_SOURCES_ppc64)
+
# The -version-info flag accepts an argument of the form
# `current[:revision[:age]]'. So, passing `-version-info 3:12:1' sets
diff --git a/src/Makefile.in b/src/Makefile.in
index 9b47820..11f3c61 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -64,7 +64,8 @@
libunwind_ptrace_a_AR = $(AR) $(ARFLAGS)
libunwind_ptrace_a_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
-am_libunwind_ptrace_a_OBJECTS = ptrace/_UPT_accessors.$(OBJEXT) \
+am_libunwind_ptrace_a_OBJECTS = ptrace/_UPT_elf.$(OBJEXT) \
+ ptrace/_UPT_accessors.$(OBJEXT) \
ptrace/_UPT_access_fpreg.$(OBJEXT) \
ptrace/_UPT_access_mem.$(OBJEXT) \
ptrace/_UPT_access_reg.$(OBJEXT) ptrace/_UPT_create.$(OBJEXT) \
@@ -78,17 +79,56 @@
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@@REMOTE_ONLY_FALSE@libunwind_hppa_la_DEPENDENCIES = libunwind.la
-am_libunwind_hppa_la_OBJECTS =
+am__libunwind_hppa_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \
+ mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \
+ dwarf/global.c elf32.c elf32.h hppa/init.h hppa/offsets.h \
+ hppa/unwind_i.h hppa/regname.c mi/Gdyn-extract.c \
+ mi/Gdyn-remote.c mi/Gfind_dynamic_proc_info.c \
+ mi/Gget_accessors.c mi/Gget_proc_info_by_ip.c \
+ mi/Gget_proc_name.c mi/Gput_dynamic_unwind_info.c \
+ mi/Gdestroy_addr_space.c mi/Gget_reg.c mi/Gset_reg.c \
+ mi/Gget_fpreg.c mi/Gset_fpreg.c mi/Gset_caching_policy.c \
+ dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c \
+ dwarf/Gstep.c dwarf/Gfind_proc_info-lsb.c \
+ hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \
+ hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \
+ hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \
+ hppa/Gresume.c hppa/Gstep.c
+am__objects_1 = os-hpux.lo
+am__objects_2 = os-linux.lo
+@OS_HPUX_FALSE@@OS_LINUX_TRUE@am__objects_3 = $(am__objects_2)
+@OS_HPUX_TRUE@am__objects_3 = $(am__objects_1)
+am__objects_4 = $(am__objects_3) mi/init.lo mi/flush_cache.lo \
+ mi/mempool.lo mi/strerror.lo
+am__objects_5 = dwarf/global.lo
+am__objects_6 = $(am__objects_4) $(am__objects_5) elf32.lo \
+ hppa/regname.lo
+am__objects_7 = mi/Gdyn-extract.lo mi/Gdyn-remote.lo \
+ mi/Gfind_dynamic_proc_info.lo mi/Gget_accessors.lo \
+ mi/Gget_proc_info_by_ip.lo mi/Gget_proc_name.lo \
+ mi/Gput_dynamic_unwind_info.lo mi/Gdestroy_addr_space.lo \
+ mi/Gget_reg.lo mi/Gset_reg.lo mi/Gget_fpreg.lo \
+ mi/Gset_fpreg.lo mi/Gset_caching_policy.lo
+am__objects_8 = dwarf/Gexpr.lo dwarf/Gfde.lo dwarf/Gparser.lo \
+ dwarf/Gpe.lo dwarf/Gstep.lo
+am__objects_9 = $(am__objects_6) $(am__objects_7) $(am__objects_8) \
+ dwarf/Gfind_proc_info-lsb.lo hppa/Gcreate_addr_space.lo \
+ hppa/Gget_save_loc.lo hppa/Gglobal.lo hppa/Ginit.lo \
+ hppa/Ginit_local.lo hppa/Ginit_remote.lo \
+ hppa/Gis_signal_frame.lo hppa/Gget_proc_info.lo hppa/Gregs.lo \
+ hppa/Gresume.lo hppa/Gstep.lo
+@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@am_libunwind_hppa_la_OBJECTS = \
+@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_9)
libunwind_hppa_la_OBJECTS = $(am_libunwind_hppa_la_OBJECTS)
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@am_libunwind_hppa_la_rpath = -rpath \
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(libdir)
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@libunwind_ia64_la_DEPENDENCIES = \
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@ libunwind.la
am__libunwind_ia64_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \
- mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \
- ia64/init.h ia64/offsets.h ia64/regs.h ia64/ucontext_i.h \
- ia64/unwind_decoder.h ia64/unwind_i.h ia64/regname.c \
- mi/Gdyn-extract.c mi/Gdyn-remote.c \
+ mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c elf64.c \
+ elf64.h ia64/init.h ia64/offsets.h ia64/regs.h \
+ ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h \
+ ia64/regname.c mi/Gdyn-extract.c mi/Gdyn-remote.c \
mi/Gfind_dynamic_proc_info.c mi/Gget_accessors.c \
mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \
mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \
@@ -99,55 +139,106 @@
ia64/Ginstall_cursor.S ia64/Gis_signal_frame.c ia64/Gparser.c \
ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c \
ia64/Gstep.c ia64/Gtables.c
-am__objects_1 = os-hpux.lo
-am__objects_2 = os-linux.lo
-@OS_HPUX_FALSE@@OS_LINUX_TRUE@am__objects_3 = $(am__objects_2)
-@OS_HPUX_TRUE@am__objects_3 = $(am__objects_1)
-am__objects_4 = $(am__objects_3) mi/init.lo mi/flush_cache.lo \
- mi/mempool.lo mi/strerror.lo
-am__objects_5 = $(am__objects_4) ia64/regname.lo
-am__objects_6 = mi/Gdyn-extract.lo mi/Gdyn-remote.lo \
- mi/Gfind_dynamic_proc_info.lo mi/Gget_accessors.lo \
- mi/Gget_proc_info_by_ip.lo mi/Gget_proc_name.lo \
- mi/Gput_dynamic_unwind_info.lo mi/Gdestroy_addr_space.lo \
- mi/Gget_reg.lo mi/Gset_reg.lo mi/Gget_fpreg.lo \
- mi/Gset_fpreg.lo mi/Gset_caching_policy.lo
-am__objects_7 = $(am__objects_5) $(am__objects_6) \
+am__objects_10 = $(am__objects_4) elf64.lo ia64/regname.lo
+am__objects_11 = $(am__objects_10) $(am__objects_7) \
ia64/Gcreate_addr_space.lo ia64/Gget_proc_info.lo \
ia64/Gget_save_loc.lo ia64/Gglobal.lo ia64/Ginit.lo \
ia64/Ginit_local.lo ia64/Ginit_remote.lo \
ia64/Ginstall_cursor.lo ia64/Gis_signal_frame.lo \
ia64/Gparser.lo ia64/Grbs.lo ia64/Gregs.lo ia64/Gresume.lo \
ia64/Gscript.lo ia64/Gstep.lo ia64/Gtables.lo
-@ARCH_IA64_TRUE@am_libunwind_ia64_la_OBJECTS = $(am__objects_7)
+@ARCH_IA64_TRUE@am_libunwind_ia64_la_OBJECTS = $(am__objects_11)
libunwind_ia64_la_OBJECTS = $(am_libunwind_ia64_la_OBJECTS)
@ARCH_IA64_TRUE@am_libunwind_ia64_la_rpath = -rpath $(libdir)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@@REMOTE_ONLY_FALSE@libunwind_ppc32_la_DEPENDENCIES = libunwind.la
+am__libunwind_ppc32_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \
+ mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \
+ dwarf/global.c elf32.c elf32.h ppc32/init.h ppc32/unwind_i.h \
+ ppc32/ucontext_i.h ppc32/is_fpreg.c ppc32/regname.c \
+ ppc32/get_func_addr.c mi/Gdyn-extract.c mi/Gdyn-remote.c \
+ mi/Gfind_dynamic_proc_info.c mi/Gget_accessors.c \
+ mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \
+ mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \
+ mi/Gget_reg.c mi/Gset_reg.c mi/Gget_fpreg.c mi/Gset_fpreg.c \
+ mi/Gset_caching_policy.c dwarf/Gexpr.c dwarf/Gfde.c \
+ dwarf/Gparser.c dwarf/Gpe.c dwarf/Gstep.c \
+ ppc/Gcreate_addr_space.c ppc/Gget_proc_info.c \
+ ppc/Gget_save_loc.c ppc/Ginit_local.c ppc/Ginit_remote.c \
+ ppc/Gis_signal_frame.c dwarf/Gfind_proc_info-lsb.c \
+ ppc32/Gglobal.c ppc32/Ginit.c ppc32/Gregs.c ppc32/Gresume.c \
+ ppc32/Gstep.c
+am__objects_12 = $(am__objects_4) $(am__objects_5) elf32.lo \
+ ppc32/is_fpreg.lo ppc32/regname.lo ppc32/get_func_addr.lo
+am__objects_13 = ppc/Gcreate_addr_space.lo ppc/Gget_proc_info.lo \
+ ppc/Gget_save_loc.lo ppc/Ginit_local.lo ppc/Ginit_remote.lo \
+ ppc/Gis_signal_frame.lo
+am__objects_14 = $(am__objects_12) $(am__objects_7) $(am__objects_8) \
+ $(am__objects_13) dwarf/Gfind_proc_info-lsb.lo \
+ ppc32/Gglobal.lo ppc32/Ginit.lo ppc32/Gregs.lo \
+ ppc32/Gresume.lo ppc32/Gstep.lo
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_ppc32_la_OBJECTS = $(am__objects_14)
+libunwind_ppc32_la_OBJECTS = $(am_libunwind_ppc32_la_OBJECTS)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_ppc32_la_rpath = -rpath \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@ $(libdir)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@@REMOTE_ONLY_FALSE@libunwind_ppc64_la_DEPENDENCIES = libunwind.la
+am__libunwind_ppc64_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \
+ mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \
+ dwarf/global.c elf64.c elf64.h ppc64/init.h ppc64/unwind_i.h \
+ ppc64/ucontext_i.h ppc64/is_fpreg.c ppc64/regname.c \
+ ppc64/get_func_addr.c mi/Gdyn-extract.c mi/Gdyn-remote.c \
+ mi/Gfind_dynamic_proc_info.c mi/Gget_accessors.c \
+ mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \
+ mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \
+ mi/Gget_reg.c mi/Gset_reg.c mi/Gget_fpreg.c mi/Gset_fpreg.c \
+ mi/Gset_caching_policy.c dwarf/Gexpr.c dwarf/Gfde.c \
+ dwarf/Gparser.c dwarf/Gpe.c dwarf/Gstep.c \
+ ppc/Gcreate_addr_space.c ppc/Gget_proc_info.c \
+ ppc/Gget_save_loc.c ppc/Ginit_local.c ppc/Ginit_remote.c \
+ ppc/Gis_signal_frame.c dwarf/Gfind_proc_info-lsb.c \
+ ppc64/Gglobal.c ppc64/Ginit.c ppc64/Gregs.c ppc64/Gresume.c \
+ ppc64/Gstep.c
+am__objects_15 = $(am__objects_4) $(am__objects_5) elf64.lo \
+ ppc64/is_fpreg.lo ppc64/regname.lo ppc64/get_func_addr.lo
+am__objects_16 = $(am__objects_15) $(am__objects_7) $(am__objects_8) \
+ $(am__objects_13) dwarf/Gfind_proc_info-lsb.lo \
+ ppc64/Gglobal.lo ppc64/Ginit.lo ppc64/Gregs.lo \
+ ppc64/Gresume.lo ppc64/Gstep.lo
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_ppc64_la_OBJECTS = $(am__objects_16)
+libunwind_ppc64_la_OBJECTS = $(am_libunwind_ppc64_la_OBJECTS)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_ppc64_la_rpath = -rpath \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@ $(libdir)
libunwind_setjmp_la_DEPENDENCIES = libunwind-$(arch).la
-am__libunwind_setjmp_la_SOURCES_DIST = longjmp.c siglongjmp.c setjmp.c \
- sigsetjmp.c x86_64/siglongjmp.S x86/siglongjmp.S \
- hppa/siglongjmp.S ia64/setjmp.S ia64/sigsetjmp.S \
- ia64/longjmp.S ia64/siglongjmp.S
-am__objects_8 = longjmp.lo siglongjmp.lo
-am__objects_9 = setjmp.lo sigsetjmp.lo x86_64/siglongjmp.lo
-am__objects_10 = setjmp.lo sigsetjmp.lo x86/siglongjmp.lo
-am__objects_11 = setjmp.lo sigsetjmp.lo hppa/siglongjmp.lo
-am__objects_12 = ia64/setjmp.lo ia64/sigsetjmp.lo ia64/longjmp.lo \
+am__libunwind_setjmp_la_SOURCES_DIST = setjmp/setjmp_i.h \
+ setjmp/longjmp.c setjmp/siglongjmp.c ppc/longjmp.S \
+ ppc/siglongjmp.S x86_64/longjmp.S x86_64/siglongjmp.S \
+ x86/longjmp.S x86/siglongjmp.S hppa/siglongjmp.S ia64/setjmp.S \
+ ia64/sigsetjmp.S ia64/longjmp.S ia64/siglongjmp.S
+am__objects_17 = setjmp/longjmp.lo setjmp/siglongjmp.lo
+am__objects_18 = ppc/longjmp.lo ppc/siglongjmp.lo
+am__objects_19 = x86_64/longjmp.lo x86_64/siglongjmp.lo
+am__objects_20 = x86/longjmp.lo x86/siglongjmp.lo
+am__objects_21 = hppa/siglongjmp.lo
+am__objects_22 = ia64/setjmp.lo ia64/sigsetjmp.lo ia64/longjmp.lo \
ia64/siglongjmp.lo
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_8) \
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@ $(am__objects_9)
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_8) \
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@ $(am__objects_10)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_17) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@ $(am__objects_18)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_17) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@ $(am__objects_18)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_17) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@ $(am__objects_19)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_17) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@ $(am__objects_20)
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@am_libunwind_setjmp_la_OBJECTS = \
-@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_8) \
-@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_11)
-@ARCH_IA64_TRUE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_8) \
-@ARCH_IA64_TRUE@ $(am__objects_12)
+@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_17) \
+@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_21)
+@ARCH_IA64_TRUE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_17) \
+@ARCH_IA64_TRUE@ $(am__objects_22)
libunwind_setjmp_la_OBJECTS = $(am_libunwind_setjmp_la_OBJECTS)
@REMOTE_ONLY_FALSE@am_libunwind_setjmp_la_rpath = -rpath $(libdir)
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@@REMOTE_ONLY_FALSE@libunwind_x86_la_DEPENDENCIES = libunwind.la
am__libunwind_x86_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \
mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \
- dwarf/dwarf-eh.h dwarf/global.c x86/init.h x86/offsets.h \
+ dwarf/global.c elf32.c elf32.h x86/init.h x86/offsets.h \
x86/unwind_i.h x86/is_fpreg.c x86/regname.c mi/Gdyn-extract.c \
mi/Gdyn-remote.c mi/Gfind_dynamic_proc_info.c \
mi/Gget_accessors.c mi/Gget_proc_info_by_ip.c \
@@ -160,17 +251,14 @@
x86/Ginit.c x86/Ginit_local.c x86/Ginit_remote.c \
x86/Gis_signal_frame.c x86/Gget_proc_info.c x86/Gregs.c \
x86/Gresume.c x86/Gstep.c
-am__objects_13 = dwarf/global.lo
-am__objects_14 = $(am__objects_4) $(am__objects_13) x86/is_fpreg.lo \
- x86/regname.lo
-am__objects_15 = dwarf/Gexpr.lo dwarf/Gfde.lo dwarf/Gparser.lo \
- dwarf/Gpe.lo dwarf/Gstep.lo
-am__objects_16 = $(am__objects_14) $(am__objects_6) $(am__objects_15) \
+am__objects_23 = $(am__objects_4) $(am__objects_5) elf32.lo \
+ x86/is_fpreg.lo x86/regname.lo
+am__objects_24 = $(am__objects_23) $(am__objects_7) $(am__objects_8) \
dwarf/Gfind_proc_info-lsb.lo x86/Gcreate_addr_space.lo \
x86/Gget_save_loc.lo x86/Gglobal.lo x86/Ginit.lo \
x86/Ginit_local.lo x86/Ginit_remote.lo x86/Gis_signal_frame.lo \
x86/Gget_proc_info.lo x86/Gregs.lo x86/Gresume.lo x86/Gstep.lo
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_x86_la_OBJECTS = $(am__objects_16)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_x86_la_OBJECTS = $(am__objects_24)
libunwind_x86_la_OBJECTS = $(am_libunwind_x86_la_OBJECTS)
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_x86_la_rpath = \
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@ -rpath \
@@ -178,9 +266,9 @@
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@@REMOTE_ONLY_FALSE@libunwind_x86_64_la_DEPENDENCIES = libunwind.la
am__libunwind_x86_64_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \
mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \
- dwarf/dwarf-eh.h dwarf/global.c x86_64/init.h \
- x86_64/unwind_i.h x86_64/ucontext_i.h x86_64/is_fpreg.c \
- x86_64/regname.c mi/Gdyn-extract.c mi/Gdyn-remote.c \
+ dwarf/global.c elf64.c elf64.h x86_64/init.h x86_64/unwind_i.h \
+ x86_64/ucontext_i.h x86_64/is_fpreg.c x86_64/regname.c \
+ x86_64/offsets.h mi/Gdyn-extract.c mi/Gdyn-remote.c \
mi/Gfind_dynamic_proc_info.c mi/Gget_accessors.c \
mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \
mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \
@@ -192,15 +280,15 @@
x86_64/Ginit_local.c x86_64/Ginit_remote.c \
x86_64/Gis_signal_frame.c x86_64/Gget_proc_info.c \
x86_64/Gregs.c x86_64/Gresume.c x86_64/Gstep.c
-am__objects_17 = $(am__objects_4) $(am__objects_13) x86_64/is_fpreg.lo \
- x86_64/regname.lo
-am__objects_18 = $(am__objects_17) $(am__objects_6) $(am__objects_15) \
+am__objects_25 = $(am__objects_4) $(am__objects_5) elf64.lo \
+ x86_64/is_fpreg.lo x86_64/regname.lo
+am__objects_26 = $(am__objects_25) $(am__objects_7) $(am__objects_8) \
dwarf/Gfind_proc_info-lsb.lo x86_64/Gcreate_addr_space.lo \
x86_64/Gget_save_loc.lo x86_64/Gglobal.lo x86_64/Ginit.lo \
x86_64/Ginit_local.lo x86_64/Ginit_remote.lo \
x86_64/Gis_signal_frame.lo x86_64/Gget_proc_info.lo \
x86_64/Gregs.lo x86_64/Gresume.lo x86_64/Gstep.lo
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_x86_64_la_OBJECTS = $(am__objects_18)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_x86_64_la_OBJECTS = $(am__objects_26)
libunwind_x86_64_la_OBJECTS = $(am_libunwind_x86_64_la_OBJECTS)
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_x86_64_la_rpath = -rpath \
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@ $(libdir)
@@ -208,51 +296,60 @@
libunwind_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__libunwind_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \
mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \
- dwarf/dwarf-eh.h dwarf/global.c x86_64/init.h \
- x86_64/unwind_i.h x86_64/ucontext_i.h x86_64/is_fpreg.c \
- x86_64/regname.c mi/_ReadULEB.c mi/_ReadSLEB.c mi/backtrace.c \
- mi/dyn-cancel.c mi/dyn-info-list.c mi/dyn-register.c \
- mi/Ldyn-extract.c mi/Lfind_dynamic_proc_info.c \
- mi/Lget_accessors.c mi/Lget_proc_info_by_ip.c \
- mi/Lget_proc_name.c mi/Lput_dynamic_unwind_info.c \
- mi/Ldestroy_addr_space.c mi/Lget_reg.c mi/Lset_reg.c \
- mi/Lget_fpreg.c mi/Lset_fpreg.c mi/Lset_caching_policy.c \
- unwind/Backtrace.c unwind/DeleteException.c \
- unwind/FindEnclosingFunction.c unwind/ForcedUnwind.c \
- unwind/GetBSP.c unwind/GetCFA.c unwind/GetDataRelBase.c \
- unwind/GetGR.c unwind/GetIP.c unwind/GetLanguageSpecificData.c \
- unwind/GetRegionStart.c unwind/GetTextRelBase.c \
- unwind/RaiseException.c unwind/Resume.c \
- unwind/Resume_or_Rethrow.c unwind/SetGR.c unwind/SetIP.c \
- elf64.c elf64.h dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c \
- dwarf/Lpe.c dwarf/Lstep.c dwarf/Lfind_proc_info-lsb.c \
+ dwarf/global.c elf64.c elf64.h ppc64/init.h ppc64/unwind_i.h \
+ ppc64/ucontext_i.h ppc64/is_fpreg.c ppc64/regname.c \
+ ppc64/get_func_addr.c mi/_ReadULEB.c mi/_ReadSLEB.c \
+ mi/backtrace.c mi/dyn-cancel.c mi/dyn-info-list.c \
+ mi/dyn-register.c mi/Ldyn-extract.c \
+ mi/Lfind_dynamic_proc_info.c mi/Lget_accessors.c \
+ mi/Lget_proc_info_by_ip.c mi/Lget_proc_name.c \
+ mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \
+ mi/Lget_reg.c mi/Lset_reg.c mi/Lget_fpreg.c mi/Lset_fpreg.c \
+ mi/Lset_caching_policy.c unwind/Backtrace.c \
+ unwind/DeleteException.c unwind/FindEnclosingFunction.c \
+ unwind/ForcedUnwind.c unwind/GetBSP.c unwind/GetCFA.c \
+ unwind/GetDataRelBase.c unwind/GetGR.c unwind/GetIP.c \
+ unwind/GetLanguageSpecificData.c unwind/GetRegionStart.c \
+ unwind/GetTextRelBase.c unwind/RaiseException.c \
+ unwind/Resume.c unwind/Resume_or_Rethrow.c unwind/SetGR.c \
+ unwind/SetIP.c dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c \
+ dwarf/Lpe.c dwarf/Lstep.c ppc/Lcreate_addr_space.c \
+ ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \
+ ppc/Linit_remote.c ppc/Lis_signal_frame.c \
+ dwarf/Lfind_proc_info-lsb.c ppc64/Lglobal.c ppc64/Linit.c \
+ ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c elf32.c elf32.h \
+ ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h \
+ ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c \
+ ppc32/Lglobal.c ppc32/Linit.c ppc32/Lregs.c ppc32/Lresume.c \
+ ppc32/Lstep.c x86_64/init.h x86_64/unwind_i.h \
+ x86_64/ucontext_i.h x86_64/is_fpreg.c x86_64/regname.c \
+ x86_64/offsets.h x86_64/setcontext.S \
x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c \
x86_64/Lglobal.c x86_64/Linit.c x86_64/Linit_local.c \
x86_64/Linit_remote.c x86_64/Lis_signal_frame.c \
x86_64/Lget_proc_info.c x86_64/Lregs.c x86_64/Lresume.c \
x86_64/Lstep.c x86/init.h x86/offsets.h x86/unwind_i.h \
- x86/is_fpreg.c x86/regname.c elf32.c elf32.h \
- x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \
- x86/Linit.c x86/Linit_local.c x86/Linit_remote.c \
- x86/Lis_signal_frame.c x86/Lget_proc_info.c x86/Lregs.c \
- x86/Lresume.c x86/Lstep.c hppa/global.c hppa/tables.c \
- hppa/init.h hppa/unwind_i.h hppa/Gget_reg.c \
- hppa/Gget_proc_name.c hppa/Ginit.c hppa/Ginit_local.c \
- hppa/Gget_proc_info.c hppa/Gregs.c hppa/Gstep.c \
- hppa/Lget_reg.c hppa/Lget_proc_name.c hppa/Linit.c \
- hppa/Linit_local.c hppa/Lget_proc_info.c hppa/Lregs.c \
- hppa/Lstep.c ia64/init.h ia64/offsets.h ia64/regs.h \
- ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h \
- ia64/regname.c ia64/dyn_info_list.S ia64/getcontext.S \
+ x86/is_fpreg.c x86/regname.c x86/Lcreate_addr_space.c \
+ x86/Lget_save_loc.c x86/Lglobal.c x86/Linit.c \
+ x86/Linit_local.c x86/Linit_remote.c x86/Lis_signal_frame.c \
+ x86/Lget_proc_info.c x86/Lregs.c x86/Lresume.c x86/Lstep.c \
+ hppa/init.h hppa/offsets.h hppa/unwind_i.h hppa/regname.c \
+ hppa/getcontext.S hppa/setcontext.S hppa/Lcreate_addr_space.c \
+ hppa/Lget_save_loc.c hppa/Lglobal.c hppa/Linit.c \
+ hppa/Linit_local.c hppa/Linit_remote.c hppa/Lis_signal_frame.c \
+ hppa/Lget_proc_info.c hppa/Lregs.c hppa/Lresume.c hppa/Lstep.c \
+ ia64/init.h ia64/offsets.h ia64/regs.h ia64/ucontext_i.h \
+ ia64/unwind_decoder.h ia64/unwind_i.h ia64/regname.c \
+ ia64/dyn_info_list.S ia64/getcontext.S \
ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c \
ia64/Lget_save_loc.c ia64/Lglobal.c ia64/Linit.c \
ia64/Linit_local.c ia64/Linit_remote.c ia64/Linstall_cursor.S \
ia64/Lis_signal_frame.c ia64/Lparser.c ia64/Lrbs.c \
ia64/Lregs.c ia64/Lresume.c ia64/Lscript.c ia64/Lstep.c \
ia64/Ltables.c
-am__objects_19 = mi/_ReadULEB.lo mi/_ReadSLEB.lo
-@OS_LINUX_TRUE@am__objects_20 = $(am__objects_19)
-am__objects_21 = $(am__objects_20) mi/backtrace.lo mi/dyn-cancel.lo \
+am__objects_27 = mi/_ReadULEB.lo mi/_ReadSLEB.lo
+@OS_LINUX_TRUE@am__objects_28 = $(am__objects_27)
+am__objects_29 = $(am__objects_28) mi/backtrace.lo mi/dyn-cancel.lo \
mi/dyn-info-list.lo mi/dyn-register.lo mi/Ldyn-extract.lo \
mi/Lfind_dynamic_proc_info.lo mi/Lget_accessors.lo \
mi/Lget_proc_info_by_ip.lo mi/Lget_proc_name.lo \
@@ -266,28 +363,39 @@
unwind/GetTextRelBase.lo unwind/RaiseException.lo \
unwind/Resume.lo unwind/Resume_or_Rethrow.lo unwind/SetGR.lo \
unwind/SetIP.lo
-am__objects_22 = dwarf/Lexpr.lo dwarf/Lfde.lo dwarf/Lparser.lo \
+am__objects_30 = dwarf/Lexpr.lo dwarf/Lfde.lo dwarf/Lparser.lo \
dwarf/Lpe.lo dwarf/Lstep.lo
-am__objects_23 = $(am__objects_17) $(am__objects_21) elf64.lo \
- $(am__objects_22) dwarf/Lfind_proc_info-lsb.lo \
+am__objects_31 = ppc/Lcreate_addr_space.lo ppc/Lget_proc_info.lo \
+ ppc/Lget_save_loc.lo ppc/Linit_local.lo ppc/Linit_remote.lo \
+ ppc/Lis_signal_frame.lo
+am__objects_32 = $(am__objects_15) $(am__objects_29) $(am__objects_30) \
+ $(am__objects_31) dwarf/Lfind_proc_info-lsb.lo \
+ ppc64/Lglobal.lo ppc64/Linit.lo ppc64/Lregs.lo \
+ ppc64/Lresume.lo ppc64/Lstep.lo
+am__objects_33 = $(am__objects_12) $(am__objects_29) $(am__objects_30) \
+ $(am__objects_31) dwarf/Lfind_proc_info-lsb.lo \
+ ppc32/Lglobal.lo ppc32/Linit.lo ppc32/Lregs.lo \
+ ppc32/Lresume.lo ppc32/Lstep.lo
+am__objects_34 = $(am__objects_25) $(am__objects_29) $(am__objects_30) \
+ dwarf/Lfind_proc_info-lsb.lo x86_64/setcontext.lo \
x86_64/Lcreate_addr_space.lo x86_64/Lget_save_loc.lo \
x86_64/Lglobal.lo x86_64/Linit.lo x86_64/Linit_local.lo \
x86_64/Linit_remote.lo x86_64/Lis_signal_frame.lo \
x86_64/Lget_proc_info.lo x86_64/Lregs.lo x86_64/Lresume.lo \
x86_64/Lstep.lo
-am__objects_24 = $(am__objects_14) $(am__objects_21) elf32.lo \
- $(am__objects_22) dwarf/Lfind_proc_info-lsb.lo \
- x86/Lcreate_addr_space.lo x86/Lget_save_loc.lo x86/Lglobal.lo \
- x86/Linit.lo x86/Linit_local.lo x86/Linit_remote.lo \
- x86/Lis_signal_frame.lo x86/Lget_proc_info.lo x86/Lregs.lo \
- x86/Lresume.lo x86/Lstep.lo
-am__objects_25 = $(am__objects_4) hppa/global.lo hppa/tables.lo \
- hppa/Gget_reg.lo hppa/Gget_proc_name.lo hppa/Ginit.lo \
- hppa/Ginit_local.lo hppa/Gget_proc_info.lo hppa/Gregs.lo \
- hppa/Gstep.lo hppa/Lget_reg.lo hppa/Lget_proc_name.lo \
- hppa/Linit.lo hppa/Linit_local.lo hppa/Lget_proc_info.lo \
- hppa/Lregs.lo hppa/Lstep.lo
-am__objects_26 = $(am__objects_5) $(am__objects_21) elf64.lo \
+am__objects_35 = $(am__objects_23) $(am__objects_29) $(am__objects_30) \
+ dwarf/Lfind_proc_info-lsb.lo x86/Lcreate_addr_space.lo \
+ x86/Lget_save_loc.lo x86/Lglobal.lo x86/Linit.lo \
+ x86/Linit_local.lo x86/Linit_remote.lo x86/Lis_signal_frame.lo \
+ x86/Lget_proc_info.lo x86/Lregs.lo x86/Lresume.lo x86/Lstep.lo
+am__objects_36 = $(am__objects_6) $(am__objects_29) hppa/getcontext.lo \
+ hppa/setcontext.lo $(am__objects_30) \
+ dwarf/Lfind_proc_info-lsb.lo hppa/Lcreate_addr_space.lo \
+ hppa/Lget_save_loc.lo hppa/Lglobal.lo hppa/Linit.lo \
+ hppa/Linit_local.lo hppa/Linit_remote.lo \
+ hppa/Lis_signal_frame.lo hppa/Lget_proc_info.lo hppa/Lregs.lo \
+ hppa/Lresume.lo hppa/Lstep.lo
+am__objects_37 = $(am__objects_10) $(am__objects_29) \
ia64/dyn_info_list.lo ia64/getcontext.lo \
ia64/Lcreate_addr_space.lo ia64/Lget_proc_info.lo \
ia64/Lget_save_loc.lo ia64/Lglobal.lo ia64/Linit.lo \
@@ -295,11 +403,13 @@
ia64/Linstall_cursor.lo ia64/Lis_signal_frame.lo \
ia64/Lparser.lo ia64/Lrbs.lo ia64/Lregs.lo ia64/Lresume.lo \
ia64/Lscript.lo ia64/Lstep.lo ia64/Ltables.lo
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_la_OBJECTS = $(am__objects_23)
-@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_la_OBJECTS = $(am__objects_24)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_la_OBJECTS = $(am__objects_32)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@am_libunwind_la_OBJECTS = $(am__objects_33)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_la_OBJECTS = $(am__objects_34)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_la_OBJECTS = $(am__objects_35)
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@am_libunwind_la_OBJECTS = \
-@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_25)
-@ARCH_IA64_TRUE@am_libunwind_la_OBJECTS = $(am__objects_26)
+@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_36)
+@ARCH_IA64_TRUE@am_libunwind_la_OBJECTS = $(am__objects_37)
libunwind_la_OBJECTS = $(am_libunwind_la_OBJECTS)
@REMOTE_ONLY_FALSE@am_libunwind_la_rpath = -rpath $(libdir)
PROGRAMS = $(noinst_PROGRAMS)
@@ -328,13 +438,16 @@
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libunwind_ptrace_a_SOURCES) $(libunwind_hppa_la_SOURCES) \
- $(libunwind_ia64_la_SOURCES) $(libunwind_setjmp_la_SOURCES) \
+ $(libunwind_ia64_la_SOURCES) $(libunwind_ppc32_la_SOURCES) \
+ $(libunwind_ppc64_la_SOURCES) $(libunwind_setjmp_la_SOURCES) \
$(libunwind_x86_la_SOURCES) $(libunwind_x86_64_la_SOURCES) \
$(libunwind_la_SOURCES) $(ia64_mk_Gcursor_i_SOURCES) \
$(ia64_mk_Lcursor_i_SOURCES)
DIST_SOURCES = $(libunwind_ptrace_a_SOURCES) \
- $(libunwind_hppa_la_SOURCES) \
+ $(am__libunwind_hppa_la_SOURCES_DIST) \
$(am__libunwind_ia64_la_SOURCES_DIST) \
+ $(am__libunwind_ppc32_la_SOURCES_DIST) \
+ $(am__libunwind_ppc64_la_SOURCES_DIST) \
$(am__libunwind_setjmp_la_SOURCES_DIST) \
$(am__libunwind_x86_la_SOURCES_DIST) \
$(am__libunwind_x86_64_la_SOURCES_DIST) \
@@ -354,6 +467,10 @@
ARCH_HPPA_TRUE = @ARCH_HPPA_TRUE@
ARCH_IA64_FALSE = @ARCH_IA64_FALSE@
ARCH_IA64_TRUE = @ARCH_IA64_TRUE@
+ARCH_PPC32_FALSE = @ARCH_PPC32_FALSE@
+ARCH_PPC32_TRUE = @ARCH_PPC32_TRUE@
+ARCH_PPC64_FALSE = @ARCH_PPC64_FALSE@
+ARCH_PPC64_TRUE = @ARCH_PPC64_TRUE@
ARCH_X86_64_FALSE = @ARCH_X86_64_FALSE@
ARCH_X86_64_TRUE = @ARCH_X86_64_TRUE@
ARCH_X86_FALSE = @ARCH_X86_FALSE@
@@ -423,6 +540,8 @@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+USE_ALTIVEC_FALSE = @USE_ALTIVEC_FALSE@
+USE_ALTIVEC_TRUE = @USE_ALTIVEC_TRUE@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
@@ -480,13 +599,9 @@
SOVERSION = 7:0:0 # See comments at end of file.
SETJMP_SO_VERSION = 0:0:0
#
-# Don't link with standard libraries, because those may mention
-# libunwind already.
+# Don't link with start-files since we don't use any constructors/destructors:
#
-COMMON_SO_LDFLAGS = -XCClinker -nostartfiles \
- -XCClinker -nostdlib \
- $(LDFLAGS_STATIC_LIBCXA)
-
+COMMON_SO_LDFLAGS = -XCClinker -nostartfiles
@REMOTE_ONLY_FALSE@LIBRARIES_cdep = libunwind-ptrace.a
@REMOTE_ONLY_TRUE@LIBRARIES_cdep =
@REMOTE_ONLY_FALSE@lib_LTLIBRARIES_cdep = libunwind.la
@@ -496,6 +611,7 @@
### libunwind-ptrace:
libunwind_ptrace_a_SOURCES = \
+ ptrace/_UPT_elf.c \
ptrace/_UPT_internal.h \
ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c \
ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c \
@@ -510,17 +626,18 @@
-version-info $(SETJMP_SO_VERSION)
libunwind_setjmp_la_LIBADD = libunwind-$(arch).la -lc
-libunwind_setjmp_la_SOURCES_common = longjmp.c siglongjmp.c
+libunwind_setjmp_la_SOURCES_common = setjmp/setjmp_i.h \
+ setjmp/longjmp.c \
+ setjmp/siglongjmp.c
+
libunwind_setjmp_la_SOURCES_ia64 = ia64/setjmp.S ia64/sigsetjmp.S \
ia64/longjmp.S ia64/siglongjmp.S
-libunwind_setjmp_la_SOURCES_hppa = setjmp.c sigsetjmp.c \
- hppa/siglongjmp.S
-
-libunwind_setjmp_la_SOURCES_x86 = setjmp.c sigsetjmp.c x86/siglongjmp.S
-libunwind_setjmp_la_SOURCES_x86_64 = setjmp.c sigsetjmp.c \
- x86_64/siglongjmp.S
-
+libunwind_setjmp_la_SOURCES_hppa = hppa/siglongjmp.S
+libunwind_setjmp_la_SOURCES_x86 = x86/longjmp.S x86/siglongjmp.S
+libunwind_setjmp_la_SOURCES_x86_64 = x86_64/longjmp.S x86_64/siglongjmp.S
+libunwind_setjmp_la_SOURCES_ppc64 = ppc/longjmp.S ppc/siglongjmp.S
+libunwind_setjmp_la_SOURCES_ppc32 = ppc/longjmp.S ppc/siglongjmp.S
### libunwind:
@@ -568,7 +685,6 @@
libunwind_la_SOURCES_os_linux_local = mi/_ReadULEB.c mi/_ReadSLEB.c
libunwind_la_SOURCES_os_hpux = os-hpux.c
dwarf_SOURCES_common = \
- dwarf/dwarf-eh.h \
dwarf/global.c
dwarf_SOURCES_local = \
@@ -580,6 +696,7 @@
# The list of files that go both into libunwind and libunwind-ia64:
libunwind_la_SOURCES_ia64_common = $(libunwind_la_SOURCES_common) \
+ elf64.c elf64.h \
ia64/init.h ia64/offsets.h ia64/regs.h \
ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h \
ia64/regname.c
@@ -589,8 +706,6 @@
libunwind_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \
$(libunwind_la_SOURCES_local) \
\
- elf64.c elf64.h \
- \
ia64/dyn_info_list.S ia64/getcontext.S \
\
ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \
@@ -609,20 +724,42 @@
ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c ia64/Gstep.c \
ia64/Gtables.c
-libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_common) \
- hppa/global.c hppa/tables.c \
- hppa/init.h hppa/unwind_i.h \
- \
- hppa/Gget_reg.c hppa/Gget_proc_name.c hppa/Ginit.c hppa/Ginit_local.c \
- hppa/Gget_proc_info.c hppa/Gregs.c hppa/Gstep.c \
- \
- hppa/Lget_reg.c hppa/Lget_proc_name.c hppa/Linit.c hppa/Linit_local.c \
- hppa/Lget_proc_info.c hppa/Lregs.c hppa/Lstep.c
+
+# The list of files that go both into libunwind and libunwind-hppa:
+libunwind_la_SOURCES_hppa_common = $(libunwind_la_SOURCES_common) \
+ $(dwarf_SOURCES_common) \
+ elf32.c elf32.h \
+ hppa/init.h hppa/offsets.h hppa/unwind_i.h \
+ hppa/regname.c
+
+
+# The list of files that go into libunwind:
+libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \
+ $(libunwind_la_SOURCES_local) \
+ hppa/getcontext.S hppa/setcontext.S \
+ $(dwarf_SOURCES_local) \
+ dwarf/Lfind_proc_info-lsb.c \
+ hppa/Lcreate_addr_space.c hppa/Lget_save_loc.c hppa/Lglobal.c \
+ hppa/Linit.c hppa/Linit_local.c hppa/Linit_remote.c \
+ hppa/Lis_signal_frame.c hppa/Lget_proc_info.c hppa/Lregs.c \
+ hppa/Lresume.c hppa/Lstep.c
+
+
+# The list of files that go into libunwind-hppa:
+libunwind_hppa_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \
+ $(libunwind_la_SOURCES_generic) \
+ $(dwarf_SOURCES_generic) \
+ dwarf/Gfind_proc_info-lsb.c \
+ hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \
+ hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \
+ hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \
+ hppa/Gresume.c hppa/Gstep.c
# The list of files that go both into libunwind and libunwind-x86:
libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \
$(dwarf_SOURCES_common) \
+ elf32.c elf32.h \
x86/init.h x86/offsets.h x86/unwind_i.h \
x86/is_fpreg.c x86/regname.c
@@ -630,7 +767,6 @@
# The list of files that go into libunwind:
libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \
$(libunwind_la_SOURCES_local) \
- elf32.c elf32.h \
$(dwarf_SOURCES_local) \
dwarf/Lfind_proc_info-lsb.c \
x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \
@@ -653,23 +789,24 @@
# The list of files that go both into libunwind and libunwind-x86_64:
libunwind_la_SOURCES_x86_64_common = $(libunwind_la_SOURCES_common) \
$(dwarf_SOURCES_common) \
+ elf64.c elf64.h \
x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h \
- x86_64/is_fpreg.c x86_64/regname.c
+ x86_64/is_fpreg.c x86_64/regname.c x86_64/offsets.h
# The list of files that go into libunwind:
libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \
$(libunwind_la_SOURCES_local) \
- elf64.c elf64.h \
$(dwarf_SOURCES_local) \
dwarf/Lfind_proc_info-lsb.c \
+ x86_64/setcontext.S \
x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \
x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \
x86_64/Lis_signal_frame.c x86_64/Lget_proc_info.c x86_64/Lregs.c \
x86_64/Lresume.c x86_64/Lstep.c
-# The list of files that go into libunwind:
+# The list of files that go into libunwind-x86_64:
libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \
$(libunwind_la_SOURCES_generic) \
$(dwarf_SOURCES_generic) \
@@ -679,6 +816,74 @@
x86_64/Gis_signal_frame.c x86_64/Gget_proc_info.c x86_64/Gregs.c \
x86_64/Gresume.c x86_64/Gstep.c
+
+# The list of local files that go to Power 64 and 32:
+libunwind_la_SOURCES_ppc = ppc/Lcreate_addr_space.c \
+ ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \
+ ppc/Linit_remote.c ppc/Lis_signal_frame.c
+
+
+# The list of generic files that go to Power 64 and 32:
+libunwind_ppc_la_SOURCES_ppc_generic = ppc/Gcreate_addr_space.c \
+ ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \
+ ppc/Ginit_remote.c ppc/Gis_signal_frame.c
+
+
+# The list of files that go both into libunwind and libunwind-ppc32:
+libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \
+ $(dwarf_SOURCES_common) \
+ elf32.c elf32.h \
+ ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h \
+ ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c
+
+
+# The list of files that go into libunwind:
+libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \
+ $(libunwind_la_SOURCES_local) \
+ $(dwarf_SOURCES_local) \
+ $(libunwind_la_SOURCES_ppc) \
+ dwarf/Lfind_proc_info-lsb.c \
+ ppc32/Lglobal.c ppc32/Linit.c \
+ ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c
+
+
+# The list of files that go into libunwind-ppc32:
+libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \
+ $(libunwind_la_SOURCES_generic) \
+ $(dwarf_SOURCES_generic) \
+ $(libunwind_ppc_la_SOURCES_ppc_generic) \
+ dwarf/Gfind_proc_info-lsb.c \
+ ppc32/Gglobal.c ppc32/Ginit.c \
+ ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c
+
+
+# The list of files that go both into libunwind and libunwind-ppc64:
+libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \
+ $(dwarf_SOURCES_common) \
+ elf64.c elf64.h \
+ ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h \
+ ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c
+
+
+# The list of files that go into libunwind:
+libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \
+ $(libunwind_la_SOURCES_local) \
+ $(dwarf_SOURCES_local) \
+ $(libunwind_la_SOURCES_ppc) \
+ dwarf/Lfind_proc_info-lsb.c \
+ ppc64/Lglobal.c ppc64/Linit.c \
+ ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c
+
+
+# The list of files that go into libunwind-ppc64:
+libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \
+ $(libunwind_la_SOURCES_generic) \
+ $(dwarf_SOURCES_generic) \
+ $(libunwind_ppc_la_SOURCES_ppc_generic) \
+ dwarf/Gfind_proc_info-lsb.c \
+ ppc64/Gglobal.c ppc64/Ginit.c \
+ ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c
+
@OS_HPUX_TRUE@libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_hpux)
@OS_LINUX_TRUE@libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_linux)
@OS_HPUX_TRUE@libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_hpux_local)
@@ -686,10 +891,14 @@
@ARCH_IA64_TRUE@ia64_mk_Gcursor_i_SOURCES = ia64/mk_Gcursor_i.c
@ARCH_IA64_TRUE@ia64_mk_Lcursor_i_SOURCES = ia64/mk_Lcursor_i.c
@ARCH_IA64_TRUE@BUILT_SOURCES = Gcursor_i.h Lcursor_i.h
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@lib_LTLIBRARIES_arch = libunwind-ppc64.la
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@lib_LTLIBRARIES_arch = libunwind-ppc32.la
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@lib_LTLIBRARIES_arch = libunwind-x86_64.la
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@lib_LTLIBRARIES_arch = libunwind-x86.la
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@lib_LTLIBRARIES_arch = libunwind-hppa.la
@ARCH_IA64_TRUE@lib_LTLIBRARIES_arch = libunwind-ia64.la
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32)
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86_64)
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86)
@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@libunwind_la_SOURCES = $(libunwind_la_SOURCES_hppa)
@@ -697,6 +906,12 @@
@ARCH_IA64_TRUE@libunwind_ia64_la_SOURCES = $(libunwind_ia64_la_SOURCES_ia64)
@ARCH_IA64_TRUE@libunwind_ia64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@libunwind_ia64_la_LIBADD = libunwind.la -lc
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@ $(libunwind_setjmp_la_SOURCES_ppc64)
+
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@ $(libunwind_setjmp_la_SOURCES_ppc32)
+
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@ $(libunwind_setjmp_la_SOURCES_x86_64)
@@ -718,13 +933,26 @@
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@libunwind_x86_64_la_SOURCES = $(libunwind_x86_64_la_SOURCES_x86_64)
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@libunwind_x86_64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@@REMOTE_ONLY_FALSE@libunwind_x86_64_la_LIBADD = libunwind.la -lc
-libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@@REMOTE_ONLY_FALSE@libunwind_ppc32_la_LIBADD = libunwind.la -lc
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_PPC32_FALSE@@ARCH_PPC64_TRUE@@ARCH_X86_64_FALSE@@ARCH_X86_FALSE@@REMOTE_ONLY_FALSE@libunwind_ppc64_la_LIBADD = libunwind.la -lc
+
+#
+# Don't link with standard libraries, because those may mention
+# libunwind already.
+#
+libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \
+ $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION)
+
libunwind_la_LIBADD = -lc $(LIBCRTS)
lib_LIBRARIES = $(LIBRARIES_cdep)
lib_LTLIBRARIES = $(lib_LTLIBRARIES_cdep) $(lib_LTLIBRARIES_arch) \
$(lib_LTLIBRARIES_cdep_setjmp)
-AM_CPPFLAGS = -I$(top_srcdir)/include/$(arch) -I$(top_srcdir)/include -I.
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I.
AM_CCASFLAGS = $(AM_CPPFLAGS)
EXTRA_DIST = elfxx.h elfxx.c unwind/unwind-internal.h \
$(libunwind_la_SOURCES_hppa) \
@@ -744,7 +972,9 @@
$(libunwind_setjmp_la_SOURCES_hppa) \
$(libunwind_setjmp_la_SOURCES_ia64) \
$(libunwind_setjmp_la_SOURCES_x86) \
- $(libunwind_setjmp_la_SOURCES_x86_64)
+ $(libunwind_setjmp_la_SOURCES_x86_64) \
+ $(libunwind_setjmp_la_SOURCES_ppc32) \
+ $(libunwind_setjmp_la_SOURCES_ppc64)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -815,6 +1045,8 @@
ptrace/$(DEPDIR)/$(am__dirstamp):
@$(mkdir_p) ptrace/$(DEPDIR)
@: > ptrace/$(DEPDIR)/$(am__dirstamp)
+ptrace/_UPT_elf.$(OBJEXT): ptrace/$(am__dirstamp) \
+ ptrace/$(DEPDIR)/$(am__dirstamp)
ptrace/_UPT_accessors.$(OBJEXT): ptrace/$(am__dirstamp) \
ptrace/$(DEPDIR)/$(am__dirstamp)
ptrace/_UPT_access_fpreg.$(OBJEXT): ptrace/$(am__dirstamp) \
@@ -870,8 +1102,6 @@
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libunwind-hppa.la: $(libunwind_hppa_la_OBJECTS) $(libunwind_hppa_la_DEPENDENCIES)
- $(LINK) $(am_libunwind_hppa_la_rpath) $(libunwind_hppa_la_LDFLAGS) $(libunwind_hppa_la_OBJECTS) $(libunwind_hppa_la_LIBADD) $(LIBS)
mi/$(am__dirstamp):
@$(mkdir_p) mi
@: > mi/$(am__dirstamp)
@@ -882,13 +1112,20 @@
mi/flush_cache.lo: mi/$(am__dirstamp) mi/$(DEPDIR)/$(am__dirstamp)
mi/mempool.lo: mi/$(am__dirstamp) mi/$(DEPDIR)/$(am__dirstamp)
mi/strerror.lo: mi/$(am__dirstamp) mi/$(DEPDIR)/$(am__dirstamp)
-ia64/$(am__dirstamp):
- @$(mkdir_p) ia64
- @: > ia64/$(am__dirstamp)
-ia64/$(DEPDIR)/$(am__dirstamp):
- @$(mkdir_p) ia64/$(DEPDIR)
- @: > ia64/$(DEPDIR)/$(am__dirstamp)
-ia64/regname.lo: ia64/$(am__dirstamp) ia64/$(DEPDIR)/$(am__dirstamp)
+dwarf/$(am__dirstamp):
+ @$(mkdir_p) dwarf
+ @: > dwarf/$(am__dirstamp)
+dwarf/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) dwarf/$(DEPDIR)
+ @: > dwarf/$(DEPDIR)/$(am__dirstamp)
+dwarf/global.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
+hppa/$(am__dirstamp):
+ @$(mkdir_p) hppa
+ @: > hppa/$(am__dirstamp)
+hppa/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) hppa/$(DEPDIR)
+ @: > hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/regname.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
mi/Gdyn-extract.lo: mi/$(am__dirstamp) mi/$(DEPDIR)/$(am__dirstamp)
mi/Gdyn-remote.lo: mi/$(am__dirstamp) mi/$(DEPDIR)/$(am__dirstamp)
mi/Gfind_dynamic_proc_info.lo: mi/$(am__dirstamp) \
@@ -907,6 +1144,40 @@
mi/Gset_fpreg.lo: mi/$(am__dirstamp) mi/$(DEPDIR)/$(am__dirstamp)
mi/Gset_caching_policy.lo: mi/$(am__dirstamp) \
mi/$(DEPDIR)/$(am__dirstamp)
+dwarf/Gexpr.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
+dwarf/Gfde.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
+dwarf/Gparser.lo: dwarf/$(am__dirstamp) \
+ dwarf/$(DEPDIR)/$(am__dirstamp)
+dwarf/Gpe.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
+dwarf/Gstep.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
+dwarf/Gfind_proc_info-lsb.lo: dwarf/$(am__dirstamp) \
+ dwarf/$(DEPDIR)/$(am__dirstamp)
+hppa/Gcreate_addr_space.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Gget_save_loc.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Gglobal.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Ginit.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Ginit_local.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Ginit_remote.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Gis_signal_frame.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Gget_proc_info.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Gregs.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Gresume.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Gstep.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
+libunwind-hppa.la: $(libunwind_hppa_la_OBJECTS) $(libunwind_hppa_la_DEPENDENCIES)
+ $(LINK) $(am_libunwind_hppa_la_rpath) $(libunwind_hppa_la_LDFLAGS) $(libunwind_hppa_la_OBJECTS) $(libunwind_hppa_la_LIBADD) $(LIBS)
+ia64/$(am__dirstamp):
+ @$(mkdir_p) ia64
+ @: > ia64/$(am__dirstamp)
+ia64/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) ia64/$(DEPDIR)
+ @: > ia64/$(DEPDIR)/$(am__dirstamp)
+ia64/regname.lo: ia64/$(am__dirstamp) ia64/$(DEPDIR)/$(am__dirstamp)
ia64/Gcreate_addr_space.lo: ia64/$(am__dirstamp) \
ia64/$(DEPDIR)/$(am__dirstamp)
ia64/Gget_proc_info.lo: ia64/$(am__dirstamp) \
@@ -932,12 +1203,84 @@
ia64/Gtables.lo: ia64/$(am__dirstamp) ia64/$(DEPDIR)/$(am__dirstamp)
libunwind-ia64.la: $(libunwind_ia64_la_OBJECTS) $(libunwind_ia64_la_DEPENDENCIES)
$(LINK) $(am_libunwind_ia64_la_rpath) $(libunwind_ia64_la_LDFLAGS) $(libunwind_ia64_la_OBJECTS) $(libunwind_ia64_la_LIBADD) $(LIBS)
+ppc32/$(am__dirstamp):
+ @$(mkdir_p) ppc32
+ @: > ppc32/$(am__dirstamp)
+ppc32/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) ppc32/$(DEPDIR)
+ @: > ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/is_fpreg.lo: ppc32/$(am__dirstamp) \
+ ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/regname.lo: ppc32/$(am__dirstamp) \
+ ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/get_func_addr.lo: ppc32/$(am__dirstamp) \
+ ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc/$(am__dirstamp):
+ @$(mkdir_p) ppc
+ @: > ppc/$(am__dirstamp)
+ppc/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) ppc/$(DEPDIR)
+ @: > ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Gcreate_addr_space.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Gget_proc_info.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Gget_save_loc.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Ginit_local.lo: ppc/$(am__dirstamp) ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Ginit_remote.lo: ppc/$(am__dirstamp) ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Gis_signal_frame.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
+ppc32/Gglobal.lo: ppc32/$(am__dirstamp) \
+ ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Ginit.lo: ppc32/$(am__dirstamp) ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Gregs.lo: ppc32/$(am__dirstamp) ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Gresume.lo: ppc32/$(am__dirstamp) \
+ ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Gstep.lo: ppc32/$(am__dirstamp) ppc32/$(DEPDIR)/$(am__dirstamp)
+libunwind-ppc32.la: $(libunwind_ppc32_la_OBJECTS) $(libunwind_ppc32_la_DEPENDENCIES)
+ $(LINK) $(am_libunwind_ppc32_la_rpath) $(libunwind_ppc32_la_LDFLAGS) $(libunwind_ppc32_la_OBJECTS) $(libunwind_ppc32_la_LIBADD) $(LIBS)
+ppc64/$(am__dirstamp):
+ @$(mkdir_p) ppc64
+ @: > ppc64/$(am__dirstamp)
+ppc64/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) ppc64/$(DEPDIR)
+ @: > ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/is_fpreg.lo: ppc64/$(am__dirstamp) \
+ ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/regname.lo: ppc64/$(am__dirstamp) \
+ ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/get_func_addr.lo: ppc64/$(am__dirstamp) \
+ ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Gglobal.lo: ppc64/$(am__dirstamp) \
+ ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Ginit.lo: ppc64/$(am__dirstamp) ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Gregs.lo: ppc64/$(am__dirstamp) ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Gresume.lo: ppc64/$(am__dirstamp) \
+ ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Gstep.lo: ppc64/$(am__dirstamp) ppc64/$(DEPDIR)/$(am__dirstamp)
+libunwind-ppc64.la: $(libunwind_ppc64_la_OBJECTS) $(libunwind_ppc64_la_DEPENDENCIES)
+ $(LINK) $(am_libunwind_ppc64_la_rpath) $(libunwind_ppc64_la_LDFLAGS) $(libunwind_ppc64_la_OBJECTS) $(libunwind_ppc64_la_LIBADD) $(LIBS)
+setjmp/$(am__dirstamp):
+ @$(mkdir_p) setjmp
+ @: > setjmp/$(am__dirstamp)
+setjmp/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) setjmp/$(DEPDIR)
+ @: > setjmp/$(DEPDIR)/$(am__dirstamp)
+setjmp/longjmp.lo: setjmp/$(am__dirstamp) \
+ setjmp/$(DEPDIR)/$(am__dirstamp)
+setjmp/siglongjmp.lo: setjmp/$(am__dirstamp) \
+ setjmp/$(DEPDIR)/$(am__dirstamp)
+ppc/longjmp.lo: ppc/$(am__dirstamp) ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/siglongjmp.lo: ppc/$(am__dirstamp) ppc/$(DEPDIR)/$(am__dirstamp)
x86_64/$(am__dirstamp):
@$(mkdir_p) x86_64
@: > x86_64/$(am__dirstamp)
x86_64/$(DEPDIR)/$(am__dirstamp):
@$(mkdir_p) x86_64/$(DEPDIR)
@: > x86_64/$(DEPDIR)/$(am__dirstamp)
+x86_64/longjmp.lo: x86_64/$(am__dirstamp) \
+ x86_64/$(DEPDIR)/$(am__dirstamp)
x86_64/siglongjmp.lo: x86_64/$(am__dirstamp) \
x86_64/$(DEPDIR)/$(am__dirstamp)
x86/$(am__dirstamp):
@@ -946,13 +1289,8 @@
x86/$(DEPDIR)/$(am__dirstamp):
@$(mkdir_p) x86/$(DEPDIR)
@: > x86/$(DEPDIR)/$(am__dirstamp)
+x86/longjmp.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
x86/siglongjmp.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
-hppa/$(am__dirstamp):
- @$(mkdir_p) hppa
- @: > hppa/$(am__dirstamp)
-hppa/$(DEPDIR)/$(am__dirstamp):
- @$(mkdir_p) hppa/$(DEPDIR)
- @: > hppa/$(DEPDIR)/$(am__dirstamp)
hppa/siglongjmp.lo: hppa/$(am__dirstamp) \
hppa/$(DEPDIR)/$(am__dirstamp)
ia64/setjmp.lo: ia64/$(am__dirstamp) ia64/$(DEPDIR)/$(am__dirstamp)
@@ -962,23 +1300,8 @@
ia64/$(DEPDIR)/$(am__dirstamp)
libunwind-setjmp.la: $(libunwind_setjmp_la_OBJECTS) $(libunwind_setjmp_la_DEPENDENCIES)
$(LINK) $(am_libunwind_setjmp_la_rpath) $(libunwind_setjmp_la_LDFLAGS) $(libunwind_setjmp_la_OBJECTS) $(libunwind_setjmp_la_LIBADD) $(LIBS)
-dwarf/$(am__dirstamp):
- @$(mkdir_p) dwarf
- @: > dwarf/$(am__dirstamp)
-dwarf/$(DEPDIR)/$(am__dirstamp):
- @$(mkdir_p) dwarf/$(DEPDIR)
- @: > dwarf/$(DEPDIR)/$(am__dirstamp)
-dwarf/global.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
x86/is_fpreg.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
x86/regname.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
-dwarf/Gexpr.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
-dwarf/Gfde.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
-dwarf/Gparser.lo: dwarf/$(am__dirstamp) \
- dwarf/$(DEPDIR)/$(am__dirstamp)
-dwarf/Gpe.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
-dwarf/Gstep.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
-dwarf/Gfind_proc_info-lsb.lo: dwarf/$(am__dirstamp) \
- dwarf/$(DEPDIR)/$(am__dirstamp)
x86/Gcreate_addr_space.lo: x86/$(am__dirstamp) \
x86/$(DEPDIR)/$(am__dirstamp)
x86/Gget_save_loc.lo: x86/$(am__dirstamp) \
@@ -1093,8 +1416,34 @@
dwarf/$(DEPDIR)/$(am__dirstamp)
dwarf/Lpe.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
dwarf/Lstep.lo: dwarf/$(am__dirstamp) dwarf/$(DEPDIR)/$(am__dirstamp)
+ppc/Lcreate_addr_space.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Lget_proc_info.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Lget_save_loc.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Linit_local.lo: ppc/$(am__dirstamp) ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Linit_remote.lo: ppc/$(am__dirstamp) ppc/$(DEPDIR)/$(am__dirstamp)
+ppc/Lis_signal_frame.lo: ppc/$(am__dirstamp) \
+ ppc/$(DEPDIR)/$(am__dirstamp)
dwarf/Lfind_proc_info-lsb.lo: dwarf/$(am__dirstamp) \
dwarf/$(DEPDIR)/$(am__dirstamp)
+ppc64/Lglobal.lo: ppc64/$(am__dirstamp) \
+ ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Linit.lo: ppc64/$(am__dirstamp) ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Lregs.lo: ppc64/$(am__dirstamp) ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Lresume.lo: ppc64/$(am__dirstamp) \
+ ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc64/Lstep.lo: ppc64/$(am__dirstamp) ppc64/$(DEPDIR)/$(am__dirstamp)
+ppc32/Lglobal.lo: ppc32/$(am__dirstamp) \
+ ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Linit.lo: ppc32/$(am__dirstamp) ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Lregs.lo: ppc32/$(am__dirstamp) ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Lresume.lo: ppc32/$(am__dirstamp) \
+ ppc32/$(DEPDIR)/$(am__dirstamp)
+ppc32/Lstep.lo: ppc32/$(am__dirstamp) ppc32/$(DEPDIR)/$(am__dirstamp)
+x86_64/setcontext.lo: x86_64/$(am__dirstamp) \
+ x86_64/$(DEPDIR)/$(am__dirstamp)
x86_64/Lcreate_addr_space.lo: x86_64/$(am__dirstamp) \
x86_64/$(DEPDIR)/$(am__dirstamp)
x86_64/Lget_save_loc.lo: x86_64/$(am__dirstamp) \
@@ -1132,27 +1481,26 @@
x86/Lregs.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
x86/Lresume.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
x86/Lstep.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
-hppa/global.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/tables.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Gget_reg.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Gget_proc_name.lo: hppa/$(am__dirstamp) \
+hppa/getcontext.lo: hppa/$(am__dirstamp) \
hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Ginit.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Ginit_local.lo: hppa/$(am__dirstamp) \
+hppa/setcontext.lo: hppa/$(am__dirstamp) \
hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Gget_proc_info.lo: hppa/$(am__dirstamp) \
+hppa/Lcreate_addr_space.lo: hppa/$(am__dirstamp) \
hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Gregs.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Gstep.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Lget_reg.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
-hppa/Lget_proc_name.lo: hppa/$(am__dirstamp) \
+hppa/Lget_save_loc.lo: hppa/$(am__dirstamp) \
hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Lglobal.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
hppa/Linit.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
hppa/Linit_local.lo: hppa/$(am__dirstamp) \
hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Linit_remote.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Lis_signal_frame.lo: hppa/$(am__dirstamp) \
+ hppa/$(DEPDIR)/$(am__dirstamp)
hppa/Lget_proc_info.lo: hppa/$(am__dirstamp) \
hppa/$(DEPDIR)/$(am__dirstamp)
hppa/Lregs.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
+hppa/Lresume.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
hppa/Lstep.lo: hppa/$(am__dirstamp) hppa/$(DEPDIR)/$(am__dirstamp)
ia64/dyn_info_list.lo: ia64/$(am__dirstamp) \
ia64/$(DEPDIR)/$(am__dirstamp)
@@ -1229,40 +1577,58 @@
-rm -f dwarf/Lstep.lo
-rm -f dwarf/global.$(OBJEXT)
-rm -f dwarf/global.lo
+ -rm -f hppa/Gcreate_addr_space.$(OBJEXT)
+ -rm -f hppa/Gcreate_addr_space.lo
-rm -f hppa/Gget_proc_info.$(OBJEXT)
-rm -f hppa/Gget_proc_info.lo
- -rm -f hppa/Gget_proc_name.$(OBJEXT)
- -rm -f hppa/Gget_proc_name.lo
- -rm -f hppa/Gget_reg.$(OBJEXT)
- -rm -f hppa/Gget_reg.lo
+ -rm -f hppa/Gget_save_loc.$(OBJEXT)
+ -rm -f hppa/Gget_save_loc.lo
+ -rm -f hppa/Gglobal.$(OBJEXT)
+ -rm -f hppa/Gglobal.lo
-rm -f hppa/Ginit.$(OBJEXT)
-rm -f hppa/Ginit.lo
-rm -f hppa/Ginit_local.$(OBJEXT)
-rm -f hppa/Ginit_local.lo
+ -rm -f hppa/Ginit_remote.$(OBJEXT)
+ -rm -f hppa/Ginit_remote.lo
+ -rm -f hppa/Gis_signal_frame.$(OBJEXT)
+ -rm -f hppa/Gis_signal_frame.lo
-rm -f hppa/Gregs.$(OBJEXT)
-rm -f hppa/Gregs.lo
+ -rm -f hppa/Gresume.$(OBJEXT)
+ -rm -f hppa/Gresume.lo
-rm -f hppa/Gstep.$(OBJEXT)
-rm -f hppa/Gstep.lo
+ -rm -f hppa/Lcreate_addr_space.$(OBJEXT)
+ -rm -f hppa/Lcreate_addr_space.lo
-rm -f hppa/Lget_proc_info.$(OBJEXT)
-rm -f hppa/Lget_proc_info.lo
- -rm -f hppa/Lget_proc_name.$(OBJEXT)
- -rm -f hppa/Lget_proc_name.lo
- -rm -f hppa/Lget_reg.$(OBJEXT)
- -rm -f hppa/Lget_reg.lo
+ -rm -f hppa/Lget_save_loc.$(OBJEXT)
+ -rm -f hppa/Lget_save_loc.lo
+ -rm -f hppa/Lglobal.$(OBJEXT)
+ -rm -f hppa/Lglobal.lo
-rm -f hppa/Linit.$(OBJEXT)
-rm -f hppa/Linit.lo
-rm -f hppa/Linit_local.$(OBJEXT)
-rm -f hppa/Linit_local.lo
+ -rm -f hppa/Linit_remote.$(OBJEXT)
+ -rm -f hppa/Linit_remote.lo
+ -rm -f hppa/Lis_signal_frame.$(OBJEXT)
+ -rm -f hppa/Lis_signal_frame.lo
-rm -f hppa/Lregs.$(OBJEXT)
-rm -f hppa/Lregs.lo
+ -rm -f hppa/Lresume.$(OBJEXT)
+ -rm -f hppa/Lresume.lo
-rm -f hppa/Lstep.$(OBJEXT)
-rm -f hppa/Lstep.lo
- -rm -f hppa/global.$(OBJEXT)
- -rm -f hppa/global.lo
+ -rm -f hppa/getcontext.$(OBJEXT)
+ -rm -f hppa/getcontext.lo
+ -rm -f hppa/regname.$(OBJEXT)
+ -rm -f hppa/regname.lo
+ -rm -f hppa/setcontext.$(OBJEXT)
+ -rm -f hppa/setcontext.lo
-rm -f hppa/siglongjmp.$(OBJEXT)
-rm -f hppa/siglongjmp.lo
- -rm -f hppa/tables.$(OBJEXT)
- -rm -f hppa/tables.lo
-rm -f ia64/Gcreate_addr_space.$(OBJEXT)
-rm -f ia64/Gcreate_addr_space.lo
-rm -f ia64/Gget_proc_info.$(OBJEXT)
@@ -1413,18 +1779,103 @@
-rm -f mi/mempool.lo
-rm -f mi/strerror.$(OBJEXT)
-rm -f mi/strerror.lo
+ -rm -f ppc/Gcreate_addr_space.$(OBJEXT)
+ -rm -f ppc/Gcreate_addr_space.lo
+ -rm -f ppc/Gget_proc_info.$(OBJEXT)
+ -rm -f ppc/Gget_proc_info.lo
+ -rm -f ppc/Gget_save_loc.$(OBJEXT)
+ -rm -f ppc/Gget_save_loc.lo
+ -rm -f ppc/Ginit_local.$(OBJEXT)
+ -rm -f ppc/Ginit_local.lo
+ -rm -f ppc/Ginit_remote.$(OBJEXT)
+ -rm -f ppc/Ginit_remote.lo
+ -rm -f ppc/Gis_signal_frame.$(OBJEXT)
+ -rm -f ppc/Gis_signal_frame.lo
+ -rm -f ppc/Lcreate_addr_space.$(OBJEXT)
+ -rm -f ppc/Lcreate_addr_space.lo
+ -rm -f ppc/Lget_proc_info.$(OBJEXT)
+ -rm -f ppc/Lget_proc_info.lo
+ -rm -f ppc/Lget_save_loc.$(OBJEXT)
+ -rm -f ppc/Lget_save_loc.lo
+ -rm -f ppc/Linit_local.$(OBJEXT)
+ -rm -f ppc/Linit_local.lo
+ -rm -f ppc/Linit_remote.$(OBJEXT)
+ -rm -f ppc/Linit_remote.lo
+ -rm -f ppc/Lis_signal_frame.$(OBJEXT)
+ -rm -f ppc/Lis_signal_frame.lo
+ -rm -f ppc/longjmp.$(OBJEXT)
+ -rm -f ppc/longjmp.lo
+ -rm -f ppc/siglongjmp.$(OBJEXT)
+ -rm -f ppc/siglongjmp.lo
+ -rm -f ppc32/Gglobal.$(OBJEXT)
+ -rm -f ppc32/Gglobal.lo
+ -rm -f ppc32/Ginit.$(OBJEXT)
+ -rm -f ppc32/Ginit.lo
+ -rm -f ppc32/Gregs.$(OBJEXT)
+ -rm -f ppc32/Gregs.lo
+ -rm -f ppc32/Gresume.$(OBJEXT)
+ -rm -f ppc32/Gresume.lo
+ -rm -f ppc32/Gstep.$(OBJEXT)
+ -rm -f ppc32/Gstep.lo
+ -rm -f ppc32/Lglobal.$(OBJEXT)
+ -rm -f ppc32/Lglobal.lo
+ -rm -f ppc32/Linit.$(OBJEXT)
+ -rm -f ppc32/Linit.lo
+ -rm -f ppc32/Lregs.$(OBJEXT)
+ -rm -f ppc32/Lregs.lo
+ -rm -f ppc32/Lresume.$(OBJEXT)
+ -rm -f ppc32/Lresume.lo
+ -rm -f ppc32/Lstep.$(OBJEXT)
+ -rm -f ppc32/Lstep.lo
+ -rm -f ppc32/get_func_addr.$(OBJEXT)
+ -rm -f ppc32/get_func_addr.lo
+ -rm -f ppc32/is_fpreg.$(OBJEXT)
+ -rm -f ppc32/is_fpreg.lo
+ -rm -f ppc32/regname.$(OBJEXT)
+ -rm -f ppc32/regname.lo
+ -rm -f ppc64/Gglobal.$(OBJEXT)
+ -rm -f ppc64/Gglobal.lo
+ -rm -f ppc64/Ginit.$(OBJEXT)
+ -rm -f ppc64/Ginit.lo
+ -rm -f ppc64/Gregs.$(OBJEXT)
+ -rm -f ppc64/Gregs.lo
+ -rm -f ppc64/Gresume.$(OBJEXT)
+ -rm -f ppc64/Gresume.lo
+ -rm -f ppc64/Gstep.$(OBJEXT)
+ -rm -f ppc64/Gstep.lo
+ -rm -f ppc64/Lglobal.$(OBJEXT)
+ -rm -f ppc64/Lglobal.lo
+ -rm -f ppc64/Linit.$(OBJEXT)
+ -rm -f ppc64/Linit.lo
+ -rm -f ppc64/Lregs.$(OBJEXT)
+ -rm -f ppc64/Lregs.lo
+ -rm -f ppc64/Lresume.$(OBJEXT)
+ -rm -f ppc64/Lresume.lo
+ -rm -f ppc64/Lstep.$(OBJEXT)
+ -rm -f ppc64/Lstep.lo
+ -rm -f ppc64/get_func_addr.$(OBJEXT)
+ -rm -f ppc64/get_func_addr.lo
+ -rm -f ppc64/is_fpreg.$(OBJEXT)
+ -rm -f ppc64/is_fpreg.lo
+ -rm -f ppc64/regname.$(OBJEXT)
+ -rm -f ppc64/regname.lo
-rm -f ptrace/_UPT_access_fpreg.$(OBJEXT)
-rm -f ptrace/_UPT_access_mem.$(OBJEXT)
-rm -f ptrace/_UPT_access_reg.$(OBJEXT)
-rm -f ptrace/_UPT_accessors.$(OBJEXT)
-rm -f ptrace/_UPT_create.$(OBJEXT)
-rm -f ptrace/_UPT_destroy.$(OBJEXT)
+ -rm -f ptrace/_UPT_elf.$(OBJEXT)
-rm -f ptrace/_UPT_find_proc_info.$(OBJEXT)
-rm -f ptrace/_UPT_get_dyn_info_list_addr.$(OBJEXT)
-rm -f ptrace/_UPT_get_proc_name.$(OBJEXT)
-rm -f ptrace/_UPT_put_unwind_info.$(OBJEXT)
-rm -f ptrace/_UPT_reg_offset.$(OBJEXT)
-rm -f ptrace/_UPT_resume.$(OBJEXT)
+ -rm -f setjmp/longjmp.$(OBJEXT)
+ -rm -f setjmp/longjmp.lo
+ -rm -f setjmp/siglongjmp.$(OBJEXT)
+ -rm -f setjmp/siglongjmp.lo
-rm -f unwind/Backtrace.$(OBJEXT)
-rm -f unwind/Backtrace.lo
-rm -f unwind/DeleteException.$(OBJEXT)
@@ -1505,6 +1956,8 @@
-rm -f x86/Lstep.lo
-rm -f x86/is_fpreg.$(OBJEXT)
-rm -f x86/is_fpreg.lo
+ -rm -f x86/longjmp.$(OBJEXT)
+ -rm -f x86/longjmp.lo
-rm -f x86/regname.$(OBJEXT)
-rm -f x86/regname.lo
-rm -f x86/siglongjmp.$(OBJEXT)
@@ -1555,8 +2008,12 @@
-rm -f x86_64/Lstep.lo
-rm -f x86_64/is_fpreg.$(OBJEXT)
-rm -f x86_64/is_fpreg.lo
+ -rm -f x86_64/longjmp.$(OBJEXT)
+ -rm -f x86_64/longjmp.lo
-rm -f x86_64/regname.$(OBJEXT)
-rm -f x86_64/regname.lo
+ -rm -f x86_64/setcontext.$(OBJEXT)
+ -rm -f x86_64/setcontext.lo
-rm -f x86_64/siglongjmp.$(OBJEXT)
-rm -f x86_64/siglongjmp.lo
@@ -1565,12 +2022,8 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/longjmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os-hpux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os-linux.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setjmp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/siglongjmp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigsetjmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@dwarf/$(DEPDIR)/Gexpr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@dwarf/$(DEPDIR)/Gfde.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@dwarf/$(DEPDIR)/Gfind_proc_info-lsb.Plo@am__quote@
@@ -1584,22 +2037,29 @@
@AMDEP_TRUE@@am__include@ @am__quote@dwarf/$(DEPDIR)/Lpe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@dwarf/$(DEPDIR)/Lstep.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@dwarf/$(DEPDIR)/global.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gcreate_addr_space.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gget_proc_info.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gget_proc_name.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gget_reg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gget_save_loc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gglobal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Ginit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Ginit_local.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Ginit_remote.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gis_signal_frame.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gregs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gresume.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Gstep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lcreate_addr_space.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lget_proc_info.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lget_proc_name.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lget_reg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lget_save_loc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lglobal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Linit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Linit_local.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Linit_remote.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lis_signal_frame.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lregs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lresume.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/Lstep.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/global.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/tables.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@hppa/$(DEPDIR)/regname.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ia64/$(DEPDIR)/Gcreate_addr_space.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ia64/$(DEPDIR)/Gget_proc_info.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ia64/$(DEPDIR)/Gget_save_loc.Plo@am__quote@
@@ -1668,18 +2128,59 @@
@AMDEP_TRUE@@am__include@ @am__quote@mi/$(DEPDIR)/init.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@mi/$(DEPDIR)/mempool.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@mi/$(DEPDIR)/strerror.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Gcreate_addr_space.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Gget_proc_info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Gget_save_loc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Ginit_local.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Ginit_remote.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Gis_signal_frame.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Lcreate_addr_space.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Lget_proc_info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Lget_save_loc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Linit_local.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Linit_remote.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc/$(DEPDIR)/Lis_signal_frame.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Gglobal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Ginit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Gregs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Gresume.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Gstep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Lglobal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Linit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Lregs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Lresume.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/Lstep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/get_func_addr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/is_fpreg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc32/$(DEPDIR)/regname.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Gglobal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Ginit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Gregs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Gresume.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Gstep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Lglobal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Linit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Lregs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Lresume.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Lstep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/get_func_addr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/is_fpreg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/regname.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_access_fpreg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_access_mem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_access_reg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_accessors.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_create.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_destroy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_elf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_find_proc_info.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_get_dyn_info_list_addr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_get_proc_name.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_put_unwind_info.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_reg_offset.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_resume.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@setjmp/$(DEPDIR)/longjmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@setjmp/$(DEPDIR)/siglongjmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@unwind/$(DEPDIR)/Backtrace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@unwind/$(DEPDIR)/DeleteException.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@unwind/$(DEPDIR)/FindEnclosingFunction.Plo@am__quote@
@@ -1788,6 +2289,10 @@
-rm -rf hppa/.libs hppa/_libs
-rm -rf ia64/.libs ia64/_libs
-rm -rf mi/.libs mi/_libs
+ -rm -rf ppc/.libs ppc/_libs
+ -rm -rf ppc32/.libs ppc32/_libs
+ -rm -rf ppc64/.libs ppc64/_libs
+ -rm -rf setjmp/.libs setjmp/_libs
-rm -rf unwind/.libs unwind/_libs
-rm -rf x86/.libs x86/_libs
-rm -rf x86_64/.libs x86_64/_libs
@@ -1845,7 +2350,7 @@
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
- $(mkdir_p) $(distdir)/dwarf $(distdir)/hppa $(distdir)/ia64 $(distdir)/mi $(distdir)/ptrace $(distdir)/unwind $(distdir)/x86 $(distdir)/x86_64
+ $(mkdir_p) $(distdir)/dwarf $(distdir)/hppa $(distdir)/ia64 $(distdir)/mi $(distdir)/ppc $(distdir)/ptrace $(distdir)/setjmp $(distdir)/unwind $(distdir)/x86 $(distdir)/x86_64
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
@@ -1909,8 +2414,16 @@
-rm -f ia64/$(am__dirstamp)
-rm -f mi/$(DEPDIR)/$(am__dirstamp)
-rm -f mi/$(am__dirstamp)
+ -rm -f ppc/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ppc/$(am__dirstamp)
+ -rm -f ppc32/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ppc32/$(am__dirstamp)
+ -rm -f ppc64/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ppc64/$(am__dirstamp)
-rm -f ptrace/$(DEPDIR)/$(am__dirstamp)
-rm -f ptrace/$(am__dirstamp)
+ -rm -f setjmp/$(DEPDIR)/$(am__dirstamp)
+ -rm -f setjmp/$(am__dirstamp)
-rm -f unwind/$(DEPDIR)/$(am__dirstamp)
-rm -f unwind/$(am__dirstamp)
-rm -f x86/$(DEPDIR)/$(am__dirstamp)
@@ -1928,7 +2441,7 @@
clean-libtool clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
- -rm -rf ./$(DEPDIR) dwarf/$(DEPDIR) hppa/$(DEPDIR) ia64/$(DEPDIR) mi/$(DEPDIR) ptrace/$(DEPDIR) unwind/$(DEPDIR) x86/$(DEPDIR) x86_64/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) dwarf/$(DEPDIR) hppa/$(DEPDIR) ia64/$(DEPDIR) mi/$(DEPDIR) ppc/$(DEPDIR) ppc32/$(DEPDIR) ppc64/$(DEPDIR) ptrace/$(DEPDIR) setjmp/$(DEPDIR) unwind/$(DEPDIR) x86/$(DEPDIR) x86_64/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
@@ -1956,7 +2469,7 @@
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR) dwarf/$(DEPDIR) hppa/$(DEPDIR) ia64/$(DEPDIR) mi/$(DEPDIR) ptrace/$(DEPDIR) unwind/$(DEPDIR) x86/$(DEPDIR) x86_64/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) dwarf/$(DEPDIR) hppa/$(DEPDIR) ia64/$(DEPDIR) mi/$(DEPDIR) ppc/$(DEPDIR) ppc32/$(DEPDIR) ppc64/$(DEPDIR) ptrace/$(DEPDIR) setjmp/$(DEPDIR) unwind/$(DEPDIR) x86/$(DEPDIR) x86_64/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/src/dwarf/Gexpr.c b/src/dwarf/Gexpr.c
index b1d9464..b62c4df 100644
--- a/src/dwarf/Gexpr.c
+++ b/src/dwarf/Gexpr.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -24,7 +24,7 @@
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "dwarf_i.h"
-#include "tdep.h"
+#include "libunwind_i.h"
/* The "pick" operator provides an index range of 0..255 indicating
that the stack could at least have a depth of up to 256 elements,
@@ -106,18 +106,7 @@
[DW_OP_call_ref] = OPND1 (OFFSET)
};
-static inline unw_word_t
-sword (unw_word_t val)
-{
- switch (sizeof (unw_word_t))
- {
- case 1: return (int8_t) val;
- case 2: return (int16_t) val;
- case 4: return (int32_t) val;
- case 8: return (int64_t) val;
- default: abort ();
- }
-}
+#define sword(X) ((unw_sword_t) (X))
static inline unw_word_t
read_operand (unw_addr_space_t as, unw_accessors_t *a,
@@ -161,7 +150,7 @@
case OFFSET: /* only used by DW_OP_call_ref, which we don't implement */
default:
- Debug (1, "Unexpected operand type %d", operand_type);
+ Debug (1, "Unexpected operand type %d\n", operand_type);
ret = -UNW_EINVAL;
}
return ret;
@@ -184,12 +173,12 @@
int ret;
# define pop() \
({ \
- if (tos >= MAX_EXPR_STACK_SIZE) \
+ if ((tos - 1) >= MAX_EXPR_STACK_SIZE) \
{ \
Debug (1, "Stack underflow\n"); \
return -UNW_EINVAL; \
} \
- stack[tos--]; \
+ stack[--tos]; \
})
# define push(x) \
do { \
@@ -202,7 +191,7 @@
} while (0)
# define pick(n) \
({ \
- unsigned int _index = tos - (n); \
+ unsigned int _index = tos - 1 - (n); \
if (_index >= MAX_EXPR_STACK_SIZE) \
{ \
Debug (1, "Out-of-stack pick\n"); \
@@ -215,10 +204,14 @@
arg = c->as_arg;
a = unw_get_accessors (as);
end_addr = *addr + len;
+ *is_register = 0;
+
+ Debug (14, "len=%lu, pushing cfa=0x%lx\n",
+ (unsigned long) len, (unsigned long) c->cfa);
push (c->cfa); /* push current CFA as required by DWARF spec */
- while (*addr < len)
+ while (*addr < end_addr)
{
if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0)
return ret;
@@ -251,7 +244,8 @@
case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26:
case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29:
case DW_OP_lit30: case DW_OP_lit31:
- push (opcode = DW_OP_lit0);
+ Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0);
+ push (opcode - DW_OP_lit0);
break;
case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2:
@@ -265,6 +259,8 @@
case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26:
case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29:
case DW_OP_breg30: case DW_OP_breg31:
+ Debug (15, "OP_breg(r%d,0x%lx)\n",
+ (int) opcode - DW_OP_breg0, (unsigned long) operand1);
if ((ret = unw_get_reg (dwarf_to_cursor (c),
dwarf_to_unw_regnum (opcode - DW_OP_breg0),
&tmp1)) < 0)
@@ -273,6 +269,8 @@
break;
case DW_OP_bregx:
+ Debug (15, "OP_bregx(r%d,0x%lx)\n",
+ (int) operand1, (unsigned long) operand2);
if ((ret = unw_get_reg (dwarf_to_cursor (c),
dwarf_to_unw_regnum (operand1), &tmp1)) < 0)
return ret;
@@ -290,11 +288,13 @@
case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26:
case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29:
case DW_OP_reg30: case DW_OP_reg31:
+ Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0);
*valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0);
*is_register = 1;
return 0;
case DW_OP_regx:
+ Debug (15, "OP_regx(r%d)\n", (int) operand1);
*valp = dwarf_to_unw_regnum (operand1);
*is_register = 1;
return 0;
@@ -307,28 +307,33 @@
case DW_OP_constu:
case DW_OP_const8s:
case DW_OP_consts:
+ Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1);
push (operand1);
break;
case DW_OP_const1s:
if (operand1 & 0x80)
operand1 |= ((unw_word_t) -1) << 8;
+ Debug (15, "OP_const1s(%ld)\n", (long) operand1);
push (operand1);
break;
case DW_OP_const2s:
if (operand1 & 0x8000)
operand1 |= ((unw_word_t) -1) << 16;
+ Debug (15, "OP_const2s(%ld)\n", (long) operand1);
push (operand1);
break;
case DW_OP_const4s:
if (operand1 & 0x80000000)
operand1 |= (((unw_word_t) -1) << 16) << 16;
+ Debug (15, "OP_const4s(%ld)\n", (long) operand1);
push (operand1);
break;
case DW_OP_deref:
+ Debug (15, "OP_deref\n");
tmp1 = pop ();
if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0)
return ret;
@@ -336,6 +341,7 @@
break;
case DW_OP_deref_size:
+ Debug (15, "OP_deref_size(%d)\n", (int) operand1);
tmp1 = pop ();
switch (operand1)
{
@@ -387,22 +393,27 @@
break;
case DW_OP_dup:
+ Debug (15, "OP_dup\n");
push (pick (0));
break;
case DW_OP_drop:
+ Debug (15, "OP_drop\n");
pop ();
break;
case DW_OP_pick:
+ Debug (15, "OP_pick(%d)\n", (int) operand1);
push (pick (operand1));
break;
case DW_OP_over:
+ Debug (15, "OP_over\n");
push (pick (1));
break;
case DW_OP_swap:
+ Debug (15, "OP_swap\n");
tmp1 = pop ();
tmp2 = pop ();
push (tmp1);
@@ -410,6 +421,7 @@
break;
case DW_OP_rot:
+ Debug (15, "OP_rot\n");
tmp1 = pop ();
tmp2 = pop ();
tmp3 = pop ();
@@ -419,6 +431,7 @@
break;
case DW_OP_abs:
+ Debug (15, "OP_abs\n");
tmp1 = pop ();
if (tmp1 & ((unw_word_t) 1 << (8 * sizeof (unw_word_t) - 1)))
tmp1 = -tmp1;
@@ -426,12 +439,14 @@
break;
case DW_OP_and:
+ Debug (15, "OP_and\n");
tmp1 = pop ();
tmp2 = pop ();
push (tmp1 & tmp2);
break;
case DW_OP_div:
+ Debug (15, "OP_div\n");
tmp1 = pop ();
tmp2 = pop ();
if (tmp1)
@@ -440,6 +455,7 @@
break;
case DW_OP_minus:
+ Debug (15, "OP_minus\n");
tmp1 = pop ();
tmp2 = pop ();
tmp1 = tmp2 - tmp1;
@@ -447,6 +463,7 @@
break;
case DW_OP_mod:
+ Debug (15, "OP_mod\n");
tmp1 = pop ();
tmp2 = pop ();
if (tmp1)
@@ -455,6 +472,7 @@
break;
case DW_OP_mul:
+ Debug (15, "OP_mul\n");
tmp1 = pop ();
tmp2 = pop ();
if (tmp1)
@@ -463,101 +481,119 @@
break;
case DW_OP_neg:
+ Debug (15, "OP_neg\n");
push (-pop ());
break;
case DW_OP_not:
+ Debug (15, "OP_not\n");
push (~pop ());
break;
case DW_OP_or:
+ Debug (15, "OP_or\n");
tmp1 = pop ();
tmp2 = pop ();
push (tmp1 | tmp2);
break;
case DW_OP_plus:
+ Debug (15, "OP_plus\n");
tmp1 = pop ();
tmp2 = pop ();
push (tmp1 + tmp2);
break;
case DW_OP_plus_uconst:
+ Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1);
tmp1 = pop ();
push (tmp1 + operand1);
break;
case DW_OP_shl:
+ Debug (15, "OP_shl\n");
tmp1 = pop ();
tmp2 = pop ();
push (tmp2 << tmp1);
break;
case DW_OP_shr:
+ Debug (15, "OP_shr\n");
tmp1 = pop ();
tmp2 = pop ();
push (tmp2 >> tmp1);
break;
case DW_OP_shra:
+ Debug (15, "OP_shra\n");
tmp1 = pop ();
tmp2 = pop ();
push (sword (tmp2) >> tmp1);
break;
case DW_OP_xor:
+ Debug (15, "OP_xor\n");
tmp1 = pop ();
tmp2 = pop ();
push (tmp1 ^ tmp2);
break;
case DW_OP_le:
+ Debug (15, "OP_le\n");
tmp1 = pop ();
tmp2 = pop ();
push (sword (tmp1) <= sword (tmp2));
break;
case DW_OP_ge:
+ Debug (15, "OP_ge\n");
tmp1 = pop ();
tmp2 = pop ();
push (sword (tmp1) >= sword (tmp2));
break;
case DW_OP_eq:
+ Debug (15, "OP_eq\n");
tmp1 = pop ();
tmp2 = pop ();
push (sword (tmp1) == sword (tmp2));
break;
case DW_OP_lt:
+ Debug (15, "OP_lt\n");
tmp1 = pop ();
tmp2 = pop ();
push (sword (tmp1) < sword (tmp2));
break;
case DW_OP_gt:
+ Debug (15, "OP_gt\n");
tmp1 = pop ();
tmp2 = pop ();
push (sword (tmp1) > sword (tmp2));
break;
case DW_OP_ne:
+ Debug (15, "OP_ne\n");
tmp1 = pop ();
tmp2 = pop ();
push (sword (tmp1) != sword (tmp2));
break;
case DW_OP_skip:
+ Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
*addr += (int16_t) operand1;
break;
case DW_OP_bra:
+ Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
tmp1 = pop ();
if (tmp1)
*addr += (int16_t) operand1;
break;
case DW_OP_nop:
+ Debug (15, "OP_nop\n");
break;
case DW_OP_call2:
@@ -574,5 +610,6 @@
}
}
*valp = pop ();
+ Debug (14, "final value = 0x%lx\n", (unsigned long) *valp);
return 0;
}
diff --git a/src/dwarf/Gfde.c b/src/dwarf/Gfde.c
index 4cc5720..8a85685 100644
--- a/src/dwarf/Gfde.c
+++ b/src/dwarf/Gfde.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,10 +23,16 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <string.h>
-
#include "dwarf_i.h"
-#include "tdep.h"
+
+static inline int
+is_cie_id (unw_word_t val)
+{
+ /* DWARF spec says CIE_id is 0xffffffff (for 32-bit ELF) or
+ 0xffffffffffffffff (for 64-bit ELF). However, the GNU toolchain
+ uses 0. */
+ return (val == 0 || val == - (unw_word_t) 1);
+}
/* Note: we don't need to keep track of more than the first four
characters of the augmentation string, because we (a) ignore any
@@ -34,12 +40,11 @@
and (b) those characters that we do recognize, can't be
repeated. */
static inline int
-parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
- unw_proc_info_t *pi, unw_dyn_dwarf_fde_info_t *dfi,
- int *lsda_encodingp, void *arg)
+parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
+ const unw_proc_info_t *pi, struct dwarf_cie_info *dci, void *arg)
{
uint8_t version, ch, augstr[5], fde_encoding, handler_encoding;
- unw_word_t len, cie_end_addr, aug_size, handler = 0;
+ unw_word_t len, cie_end_addr, aug_size;
uint32_t u32val;
uint64_t u64val;
size_t i;
@@ -59,10 +64,10 @@
default: fde_encoding = DW_EH_PE_omit; break;
}
- *lsda_encodingp = DW_EH_PE_omit;
- dfi->flags = 0;
+ dci->lsda_encoding = DW_EH_PE_omit;
+ dci->handler = 0;
- if ((ret = dwarf_readu32 (as, a, addr, &u32val, arg)) < 0)
+ if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0)
return ret;
if (u32val != 0xffffffff)
@@ -71,8 +76,8 @@
uint32_t cie_id;
len = u32val;
- cie_end_addr = *addr + len;
- if ((ret = dwarf_readu32 (as, a, addr, &cie_id, arg)) < 0)
+ cie_end_addr = addr + len;
+ if ((ret = dwarf_readu32 (as, a, &addr, &cie_id, arg)) < 0)
return ret;
/* DWARF says CIE id should be 0xffffffff, but in .eh_frame, it's 0 */
if (cie_id != 0)
@@ -86,11 +91,11 @@
/* the CIE is in the 64-bit DWARF format */
uint64_t cie_id;
- if ((ret = dwarf_readu64 (as, a, addr, &u64val, arg)) < 0)
+ if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0)
return ret;
len = u64val;
- cie_end_addr = *addr + len;
- if ((ret = dwarf_readu64 (as, a, addr, &cie_id, arg)) < 0)
+ cie_end_addr = addr + len;
+ if ((ret = dwarf_readu64 (as, a, &addr, &cie_id, arg)) < 0)
return ret;
/* DWARF says CIE id should be 0xffffffffffffffff, but in
.eh_frame, it's 0 */
@@ -100,9 +105,9 @@
return -UNW_EINVAL;
}
}
- dfi->cie_instr_end = cie_end_addr;
+ dci->cie_instr_end = cie_end_addr;
- if ((ret = dwarf_readu8 (as, a, addr, &version, arg)) < 0)
+ if ((ret = dwarf_readu8 (as, a, &addr, &version, arg)) < 0)
return ret;
if (version != 1 && version != DWARF_CIE_VERSION)
@@ -116,7 +121,7 @@
memset (augstr, 0, sizeof (augstr));
for (i = 0;;)
{
- if ((ret = dwarf_readu8 (as, a, addr, &ch, arg)) < 0)
+ if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0)
return ret;
if (!ch)
@@ -126,26 +131,25 @@
augstr[i++] = ch;
}
- if ((ret = dwarf_read_uleb128 (as, a, addr, &dfi->code_align, arg)) < 0
- || (ret = dwarf_read_sleb128 (as, a, addr, &dfi->data_align, arg)) < 0)
+ if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->code_align, arg)) < 0
+ || (ret = dwarf_read_sleb128 (as, a, &addr, &dci->data_align, arg)) < 0)
return ret;
/* Read the return-address column either as a u8 or as a uleb128. */
if (version == 1)
{
- if ((ret = dwarf_readu8 (as, a, addr, &ch, arg)) < 0)
+ if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0)
return ret;
- dfi->ret_addr_column = ch;
+ dci->ret_addr_column = ch;
}
- else if ((ret = dwarf_read_uleb128 (as, a, addr, &dfi->ret_addr_column, arg))
- < 0)
+ else if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->ret_addr_column,
+ arg)) < 0)
return ret;
if (augstr[0] == 'z')
{
- dfi->flags |= UNW_DYN_DFI_FLAG_AUGMENTATION_HAS_SIZE;
- if ((ret = dwarf_read_uleb128 (as, a, addr, &aug_size, arg))
- < 0)
+ dci->sized_augmentation = 1;
+ if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0)
return ret;
}
@@ -154,28 +158,34 @@
{
case 'L':
/* read the LSDA pointer-encoding format. */
- if ((ret = dwarf_readu8 (as, a, addr, &ch, arg)) < 0)
+ if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0)
return ret;
- *lsda_encodingp = ch;
+ dci->lsda_encoding = ch;
break;
case 'R':
/* read the FDE pointer-encoding format. */
- if ((ret = dwarf_readu8 (as, a, addr, &fde_encoding, arg)) < 0)
+ if ((ret = dwarf_readu8 (as, a, &addr, &fde_encoding, arg)) < 0)
return ret;
break;
case 'P':
/* read the personality-routine pointer-encoding format. */
- if ((ret = dwarf_readu8 (as, a, addr, &handler_encoding, arg)) < 0)
+ if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0)
return ret;
- if ((ret = dwarf_read_encoded_pointer (as, a, addr, handler_encoding,
- pi, &handler, arg)) < 0)
+ if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding,
+ pi, &dci->handler, arg)) < 0)
return ret;
break;
+ case 'S':
+ /* Temporarily set it to one so dwarf_parse_fde() knows that
+ it should fetch the actual ABI/TAG pair from the FDE. */
+ dci->have_abi_marker = 1;
+ break;
+
default:
- if (dfi->flags & UNW_DYN_DFI_FLAG_AUGMENTATION_HAS_SIZE)
+ if (dci->sized_augmentation)
/* If we have the size of the augmentation body, we can skip
over the parts that we don't understand, so we're OK. */
return 0;
@@ -185,43 +195,56 @@
return -UNW_EINVAL;
}
}
- dfi->flags |= fde_encoding & UNW_DYN_DFI_FLAG_FDE_PE_MASK;
- pi->handler = handler;
+ dci->fde_encoding = fde_encoding;
+ dci->cie_instr_start = addr;
Debug (15, "CIE parsed OK, augmentation = \"%s\", handler=0x%lx\n",
- augstr, (long) handler);
- dfi->cie_instr_start = *addr;
+ augstr, (long) dci->handler);
return 0;
}
+/* Extract proc-info from the FDE starting at adress ADDR. */
+
HIDDEN int
-dwarf_parse_fde (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
- unw_proc_info_t *pi, unw_dyn_dwarf_fde_info_t *dfi, void *arg)
+dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
+ unw_word_t *addrp, unw_proc_info_t *pi,
+ int need_unwind_info,
+ void *arg)
{
unw_word_t fde_end_addr, cie_addr, cie_offset_addr, aug_end_addr = 0;
- int ret, fde_encoding, ip_range_encoding, lsda_encoding;
- unw_word_t start_ip, ip_range, aug_size;
+ unw_word_t start_ip, ip_range, aug_size, addr = *addrp;
+ int ret, ip_range_encoding;
+ struct dwarf_cie_info dci;
uint64_t u64val;
uint32_t u32val;
- Debug (12, "FDE @ 0x%lx\n", (long) *addr);
+ Debug (12, "FDE @ 0x%lx\n", (long) addr);
- /* Parse enough of the FDE to get the procedure info (LSDA and handler). */
+ memset (&dci, 0, sizeof (dci));
- if ((ret = dwarf_readu32 (as, a, addr, &u32val, arg)) < 0)
+ if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0)
return ret;
if (u32val != 0xffffffff)
{
uint32_t cie_offset;
+ /* In some configurations, an FDE with a 0 length indicates the
+ end of the FDE-table. */
+ if (u32val == 0)
+ return -UNW_ENOINFO;
+
/* the FDE is in the 32-bit DWARF format */
- fde_end_addr = *addr + u32val;
- cie_offset_addr = *addr;
+ *addrp = fde_end_addr = addr + u32val;
+ cie_offset_addr = addr;
- if ((ret = dwarf_reads32 (as, a, addr, &cie_offset, arg)) < 0)
+ if ((ret = dwarf_reads32 (as, a, &addr, &cie_offset, arg)) < 0)
return ret;
+ if (is_cie_id (cie_offset))
+ /* ignore CIEs (happens during linear searches) */
+ return 0;
+
/* DWARF says that the CIE_pointer in the FDE is a
.debug_frame-relative offset, but the GCC-generated .eh_frame
sections instead store a "pcrelative" offset, which is just
@@ -234,65 +257,80 @@
/* the FDE is in the 64-bit DWARF format */
- if ((ret = dwarf_readu64 (as, a, addr, &u64val, arg)) < 0)
+ if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0)
return ret;
- fde_end_addr = *addr + u64val;
- cie_offset_addr = *addr;
+ *addrp = fde_end_addr = addr + u64val;
+ cie_offset_addr = addr;
- if ((ret = dwarf_reads64 (as, a, addr, &cie_offset, arg)) < 0)
+ if ((ret = dwarf_reads64 (as, a, &addr, &cie_offset, arg)) < 0)
return ret;
+ if (is_cie_id (cie_offset))
+ /* ignore CIEs (happens during linear searches) */
+ return 0;
+
/* DWARF says that the CIE_pointer in the FDE is a
.debug_frame-relative offset, but the GCC-generated .eh_frame
sections instead store a "pcrelative" offset, which is just
as fine as it's self-contained. */
cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset);
}
- pi->extra.dwarf_info.fde_instr_end = fde_end_addr;
- if ((ret = parse_cie (as, a, &cie_addr, pi, &pi->extra.dwarf_info,
- &lsda_encoding, arg)) < 0)
+ if ((ret = parse_cie (as, a, cie_addr, pi, &dci, arg)) < 0)
return ret;
- fde_encoding = pi->extra.dwarf_info.flags & UNW_DYN_DFI_FLAG_FDE_PE_MASK;
/* IP-range has same encoding as FDE pointers, except that it's
always an absolute value: */
- ip_range_encoding = fde_encoding & DW_EH_PE_FORMAT_MASK;
+ ip_range_encoding = dci.fde_encoding & DW_EH_PE_FORMAT_MASK;
- if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding,
+ if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.fde_encoding,
pi, &start_ip, arg)) < 0
- || (ret = dwarf_read_encoded_pointer (as, a, addr, ip_range_encoding,
+ || (ret = dwarf_read_encoded_pointer (as, a, &addr, ip_range_encoding,
pi, &ip_range, arg)) < 0)
return ret;
pi->start_ip = start_ip;
pi->end_ip = start_ip + ip_range;
+ pi->handler = dci.handler;
- if (pi->extra.dwarf_info.flags & UNW_DYN_DFI_FLAG_AUGMENTATION_HAS_SIZE)
+ if (dci.sized_augmentation)
{
- if ((ret = dwarf_read_uleb128 (as, a, addr, &aug_size, arg))
- < 0)
+ if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0)
return ret;
- aug_end_addr = *addr + aug_size;
+ aug_end_addr = addr + aug_size;
}
- if ((ret = dwarf_read_encoded_pointer (as, a, addr, lsda_encoding,
+ if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.lsda_encoding,
pi, &pi->lsda, arg)) < 0)
return ret;
- if (pi->extra.dwarf_info.flags & UNW_DYN_DFI_FLAG_AUGMENTATION_HAS_SIZE)
- pi->extra.dwarf_info.fde_instr_start = aug_end_addr;
- else
- pi->extra.dwarf_info.fde_instr_start = *addr;
-
- /* Always set the unwind info, whether or not need_unwind_info is
- set. We had to do all the work anyhow, so there is no point in
- not doing so. */
- pi->format = UNW_INFO_FORMAT_DWARF_FDE;
- pi->unwind_info_size = sizeof (pi->extra.dwarf_info) / sizeof (unw_word_t);
- pi->unwind_info = &pi->extra.dwarf_info;
-
Debug (15, "FDE covers IP 0x%lx-0x%lx, LSDA=0x%lx\n",
(long) pi->start_ip, (long) pi->end_ip, (long) pi->lsda);
+
+ if (need_unwind_info)
+ {
+ pi->format = UNW_INFO_FORMAT_TABLE;
+ pi->unwind_info_size = sizeof (dci);
+ pi->unwind_info = mempool_alloc (&dwarf_cie_info_pool);
+ if (!pi->unwind_info)
+ return UNW_ENOMEM;
+
+ if (dci.have_abi_marker)
+ {
+ if ((ret = dwarf_readu16 (as, a, &addr, &dci.abi, arg)) < 0
+ || (ret = dwarf_readu16 (as, a, &addr, &dci.tag, arg)) < 0)
+ return ret;
+ Debug (13, "Found ABI marker = (abi=%u, tag=%u)\n",
+ dci.abi, dci.tag);
+ }
+
+ if (dci.sized_augmentation)
+ dci.fde_instr_start = aug_end_addr;
+ else
+ dci.fde_instr_start = addr;
+ dci.fde_instr_end = fde_end_addr;
+
+ memcpy (pi->unwind_info, &dci, sizeof (dci));
+ }
return 0;
}
diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c
index 83becb6..a8a3b69 100644
--- a/src/dwarf/Gfind_proc_info-lsb.c
+++ b/src/dwarf/Gfind_proc_info-lsb.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -27,13 +27,11 @@
(http://www.linuxbase.org/spec/). */
#include <link.h>
-#include <stdlib.h>
#include <stddef.h>
-#include <string.h>
#include "dwarf_i.h"
#include "dwarf-eh.h"
-#include "tdep.h"
+#include "libunwind_i.h"
struct table_entry
{
@@ -43,22 +41,68 @@
#ifndef UNW_REMOTE_ONLY
+struct callback_data
+ {
+ /* in: */
+ unw_word_t ip; /* instruction-pointer we're looking for */
+ unw_proc_info_t *pi; /* proc-info pointer */
+ int need_unwind_info;
+ /* out: */
+ int single_fde; /* did we find a single FDE? (vs. a table) */
+ unw_dyn_info_t di; /* table info (if single_fde is false) */
+ };
+
+static int
+linear_search (unw_addr_space_t as, unw_word_t ip,
+ unw_word_t eh_frame_start, unw_word_t eh_frame_end,
+ unw_word_t fde_count,
+ unw_proc_info_t *pi, int need_unwind_info, void *arg)
+{
+ unw_accessors_t *a = unw_get_accessors (unw_local_addr_space);
+ unw_word_t i = 0, fde_addr, addr = eh_frame_start;
+ int ret;
+
+ while (i++ < fde_count && addr < eh_frame_end)
+ {
+ fde_addr = addr;
+ if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, 0, arg))
+ < 0)
+ return ret;
+
+ if (ip >= pi->start_ip && ip < pi->end_ip)
+ {
+ if (!need_unwind_info)
+ return 1;
+ addr = fde_addr;
+ if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi,
+ need_unwind_info, arg))
+ < 0)
+ return ret;
+ return 1;
+ }
+ }
+ return -UNW_ENOINFO;
+}
+
/* Info is a pointer to a unw_dyn_info_t structure and, on entry,
member u.rti.segbase contains the instruction-pointer we're looking
for. */
static int
callback (struct dl_phdr_info *info, size_t size, void *ptr)
{
- unw_dyn_info_t *di = ptr;
+ struct callback_data *cb_data = ptr;
+ unw_dyn_info_t *di = &cb_data->di;
const Elf_W(Phdr) *phdr, *p_eh_hdr, *p_dynamic, *p_text;
- unw_word_t addr, eh_frame_ptr, fde_count;
- Elf_W(Addr) load_base, segbase = 0;
+ unw_word_t addr, eh_frame_start, eh_frame_end, fde_count, ip;
+ Elf_W(Addr) load_base, segbase = 0, max_load_addr = 0;
+ int ret, need_unwind_info = cb_data->need_unwind_info;
+ unw_proc_info_t *pi = cb_data->pi;
struct dwarf_eh_frame_hdr *hdr;
- unw_proc_info_t pi;
unw_accessors_t *a;
- int ret;
long n;
+ ip = cb_data->ip;
+
/* Make sure struct dl_phdr_info is at least as big as we need. */
if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
+ sizeof (info->dlpi_phnum))
@@ -80,9 +124,12 @@
if (phdr->p_type == PT_LOAD)
{
Elf_W(Addr) vaddr = phdr->p_vaddr + load_base;
- if (di->u.rti.segbase >= vaddr
- && di->u.rti.segbase < vaddr + phdr->p_memsz)
+
+ if (ip >= vaddr && ip < vaddr + phdr->p_memsz)
p_text = phdr;
+
+ if (vaddr + phdr->p_filesz > max_load_addr)
+ max_load_addr = vaddr + phdr->p_filesz;
}
else if (phdr->p_type == PT_GNU_EH_FRAME)
p_eh_hdr = phdr;
@@ -133,6 +180,7 @@
that data-relative addresses are relative to 0, i.e.,
absolute. */
di->gp = 0;
+ pi->gp = di->gp;
hdr = (struct dwarf_eh_frame_hdr *) (p_eh_hdr->p_vaddr + load_base);
if (hdr->version != DW_EH_VERSION)
@@ -142,37 +190,46 @@
return 0;
}
- if (hdr->table_enc == DW_EH_PE_omit)
- {
- Debug (1, "table `%s' doesn't have a binary search table\n",
- info->dlpi_name);
- return 0;
- }
- /* For now, only support binary-search tables which are
- data-relative and whose entries are 32 bits wide. */
- if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
- {
- Debug (1, "search table in `%s' has unexpected encoding 0x%x\n",
- info->dlpi_name, hdr->table_enc);
- return 0;
- }
-
- addr = (unw_word_t) (hdr + 1);
a = unw_get_accessors (unw_local_addr_space);
- pi.gp = di->gp;
+ addr = (unw_word_t) (hdr + 1);
- /* Read eh_frame_ptr: */
+ /* (Optionally) read eh_frame_ptr: */
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
- &addr, hdr->eh_frame_ptr_enc, &pi,
- &eh_frame_ptr, NULL)) < 0)
+ &addr, hdr->eh_frame_ptr_enc, pi,
+ &eh_frame_start, NULL)) < 0)
return ret;
- /* Read fde_count: */
+ /* (Optionally) read fde_count: */
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
- &addr, hdr->fde_count_enc, &pi,
+ &addr, hdr->fde_count_enc, pi,
&fde_count, NULL)) < 0)
return ret;
+ if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
+ {
+ /* If there is no search table or it has an unsupported
+ encoding, fall back on linear search. */
+ if (hdr->table_enc == DW_EH_PE_omit)
+ Debug (4, "table `%s' lacks search table; doing linear search\n",
+ info->dlpi_name);
+ else
+ Debug (4, "table `%s' has encoding 0x%x; doing linear search\n",
+ info->dlpi_name, hdr->table_enc);
+
+ eh_frame_end = max_load_addr; /* XXX can we do better? */
+
+ if (hdr->fde_count_enc == DW_EH_PE_omit)
+ fde_count = ~0UL;
+ if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit)
+ abort ();
+
+ cb_data->single_fde = 1;
+ return linear_search (unw_local_addr_space, ip,
+ eh_frame_start, eh_frame_end, fde_count,
+ pi, need_unwind_info, NULL);
+ }
+
+ cb_data->single_fde = 0;
di->format = UNW_INFO_FORMAT_REMOTE_TABLE;
di->start_ip = p_text->p_vaddr + load_base;
di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz;
@@ -196,16 +253,19 @@
dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info, void *arg)
{
- sigset_t saved_sigmask;
- unw_dyn_info_t di;
+ struct callback_data cb_data;
+ intrmask_t saved_mask;
int ret;
Debug (14, "looking for IP=0x%lx\n", (long) ip);
- di.u.rti.segbase = ip; /* this is cheap... */
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
- ret = dl_iterate_phdr (callback, &di);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ cb_data.ip = ip;
+ cb_data.pi = pi;
+ cb_data.need_unwind_info = need_unwind_info;
+
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
+ ret = dl_iterate_phdr (callback, &cb_data);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
if (ret <= 0)
{
@@ -213,8 +273,13 @@
return -UNW_ENOINFO;
}
- /* now search the table: */
- return dwarf_search_unwind_table (as, ip, &di, pi, need_unwind_info, arg);
+ if (cb_data.single_fde)
+ /* already got the result in *pi */
+ return 0;
+ else
+ /* search the table: */
+ return dwarf_search_unwind_table (as, ip, &cb_data.di,
+ pi, need_unwind_info, arg);
}
static inline const struct table_entry *
@@ -293,20 +358,14 @@
unw_accessors_t *a;
#ifndef UNW_LOCAL_ONLY
struct table_entry ent;
- int ret;
#endif
+ int ret;
assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE
&& (ip >= di->start_ip && ip < di->end_ip));
a = unw_get_accessors (as);
- pi->flags = 0;
- pi->unwind_info = 0;
- pi->handler = 0;
- pi->gp = 0;
- memset (&pi->extra, 0, sizeof (pi->extra));
-
#ifndef UNW_REMOTE_ONLY
if (as == unw_local_addr_space)
{
@@ -338,7 +397,14 @@
Debug (15, "ip=0x%lx, start_ip=0x%lx\n",
(long) ip, (long) (e->start_ip_offset + segbase));
fde_addr = e->fde_offset + segbase;
- return dwarf_parse_fde (as, a, &fde_addr, pi, &pi->extra.dwarf_info, arg);
+ if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi,
+ need_unwind_info, arg)) < 0)
+ return ret;
+
+ if (ip < pi->start_ip || ip >= pi->end_ip)
+ return -UNW_ENOINFO;
+
+ return 0;
}
HIDDEN void
diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c
index 3d64afe..aa87d61 100644
--- a/src/dwarf/Gparser.c
+++ b/src/dwarf/Gparser.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,10 +23,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <string.h>
-
+#include <stddef.h>
#include "dwarf_i.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool))
#define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs))
@@ -60,7 +59,7 @@
static int
run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
unw_word_t ip, unw_word_t *addr, unw_word_t end_addr,
- unw_dyn_dwarf_fde_info_t *dfi)
+ struct dwarf_cie_info *dci)
{
unw_word_t curr_ip, operand = 0, regnum, val, len, fde_encoding;
dwarf_reg_state_t *rs_stack = NULL, *new_rs, *old_rs;
@@ -90,28 +89,28 @@
switch ((dwarf_cfa_t) op)
{
case DW_CFA_advance_loc:
- curr_ip += operand * dfi->code_align;
+ curr_ip += operand * dci->code_align;
Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip);
break;
case DW_CFA_advance_loc1:
if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0)
goto fail;
- curr_ip += u8 * dfi->code_align;
+ curr_ip += u8 * dci->code_align;
Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip);
break;
case DW_CFA_advance_loc2:
if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0)
goto fail;
- curr_ip += u16 * dfi->code_align;
+ curr_ip += u16 * dci->code_align;
Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip);
break;
case DW_CFA_advance_loc4:
if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0)
goto fail;
- curr_ip += u32 * dfi->code_align;
+ curr_ip += u32 * dci->code_align;
Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip);
break;
@@ -122,7 +121,7 @@
if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0)
goto fail;
- curr_ip += u64 * dfi->code_align;
+ curr_ip += u64 * dci->code_align;
Debug (15, "CFA_MIPS_advance_loc8\n");
break;
}
@@ -143,27 +142,27 @@
}
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dfi->data_align);
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset r%lu at cfa+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_offset_extended:
if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dfi->data_align);
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_offset_extended_sf:
if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
|| ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0))
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dfi->data_align);
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_restore:
@@ -197,7 +196,7 @@
break;
case DW_CFA_set_loc:
- fde_encoding = dfi->flags & UNW_DYN_DFI_FLAG_FDE_PE_MASK;
+ fde_encoding = dci->fde_encoding;
if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding,
&c->pi, &curr_ip,
arg)) < 0)
@@ -271,9 +270,9 @@
goto fail;
set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum);
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0,
- val * dfi->data_align); /* factored! */
+ val * dci->data_align); /* factored! */
Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_def_cfa_register:
@@ -287,16 +286,16 @@
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
goto fail;
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */
- Debug (15, "CFA_def_cfa_offsets 0x%lx\n", (long) val);
+ Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val);
break;
case DW_CFA_def_cfa_offset_sf:
if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)
goto fail;
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0,
- val * dfi->data_align); /* factored! */
- Debug (15, "CFA_def_cfa_offsets_sf 0x%lx\n",
- (long) (val * dfi->data_align));
+ val * dci->data_align); /* factored! */
+ Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n",
+ (long) (val * dci->data_align));
break;
case DW_CFA_def_cfa_expression:
@@ -311,7 +310,7 @@
*addr += len;
break;
- case DW_CFA_CFA_expression:
+ case DW_CFA_expression:
if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
goto fail;
@@ -340,9 +339,9 @@
if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dfi->data_align));
- Debug (15, "CFA_GNU_negative_offsets_extended cfa+0x%lx\n",
- (long) -(val * dfi->data_align));
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align));
+ Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n",
+ (long) -(val * dci->data_align));
break;
case DW_CFA_GNU_window_save:
@@ -359,7 +358,7 @@
#endif
case DW_CFA_lo_user:
case DW_CFA_hi_user:
- Debug (1, "Unexpected CFA opcode 0x%x", op);
+ Debug (1, "Unexpected CFA opcode 0x%x\n", op);
ret = -UNW_EINVAL;
goto fail;
}
@@ -382,9 +381,13 @@
{
int ret, dynamic = 1;
+ --ip;
+
if (c->pi_valid && !need_unwind_info)
return 0;
+ memset (&c->pi, 0, sizeof (c->pi));
+
/* check dynamic info first --- it overrides everything else */
ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info,
c->as_arg);
@@ -419,32 +422,212 @@
if (c->pi_is_dynamic)
unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg);
+ else if (pi->unwind_info);
+ {
+ mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
+ pi->unwind_info = NULL;
+ }
}
static inline int
parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr)
{
- unw_dyn_dwarf_fde_info_t *dfi;
+ struct dwarf_cie_info *dci;
unw_word_t addr;
int ret;
- dfi = c->pi.unwind_info;
- c->ret_addr_column = dfi->ret_addr_column;
+ dci = c->pi.unwind_info;
+ c->ret_addr_column = dci->ret_addr_column;
- addr = dfi->cie_instr_start;
+ addr = dci->cie_instr_start;
if ((ret = run_cfi_program (c, sr, ~(unw_word_t) 0, &addr,
- dfi->cie_instr_end, dfi)) < 0)
+ dci->cie_instr_end, dci)) < 0)
return ret;
memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial));
- addr = dfi->fde_instr_start;
- if ((ret = run_cfi_program (c, sr, ip, &addr, dfi->fde_instr_end, dfi)) < 0)
+ addr = dci->fde_instr_start;
+ if ((ret = run_cfi_program (c, sr, ip, &addr, dci->fde_instr_end, dci)) < 0)
return ret;
return 0;
}
+static inline void
+flush_rs_cache (struct dwarf_rs_cache *cache)
+{
+ int i;
+
+ cache->lru_head = DWARF_UNW_CACHE_SIZE - 1;
+ cache->lru_tail = 0;
+
+ for (i = 0; i < DWARF_UNW_CACHE_SIZE; ++i)
+ {
+ if (i > 0)
+ cache->buckets[i].lru_chain = (i - 1);
+ cache->buckets[i].coll_chain = -1;
+ cache->buckets[i].ip = 0;
+ }
+ for (i = 0; i<DWARF_UNW_HASH_SIZE; ++i)
+ cache->hash[i] = -1;
+}
+
+static inline struct dwarf_rs_cache *
+get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
+{
+ struct dwarf_rs_cache *cache = &as->global_cache;
+ unw_caching_policy_t caching = as->caching_policy;
+
+ if (caching == UNW_CACHE_NONE)
+ return NULL;
+
+#ifdef HAVE_ATOMIC_H
+ if (!spin_trylock_irqsave (&cache->busy, *saved_maskp))
+ return NULL;
+#else
+# ifdef HAVE_ATOMIC_OPS_H
+ if (AO_test_and_set (&cache->busy) == AO_TS_SET)
+ return NULL;
+# else
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, saved_maskp);
+ if (likely (caching == UNW_CACHE_GLOBAL))
+ {
+ Debug (16, "%s: acquiring lock\n", __FUNCTION__);
+ mutex_lock (&cache->lock);
+ }
+# endif
+#endif
+
+ if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation))
+ {
+ flush_rs_cache (cache);
+ cache->generation = as->cache_generation;
+ }
+
+ return cache;
+}
+
+static inline void
+put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache,
+ intrmask_t *saved_maskp)
+{
+ assert (as->caching_policy != UNW_CACHE_NONE);
+
+ Debug (16, "unmasking signals/interrupts and releasing lock\n");
+#ifdef HAVE_ATOMIC_H
+ spin_unlock_irqrestore (&cache->busy, *saved_maskp);
+#else
+# ifdef HAVE_ATOMIC_OPS_H
+ AO_CLEAR (&cache->busy);
+# else
+ if (likely (as->caching_policy == UNW_CACHE_GLOBAL))
+ mutex_unlock (&cache->lock);
+ sigprocmask (SIG_SETMASK, saved_maskp, NULL);
+# endif
+#endif
+}
+
+static inline unw_hash_index_t
+hash (unw_word_t ip)
+{
+ /* based on (sqrt(5)/2-1)*2^64 */
+# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL)
+
+ return ip * magic >> ((sizeof(unw_word_t) * 8) - DWARF_LOG_UNW_HASH_SIZE);
+}
+
+static inline long
+cache_match (dwarf_reg_state_t *rs, unw_word_t ip)
+{
+ if (ip == rs->ip)
+ return 1;
+ return 0;
+}
+
+static dwarf_reg_state_t *
+rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c)
+{
+ dwarf_reg_state_t *rs = cache->buckets + c->hint;
+ unsigned short index;
+ unw_word_t ip;
+
+ ip = c->ip;
+
+ if (cache_match (rs, ip))
+ return rs;
+
+ index = cache->hash[hash (ip)];
+ if (index >= DWARF_UNW_CACHE_SIZE)
+ return 0;
+
+ rs = cache->buckets + index;
+ while (1)
+ {
+ if (cache_match (rs, ip))
+ {
+ /* update hint; no locking needed: single-word writes are atomic */
+ c->hint = cache->buckets[c->prev_rs].hint =
+ (rs - cache->buckets);
+ return rs;
+ }
+ if (rs->coll_chain >= DWARF_UNW_HASH_SIZE)
+ return 0;
+ rs = cache->buckets + rs->coll_chain;
+ }
+}
+
+static inline dwarf_reg_state_t *
+rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c)
+{
+ dwarf_reg_state_t *rs, *prev, *tmp;
+ unw_hash_index_t index;
+ unsigned short head;
+
+ head = cache->lru_head;
+ rs = cache->buckets + head;
+ cache->lru_head = rs->lru_chain;
+
+ /* re-insert rs at the tail of the LRU chain: */
+ cache->buckets[cache->lru_tail].lru_chain = head;
+ cache->lru_tail = head;
+
+ /* remove the old rs from the hash table (if it's there): */
+ if (rs->ip)
+ {
+ index = hash (rs->ip);
+ tmp = cache->buckets + cache->hash[index];
+ prev = 0;
+ while (1)
+ {
+ if (tmp == rs)
+ {
+ if (prev)
+ prev->coll_chain = tmp->coll_chain;
+ else
+ cache->hash[index] = tmp->coll_chain;
+ break;
+ }
+ else
+ prev = tmp;
+ if (tmp->coll_chain >= DWARF_UNW_CACHE_SIZE)
+ /* old rs wasn't in the hash-table */
+ break;
+ tmp = cache->buckets + tmp->coll_chain;
+ }
+ }
+
+ /* enter new rs in the hash table */
+ index = hash (c->ip);
+ rs->coll_chain = cache->hash[index];
+ cache->hash[index] = rs - cache->buckets;
+
+ rs->hint = 0;
+ rs->ip = c->ip;
+ rs->ret_addr_column = c->ret_addr_column;
+
+ return rs;
+}
+
static int
create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr,
unw_word_t ip)
@@ -453,12 +636,14 @@
assert (c->pi_valid);
- for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
+ memset (sr, 0, sizeof (*sr));
+ for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i)
set_reg (sr, i, DWARF_WHERE_SAME, 0);
switch (c->pi.format)
{
- case UNW_INFO_FORMAT_DWARF_FDE:
+ case UNW_INFO_FORMAT_TABLE:
+ case UNW_INFO_FORMAT_REMOTE_TABLE:
ret = parse_fde (c, ip, sr);
break;
@@ -466,8 +651,6 @@
ret = parse_dynamic (c, ip, sr);
break;
- case UNW_INFO_FORMAT_REMOTE_TABLE:
- case UNW_INFO_FORMAT_TABLE:
default:
Debug (1, "Unexpected unwind-info format %d\n", c->pi.format);
ret = -UNW_EINVAL;
@@ -502,20 +685,22 @@
static int
apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
{
- unw_word_t regnum, addr, cfa;
+ unw_word_t regnum, addr, cfa, ip;
+ unw_word_t prev_ip, prev_cfa;
unw_addr_space_t as;
dwarf_loc_t cfa_loc;
unw_accessors_t *a;
int i, ret;
void *arg;
+ prev_ip = c->ip;
+ prev_cfa = c->cfa;
+
as = c->as;
arg = c->as_arg;
a = unw_get_accessors (as);
- c->cfa_is_sp = 0;
-
- /* Evaluate the CFA first, because it may be referred to be other
+ /* Evaluate the CFA first, because it may be referred to by other
expressions. */
if (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG)
@@ -527,10 +712,7 @@
the stack-pointer as well. */
if ((rs->reg[DWARF_CFA_REG_COLUMN].val == UNW_TDEP_SP)
&& (rs->reg[UNW_TDEP_SP].where == DWARF_WHERE_SAME))
- {
cfa = c->cfa;
- c->cfa_is_sp = 1;
- }
else
{
regnum = dwarf_to_unw_regnum (rs->reg[DWARF_CFA_REG_COLUMN].val);
@@ -548,10 +730,11 @@
addr = rs->reg[DWARF_CFA_REG_COLUMN].val;
if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0)
return ret;
- if ((ret = dwarf_get (c, cfa_loc, &cfa)) < 0)
- return ret;
+ /* the returned location better be a memory location... */
+ if (DWARF_IS_REG_LOC (cfa_loc))
+ return -UNW_EBADFRAME;
+ cfa = DWARF_GET_LOC (cfa_loc);
}
- c->cfa = cfa;
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
{
@@ -579,11 +762,24 @@
break;
}
}
+ c->cfa = cfa;
+ ret = dwarf_get (c, c->loc[c->ret_addr_column], &ip);
+ if (ret < 0)
+ return ret;
+ c->ip = ip;
+ /* XXX: check for ip to be code_aligned */
+
+ if (c->ip == prev_ip && c->cfa == prev_cfa)
+ {
+ dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n",
+ __FUNCTION__, (long) c->ip);
+ return -UNW_EBADFRAME;
+ }
return 0;
}
-HIDDEN int
-dwarf_find_save_locs (struct dwarf_cursor *c)
+static int
+uncached_dwarf_find_save_locs (struct dwarf_cursor *c)
{
dwarf_state_record_t sr;
int ret;
@@ -601,6 +797,69 @@
return 0;
}
+/* The function finds the saved locations and applies the register
+ state as well. */
+HIDDEN int
+dwarf_find_save_locs (struct dwarf_cursor *c)
+{
+ dwarf_state_record_t sr;
+ dwarf_reg_state_t *rs, *rs1;
+ struct dwarf_rs_cache *cache;
+ int ret = 0;
+ intrmask_t saved_mask;
+
+ if (c->as->caching_policy == UNW_CACHE_NONE)
+ return uncached_dwarf_find_save_locs (c);
+
+ cache = get_rs_cache(c->as, &saved_mask);
+ if (!cache)
+ return -UNW_ENOINFO; /* cache is busy */
+ rs = rs_lookup(cache, c);
+
+ if (rs)
+ {
+ c->ret_addr_column = rs->ret_addr_column;
+ goto apply;
+ }
+
+ if ((ret = fetch_proc_info (c, c->ip, 1)) < 0)
+ goto out;
+
+ if ((ret = create_state_record_for (c, &sr, c->ip)) < 0)
+ goto out;
+
+ rs1 = &sr.rs_current;
+ if (rs1)
+ {
+ rs = rs_new (cache, c);
+ memcpy(rs, rs1, offsetof(struct dwarf_reg_state, ip));
+ if (!rs)
+ {
+ dprintf ("%s: failed to create unwind rs\n", __FUNCTION__);
+ ret = -UNW_EUNSPEC;
+ goto out;
+ }
+ }
+ cache->buckets[c->prev_rs].hint = rs - cache->buckets;
+
+ c->hint = rs->hint;
+ c->prev_rs = rs - cache->buckets;
+
+ put_unwind_info (c, &c->pi);
+ ret = apply_reg_state (c, rs);
+
+out:
+ put_rs_cache (c->as, cache, &saved_mask);
+ return ret;
+
+apply:
+ put_rs_cache (c->as, cache, &saved_mask);
+ if ((ret = apply_reg_state (c, rs)) < 0)
+ return ret;
+
+ return 0;
+}
+
/* The proc-info must be valid for IP before this routine can be
called. */
HIDDEN int
diff --git a/src/dwarf/Gpe.c b/src/dwarf/Gpe.c
index 9f7b5cf..4ca0d64 100644
--- a/src/dwarf/Gpe.c
+++ b/src/dwarf/Gpe.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -24,139 +24,14 @@
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "dwarf_i.h"
-#include "tdep.h"
+#include "libunwind_i.h"
HIDDEN int
dwarf_read_encoded_pointer (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, unsigned char encoding,
- unw_proc_info_t *pi,
+ const unw_proc_info_t *pi,
unw_word_t *valp, void *arg)
{
- unw_word_t val, initial_addr = *addr;
- uint16_t uval16;
- uint32_t uval32;
- uint64_t uval64;
- int16_t sval16;
- int32_t sval32;
- int64_t sval64;
- int ret;
-
- /* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal
- format/application encoding. Handle them first. */
- if (encoding == DW_EH_PE_omit)
- {
- *valp = 0;
- return 0;
- }
- else if (encoding == DW_EH_PE_aligned)
- {
- *addr = (initial_addr + sizeof (unw_word_t) - 1) & -sizeof (unw_word_t);
- return dwarf_readw (as, a, addr, valp, arg);
- }
-
- switch (encoding & DW_EH_PE_FORMAT_MASK)
- {
- case DW_EH_PE_ptr:
- if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
- return ret;
- break;
-
- case DW_EH_PE_uleb128:
- if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
- return ret;
- break;
-
- case DW_EH_PE_udata2:
- if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
- return ret;
- val = uval16;
- break;
-
- case DW_EH_PE_udata4:
- if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
- return ret;
- val = uval32;
- break;
-
- case DW_EH_PE_udata8:
- if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
- return ret;
- val = uval64;
- break;
-
- case DW_EH_PE_sleb128:
- if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
- return ret;
- break;
-
- case DW_EH_PE_sdata2:
- if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
- return ret;
- val = sval16;
- break;
-
- case DW_EH_PE_sdata4:
- if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
- return ret;
- val = sval32;
- break;
-
- case DW_EH_PE_sdata8:
- if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
- return ret;
- val = sval64;
- break;
-
- default:
- Debug (1, "unexpected encoding format 0x%x\n",
- encoding & DW_EH_PE_FORMAT_MASK);
- return -UNW_EINVAL;
- }
-
- if (val == 0)
- {
- /* 0 is a special value and always absolute. */
- *valp = 0;
- return 0;
- }
-
- switch (encoding & DW_EH_PE_APPL_MASK)
- {
- case DW_EH_PE_absptr:
- break;
-
- case DW_EH_PE_pcrel:
- val += initial_addr;
- break;
-
- case DW_EH_PE_datarel:
- /* XXX For now, assume that data-relative addresses are relative
- to the global pointer. */
- val += pi->gp;
- break;
-
- case DW_EH_PE_funcrel:
- val += pi->start_ip;
- break;
-
- case DW_EH_PE_textrel:
- /* XXX For now we don't support text-rel values. If there is a
- platform which needs this, we probably would have to add a
- "segbase" member to unw_proc_info_t. */
- default:
- Debug (1, "unexpected application type 0x%x\n",
- encoding & DW_EH_PE_APPL_MASK);
- return -UNW_EINVAL;
- }
-
- if (encoding & DW_EH_PE_indirect)
- {
- unw_word_t indirect_addr = val;
-
- if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
- return ret;
- }
-
- *valp = val;
- return 0;
+ return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding,
+ pi, valp, arg);
}
diff --git a/src/dwarf/Gstep.c b/src/dwarf/Gstep.c
index d75351f..a9b789c 100644
--- a/src/dwarf/Gstep.c
+++ b/src/dwarf/Gstep.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -24,112 +24,19 @@
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "dwarf.h"
-#include "tdep.h"
-
-static int
-update_frame_state (struct dwarf_cursor *c)
-{
- unw_word_t prev_ip, prev_cfa, ip;
- int ret;
-
- prev_ip = c->ip;
- prev_cfa = c->cfa;
-
- /* Update the IP cache (do this first: if we reach the end of the
- frame-chain, the rest of the info may not be valid/useful
- anymore. */
- ret = dwarf_get (c, c->loc[c->ret_addr_column], &ip);
- if (ret < 0)
- return ret;
- c->ip = ip;
-
-#if 0
- /* ??? fix me---perhaps move to where we have convenient access to
- code_align? */
- if ((ip & (c->code_align - 1)) != 0)
- {
- /* don't let obviously bad addresses pollute the cache */
- Debug (1, "rejecting bad ip=0x%lx\n", (long) c->ip);
- return -UNW_EINVALIDIP;
- }
-#endif
- if (ip == 0)
- /* end of frame-chain reached */
- return 0;
-
-#if 0
- num_regs = 0;
- if (unlikely (c->abi_marker))
- {
- c->last_abi_marker = c->abi_marker;
- switch (c->abi_marker)
- {
- case ABI_MARKER_LINUX_SIGTRAMP:
- case ABI_MARKER_OLD_LINUX_SIGTRAMP:
- c->as->abi = ABI_LINUX;
- if ((ret = linux_sigtramp (c, &num_regs)) < 0)
- return ret;
- break;
-
- case ABI_MARKER_OLD_LINUX_INTERRUPT:
- case ABI_MARKER_LINUX_INTERRUPT:
- c->as->abi = ABI_LINUX;
- if ((ret = linux_interrupt (c, &num_regs, c->abi_marker)) < 0)
- return ret;
- break;
-
- case ABI_MARKER_HP_UX_SIGTRAMP:
- c->as->abi = ABI_HPUX;
- if ((ret = hpux_sigtramp (c, &num_regs)) < 0)
- return ret;
- break;
-
- default:
- Debug (1, "unknown ABI marker: ABI=%u, context=%u\n",
- c->abi_marker >> 8, c->abi_marker & 0xff);
- return -UNW_EINVAL;
- }
- Debug (10, "sigcontext_addr=%lx (ret=%d)\n",
- (unsigned long) c->sigcontext_addr, ret);
-
- c->sigcontext_off = c->sigcontext_addr - c->cfa;
-
- /* update the IP cache: */
- if ((ret = ia64_get (c, c->loc[IA64_REG_IP], &ip)) < 0)
- return ret;
- c->ip = ip;
- if (ip == 0)
- /* end of frame-chain reached */
- return 0;
- }
- else
- num_regs = (c->cfm >> 7) & 0x7f; /* size of locals */
-
- c->abi_marker = 0;
-#endif
-
- if (c->ip == prev_ip && c->cfa == prev_cfa)
- {
- dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n",
- __FUNCTION__, (long) ip);
- return -UNW_EBADFRAME;
- }
-
- c->pi_valid = 0;
- return 0;
-}
+#include "libunwind_i.h"
HIDDEN int
dwarf_step (struct dwarf_cursor *c)
{
+ unw_word_t prev_cfa = c->cfa;
int ret;
- if ((ret = dwarf_find_save_locs (c)) < 0)
- return ret;
+ if ((ret = dwarf_find_save_locs (c)) >= 0) {
+ c->pi_valid = 0;
+ ret = (c->ip == 0) ? 0 : 1;
+ }
- if ((ret = update_frame_state (c)) < 0)
- return ret;
-
- Debug (15, "done\n");
- return (c->ip == 0) ? 0 : 1;
+ Debug (15, "returning %d\n", ret);
+ return ret;
}
diff --git a/src/dwarf/global.c b/src/dwarf/global.c
index b2812af..4658ccf 100644
--- a/src/dwarf/global.c
+++ b/src/dwarf/global.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,13 +23,15 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "dwarf.h"
+#include "dwarf_i.h"
HIDDEN struct mempool dwarf_reg_state_pool;
+HIDDEN struct mempool dwarf_cie_info_pool;
HIDDEN int
dwarf_init (void)
{
mempool_init (&dwarf_reg_state_pool, sizeof (dwarf_reg_state_t), 0);
+ mempool_init (&dwarf_cie_info_pool, sizeof (struct dwarf_cie_info), 0);
return 0;
}
diff --git a/src/elfxx.c b/src/elfxx.c
index 592b0bf..05b9943 100644
--- a/src/elfxx.c
+++ b/src/elfxx.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003-2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2003-2005 Hewlett-Packard Co
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -24,14 +25,10 @@
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
+#include "libunwind_i.h"
-#include "tdep.h"
-
-PROTECTED int
+HIDDEN int
elf_w (valid_object) (struct elf_image *ei)
{
if (ei->size <= EI_CLASS)
@@ -43,7 +40,8 @@
static int
-elf_w (lookup_symbol) (unw_word_t ip, struct elf_image *ei,
+elf_w (lookup_symbol) (unw_addr_space_t as,
+ unw_word_t ip, struct elf_image *ei,
Elf_W (Addr) load_offset,
char *buf, size_t buf_len, unw_word_t *offp)
{
@@ -102,7 +100,8 @@
if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC
&& sym->st_shndx != SHN_UNDEF)
{
- val = sym->st_value;
+ if (tdep_get_func_addr (as, sym->st_value, &val) < 0)
+ continue;
if (sym->st_shndx != SHN_ABS)
val += load_offset;
Debug (16, "0x%016lx info=0x%02x %s\n",
@@ -137,9 +136,9 @@
sped up greatly, but until an application materializes that's
sensitive to the performance of this routine, why bother... */
-PROTECTED int
-elf_w (get_proc_name) (pid_t pid, unw_word_t ip, char *buf, size_t buf_len,
- unw_word_t *offp)
+HIDDEN int
+elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip,
+ char *buf, size_t buf_len, unw_word_t *offp)
{
unsigned long segbase, mapoff;
Elf_W (Addr) load_offset = 0;
@@ -162,7 +161,7 @@
break;
}
- ret = elf_w (lookup_symbol) (ip, &ei, load_offset, buf, buf_len, offp);
+ ret = elf_w (lookup_symbol) (as, ip, &ei, load_offset, buf, buf_len, offp);
munmap (ei.image, ei.size);
ei.image = NULL;
diff --git a/src/elfxx.h b/src/elfxx.h
index 694c03d..7742806 100644
--- a/src/elfxx.h
+++ b/src/elfxx.h
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2003, 2005 Hewlett-Packard Co
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -30,7 +31,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
-#include "internal.h"
+#include "libunwind_i.h"
#if ELF_CLASS == ELFCLASS32
# define ELF_W(x) ELF32_##x
@@ -68,6 +69,7 @@
}
extern int elf_w (valid_object) (struct elf_image *ei);
-extern int elf_w (get_proc_name) (pid_t pid, unw_word_t ip,
+extern int elf_w (get_proc_name) (unw_addr_space_t as,
+ pid_t pid, unw_word_t ip,
char *buf, size_t len,
unw_word_t *offp);
diff --git a/src/hppa/Gget_reg.c b/src/hppa/Gcreate_addr_space.c
similarity index 69%
copy from src/hppa/Gget_reg.c
copy to src/hppa/Gcreate_addr_space.c
index 4553f65..8f4301f 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/hppa/Gcreate_addr_space.c
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,12 +23,30 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#include <stdlib.h>
+
#include "unwind_i.h"
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+PROTECTED unw_addr_space_t
+unw_create_addr_space (unw_accessors_t *a, int byte_order)
{
- struct cursor *c = (struct cursor *) cursor;
+#ifdef UNW_LOCAL_ONLY
+ return NULL;
+#else
+ unw_addr_space_t as = malloc (sizeof (*as));
- return hppa_access_reg (c, regnum, valp, 0);
+ if (!as)
+ return NULL;
+
+ memset (as, 0, sizeof (*as));
+
+ as->acc = *a;
+
+ /*
+ * hppa supports only big-endian.
+ */
+ if (byte_order != 0 && byte_order != __BIG_ENDIAN)
+ return NULL;
+ return as;
+#endif
}
diff --git a/src/hppa/Gget_proc_info.c b/src/hppa/Gget_proc_info.c
index cb0c560..8d2c1fd 100644
--- a/src/hppa/Gget_proc_info.c
+++ b/src/hppa/Gget_proc_info.c
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -28,15 +28,19 @@
PROTECTED int
unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi)
{
-#if 0
struct cursor *c = (struct cursor *) cursor;
- int ret;
-#endif
- printf ("%s: implement me, please\n", __FUNCTION__);
-#if 0
- if ((ret = ia64_make_proc_info (c)) < 0)
- return ret;
-#endif
+ if (dwarf_make_proc_info (&c->dwarf) < 0)
+ {
+ /* On hppa, some key routines such as _start() and _dl_start()
+ are missing DWARF unwind info. We don't want to fail in that
+ case, because those frames are uninteresting and just mark
+ the end of the frame-chain anyhow. */
+ memset (pi, 0, sizeof (*pi));
+ pi->start_ip = c->dwarf.ip;
+ pi->end_ip = c->dwarf.ip + 4;
+ return 0;
+ }
+ *pi = c->dwarf.pi;
return 0;
}
diff --git a/src/hppa/Gget_proc_name.c b/src/hppa/Gget_proc_name.c
deleted file mode 100644
index 82bb34a..0000000
--- a/src/hppa/Gget_proc_name.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
-
-This file is part of libunwind.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "unwind_i.h"
-
-PROTECTED int
-unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return unwi_get_proc_name (c->as, c->ip,
- buf, buf_len, c->as_arg);
-}
diff --git a/src/hppa/Gget_reg.c b/src/hppa/Gget_save_loc.c
similarity index 64%
copy from src/hppa/Gget_reg.c
copy to src/hppa/Gget_save_loc.c
index 4553f65..7aa6f31 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/hppa/Gget_save_loc.c
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -26,9 +26,34 @@
#include "unwind_i.h"
PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc)
{
struct cursor *c = (struct cursor *) cursor;
+ dwarf_loc_t loc;
- return hppa_access_reg (c, regnum, valp, 0);
+ loc = DWARF_NULL_LOC; /* default to "not saved" */
+
+#warning FIX ME!
+
+ memset (sloc, 0, sizeof (sloc));
+
+ if (DWARF_IS_NULL_LOC (loc))
+ {
+ sloc->type = UNW_SLT_NONE;
+ return 0;
+ }
+
+#if !defined(UNW_LOCAL_ONLY)
+ if (DWARF_IS_REG_LOC (loc))
+ {
+ sloc->type = UNW_SLT_REG;
+ sloc->u.regnum = DWARF_GET_LOC (loc);
+ }
+ else
+#endif
+ {
+ sloc->type = UNW_SLT_MEMORY;
+ sloc->u.addr = DWARF_GET_LOC (loc);
+ }
+ return 0;
}
diff --git a/include/x86/dwarf-config.h b/src/hppa/Gglobal.c
similarity index 61%
copy from include/x86/dwarf-config.h
copy to src/hppa/Gglobal.c
index b428bc9..a56426d 100644
--- a/include/x86/dwarf-config.h
+++ b/src/hppa/Gglobal.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,29 +23,35 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef dwarf_config_h
-#define dwarf_config_h
+#include "unwind_i.h"
-/* This matches the value used by GCC, which leaves plenty of room for
- expansion. */
-#define DWARF_NUM_PRESERVED_REGS 17
+HIDDEN pthread_mutex_t hppa_lock = PTHREAD_MUTEX_INITIALIZER;
+HIDDEN int tdep_needs_initialization = 1;
-#define DWARF_REGNUM_MAP_LENGTH 19
+HIDDEN void
+tdep_init (void)
+{
+ intrmask_t saved_mask;
-/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
-#define dwarf_is_big_endian(addr_space) 0
+ sigfillset (&unwi_full_mask);
-/* Convert a pointer to a dwarf_cursor structure to a pointer to
- unw_cursor_t. */
-#define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
-
-typedef struct dwarf_loc
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
+ mutex_lock (&hppa_lock);
{
- unw_word_t val;
-#ifndef UNW_LOCAL_ONLY
- unw_word_t type; /* see X86_LOC_TYPE_* macros. */
-#endif
- }
-dwarf_loc_t;
+ if (!tdep_needs_initialization)
+ /* another thread else beat us to it... */
+ goto out;
-#endif /* dwarf_config_h */
+ mi_init ();
+
+ dwarf_init ();
+
+#ifndef UNW_REMOTE_ONLY
+ hppa_local_addr_space_init ();
+#endif
+ tdep_needs_initialization = 0; /* signal that we're initialized... */
+ }
+ out:
+ mutex_unlock (&hppa_lock);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
+}
diff --git a/src/hppa/Ginit.c b/src/hppa/Ginit.c
index b95305a..5326b82 100644
--- a/src/hppa/Ginit.c
+++ b/src/hppa/Ginit.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2002, 2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -44,28 +45,19 @@
{
void *addr;
- switch (reg)
- {
- case UNW_X86_EAX: addr = &uc->uc_mcontext.gregs[REG_EAX]; break;
- case UNW_X86_EBX: addr = &uc->uc_mcontext.gregs[REG_EBX]; break;
- case UNW_X86_ECX: addr = &uc->uc_mcontext.gregs[REG_ECX]; break;
- case UNW_X86_EDX: addr = &uc->uc_mcontext.gregs[REG_EDX]; break;
- case UNW_X86_ESI: addr = &uc->uc_mcontext.gregs[REG_ESI]; break;
- case UNW_X86_EDI: addr = &uc->uc_mcontext.gregs[REG_EDI]; break;
- case UNW_X86_EBP: addr = &uc->uc_mcontext.gregs[REG_EBP]; break;
- case UNW_X86_EIP: addr = &uc->uc_mcontext.gregs[REG_EIP]; break;
- case UNW_X86_ESP: addr = &uc->uc_mcontext.gregs[REG_ESP]; break;
-
- default:
- addr = NULL;
- }
+ if ((unsigned) (reg - UNW_HPPA_GR) < 32)
+ addr = &uc->uc_mcontext.sc_gr[reg - UNW_HPPA_GR];
+ else if ((unsigned) (reg - UNW_HPPA_FR) < 32)
+ addr = &uc->uc_mcontext.sc_fr[reg - UNW_HPPA_FR];
+ else
+ addr = NULL;
return addr;
}
# ifdef UNW_LOCAL_ONLY
void *
-_Ux86_uc_addr (ucontext_t *uc, int reg)
+_Uhppa_uc_addr (ucontext_t *uc, int reg)
{
return uc_addr (uc, reg);
}
@@ -99,13 +91,13 @@
{
if (write)
{
- Debug (16, "mem[%x] <- %x\n", addr, *val);
+ Debug (12, "mem[%x] <- %x\n", addr, *val);
*(unw_word_t *) addr = *val;
}
else
{
*val = *(unw_word_t *) addr;
- Debug (16, "mem[%x] -> %x\n", addr, *val);
+ Debug (12, "mem[%x] -> %x\n", addr, *val);
}
return 0;
}
@@ -117,10 +109,8 @@
unw_word_t *addr;
ucontext_t *uc = arg;
-#if 0
- if (reg >= UNW_IA64_FR && reg < UNW_IA64_FR + 128)
+ if ((unsigned int) (reg - UNW_HPPA_FR) < 32)
goto badreg;
-#endif
addr = uc_addr (uc, reg);
if (!addr)
@@ -129,12 +119,12 @@
if (write)
{
*(unw_word_t *) addr = *val;
- Debug (16, "%s <- %x\n", unw_regname (reg), *val);
+ Debug (12, "%s <- %x\n", unw_regname (reg), *val);
}
else
{
*val = *(unw_word_t *) addr;
- Debug (16, "%s -> %x\n", unw_regname (reg), *val);
+ Debug (12, "%s -> %x\n", unw_regname (reg), *val);
}
return 0;
@@ -147,14 +137,10 @@
access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg)
{
-#if 1
- printf ("access_fpreg: screams to get implemented, doesn't it?\n");
- return 0;
-#else
ucontext_t *uc = arg;
unw_fpreg_t *addr;
- if (reg < UNW_IA64_FR || reg >= UNW_IA64_FR + 128)
+ if ((unsigned) (reg - UNW_HPPA_FR) > 32)
goto badreg;
addr = uc_addr (uc, reg);
@@ -163,14 +149,14 @@
if (write)
{
- Debug (16, "%s <- %016lx.%016lx\n",
+ Debug (12, "%s <- %08x.%08x\n",
unw_regname (reg), val->raw.bits[1], val->raw.bits[0]);
*(unw_fpreg_t *) addr = *val;
}
else
{
*val = *(unw_fpreg_t *) addr;
- Debug (16, "%s -> %016lx.%016lx\n",
+ Debug (12, "%s -> %08x.%08x\n",
unw_regname (reg), val->raw.bits[1], val->raw.bits[0]);
}
return 0;
@@ -179,21 +165,30 @@
Debug (1, "bad register number %u\n", reg);
/* attempt to access a non-preserved register */
return -UNW_EBADREG;
-#endif
+}
+
+static int
+get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
+ char *buf, size_t buf_len, unw_word_t *offp,
+ void *arg)
+{
+ return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
}
HIDDEN void
-x86_local_addr_space_init (void)
+hppa_local_addr_space_init (void)
{
memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL;
- local_addr_space.acc.find_proc_info = UNW_ARCH_OBJ (find_proc_info);
+ local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
local_addr_space.acc.access_mem = access_mem;
local_addr_space.acc.access_reg = access_reg;
local_addr_space.acc.access_fpreg = access_fpreg;
- local_addr_space.acc.resume = x86_local_resume;
+ local_addr_space.acc.resume = hppa_local_resume;
+ local_addr_space.acc.get_proc_name = get_static_proc_name;
+ unw_flush_cache (&local_addr_space, 0, 0);
}
#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/hppa/Ginit_local.c b/src/hppa/Ginit_local.c
index 57290ab..243ffd4 100644
--- a/src/hppa/Ginit_local.c
+++ b/src/hppa/Ginit_local.c
@@ -41,14 +41,13 @@
{
struct cursor *c = (struct cursor *) cursor;
- if (hppa_needs_initialization)
- {
- hppa_needs_initialization = 0;
- hppa_init ();
- }
+ if (tdep_needs_initialization)
+ tdep_init ();
- c->as = unw_local_addr_space;
- c->as_arg = uc;
+ Debug (1, "(cursor=%p)\n", c);
+
+ c->dwarf.as = unw_local_addr_space;
+ c->dwarf.as_arg = uc;
return common_init (c);
}
diff --git a/src/hppa/Gget_reg.c b/src/hppa/Ginit_remote.c
similarity index 71%
copy from src/hppa/Gget_reg.c
copy to src/hppa/Ginit_remote.c
index 4553f65..3d6606d 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/hppa/Ginit_remote.c
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,12 +23,24 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#include "init.h"
#include "unwind_i.h"
PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg)
{
+#ifdef UNW_LOCAL_ONLY
+ return -UNW_EINVAL;
+#else /* !UNW_LOCAL_ONLY */
struct cursor *c = (struct cursor *) cursor;
- return hppa_access_reg (c, regnum, valp, 0);
+ if (tdep_needs_initialization)
+ tdep_init ();
+
+ Debug (1, "(cursor=%p)\n", c);
+
+ c->dwarf.as = as;
+ c->dwarf.as_arg = as_arg;
+ return common_init (c);
+#endif /* !UNW_LOCAL_ONLY */
}
diff --git a/src/hppa/Gis_signal_frame.c b/src/hppa/Gis_signal_frame.c
new file mode 100644
index 0000000..202b570
--- /dev/null
+++ b/src/hppa/Gis_signal_frame.c
@@ -0,0 +1,74 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+PROTECTED int
+unw_is_signal_frame (unw_cursor_t *cursor)
+{
+#ifdef __linux__
+ struct cursor *c = (struct cursor *) cursor;
+ unw_word_t w0, w1, w2, w3, ip;
+ unw_addr_space_t as;
+ unw_accessors_t *a;
+ void *arg;
+ int ret;
+
+ as = c->dwarf.as;
+ a = unw_get_accessors (as);
+ arg = c->dwarf.as_arg;
+
+ /* Check if IP points at sigreturn() sequence. On Linux, this normally is:
+
+ rt_sigreturn:
+ 0x34190000 ldi 0, %r25
+ 0x3414015a ldi __NR_rt_sigreturn,%r20
+ 0xe4008200 be,l 0x100(%sr2,%r0),%sr0,%r31
+ 0x08000240 nop
+
+ When a signal interrupts a system call, the first word is instead:
+
+ 0x34190002 ldi 1, %r25
+ */
+ ip = c->dwarf.ip;
+ if (!ip)
+ return 0;
+ if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
+ || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0
+ || (ret = (*a->access_mem) (as, ip + 8, &w2, 0, arg)) < 0
+ || (ret = (*a->access_mem) (as, ip + 12, &w3, 0, arg)) < 0)
+ {
+ Debug (1, "failed to read sigreturn code (ret=%d)\n", ret);
+ return ret;
+ }
+ ret = ((w0 == 0x34190000 || w0 == 0x34190002)
+ && w1 == 0x3414015a && w2 == 0xe4008200 && w3 == 0x08000240);
+ Debug (1, "(cursor=%p, ip=0x%08lx) -> %d\n", c, (unsigned) ip, ret);
+ return ret;
+#else
+ printf ("%s: implement me\n", __FUNCTION__);
+#endif
+ return -UNW_ENOINFO;
+}
diff --git a/src/hppa/Gregs.c b/src/hppa/Gregs.c
index 14b6bb0..e6d84e3 100644
--- a/src/hppa/Gregs.c
+++ b/src/hppa/Gregs.c
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -26,31 +26,62 @@
#include "unwind_i.h"
HIDDEN int
-hppa_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
- int write)
+tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
+ int write)
{
- struct hppa_loc loc = HPPA_LOC (0, 0);
+ struct dwarf_loc loc;
switch (reg)
{
case UNW_HPPA_IP:
if (write)
- c->ip = *valp; /* also update the IP cache */
- loc = c->ip_loc;
+ c->dwarf.ip = *valp; /* update the IP cache */
+ if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip
+ || *valp >= c->dwarf.pi.end_ip))
+ c->dwarf.pi_valid = 0; /* new IP outside of current proc */
break;
+ case UNW_HPPA_CFA:
case UNW_HPPA_SP:
if (write)
return -UNW_EREADONLYREG;
- *valp = c->sp;
+ *valp = c->dwarf.cfa;
return 0;
+ /* Do the exception-handling register remapping: */
+ case UNW_HPPA_EH0: reg = UNW_HPPA_GR + 20; break;
+ case UNW_HPPA_EH1: reg = UNW_HPPA_GR + 21; break;
+ case UNW_HPPA_EH2: reg = UNW_HPPA_GR + 22; break;
+ case UNW_HPPA_EH3: reg = UNW_HPPA_GR + 31; break;
+
default:
- return -UNW_EBADREG;
+ break;
}
+ if ((unsigned) (reg - UNW_HPPA_GR) >= 32)
+ return -UNW_EBADREG;
+
+ loc = c->dwarf.loc[reg];
+
if (write)
- return hppa_put (c, loc, *valp);
+ return dwarf_put (&c->dwarf, loc, *valp);
else
- return hppa_get (c, loc, valp);
+ return dwarf_get (&c->dwarf, loc, valp);
+}
+
+HIDDEN int
+tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
+ int write)
+{
+ struct dwarf_loc loc;
+
+ if ((unsigned) (reg - UNW_HPPA_FR) >= 32)
+ return -UNW_EBADREG;
+
+ loc = c->dwarf.loc[reg];
+
+ if (write)
+ return dwarf_putfp (&c->dwarf, loc, *valp);
+ else
+ return dwarf_getfp (&c->dwarf, loc, valp);
}
diff --git a/src/hppa/Gresume.c b/src/hppa/Gresume.c
new file mode 100644
index 0000000..92d506d
--- /dev/null
+++ b/src/hppa/Gresume.c
@@ -0,0 +1,145 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <stdlib.h>
+
+#include "unwind_i.h"
+
+#ifndef UNW_REMOTE_ONLY
+
+#if defined(__linux)
+
+# include <sys/syscall.h>
+
+static NORETURN inline long
+my_rt_sigreturn (void *new_sp, int in_syscall)
+{
+ register unsigned long r25 __asm__ ("r25") = (in_syscall != 0);
+ register unsigned long r20 __asm__ ("r20") = SYS_rt_sigreturn;
+
+ __asm__ __volatile__ ("copy %0, %%sp\n"
+ "be,l 0x100(%%sr2,%%r0),%%sr0,%%r31\n"
+ "nop"
+ :
+ : "r"(new_sp), "r"(r20), "r"(r25)
+ : "memory");
+ abort ();
+}
+
+#endif /* __linux */
+
+HIDDEN inline int
+hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
+{
+#if defined(__linux)
+ struct cursor *c = (struct cursor *) cursor;
+ ucontext_t *uc = c->dwarf.as_arg;
+
+ /* Ensure c->pi is up-to-date. On PA-RISC, it's relatively common to be
+ missing DWARF unwind info. We don't want to fail in that case,
+ because the frame-chain still would let us do a backtrace at
+ least. */
+ dwarf_make_proc_info (&c->dwarf);
+
+ if (unlikely (c->sigcontext_format != HPPA_SCF_NONE))
+ {
+ struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
+
+ Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
+ my_rt_sigreturn (sc, (sc->sc_flags & PARISC_SC_FLAG_IN_SYSCALL) != 0);
+ }
+ else
+ {
+ Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
+ setcontext (uc);
+ }
+#else
+# warning Implement me!
+#endif
+ return -UNW_EINVAL;
+}
+
+#endif /* !UNW_REMOTE_ONLY */
+
+/* This routine is responsible for copying the register values in
+ cursor C and establishing them as the current machine state. */
+
+static inline int
+establish_machine_state (struct cursor *c)
+{
+ int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *,
+ int write, void *);
+ int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *,
+ int write, void *);
+ unw_addr_space_t as = c->dwarf.as;
+ void *arg = c->dwarf.as_arg;
+ unw_fpreg_t fpval;
+ unw_word_t val;
+ int reg;
+
+ access_reg = as->acc.access_reg;
+ access_fpreg = as->acc.access_fpreg;
+
+ Debug (8, "copying out cursor state\n");
+
+ for (reg = 0; reg <= UNW_REG_LAST; ++reg)
+ {
+ Debug (16, "copying %s %d\n", unw_regname (reg), reg);
+ if (unw_is_fpreg (reg))
+ {
+ if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
+ (*access_fpreg) (as, reg, &fpval, 1, arg);
+ }
+ else
+ {
+ if (tdep_access_reg (c, reg, &val, 0) >= 0)
+ (*access_reg) (as, reg, &val, 1, arg);
+ }
+ }
+ return 0;
+}
+
+PROTECTED int
+unw_resume (unw_cursor_t *cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ int ret;
+
+ Debug (1, "(cursor=%p)\n", c);
+
+ if (!c->dwarf.ip)
+ {
+ /* This can happen easily when the frame-chain gets truncated
+ due to bad or missing unwind-info. */
+ Debug (1, "refusing to resume execution at address 0\n");
+ return -UNW_EINVAL;
+ }
+
+ if ((ret = establish_machine_state (c)) < 0)
+ return ret;
+
+ return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c,
+ c->dwarf.as_arg);
+}
diff --git a/src/hppa/Gstep.c b/src/hppa/Gstep.c
index d49fdfc..abff456 100644
--- a/src/hppa/Gstep.c
+++ b/src/hppa/Gstep.c
@@ -24,117 +24,73 @@
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "unwind_i.h"
-
-static inline int
-update_frame_state (struct cursor *c)
-{
-#if 0
- unw_word_t prev_ip, prev_sp, prev_bsp, ip, pr, num_regs, cfm;
- int ret;
-
- prev_ip = c->ip;
- prev_sp = c->sp;
- prev_bsp = c->bsp;
-
- c->cfm_loc = c->pfs_loc;
-
- num_regs = 0;
- if (c->is_signal_frame)
- {
- ret = ia64_get (c, c->sp + 0x10 + SIGFRAME_ARG2_OFF, &c->sigcontext_loc);
- Debug (12, "sigcontext_loc=%lx (ret=%d)\n", c->sigcontext_loc, ret);
- if (ret < 0)
- return ret;
-
- if (c->ip_loc == c->sigcontext_loc + SIGCONTEXT_BR_OFF + 0*8)
- {
- /* Earlier kernels (before 2.4.19 and 2.5.10) had buggy
- unwind info for sigtramp. Fix it up here. */
- c->ip_loc = (c->sigcontext_loc + SIGCONTEXT_IP_OFF);
- c->cfm_loc = (c->sigcontext_loc + SIGCONTEXT_CFM_OFF);
- }
-
- /* do what can't be described by unwind directives: */
- c->pfs_loc = (c->sigcontext_loc + SIGCONTEXT_AR_PFS_OFF);
-
- ret = ia64_get (c, c->cfm_loc, &cfm);
- if (ret < 0)
- return ret;
-
- num_regs = cfm & 0x7f; /* size of frame */
- }
- else
- {
- ret = ia64_get (c, c->cfm_loc, &cfm);
- if (ret < 0)
- return ret;
- num_regs = (cfm >> 7) & 0x7f; /* size of locals */
- }
- c->bsp = ia64_rse_skip_regs (c->bsp, -num_regs);
-
- /* update the IP cache: */
- ret = ia64_get (c, c->ip_loc, &ip);
- if (ret < 0)
- return ret;
- c->ip = ip;
-
- if ((ip & 0xc) != 0)
- {
- /* don't let obviously bad addresses pollute the cache */
- Debug (1, "rejecting bad ip=0x%lx\n", (long) c->ip);
- return -UNW_EINVALIDIP;
- }
- if (ip == 0)
- /* end of frame-chain reached */
- return 0;
-
- pr = c->pr;
- c->sp = c->psp;
- c->is_signal_frame = 0;
-
- if (c->ip == prev_ip && c->sp == prev_sp && c->bsp == prev_bsp)
- {
- dprintf ("%s: ip, sp, and bsp unchanged; stopping here (ip=0x%lx)\n",
- __FUNCTION__, (long) ip);
- return -UNW_EBADFRAME;
- }
-
- /* as we unwind, the saved ar.unat becomes the primary unat: */
- c->pri_unat_loc = c->unat_loc;
-
- /* restore the predicates: */
- ret = ia64_get (c, c->pr_loc, &c->pr);
- if (ret < 0)
- return ret;
-
- c->pi_valid = 0;
-#endif
- return 0;
-}
-
+#include "offsets.h"
PROTECTED int
unw_step (unw_cursor_t *cursor)
{
struct cursor *c = (struct cursor *) cursor;
- int ret;
+ int ret, i;
- ret = hppa_get (c, c->sp_loc, &c->sp);
- if (ret < 0)
- return ret;
+ Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);
- c->sp_loc = HPPA_LOC (c->sp, 0);
- c->ip_loc = HPPA_LOC (c->sp + 4, 0);
- c->sp += 8;
+ /* Try DWARF-based unwinding... */
+ ret = dwarf_step (&c->dwarf);
- if (HPPA_GET_LOC (c->sp_loc))
+ if (ret < 0 && ret != -UNW_ENOINFO)
{
- ret = hppa_get (c, c->ip_loc, &c->ip);
- if (ret < 0)
- return ret;
+ Debug (2, "returning %d\n", ret);
+ return ret;
}
- else
- c->ip = 0;
- return (c->ip == 0) ? 0 : 1;
+ if (unlikely (ret < 0))
+ {
+ /* DWARF failed, let's see if we can follow the frame-chain
+ or skip over the signal trampoline. */
+
+ Debug (13, "dwarf_step() failed (ret=%d), trying fallback\n", ret);
+
+ if (unw_is_signal_frame (cursor))
+ {
+#ifdef __linux__
+ /* Assume that the trampoline is at the beginning of the
+ sigframe. */
+ unw_word_t ip, sc_addr = c->dwarf.ip + LINUX_RT_SIGFRAME_UC_OFF;
+ dwarf_loc_t iaoq_loc = DWARF_LOC (sc_addr + LINUX_SC_IAOQ_OFF, 0);
+
+ c->sigcontext_format = HPPA_SCF_LINUX_RT_SIGFRAME;
+ c->sigcontext_addr = sc_addr;
+ c->dwarf.ret_addr_column = UNW_HPPA_RP;
+
+ if ((ret = dwarf_get (&c->dwarf, iaoq_loc, &ip)) , 0)
+ {
+ Debug (2, "failed to read IAOQ[1] (ret=%d)\n", ret);
+ return ret;
+ }
+ c->dwarf.ip = ip & ~0x3; /* mask out the privilege level */
+
+ for (i = 0; i < 32; ++i)
+ {
+ c->dwarf.loc[UNW_HPPA_GR + i]
+ = DWARF_LOC (sc_addr + LINUX_SC_GR_OFF + 4*i, 0);
+ c->dwarf.loc[UNW_HPPA_FR + i]
+ = DWARF_LOC (sc_addr + LINUX_SC_FR_OFF + 4*i, 0);
+ }
+
+ if ((ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP],
+ &c->dwarf.cfa)) < 0)
+ {
+ Debug (2, "failed to read SP (ret=%d)\n", ret);
+ return ret;
+ }
+#else
+# error Implement me!
+#endif
+ }
+ else
+ c->dwarf.ip = 0;
+ }
+ ret = (c->dwarf.ip == 0) ? 0 : 1;
+ Debug (2, "returning %d\n", ret);
+ return ret;
}
diff --git a/src/hppa/Lget_proc_name.c b/src/hppa/Lcreate_addr_space.c
similarity index 77%
copy from src/hppa/Lget_proc_name.c
copy to src/hppa/Lcreate_addr_space.c
index 378097b..0f2dc6b 100644
--- a/src/hppa/Lget_proc_name.c
+++ b/src/hppa/Lcreate_addr_space.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_proc_name.c"
+#include "Gcreate_addr_space.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/hppa/Lget_save_loc.c
similarity index 80%
copy from src/hppa/Lget_reg.c
copy to src/hppa/Lget_save_loc.c
index effe8a8..9ea048a 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/hppa/Lget_save_loc.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gget_save_loc.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/hppa/Lglobal.c
similarity index 83%
copy from src/hppa/Lget_reg.c
copy to src/hppa/Lglobal.c
index effe8a8..6d7b489 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/hppa/Lglobal.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gglobal.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/hppa/Linit_remote.c
similarity index 80%
copy from src/hppa/Lget_reg.c
copy to src/hppa/Linit_remote.c
index effe8a8..58cb04a 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/hppa/Linit_remote.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Ginit_remote.c"
#endif
diff --git a/src/hppa/Lget_proc_name.c b/src/hppa/Lis_signal_frame.c
similarity index 78%
copy from src/hppa/Lget_proc_name.c
copy to src/hppa/Lis_signal_frame.c
index 378097b..b9a7c4f 100644
--- a/src/hppa/Lget_proc_name.c
+++ b/src/hppa/Lis_signal_frame.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_proc_name.c"
+#include "Gis_signal_frame.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/hppa/Lresume.c
similarity index 83%
rename from src/hppa/Lget_reg.c
rename to src/hppa/Lresume.c
index effe8a8..41a8cf0 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/hppa/Lresume.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gresume.c"
#endif
diff --git a/src/hppa/getcontext.S b/src/hppa/getcontext.S
new file mode 100644
index 0000000..ec7554a
--- /dev/null
+++ b/src/hppa/getcontext.S
@@ -0,0 +1,74 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define SPILL(n) stw %r##n, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26)
+
+#include "offsets.h"
+
+ .align 4
+ .protected _Uhppa_getcontext
+ .global _Uhppa_getcontext
+ .proc
+ .callinfo
+_Uhppa_getcontext:
+ SPILL (2) /* return-pointer */
+ SPILL (3) /* frame pointer */
+ SPILL (4) /* 2nd-ary frame pointer */
+ SPILL (5) /* preserved register */
+ SPILL (6) /* preserved register */
+ SPILL (7) /* preserved register */
+ SPILL (8) /* preserved register */
+ SPILL (9) /* preserved register */
+ SPILL (10) /* preserved register */
+ SPILL (11) /* preserved register */
+ SPILL (12) /* preserved register */
+ SPILL (13) /* preserved register */
+ SPILL (14) /* preserved register */
+ SPILL (15) /* preserved register */
+ SPILL (16) /* preserved register */
+ SPILL (17) /* preserved register */
+ SPILL (18) /* preserved register */
+ SPILL (19) /* linkage-table register */
+ SPILL (27) /* global-data pointer */
+ SPILL (30) /* stack pointer */
+
+ ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29
+ fstds,ma %fr12, 8(%r29)
+ fstds,ma %fr13, 8(%r29)
+ fstds,ma %fr14, 8(%r29)
+ fstds,ma %fr15, 8(%r29)
+ fstds,ma %fr16, 8(%r29)
+ fstds,ma %fr17, 8(%r29)
+ fstds,ma %fr18, 8(%r29)
+ fstds,ma %fr19, 8(%r29)
+ fstds,ma %fr20, 8(%r29)
+ fstds %fr21, 8(%r29)
+
+ bv,n %r0(%rp)
+ .procend
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/hppa/global.c b/src/hppa/global.c
deleted file mode 100644
index 11237dc..0000000
--- a/src/hppa/global.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "unwind_i.h"
-
-HIDDEN int hppa_needs_initialization = 1;
-
-HIDDEN void
-hppa_init (void)
-{
- extern void _ULhppa_local_addr_space_init (void);
-
- mi_init();
-
- _Uhppa_local_addr_space_init ();
- _ULhppa_local_addr_space_init ();
-}
diff --git a/src/hppa/offsets.h b/src/hppa/offsets.h
new file mode 100644
index 0000000..d824770
--- /dev/null
+++ b/src/hppa/offsets.h
@@ -0,0 +1,17 @@
+#define LINUX_UC_FLAGS_OFF 0x000
+#define LINUX_UC_LINK_OFF 0x004
+#define LINUX_UC_STACK_OFF 0x008
+#define LINUX_UC_MCONTEXT_OFF 0x018
+#define LINUX_UC_SIGMASK_OFF 0x1b8
+
+#define LINUX_SC_FLAGS_OFF 0x000
+#define LINUX_SC_GR_OFF 0x004
+#define LINUX_SC_FR_OFF 0x088
+#define LINUX_SC_IASQ_OFF 0x188
+#define LINUX_SC_IAOQ_OFF 0x190
+#define LINUX_SC_SAR_OFF 0x198
+
+/* The signal frame contains 4 words of space for the sigreturn
+ trampoline, the siginfo structure, and then the sigcontext
+ structure. See include/asm-parisc/compat_rt_sigframe.h. */
+#define LINUX_RT_SIGFRAME_UC_OFF 0xac
diff --git a/src/hppa/regname.c b/src/hppa/regname.c
new file mode 100644
index 0000000..07cae8e
--- /dev/null
+++ b/src/hppa/regname.c
@@ -0,0 +1,50 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+static const char *regname[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
+ "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31",
+ "ip",
+ "eh0", "eh1", "eh2", "eh3",
+ "cfa"
+ };
+
+PROTECTED const char *
+unw_regname (unw_regnum_t reg)
+{
+ if (reg < (unw_regnum_t) ARRAY_SIZE (regname))
+ return regname[reg];
+ else
+ return "???";
+}
diff --git a/src/hppa/setcontext.S b/src/hppa/setcontext.S
new file mode 100644
index 0000000..a36ea35
--- /dev/null
+++ b/src/hppa/setcontext.S
@@ -0,0 +1,77 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+/* The setcontext() in glibc is a no-op (as of 4 Dec 2004), so we have
+ to implement something useful on our own here. */
+
+#define FILL(n) ldw (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26),%r##n
+
+#include "offsets.h"
+
+ .align 4
+ .global _Uhppa_setcontext
+ .protected _Uhppa_setcontext
+ .proc
+ .callinfo
+_Uhppa_setcontext:
+ FILL (2) /* return-pointer */
+ FILL (3) /* frame pointer */
+ FILL (4) /* 2nd-ary frame pointer */
+ FILL (5) /* preserved register */
+ FILL (6) /* preserved register */
+ FILL (7) /* preserved register */
+ FILL (8) /* preserved register */
+ FILL (9) /* preserved register */
+ FILL (10) /* preserved register */
+ FILL (11) /* preserved register */
+ FILL (12) /* preserved register */
+ FILL (13) /* preserved register */
+ FILL (14) /* preserved register */
+ FILL (15) /* preserved register */
+ FILL (16) /* preserved register */
+ FILL (17) /* preserved register */
+ FILL (18) /* preserved register */
+ FILL (19) /* linkage-table register */
+ FILL (27) /* global-data pointer */
+ FILL (30) /* stack pointer */
+
+ ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29
+ fldds,ma 8(%r29), %fr12
+ fldds,ma 8(%r29), %fr13
+ fldds,ma 8(%r29), %fr14
+ fldds,ma 8(%r29), %fr15
+ fldds,ma 8(%r29), %fr16
+ fldds,ma 8(%r29), %fr17
+ fldds,ma 8(%r29), %fr18
+ fldds,ma 8(%r29), %fr19
+ fldds,ma 8(%r29), %fr20
+ fldds 8(%r29), %fr21
+
+ bv,n %r0(%rp)
+ .procend
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/hppa/siglongjmp.S b/src/hppa/siglongjmp.S
index 194f205..34878db 100644
--- a/src/hppa/siglongjmp.S
+++ b/src/hppa/siglongjmp.S
@@ -1 +1,16 @@
-# warning Implement me.
+ /* Dummy implementation for now. */
+
+ .globl _UI_siglongjmp_cont
+ .globl _UI_longjmp_cont
+
+_UI_siglongjmp_cont:
+_UI_longjmp_cont:
+ .proc
+ .callinfo
+#warning fix me
+ bv %r0(%rp)
+ .procend
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/hppa/unwind_i.h b/src/hppa/unwind_i.h
index 62b8111..d3c11be 100644
--- a/src/hppa/unwind_i.h
+++ b/src/hppa/unwind_i.h
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004-2005 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -31,122 +31,18 @@
#include <libunwind-hppa.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
-#define HPPA_GET_LOC(l) ((l).val)
-
-#ifdef UNW_LOCAL_ONLY
-# define HPPA_LOC(r, t) ((struct hppa_loc) { .val = (r) })
-# define HPPA_REG_LOC(c,r) (HPPA_LOC((unw_word_t) \
- tdep_uc_addr((c)->as_arg, (r)), 0))
-# define HPPA_FPREG_FLOC(c,r) (HPPA_LOC((unw_word_t) \
- tdep_uc_addr((c)->as_arg, (r)), 0))
-
-static inline int
-hppa_getfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t *val)
-{
- if (!HPPA_GET_LOC (loc))
- return -1;
- *val = *(unw_fpreg_t *) HPPA_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-hppa_putfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t *val)
-{
- if (!HPPA_GET_LOC (loc))
- return -1;
- *(unw_fpreg_t *) HPPA_GET_LOC (loc) = *val;
- return 0;
-}
-
-static inline int
-hppa_get (struct cursor *c, struct hppa_loc loc, unw_word_t *val)
-{
- if (!HPPA_GET_LOC (loc))
- return -1;
- *val = *(unw_word_t *) HPPA_GET_LOC (loc);
- return 0;
-}
-
-static inline int
-hppa_put (struct cursor *c, struct hppa_loc loc, unw_word_t val)
-{
- if (!HPPA_GET_LOC (loc))
- return -1;
- *(unw_word_t *) HPPA_GET_LOC (loc) = val;
- return 0;
-}
-
-#else /* !UNW_LOCAL_ONLY */
-# define HPPA_LOC_TYPE_FP (1 << 0)
-# define HPPA_LOC_TYPE_REG (1 << 1)
-# define HPPA_LOC(r, t) ((struct hppa_loc) { .val = (r), .type = (t) })
-# define HPPA_IS_REG_LOC(l) (((l).type & HPPA_LOC_TYPE_REG) != 0)
-# define HPPA_IS_FP_LOC(l) (((l).type & HPPA_LOC_TYPE_FP) != 0)
-# define HPPA_REG_LOC(c,r) HPPA_LOC((r), HPPA_LOC_TYPE_REG)
-# define HPPA_FPREG_LOC(c,r) HPPA_LOC((r), (HPPA_LOC_TYPE_REG \
- | HPPA_LOC_TYPE_FP))
-
-static inline int
-hppa_getfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t *val)
-{
- abort ();
-}
-
-static inline int
-hppa_putfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t val)
-{
- abort ();
-}
-
-static inline int
-hppa_get (struct cursor *c, struct hppa_loc loc, unw_word_t *val)
-{
- if (HPPA_IS_FP_LOC (loc))
- abort ();
-
- if (HPPA_IS_REG_LOC (loc))
- return (*c->as->acc.access_reg)(c->as, HPPA_GET_LOC (loc), val, 0,
- c->as_arg);
- else
- return (*c->as->acc.access_mem)(c->as, HPPA_GET_LOC (loc), val, 0,
- c->as_arg);
-}
-
-static inline int
-hppa_put (struct cursor *c, struct hppa_loc loc, unw_word_t val)
-{
- if (HPPA_IS_FP_LOC (loc))
- abort ();
-
- if (HPPA_IS_REG_LOC (loc))
- return (*c->as->acc.access_reg)(c->as, HPPA_GET_LOC (loc), &val, 1,
- c->as_arg);
- else
- return (*c->as->acc.access_mem)(c->as, HPPA_GET_LOC (loc), &val, 1,
- c->as_arg);
-}
-
-#endif /* !UNW_LOCAL_ONLY */
-
-#define hppa_needs_initialization UNW_ARCH_OBJ(needs_initialization)
-#define hppa_init UNW_ARCH_OBJ(init)
-#define hppa_access_reg UNW_OBJ(access_reg)
-#define hppa_access_fpreg UNW_OBJ(access_fpreg)
+#define hppa_lock UNW_OBJ(lock)
#define hppa_local_resume UNW_OBJ(local_resume)
#define hppa_local_addr_space_init UNW_OBJ(local_addr_space_init)
+#define hppa_scratch_loc UNW_OBJ(scratch_loc)
+#define setcontext UNW_ARCH_OBJ (setcontext)
-extern int hppa_needs_initialization;
-
-extern void hppa_init (void);
-extern int hppa_access_reg (struct cursor *c, unw_regnum_t reg,
- unw_word_t *valp, int write);
-extern int hppa_access_fpreg (struct cursor *c, unw_regnum_t reg,
- unw_fpreg_t *valp, int write);
extern void hppa_local_addr_space_init (void);
extern int hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
void *arg);
+extern dwarf_loc_t hppa_scratch_loc (struct cursor *c, unw_regnum_t reg);
+extern int setcontext (const ucontext_t *ucp);
#endif /* unwind_i_h */
diff --git a/src/ia64/Gget_save_loc.c b/src/ia64/Gget_save_loc.c
index 80e42d6..7bc2b19 100644
--- a/src/ia64/Gget_save_loc.c
+++ b/src/ia64/Gget_save_loc.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2003 Hewlett-Packard Co
+ Copyright (C) 2002-2003, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -25,7 +25,7 @@
#include <assert.h>
-#include "ia64/rse.h"
+#include "rse.h"
#include "offsets.h"
#include "regs.h"
diff --git a/src/ia64/Gglobal.c b/src/ia64/Gglobal.c
index 65711ca..9525f8c 100644
--- a/src/ia64/Gglobal.c
+++ b/src/ia64/Gglobal.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -65,13 +65,13 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
uint8_t *lep, *bep;
long i;
- sigfillset (&unwi_full_sigmask);
+ sigfillset (&unwi_full_mask);
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
mutex_lock (&unw.lock);
{
if (!tdep_needs_initialization)
@@ -121,5 +121,5 @@
}
out:
mutex_unlock (&unw.lock);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
}
diff --git a/src/ia64/Ginit.c b/src/ia64/Ginit.c
index 41aab73..5afa9ab 100644
--- a/src/ia64/Ginit.c
+++ b/src/ia64/Ginit.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2001-2005 Hewlett-Packard Co
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -23,52 +24,12 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <alloca.h>
-#include <stdlib.h>
-
#include "unwind_i.h"
#ifdef HAVE_SYS_UC_ACCESS_H
# include <sys/uc_access.h>
#endif
-#if UNW_DEBUG
-
-HIDDEN const char *
-ia64_strloc (ia64_loc_t loc)
-{
- static char buf[128];
-
- if (IA64_IS_NULL_LOC (loc))
- return "<null>";
-
- buf[0] = '\0';
-
- if (IA64_IS_MEMSTK_NAT (loc))
- strcat (buf, "memstk_nat(");
- if (IA64_IS_UC_LOC (loc))
- strcat (buf, "uc(");
- if (IA64_IS_FP_LOC (loc))
- strcat (buf, "fp(");
-
- if (IA64_IS_REG_LOC (loc))
- sprintf (buf + strlen (buf), "%s", unw_regname (IA64_GET_REG (loc)));
- else
- sprintf (buf + strlen (buf), "0x%llx",
- (unsigned long long) IA64_GET_ADDR (loc));
-
- if (IA64_IS_FP_LOC (loc))
- strcat (buf, ")");
- if (IA64_IS_UC_LOC (loc))
- strcat (buf, ")");
- if (IA64_IS_MEMSTK_NAT (loc))
- strcat (buf, ")");
-
- return buf;
-}
-
-#endif /* UNW_DEBUG */
-
#ifdef UNW_REMOTE_ONLY
/* unw_local_addr_space is a NULL pointer in this case. */
@@ -387,7 +348,7 @@
char *buf, size_t buf_len, unw_word_t *offp,
void *arg)
{
- return _Uelf64_get_proc_name (getpid (), ip, buf, buf_len, offp);
+ return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
}
HIDDEN void
diff --git a/src/ia64/Ginit_local.c b/src/ia64/Ginit_local.c
index 0aa06fd..42f8b1f 100644
--- a/src/ia64/Ginit_local.c
+++ b/src/ia64/Ginit_local.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2003 Hewlett-Packard Co
+ Copyright (C) 2001-2003, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,9 +23,6 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <string.h>
-#include <stdlib.h>
-
#include "init.h"
#include "unwind_i.h"
@@ -39,47 +36,75 @@
#else /* !UNW_REMOTE_ONLY */
+static inline void
+set_as_arg (struct cursor *c, unw_context_t *uc)
+{
+#if defined(__linux) && defined(__KERNEL__)
+ c->task = current;
+ c->as_arg = &uc->sw;
+#else
+ c->as_arg = uc;
+#endif
+}
+
+static inline int
+get_initial_stack_pointers (struct cursor *c, unw_context_t *uc,
+ unw_word_t *sp, unw_word_t *bsp)
+{
+#if defined(__linux)
+ unw_word_t sol, bspstore;
+
+#ifdef __KERNEL__
+ sol = (uc->sw.ar_pfs >> 7) & 0x7f;
+ bspstore = uc->sw.ar_bspstore;
+ *sp = uc->ksp;
+# else
+ sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f;
+ bspstore = uc->uc_mcontext.sc_ar_bsp;
+ *sp = uc->uc_mcontext.sc_gr[12];
+# endif
+ *bsp = rse_skip_regs (bspstore, -sol);
+#elif defined(__hpux)
+ int ret;
+
+ if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), sp)) < 0
+ || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), bsp)) < 0)
+ return ret;
+#else
+# error Fix me.
+#endif
+ return 0;
+}
+
PROTECTED int
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
{
struct cursor *c = (struct cursor *) cursor;
- unw_word_t sol;
+ unw_word_t sp, bsp;
+ int ret;
if (tdep_needs_initialization)
tdep_init ();
Debug (1, "(cursor=%p)\n", c);
-#ifdef __hpux
- {
- int ret;
-
- c->as = unw_local_addr_space;
- c->as_arg = uc;
- if ((ret = common_init (c)) < 0)
- return ret;
-
- /* On HP-UX, the context created by getcontext() points to the
- getcontext() system call stub. Step over it: */
- return unw_step (cursor);
- }
-#else
- /* The bsp value stored by getcontext() points to the *end* of the
- register frame of the initial function. We correct for this by
- storing the adjusted value in sc_rbs_base, which isn't used by
- getcontext()/setcontext(). We can be certain that the entire
- frame is stored in a contiguous rbs-area because the frame didn't
- become part of the dirty partition until getcontext() was called
- and we know that getcontext() doesn't switch the register-backing
- store. */
- sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f;
- uc->uc_mcontext.sc_rbs_base = ia64_rse_skip_regs (uc->uc_mcontext.sc_ar_bsp,
- -sol);
-#endif
-
c->as = unw_local_addr_space;
- c->as_arg = uc;
- return common_init (c);
+ set_as_arg (c, uc);
+
+ if ((ret = get_initial_stack_pointers (c, uc, &sp, &bsp)) < 0)
+ return ret;
+
+ Debug (4, "initial bsp=%lx, sp=%lx\n", bsp, sp);
+
+ if ((ret = common_init (c, sp, bsp)) < 0)
+ return ret;
+
+#ifdef __hpux
+ /* On HP-UX, the context created by getcontext() points to the
+ getcontext() system call stub. Step over it: */
+ ret = unw_step (cursor);
+#endif
+ return ret;
}
#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/ia64/Ginit_remote.c b/src/ia64/Ginit_remote.c
index 302c6fb..ae0b718 100644
--- a/src/ia64/Ginit_remote.c
+++ b/src/ia64/Ginit_remote.c
@@ -33,6 +33,8 @@
return -UNW_EINVAL;
#else /* !UNW_LOCAL_ONLY */
struct cursor *c = (struct cursor *) cursor;
+ unw_word_t sp, bsp;
+ int ret;
if (tdep_needs_initialization)
tdep_init ();
@@ -49,6 +51,11 @@
c->as = as;
c->as_arg = as_arg;
- return common_init (c);
+
+ if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), &sp)) < 0
+ || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), &bsp)) < 0)
+ return ret;
+
+ return common_init (c, sp, bsp);
#endif /* !UNW_LOCAL_ONLY */
}
diff --git a/src/ia64/Ginstall_cursor.S b/src/ia64/Ginstall_cursor.S
index 5e5862f..6fb4401 100644
--- a/src/ia64/Ginstall_cursor.S
+++ b/src/ia64/Ginstall_cursor.S
@@ -342,3 +342,7 @@
.endp ia64_install_cursor
#endif /* !UNW_REMOTE_ONLY */
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/Gis_signal_frame.c b/src/ia64/Gis_signal_frame.c
index f9e0f62..cc69bd6 100644
--- a/src/ia64/Gis_signal_frame.c
+++ b/src/ia64/Gis_signal_frame.c
@@ -49,5 +49,6 @@
ia64_free_state_record (&sr);
+ Debug (1, "(cursor=%p, ip=0x%016lx) -> %d\n", c, c->ip, ret);
return ret;
}
diff --git a/src/ia64/Gparser.c b/src/ia64/Gparser.c
index 3636c2a..001581d 100644
--- a/src/ia64/Gparser.c
+++ b/src/ia64/Gparser.c
@@ -23,11 +23,6 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#include "unwind_i.h"
/* forward declaration: */
@@ -210,7 +205,7 @@
/* First, resolve implicit register save locations (see Section
"11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
- for (i = 0; i < (int) NELEMS (unw.save_order); ++i)
+ for (i = 0; i < (int) ARRAY_SIZE (unw.save_order); ++i)
{
reg = sr->curr.reg + unw.save_order[i];
if (reg->where == IA64_WHERE_GR_SAVE)
@@ -694,6 +689,8 @@
#include "unwind_decoder.h"
+#ifdef _U_dyn_op
+
/* parse dynamic unwind info */
static struct ia64_reg_info *
@@ -916,6 +913,9 @@
}
return 0;
}
+#else
+# define parse_dynamic(c,sr) (-UNW_EINVAL)
+#endif /* _U_dyn_op */
HIDDEN int
@@ -1117,9 +1117,15 @@
HIDDEN int
ia64_make_proc_info (struct cursor *c)
{
- if (c->as->caching_policy == UNW_CACHE_NONE
- || ia64_get_cached_proc_info (c) < 0)
- /* Lookup it up the slow way... */
- return ia64_fetch_proc_info (c, c->ip, 0);
+ int ret, caching = c->as->caching_policy != UNW_CACHE_NONE;
+
+ if (!caching || ia64_get_cached_proc_info (c) < 0)
+ {
+ /* Lookup it up the slow way... */
+ if ((ret = ia64_fetch_proc_info (c, c->ip, 0)) < 0)
+ return ret;
+ if (caching)
+ ia64_cache_proc_info (c);
+ }
return 0;
}
diff --git a/src/ia64/Grbs.c b/src/ia64/Grbs.c
index 6ff6b39..4230cf3 100644
--- a/src/ia64/Grbs.c
+++ b/src/ia64/Grbs.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003-2004 Hewlett-Packard Co
+ Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -39,19 +39,57 @@
#include "unwind_i.h"
+#if UNW_DEBUG
+
+HIDDEN const char *
+ia64_strloc (ia64_loc_t loc)
+{
+ static char buf[128];
+
+ if (IA64_IS_NULL_LOC (loc))
+ return "<null>";
+
+ buf[0] = '\0';
+
+ if (IA64_IS_MEMSTK_NAT (loc))
+ strcat (buf, "memstk_nat(");
+ if (IA64_IS_UC_LOC (loc))
+ strcat (buf, "uc(");
+ if (IA64_IS_FP_LOC (loc))
+ strcat (buf, "fp(");
+
+ if (IA64_IS_REG_LOC (loc))
+ sprintf (buf + strlen (buf), "%s", unw_regname (IA64_GET_REG (loc)));
+ else
+ sprintf (buf + strlen (buf), "0x%llx",
+ (unsigned long long) IA64_GET_ADDR (loc));
+
+ if (IA64_IS_FP_LOC (loc))
+ strcat (buf, ")");
+ if (IA64_IS_UC_LOC (loc))
+ strcat (buf, ")");
+ if (IA64_IS_MEMSTK_NAT (loc))
+ strcat (buf, ")");
+
+ return buf;
+}
+
+#endif /* UNW_DEBUG */
+
HIDDEN int
rbs_switch (struct cursor *c,
unw_word_t saved_bsp, unw_word_t saved_bspstore,
ia64_loc_t saved_rnat_loc)
{
struct rbs_area *rbs = &c->rbs_area[c->rbs_curr];
- unw_word_t lo, ndirty;
+ unw_word_t lo, ndirty, rbs_base;
+ int ret;
Debug (10, "(left=%u, curr=%u)\n", c->rbs_left_edge, c->rbs_curr);
/* Calculate address "lo" at which the backing store starts: */
- ndirty = ia64_rse_num_regs (saved_bspstore, saved_bsp);
- lo = ia64_rse_skip_regs (c->bsp, -ndirty);
+ ndirty = rse_num_regs (saved_bspstore, saved_bsp);
+ lo = rse_skip_regs (c->bsp, -ndirty);
rbs->size = (rbs->end - lo);
@@ -62,19 +100,23 @@
Debug (10, "inner=[0x%lx-0x%lx)\n",
(long) (rbs->end - rbs->size), (long) rbs->end);
- c->rbs_curr = (c->rbs_curr + 1) % NELEMS (c->rbs_area);
+ c->rbs_curr = (c->rbs_curr + 1) % ARRAY_SIZE (c->rbs_area);
rbs = c->rbs_area + c->rbs_curr;
if (c->rbs_curr == c->rbs_left_edge)
- c->rbs_left_edge = (c->rbs_left_edge + 1) % NELEMS (c->rbs_area);
+ c->rbs_left_edge = (c->rbs_left_edge + 1) % ARRAY_SIZE (c->rbs_area);
}
+
+ if ((ret = rbs_get_base (c, saved_bspstore, &rbs_base)) < 0)
+ return ret;
+
rbs->end = saved_bspstore;
- rbs->size = ((unw_word_t) 1) << 63; /* initial guess... */
+ rbs->size = saved_bspstore - rbs_base;
rbs->rnat_loc = saved_rnat_loc;
c->bsp = saved_bsp;
- Debug (10, "outer=[?????????????????\?-0x%llx), rnat@%s\n",
+ Debug (10, "outer=[0x%llx-0x%llx), rnat@%s\n", (long long) rbs_base,
(long long) rbs->end, ia64_strloc (rbs->rnat_loc));
return 0;
}
@@ -97,22 +139,21 @@
return -UNW_EBADREG;
}
- n = ia64_rse_num_regs (c->rbs_area[curr].end, bsp);
- curr = (curr + NELEMS (c->rbs_area) - 1) % NELEMS (c->rbs_area);
- bsp = ia64_rse_skip_regs (c->rbs_area[curr].end - c->rbs_area[curr].size,
- n);
+ n = rse_num_regs (c->rbs_area[curr].end, bsp);
+ curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area);
+ bsp = rse_skip_regs (c->rbs_area[curr].end - c->rbs_area[curr].size, n);
}
while (1)
{
- nregs = ia64_rse_num_regs (bsp, c->rbs_area[curr].end);
+ nregs = rse_num_regs (bsp, c->rbs_area[curr].end);
if (regs_to_skip < nregs)
{
/* found it: */
unw_word_t addr;
- addr = ia64_rse_skip_regs (bsp, regs_to_skip);
+ addr = rse_skip_regs (bsp, regs_to_skip);
if (locp)
*locp = rbs_loc (c->rbs_area + curr, addr);
if (rnat_locp)
@@ -128,12 +169,12 @@
regs_to_skip -= nregs;
- curr = (curr + NELEMS (c->rbs_area) - 1) % NELEMS (c->rbs_area);
+ curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area);
bsp = c->rbs_area[curr].end - c->rbs_area[curr].size;
}
}
-#ifndef UNW_REMOTE_ONLY
+#ifdef NEED_RBS_COVER_AND_FLUSH
static inline int
get_rnat (struct cursor *c, struct rbs_area *rbs, unw_word_t bsp,
@@ -165,12 +206,12 @@
int ret;
bsp = c->bsp;
- c->bsp = ia64_rse_skip_regs (bsp, nregs);
+ c->bsp = rse_skip_regs (bsp, nregs);
if (likely (rbs_contains (rbs, bsp)))
{
/* at least _some_ registers are on rbs... */
- n = ia64_rse_num_regs (bsp, rbs->end);
+ n = rse_num_regs (bsp, rbs->end);
if (likely (n >= nregs))
{
/* common case #1: all registers are on current rbs... */
@@ -190,13 +231,12 @@
}
nregs -= n; /* account for registers already on the rbs */
- assert (ia64_rse_skip_regs (c->bsp, -nregs) ==
- ia64_rse_skip_regs (rbs->end, 0));
+ assert (rse_skip_regs (c->bsp, -nregs) == rse_skip_regs (rbs->end, 0));
}
else
/* Earlier frames also didn't get spilled; need to "loadrs" those,
too... */
- nregs += ia64_rse_num_regs (rbs->end, bsp);
+ nregs += rse_num_regs (rbs->end, bsp);
/* OK, we need to copy NREGS registers to the dirty partition. */
@@ -221,9 +261,10 @@
return -UNW_EBADREG;
}
- assert (ia64_rse_num_regs (rbs->end, bsp) == 0);
+ assert (rse_num_regs (rbs->end, bsp) == 0);
- curr = (curr + NELEMS (c->rbs_area) - 1) % NELEMS (c->rbs_area);
+ curr = (curr + ARRAY_SIZE (c->rbs_area) - 1)
+ % ARRAY_SIZE (c->rbs_area);
rbs = c->rbs_area + curr;
bsp = rbs->end - rbs->size;
}
@@ -233,20 +274,20 @@
return ret;
}
- if (unlikely (ia64_rse_is_rnat_slot (bsp)))
+ if (unlikely (rse_is_rnat_slot (bsp)))
{
bsp += 8;
if ((ret = get_rnat (c, rbs, bsp, &src_rnat)) < 0)
return ret;
}
- if (unlikely (ia64_rse_is_rnat_slot ((unw_word_t) dst)))
+ if (unlikely (rse_is_rnat_slot ((unw_word_t) dst)))
{
*dst++ = dst_rnat;
dst_rnat = 0;
}
- src_mask = ((unw_word_t) 1) << ia64_rse_slot_num (bsp);
- dst_mask = ((unw_word_t) 1) << ia64_rse_slot_num ((unw_word_t) dst);
+ src_mask = ((unw_word_t) 1) << rse_slot_num (bsp);
+ dst_mask = ((unw_word_t) 1) << rse_slot_num ((unw_word_t) dst);
if (src_rnat & src_mask)
dst_rnat |= dst_mask;
@@ -262,7 +303,7 @@
bsp += 8;
++dst;
}
- if (unlikely (ia64_rse_is_rnat_slot ((unw_word_t) dst)))
+ if (unlikely (rse_is_rnat_slot ((unw_word_t) dst)))
{
/* The LOADRS instruction loads "the N bytes below the current
BSP" but BSP can never point to an RNaT slot so if the last
diff --git a/src/ia64/Gregs.c b/src/ia64/Gregs.c
index 6de5ace..f3e4075 100644
--- a/src/ia64/Gregs.c
+++ b/src/ia64/Gregs.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
+ Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,9 +23,6 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <assert.h>
-#include <stddef.h>
-
#include "offsets.h"
#include "regs.h"
#include "unwind_i.h"
@@ -37,8 +34,8 @@
unw_word_t addr = c->sigcontext_addr, flags, tmp_addr;
int i;
- if (c->last_abi_marker == ABI_MARKER_LINUX_SIGTRAMP
- || c->last_abi_marker == ABI_MARKER_OLD_LINUX_SIGTRAMP)
+ if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_SIGTRAMP
+ || ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_SIGTRAMP)
{
switch (reg)
{
@@ -90,7 +87,10 @@
case UNW_IA64_AR_CCV: addr += LINUX_SC_AR_CCV; break;
default:
- return IA64_REG_LOC (c, reg);
+ if (unw_is_fpreg (reg))
+ return IA64_FPREG_LOC (c, reg);
+ else
+ return IA64_REG_LOC (c, reg);
}
return IA64_LOC_ADDR (addr, 0);
}
@@ -103,7 +103,7 @@
is_nat = 1;
reg -= (UNW_IA64_NAT - UNW_IA64_GR);
}
- if (c->last_abi_marker == ABI_MARKER_LINUX_INTERRUPT)
+ if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_INTERRUPT)
{
switch (reg)
{
@@ -118,9 +118,30 @@
addr += LINUX_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8));
break;
+ case UNW_IA64_IP: addr += LINUX_PT_IIP_OFF; break;
+ case UNW_IA64_CFM: addr += LINUX_PT_IFS_OFF; break;
+ case UNW_IA64_AR_UNAT: addr += LINUX_PT_UNAT_OFF; break;
+ case UNW_IA64_AR_PFS: addr += LINUX_PT_PFS_OFF; break;
case UNW_IA64_AR_RSC: addr += LINUX_PT_RSC_OFF; break;
+ case UNW_IA64_AR_RNAT: addr += LINUX_PT_RNAT_OFF; break;
+ case UNW_IA64_AR_BSPSTORE: addr += LINUX_PT_BSPSTORE_OFF; break;
+ case UNW_IA64_PR: addr += LINUX_PT_PR_OFF; break;
case UNW_IA64_BR + 0: addr += LINUX_PT_B0_OFF; break;
- case UNW_IA64_GR + 1: addr += LINUX_PT_R1_OFF; break;
+
+ case UNW_IA64_GR + 1:
+ /* The saved r1 value is valid only in the frame in which
+ it was saved; for everything else we need to look up
+ the appropriate gp value. */
+ if (c->sigcontext_addr != c->sp + 0x10)
+ return IA64_NULL_LOC;
+ addr += LINUX_PT_R1_OFF;
+ break;
+
+ case UNW_IA64_GR + 12: addr += LINUX_PT_R12_OFF; break;
+ case UNW_IA64_GR + 13: addr += LINUX_PT_R13_OFF; break;
+ case UNW_IA64_AR_FPSR: addr += LINUX_PT_FPSR_OFF; break;
+ case UNW_IA64_GR + 15: addr += LINUX_PT_R15_OFF; break;
+ case UNW_IA64_GR + 14: addr += LINUX_PT_R14_OFF; break;
case UNW_IA64_GR + 2: addr += LINUX_PT_R2_OFF; break;
case UNW_IA64_GR + 3: addr += LINUX_PT_R3_OFF; break;
@@ -135,15 +156,27 @@
return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP);
default:
- return IA64_REG_LOC (c, reg);
+ if (unw_is_fpreg (reg))
+ return IA64_FPREG_LOC (c, reg);
+ else
+ return IA64_REG_LOC (c, reg);
}
}
- else if (c->last_abi_marker == ABI_MARKER_OLD_LINUX_INTERRUPT)
+ else if (ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_INTERRUPT)
{
switch (reg)
{
- case UNW_IA64_GR + 1 ... UNW_IA64_GR + 3:
- addr += LINUX_OLD_PT_R1_OFF + 8 * (reg - (UNW_IA64_GR + 1));
+ case UNW_IA64_GR + 1:
+ /* The saved r1 value is valid only in the frame in which
+ it was saved; for everything else we need to look up
+ the appropriate gp value. */
+ if (c->sigcontext_addr != c->sp + 0x10)
+ return IA64_NULL_LOC;
+ addr += LINUX_OLD_PT_R1_OFF;
+ break;
+
+ case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3:
+ addr += LINUX_OLD_PT_R2_OFF + 8 * (reg - (UNW_IA64_GR + 2));
break;
case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11:
@@ -166,7 +199,10 @@
case UNW_IA64_AR_CCV: addr += LINUX_OLD_PT_CCV_OFF; break;
default:
- return IA64_REG_LOC (c, reg);
+ if (unw_is_fpreg (reg))
+ return IA64_FPREG_LOC (c, reg);
+ else
+ return IA64_REG_LOC (c, reg);
}
}
if (is_nat)
@@ -198,9 +234,9 @@
{
if (c->sigcontext_addr)
{
- if (c->as->abi == ABI_LINUX)
+ if (ia64_get_abi (c) == ABI_LINUX)
return linux_scratch_loc (c, reg, nat_bitnr);
- else if (c->as->abi == ABI_HPUX)
+ else if (ia64_get_abi (c) == ABI_HPUX)
return hpux_scratch_loc (c, reg, nat_bitnr);
else
return IA64_NULL_LOC;
@@ -250,13 +286,14 @@
{
if (*valp)
{
- if (c->as->big_endian)
+ if (ia64_is_big_endian (c))
ret = ia64_putfp (c, reg_loc, unw.nat_val_be);
else
ret = ia64_putfp (c, reg_loc, unw.nat_val_le);
}
else
{
+ unw_word_t *src, *dst;
unw_fpreg_t tmp;
ret = ia64_getfp (c, reg_loc, &tmp);
@@ -265,10 +302,11 @@
/* Reset the exponent to 0x1003e so that the significand
will be interpreted as an integer value. */
- if (c->as->big_endian)
- tmp.raw.bits[0] = unw.int_val_be.raw.bits[0];
- else
- tmp.raw.bits[1] = unw.int_val_le.raw.bits[1];
+ src = (unw_word_t *) &unw.int_val_be;
+ dst = (unw_word_t *) &tmp;
+ if (!ia64_is_big_endian (c))
+ ++src, ++dst;
+ *dst = *src;
ret = ia64_putfp (c, reg_loc, tmp);
}
@@ -279,7 +317,7 @@
if (ret < 0)
return ret;
- if (c->as->big_endian)
+ if (ia64_is_big_endian (c))
*valp = (memcmp (&tmp, &unw.nat_val_be, sizeof (tmp)) == 0);
else
*valp = (memcmp (&tmp, &unw.nat_val_le, sizeof (tmp)) == 0);
@@ -323,9 +361,9 @@
int write)
{
ia64_loc_t loc, reg_loc, nat_loc;
- unw_word_t nat, mask, pr;
- int ret, readonly = 0;
+ unw_word_t mask, val;
uint8_t nat_bitnr;
+ int ret;
switch (reg)
{
@@ -333,14 +371,16 @@
case UNW_IA64_BSP:
if (write)
- return -UNW_EREADONLYREG;
- *valp = c->bsp;
+ c->bsp = *valp;
+ else
+ *valp = c->bsp;
return 0;
case UNW_REG_SP:
if (write)
- return -UNW_EREADONLYREG;
- *valp = c->sp;
+ c->sp = *valp;
+ else
+ *valp = c->sp;
return 0;
case UNW_REG_IP:
@@ -385,20 +425,17 @@
break;
case UNW_IA64_PR:
+ /*
+ * Note: broad-side access to the predicates is NOT rotated
+ * (i.e., it is done as if CFM.rrb.pr == 0.
+ */
if (write)
{
c->pr = *valp; /* update the predicate cache */
- pr = pr_ltop (c, *valp);
- return ia64_put (c, c->loc[IA64_REG_PR], pr);
+ return ia64_put (c, c->loc[IA64_REG_PR], *valp);
}
else
- {
- ret = ia64_get (c, c->loc[IA64_REG_PR], &pr);
- if (ret < 0)
- return ret;
- *valp = pr_ptol (c, pr);
- }
- return 0;
+ return ia64_get (c, c->loc[IA64_REG_PR], valp);
case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */
reg = rotate_gr (c, reg - UNW_IA64_GR);
@@ -417,19 +454,21 @@
if (ret < 0)
return ret;
assert (!IA64_IS_REG_LOC (loc));
- mask = (unw_word_t) 1 << ia64_rse_slot_num (IA64_GET_ADDR (loc));
+ mask = (unw_word_t) 1 << rse_slot_num (IA64_GET_ADDR (loc));
return update_nat (c, nat_loc, mask, valp, write);
case UNW_IA64_AR_EC:
+ if ((ret = ia64_get (c, c->ec_loc, &val)) < 0)
+ return ret;
+
if (write)
{
- c->cfm = ((c->cfm & ~((unw_word_t) 0x3f << 52))
- | ((*valp & 0x3f) << 52));
- return ia64_put (c, c->cfm_loc, c->cfm);
+ val = ((val & ~((unw_word_t) 0x3f << 52)) | ((*valp & 0x3f) << 52));
+ return ia64_put (c, c->ec_loc, val);
}
else
{
- *valp = (c->cfm >> 52) & 0x3f;
+ *valp = (val >> 52) & 0x3f;
return 0;
}
@@ -441,47 +480,28 @@
*valp = 0;
return 0;
- case UNW_IA64_GR + 1: /* global pointer */
- if (write)
- return -UNW_EREADONLYREG;
-
- /* ensure c->pi is up-to-date: */
- if ((ret = ia64_make_proc_info (c)) < 0)
- return ret;
- *valp = c->pi.gp;
- return 0;
-
case UNW_IA64_NAT + 0:
- case UNW_IA64_NAT + 1: /* global pointer */
if (write)
return -UNW_EREADONLYREG;
*valp = 0;
return 0;
+ case UNW_IA64_NAT + 1:
case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3:
case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31:
loc = ia64_scratch_loc (c, reg, &nat_bitnr);
+ if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_NAT + 1)
+ {
+ /* access to GP */
+ if (write)
+ return -UNW_EREADONLYREG;
+ *valp = 0;
+ return 0;
+ }
if (!(IA64_IS_REG_LOC (loc) || IA64_IS_UC_LOC (loc)
|| IA64_IS_FP_LOC (loc)))
- {
- /* We're dealing with a NaT bit stored in memory. */
- mask = (unw_word_t) 1 << nat_bitnr;
-
- if ((ret = ia64_get (c, loc, &nat)) < 0)
- return ret;
-
- if (write)
- {
- if (*valp)
- nat |= mask;
- else
- nat &= ~mask;
- ret = ia64_put (c, loc, nat);
- }
- else
- *valp = (nat & mask) != 0;
- return ret;
- }
+ /* We're dealing with a NaT bit stored in memory. */
+ return update_nat(c, loc, (unw_word_t) 1 << nat_bitnr, valp, write);
break;
case UNW_IA64_GR + 15 ... UNW_IA64_GR + 18:
@@ -494,13 +514,14 @@
}
else if ((c->eh_valid_mask & mask) != 0)
{
- *valp = c->eh_args[reg - (UNW_IA64_GR + 15)] = *valp;
+ *valp = c->eh_args[reg - (UNW_IA64_GR + 15)];
return 0;
}
else
loc = ia64_scratch_loc (c, reg, NULL);
break;
+ case UNW_IA64_GR + 1: /* global pointer */
case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3:
case UNW_IA64_GR + 8 ... UNW_IA64_GR + 14:
case UNW_IA64_GR + 19 ... UNW_IA64_GR + 31:
@@ -512,6 +533,18 @@
case UNW_IA64_AR_SSD:
case UNW_IA64_AR_CCV:
loc = ia64_scratch_loc (c, reg, NULL);
+ if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_GR + 1)
+ {
+ /* access to GP */
+ if (write)
+ return -UNW_EREADONLYREG;
+
+ /* ensure c->pi is up-to-date: */
+ if ((ret = ia64_make_proc_info (c)) < 0)
+ return ret;
+ *valp = c->pi.gp;
+ return 0;
+ }
break;
default:
@@ -520,11 +553,7 @@
}
if (write)
- {
- if (readonly)
- return -UNW_EREADONLYREG;
- return ia64_put (c, loc, *valp);
- }
+ return ia64_put (c, loc, *valp);
else
return ia64_get (c, loc, valp);
}
@@ -547,7 +576,7 @@
if (write)
return -UNW_EREADONLYREG;
- if (c->as->big_endian)
+ if (ia64_is_big_endian (c))
*valp = unw.read_only.f1_be;
else
*valp = unw.read_only.f1_le;
diff --git a/src/ia64/Gresume.c b/src/ia64/Gresume.c
index f8946b1..fe23f76 100644
--- a/src/ia64/Gresume.c
+++ b/src/ia64/Gresume.c
@@ -240,7 +240,7 @@
Debug (8, "copying out cursor state\n");
- for (reg = 0; reg < UNW_REG_LAST; ++reg)
+ for (reg = 0; reg <= UNW_REG_LAST; ++reg)
{
if (unw_is_fpreg (reg))
{
@@ -264,7 +264,7 @@
{
struct cursor *c = (struct cursor *) cursor;
- Debug (1, "(cursor=%p)\n", c);
+ Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip);
#ifdef UNW_LOCAL_ONLY
return local_resume (c->as, cursor, c->as_arg);
diff --git a/src/ia64/Gscript.c b/src/ia64/Gscript.c
index 7ac8da6..bf9ca02 100644
--- a/src/ia64/Gscript.c
+++ b/src/ia64/Gscript.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
+ Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -38,7 +38,7 @@
IA64_INSN_MOVE, /* s[dst] = s[val] */
IA64_INSN_MOVE_NAT, /* like above, but with NaT info */
IA64_INSN_MOVE_NO_NAT, /* like above, but clear NaT info */
- IA64_INSN_MOVE_STACKED, /* s[dst] = ia64_rse_skip(*s.bsp_loc, val) */
+ IA64_INSN_MOVE_STACKED, /* s[dst] = rse_skip(*s.bsp_loc, val) */
IA64_INSN_MOVE_STACKED_NAT, /* like above, but with NaT info */
IA64_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */
IA64_INSN_MOVE_SCRATCH_NAT, /* like above, but with NaT info */
@@ -93,7 +93,7 @@
}
static inline struct ia64_script_cache *
-get_script_cache (unw_addr_space_t as, sigset_t *saved_sigmaskp)
+get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
{
struct ia64_script_cache *cache = &as->global_cache;
unw_caching_policy_t caching = as->caching_policy;
@@ -101,24 +101,28 @@
if (caching == UNW_CACHE_NONE)
return NULL;
-#ifdef HAVE___THREAD
- if (as->caching_policy == UNW_CACHE_PER_THREAD)
- cache = &ia64_per_thread_cache;
-#endif
-
-#ifdef HAVE_ATOMIC_OPS_H
- if (AO_test_and_set (&cache->busy) == AO_TS_SET)
+#ifdef HAVE_ATOMIC_H
+ if (!spin_trylock_irqsave (&cache->busy, *saved_maskp))
return NULL;
#else
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, saved_sigmaskp);
+# ifdef HAVE___THREAD
+ if (as->caching_policy == UNW_CACHE_PER_THREAD)
+ cache = &ia64_per_thread_cache;
+# endif
+# ifdef HAVE_ATOMIC_OPS_H
+ if (AO_test_and_set (&cache->busy) == AO_TS_SET)
+ return NULL;
+# else
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, saved_maskp);
if (likely (caching == UNW_CACHE_GLOBAL))
{
- Debug (16, "%s: acquiring lock\n");
+ Debug (16, "%s: acquiring lock\n", __FUNCTION__);
mutex_lock (&cache->lock);
}
+# endif
#endif
- if (as->cache_generation != cache->generation)
+ if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation))
{
flush_script_cache (cache);
cache->generation = as->cache_generation;
@@ -128,17 +132,21 @@
static inline void
put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache,
- sigset_t *saved_sigmaskp)
+ intrmask_t *saved_maskp)
{
assert (as->caching_policy != UNW_CACHE_NONE);
- Debug (16, "unmasking signals/releasing lock\n");
-#ifdef HAVE_ATOMIC_OPS_H
- AO_CLEAR (&cache->busy);
+ Debug (16, "unmasking signals/interrupts and releasing lock\n");
+#ifdef HAVE_ATOMIC_H
+ spin_unlock_irqrestore (&cache->busy, *saved_maskp);
#else
+# ifdef HAVE_ATOMIC_OPS_H
+ AO_CLEAR (&cache->busy);
+# else
if (likely (as->caching_policy == UNW_CACHE_GLOBAL))
mutex_unlock (&cache->lock);
- sigprocmask (SIG_SETMASK, saved_sigmaskp, NULL);
+ sigprocmask (SIG_SETMASK, saved_maskp, NULL);
+# endif
#endif
}
@@ -175,25 +183,6 @@
}
}
-HIDDEN int
-ia64_get_cached_proc_info (struct cursor *c)
-{
- struct ia64_script_cache *cache;
- struct ia64_script *script;
- sigset_t saved_sigmask;
-
- cache = get_script_cache (c->as, &saved_sigmask);
- if (!cache)
- return -UNW_ENOINFO; /* cache is busy */
- {
- script = script_lookup (cache, c);
- if (script)
- c->pi = script->pi;
- }
- put_script_cache (c->as, cache, &saved_sigmask);
- return script ? 0 : -UNW_ENOINFO;
-}
-
static inline void
script_init (struct ia64_script *script, unw_word_t ip)
{
@@ -614,8 +603,7 @@
if ((ret = ia64_get_stacked (c, val, &loc, &nat_loc)) < 0)
return ret;
assert (!IA64_IS_REG_LOC (loc));
- set_nat_info (c, dst,
- nat_loc, ia64_rse_slot_num (IA64_GET_ADDR (loc)));
+ set_nat_info (c, dst, nat_loc, rse_slot_num (IA64_GET_ADDR (loc)));
break;
case IA64_INSN_MOVE_SCRATCH_NAT:
@@ -655,13 +643,13 @@
{
struct ia64_script_cache *cache = NULL;
struct ia64_script *script = NULL;
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
int ret = 0;
if (c->as->caching_policy == UNW_CACHE_NONE)
return uncached_find_save_locs (c);
- cache = get_script_cache (c->as, &saved_sigmask);
+ cache = get_script_cache (c->as, &saved_mask);
if (!cache)
{
Debug (1, "contention on script-cache; doing uncached lookup\n");
@@ -671,11 +659,15 @@
script = script_lookup (cache, c);
Debug (8, "ip %lx %s in script cache\n", (long) c->ip,
script ? "hit" : "missed");
- if (!script)
+
+ if (!script || (script->count == 0 && !script->pi.unwind_info))
{
if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0)
goto out;
+ }
+ if (!script)
+ {
script = script_new (cache, c->ip);
if (!script)
{
@@ -683,10 +675,14 @@
ret = -UNW_EUNSPEC;
goto out;
}
- cache->buckets[c->prev_script].hint = script - cache->buckets;
-
- ret = build_script (c, script);
}
+ cache->buckets[c->prev_script].hint = script - cache->buckets;
+
+ if (script->count == 0)
+ ret = build_script (c, script);
+
+ assert (script->count > 0);
+
c->hint = script->hint;
c->prev_script = script - cache->buckets;
@@ -701,7 +697,7 @@
ret = run_script (script, c);
}
out:
- put_script_cache (c->as, cache, &saved_sigmask);
+ put_script_cache (c->as, cache, &saved_mask);
return ret;
}
@@ -718,3 +714,54 @@
unwi_dyn_validate_cache (as, arg);
#endif
}
+
+HIDDEN int
+ia64_cache_proc_info (struct cursor *c)
+{
+ struct ia64_script_cache *cache;
+ struct ia64_script *script;
+ intrmask_t saved_mask;
+ int ret = 0;
+
+ cache = get_script_cache (c->as, &saved_mask);
+ if (!cache)
+ return ret; /* cache is busy */
+
+ /* Re-check to see if a cache entry has been added in the meantime: */
+ script = script_lookup (cache, c);
+ if (script)
+ goto out;
+
+ script = script_new (cache, c->ip);
+ if (!script)
+ {
+ dprintf ("%s: failed to create unwind script\n", __FUNCTION__);
+ ret = -UNW_EUNSPEC;
+ goto out;
+ }
+
+ script->pi = c->pi;
+
+ out:
+ put_script_cache (c->as, cache, &saved_mask);
+ return ret;
+}
+
+HIDDEN int
+ia64_get_cached_proc_info (struct cursor *c)
+{
+ struct ia64_script_cache *cache;
+ struct ia64_script *script;
+ intrmask_t saved_mask;
+
+ cache = get_script_cache (c->as, &saved_mask);
+ if (!cache)
+ return -UNW_ENOINFO; /* cache is busy */
+ {
+ script = script_lookup (cache, c);
+ if (script)
+ c->pi = script->pi;
+ }
+ put_script_cache (c->as, cache, &saved_mask);
+ return script ? 0 : -UNW_ENOINFO;
+}
diff --git a/src/ia64/Gstep.c b/src/ia64/Gstep.c
index 002da37..4390d26 100644
--- a/src/ia64/Gstep.c
+++ b/src/ia64/Gstep.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
+ Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -27,7 +27,8 @@
#include "unwind_i.h"
static inline int
-linux_sigtramp (struct cursor *c, unw_word_t *num_regsp)
+linux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc,
+ unw_word_t *num_regsp)
{
#if defined(UNW_LOCAL_ONLY) && !defined(__linux)
return -UNW_EINVAL;
@@ -53,18 +54,17 @@
/* do what can't be described by unwind directives: */
c->loc[IA64_REG_PFS] = IA64_LOC_ADDR (sc_addr + LINUX_SC_AR_PFS_OFF, 0);
+ c->ec_loc = prev_cfm_loc;
*num_regsp = c->cfm & 0x7f; /* size of frame */
return 0;
#endif
}
static inline int
-linux_interrupt (struct cursor *c, unw_word_t *num_regsp, int marker)
+linux_interrupt (struct cursor *c, ia64_loc_t prev_cfm_loc,
+ unw_word_t *num_regsp, int marker)
{
-#if defined(UNW_LOCAL_ONLY)
- /* Perhaps libunwind will some day become the Linux kernel unwinder.
- Until such time, linux_interrupt() is needed only for non-local
- unwinding. */
+#if defined(UNW_LOCAL_ONLY) && !(defined(__linux) && defined(__KERNEL__))
return -UNW_EINVAL;
#else
unw_word_t sc_addr, num_regs;
@@ -83,13 +83,15 @@
else
pfs_loc = IA64_LOC_ADDR (sc_addr + LINUX_PT_PFS_OFF, 0);
c->loc[IA64_REG_PFS] = pfs_loc;
+ c->ec_loc = prev_cfm_loc;
*num_regsp = num_regs; /* size of frame */
return 0;
#endif
}
static inline int
-hpux_sigtramp (struct cursor *c, unw_word_t *num_regsp)
+hpux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc,
+ unw_word_t *num_regsp)
{
#if defined(UNW_LOCAL_ONLY) && !defined(__hpux)
return -UNW_EINVAL;
@@ -157,7 +159,9 @@
itself. We'll need to access it via uc_access(3). */
rbs_switch (c, bsp, bspstore, IA64_LOC_UC_ADDR (bsp | 0x1f8, 0));
- *num_regsp = 0;
+ c->ec_loc = prev_cfm_loc;
+
+ *num_regsp = 0;
return 0;
#endif
}
@@ -204,8 +208,8 @@
&loadrs) < 0))
return ret;
loadrs >>= 16;
- ndirty = ia64_rse_num_regs (c->bsp - loadrs, c->bsp);
- saved_bspstore = ia64_rse_skip_regs (saved_bsp, -ndirty);
+ ndirty = rse_num_regs (c->bsp - loadrs, c->bsp);
+ saved_bspstore = rse_skip_regs (saved_bsp, -ndirty);
}
if (saved_bsp == c->bsp)
@@ -218,8 +222,10 @@
update_frame_state (struct cursor *c)
{
unw_word_t prev_ip, prev_sp, prev_bsp, ip, num_regs;
+ ia64_loc_t prev_cfm_loc;
int ret;
+ prev_cfm_loc = c->cfm_loc;
prev_ip = c->ip;
prev_sp = c->sp;
prev_bsp = c->bsp;
@@ -238,9 +244,6 @@
Debug (1, "rejecting bad ip=0x%lx\n", (long) c->ip);
return -UNW_EINVALIDIP;
}
- if (ip == 0)
- /* end of frame-chain reached */
- return 0;
c->cfm_loc = c->loc[IA64_REG_PFS];
/* update the CFM cache: */
@@ -248,29 +251,41 @@
if (ret < 0)
return ret;
+ /* Normally, AR.EC is stored in the CFM save-location. That
+ save-location contains the full function-state as defined by
+ AR.PFS. However, interruptions only save the frame-marker, not
+ any other info in CFM. Instead, AR.EC gets saved on the first
+ call by the interruption-handler. Thus, interruption-related
+ frames need to track the _previous_ CFM save-location since
+ that's were AR.EC is saved. We support this by setting ec_loc to
+ cfm_loc by default and giving frames marked with an ABI-marker
+ the chance to override this value with prev_cfm_loc. */
+ c->ec_loc = c->cfm_loc;
+
num_regs = 0;
if (unlikely (c->abi_marker))
{
c->last_abi_marker = c->abi_marker;
- switch (c->abi_marker)
+ switch (ia64_get_abi_marker (c))
{
case ABI_MARKER_LINUX_SIGTRAMP:
case ABI_MARKER_OLD_LINUX_SIGTRAMP:
- c->as->abi = ABI_LINUX;
- if ((ret = linux_sigtramp (c, &num_regs)) < 0)
+ ia64_set_abi (c, ABI_LINUX);
+ if ((ret = linux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0)
return ret;
break;
case ABI_MARKER_OLD_LINUX_INTERRUPT:
case ABI_MARKER_LINUX_INTERRUPT:
- c->as->abi = ABI_LINUX;
- if ((ret = linux_interrupt (c, &num_regs, c->abi_marker)) < 0)
+ ia64_set_abi (c, ABI_LINUX);
+ if ((ret = linux_interrupt (c, prev_cfm_loc, &num_regs,
+ c->abi_marker)) < 0)
return ret;
break;
case ABI_MARKER_HP_UX_SIGTRAMP:
- c->as->abi = ABI_HPUX;
- if ((ret = hpux_sigtramp (c, &num_regs)) < 0)
+ ia64_set_abi (c, ABI_HPUX);
+ if ((ret = hpux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0)
return ret;
break;
@@ -302,7 +317,7 @@
return ret;
}
- c->bsp = ia64_rse_skip_regs (c->bsp, -num_regs);
+ c->bsp = rse_skip_regs (c->bsp, -num_regs);
c->sp = c->psp;
c->abi_marker = 0;
@@ -333,15 +348,12 @@
struct cursor *c = (struct cursor *) cursor;
int ret;
- Debug (1, "(cursor=%p)\n", c);
+ Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip);
- ret = ia64_find_save_locs (c);
- if (ret < 0)
- return ret;
+ if ((ret = ia64_find_save_locs (c)) >= 0
+ && (ret = update_frame_state (c)) >= 0)
+ ret = (c->ip == 0) ? 0 : 1;
- ret = update_frame_state (c);
- if (ret < 0)
- return ret;
-
- return (c->ip == 0) ? 0 : 1;
+ Debug (2, "returning %d (ip=0x%016lx)\n", ret, (unsigned long) c->ip);
+ return ret;
}
diff --git a/src/ia64/Gtables.c b/src/ia64/Gtables.c
index fedfd90..c3448c8 100644
--- a/src/ia64/Gtables.c
+++ b/src/ia64/Gtables.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2001-2004 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2001-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -255,7 +255,7 @@
unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp;
const struct ia64_table_entry *e = NULL;
unw_word_t handler_offset, segbase = 0;
- int ret;
+ int ret, is_local;
assert ((di->format == UNW_INFO_FORMAT_TABLE
|| di->format == UNW_INFO_FORMAT_REMOTE_TABLE)
@@ -305,20 +305,33 @@
hdr_addr = e->info_offset + segbase;
info_addr = hdr_addr + 8;
- /* read the header word: */
+ /* Read the header word. Note: the actual unwind-info is always
+ assumed to reside in memory, independent of whether di->format is
+ UNW_INFO_FORMAT_TABLE or UNW_INFO_FORMAT_REMOTE_TABLE. */
+
if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0)
return ret;
if (IA64_UNW_VER (hdr) != 1)
- return -UNW_EBADVERSION;
+ {
+ Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n",
+ IA64_UNW_VER (hdr), (unsigned long) hdr,
+ (unsigned long) hdr_addr);
+ return -UNW_EBADVERSION;
+ }
info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr);
- if (need_unwind_info)
+ is_local = is_local_addr_space (as);
+
+ /* If we must have the unwind-info, return it. Also, if we are in
+ the local address-space, return the unwind-info because it's so
+ cheap to do so and it may come in handy later on. */
+ if (need_unwind_info || is_local)
{
pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr);
- if (is_local_addr_space (as))
+ if (is_local)
pi->unwind_info = (void *) (uintptr_t) info_addr;
else
{
@@ -606,12 +619,12 @@
static inline int
validate_cache (unw_addr_space_t as)
{
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
int ret;
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
ret = dl_iterate_phdr (check_callback, as);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
return ret;
}
@@ -635,14 +648,14 @@
{
# if defined(HAVE_DL_ITERATE_PHDR)
unw_dyn_info_t di, *dip = &di;
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
int ret;
di.u.ti.segbase = ip; /* this is cheap... */
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
ret = dl_iterate_phdr (callback, &di);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
if (ret <= 0)
{
diff --git a/src/ia64/Linstall_cursor.S b/src/ia64/Linstall_cursor.S
index 44a7f5a..8c72339 100644
--- a/src/ia64/Linstall_cursor.S
+++ b/src/ia64/Linstall_cursor.S
@@ -1,2 +1,6 @@
#define UNW_LOCAL_ONLY
#include "Ginstall_cursor.S"
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/dyn_info_list.S b/src/ia64/dyn_info_list.S
index 962b234..31265f6 100644
--- a/src/ia64/dyn_info_list.S
+++ b/src/ia64/dyn_info_list.S
@@ -20,3 +20,7 @@
data8 0, 0, @segrel(.info)
#endif
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/getcontext.S b/src/ia64/getcontext.S
index a4f13ab..d8da732 100644
--- a/src/ia64/getcontext.S
+++ b/src/ia64/getcontext.S
@@ -171,3 +171,7 @@
mov r8 = 0
br.ret.sptk.many rp
.endp _Uia64_getcontext
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/init.h b/src/ia64/init.h
index 9322b98..d6a1b22 100644
--- a/src/ia64/init.h
+++ b/src/ia64/init.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -25,10 +25,10 @@
#include "unwind_i.h"
-static inline ALWAYS_INLINE int
-common_init (struct cursor *c)
+static ALWAYS_INLINE int
+common_init (struct cursor *c, unw_word_t sp, unw_word_t bsp)
{
- unw_word_t bspstore;
+ unw_word_t bspstore, rbs_base;
uint8_t *natp;
int ret;
@@ -37,7 +37,7 @@
ia64_validate_cache (c->as, c->as_arg);
c->cfm_loc = IA64_REG_LOC (c, UNW_IA64_CFM);
- c->loc[IA64_REG_BSP] = IA64_REG_LOC (c, UNW_IA64_AR_BSP);
+ c->loc[IA64_REG_BSP] = IA64_NULL_LOC;
c->loc[IA64_REG_BSPSTORE] = IA64_REG_LOC (c, UNW_IA64_AR_BSPSTORE);
c->loc[IA64_REG_PFS] = IA64_REG_LOC (c, UNW_IA64_AR_PFS);
c->loc[IA64_REG_RNAT] = IA64_REG_LOC (c, UNW_IA64_AR_RNAT);
@@ -98,15 +98,8 @@
if (ret < 0)
return ret;
- ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), &c->sp);
- if (ret < 0)
- return ret;
-
- c->psp = c->sp;
-
- ret = ia64_get (c, c->loc[IA64_REG_BSP], &c->bsp);
- if (ret < 0)
- return ret;
+ c->sp = c->psp = sp;
+ c->bsp = bsp;
ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &bspstore);
if (ret < 0)
@@ -114,16 +107,17 @@
c->rbs_curr = c->rbs_left_edge = 0;
- /* There is no way to know the real size of the most recent
- (right-most) RBS so we'll just assume it to occupy a quarter of
- the address space (so we have a notion of "above" and "below" and
- one bit to indicate whether the backing store needs to be
- accessed via uc_access(3)). */
+ /* Try to find a base of the register backing-store. We may default
+ to a reasonable value (e.g., half the address-space down from
+ bspstore). If the BSPSTORE looks corrupt, we fail. */
+ if ((ret = rbs_get_base (c, bspstore, &rbs_base)) < 0)
+ return ret;
+
c->rbs_area[0].end = bspstore;
- c->rbs_area[0].size = ((unw_word_t) 1) << 63; /* initial guess... */
+ c->rbs_area[0].size = bspstore - rbs_base;
c->rbs_area[0].rnat_loc = IA64_REG_LOC (c, UNW_IA64_AR_RNAT);
- Debug (10, "initial rbs-area: [?-0x%llx), rnat@%s\n",
- (long long) c->rbs_area[0].end,
+ Debug (10, "initial rbs-area: [0x%llx-0x%llx), rnat@%s\n",
+ (long long) rbs_base, (long long) c->rbs_area[0].end,
ia64_strloc (c->rbs_area[0].rnat_loc));
c->pi.flags = 0;
diff --git a/src/ia64/longjmp.S b/src/ia64/longjmp.S
index 7590522..2a2f286 100644
--- a/src/ia64/longjmp.S
+++ b/src/ia64/longjmp.S
@@ -36,3 +36,7 @@
mov r8 = r16
br.sptk.many rp
.endp longjmp_continuation
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/mk_Gcursor_i.c b/src/ia64/mk_Gcursor_i.c
index 6acaa42..51cb0f4 100644
--- a/src/ia64/mk_Gcursor_i.c
+++ b/src/ia64/mk_Gcursor_i.c
@@ -26,10 +26,8 @@
/* Utility to generate cursor_i.h. */
#include <stdio.h>
-#include <string.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#ifdef offsetof
# undef offsetof
diff --git a/src/ia64/regname.c b/src/ia64/regname.c
index 9069b3e..4936a3d 100644
--- a/src/ia64/regname.c
+++ b/src/ia64/regname.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -37,7 +37,7 @@
example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this
purpose. */
-#include "internal.h"
+#include "libunwind_i.h"
/* Maintain the register names as a single string to keep the number
of dynamic relocations in the shared object to a minimum. */
diff --git a/src/ia64/regs.h b/src/ia64/regs.h
index 49df753..1e748bb 100644
--- a/src/ia64/regs.h
+++ b/src/ia64/regs.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -71,31 +71,3 @@
Debug (15, "rrb.fr=%u, f%d -> f%d\n", rrb_fr, reg, preg);
return preg;
}
-
-/* Apply logical-to-physical rotation. */
-
-static inline unw_word_t
-pr_ltop (struct cursor *c, unw_word_t pr)
-{
- unw_word_t rrb_pr, mask, rot;
-
- rrb_pr = (c->cfm >> 32) & 0x3f;
- rot = pr >> 16;
- mask = ((unw_word_t) 1 << rrb_pr) - 1;
- rot = ((pr & mask) << (48 - rrb_pr)) | ((pr >> rrb_pr) & mask);
- return (pr & 0xffff) | (rot << 16);
-}
-
-/* Apply physical-to-logical rotation. */
-
-static inline unw_word_t
-pr_ptol (struct cursor *c, unw_word_t pr)
-{
- unw_word_t rrb_pr, mask, rot;
-
- rrb_pr = 48 - ((c->cfm >> 32) & 0x3f);
- rot = pr >> 16;
- mask = ((unw_word_t) 1 << rrb_pr) - 1;
- rot = ((pr & mask) << (48 - rrb_pr)) | ((pr >> rrb_pr) & mask);
- return (pr & 0xffff) | (rot << 16);
-}
diff --git a/src/ia64/setjmp.S b/src/ia64/setjmp.S
index d7a7a2b..384615b 100644
--- a/src/ia64/setjmp.S
+++ b/src/ia64/setjmp.S
@@ -45,3 +45,7 @@
br.ret.sptk.many rp
.endp _setjmp
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/siglongjmp.S b/src/ia64/siglongjmp.S
index 3c58355..d77b437 100644
--- a/src/ia64/siglongjmp.S
+++ b/src/ia64/siglongjmp.S
@@ -63,3 +63,7 @@
mov r8 = loc2
br.ret.sptk.many rp
.endp siglongjmp_continuation
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/sigsetjmp.S b/src/ia64/sigsetjmp.S
index 13b2bde..02f7af4 100644
--- a/src/ia64/sigsetjmp.S
+++ b/src/ia64/sigsetjmp.S
@@ -63,3 +63,7 @@
br.ret.sptk.many rp
.endp __sigsetjmp
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ia64/unwind_i.h b/src/ia64/unwind_i.h
index ad34778..4643975 100644
--- a/src/ia64/unwind_i.h
+++ b/src/ia64/unwind_i.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
+ Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -31,9 +31,9 @@
#include <libunwind-ia64.h>
-#include "ia64/rse.h"
+#include "rse.h"
-#include "internal.h"
+#include "libunwind_i.h"
#define IA64_UNW_VER(x) ((x) >> 48)
#define IA64_UNW_FLAG_MASK ((unw_word_t) 0x0000ffff00000000ULL)
@@ -47,11 +47,9 @@
#endif
#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#include "tdep.h"
-
#if !defined(HAVE_SYS_UC_ACCESS_H) && !defined(UNW_REMOTE_ONLY)
-static inline ALWAYS_INLINE void *
+static ALWAYS_INLINE void *
inlined_uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr)
{
unw_word_t reg_addr;
@@ -75,13 +73,6 @@
case UNW_IA64_AR_LC: addr = &uc->uc_mcontext.sc_ar_lc; break;
case UNW_IA64_AR_FPSR: addr = &uc->uc_mcontext.sc_ar_fpsr; break;
case UNW_IA64_PR: addr = &uc->uc_mcontext.sc_pr; break;
- /* This may look confusing, but it's correct: AR_BSPSTORE needs
- to return the address past the last word written, which is
- stored in sc_ar_bsp. On the other hand, AR_BSP needs to
- return the address that was in ar.bsp at the time the context
- was captured. As described in unw_init_local(), sc_ar_bsp is
- (ab-)used for this purpose. */
- case UNW_IA64_AR_BSP: addr = &uc->uc_mcontext.sc_rbs_base; break;
case UNW_IA64_AR_BSPSTORE: addr = &uc->uc_mcontext.sc_ar_bsp; break;
case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7:
@@ -499,7 +490,6 @@
#define ia64_install_cursor UNW_OBJ(install_cursor)
#define rbs_switch UNW_OBJ(rbs_switch)
#define rbs_find_stacked UNW_OBJ(rbs_find_stacked)
-#define rbs_cover_and_flush UNW_OBJ(rbs_cover_and_flush)
extern int ia64_make_proc_info (struct cursor *c);
extern int ia64_fetch_proc_info (struct cursor *c, unw_word_t ip,
@@ -530,10 +520,15 @@
ia64_loc_t saved_rnat_loc);
extern int rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip,
ia64_loc_t *locp, ia64_loc_t *rnat_locp);
-extern int rbs_cover_and_flush (struct cursor *c, unw_word_t nregs,
- unw_word_t *dirty_partition,
- unw_word_t *dirty_rnat,
- unw_word_t *bspstore);
+
+#ifndef UNW_REMOTE_ONLY
+# define NEED_RBS_COVER_AND_FLUSH
+# define rbs_cover_and_flush UNW_OBJ(rbs_cover_and_flush)
+ extern int rbs_cover_and_flush (struct cursor *c, unw_word_t nregs,
+ unw_word_t *dirty_partition,
+ unw_word_t *dirty_rnat,
+ unw_word_t *bspstore);
+#endif
/* Warning: ia64_strloc() is for debugging only and it is NOT re-entrant! */
extern const char *ia64_strloc (ia64_loc_t loc);
@@ -566,7 +561,7 @@
static inline ia64_loc_t
rbs_get_rnat_loc (struct rbs_area *rbs, unw_word_t bsp)
{
- unw_word_t rnat_addr = ia64_rse_rnat_addr (bsp);
+ unw_word_t rnat_addr = rse_rnat_addr (bsp);
ia64_loc_t rnat_loc;
if (rbs_contains (rbs, rnat_addr))
@@ -600,7 +595,7 @@
assert (reg >= 32 && reg < 128);
- addr = ia64_rse_skip_regs (c->bsp, regs_to_skip);
+ addr = rse_skip_regs (c->bsp, regs_to_skip);
if (locp)
*locp = rbs_loc (rbs, addr);
if (rnat_locp)
@@ -614,7 +609,15 @@
/* The UNaT slot # calculation is identical to the one for RNaT slots,
but for readability/clarity, we don't want to use
ia64_rnat_slot_num() directly. */
-#define ia64_unat_slot_num(addr) ia64_rse_slot_num(addr)
+#define ia64_unat_slot_num(addr) rse_slot_num(addr)
+
+/* The following are helper macros which makes it easier for libunwind
+ to be used in the kernel. They allow the kernel to optimize away
+ any unused code without littering everything with #ifdefs. */
+#define ia64_is_big_endian(c) ((c)->as->big_endian)
+#define ia64_get_abi(c) ((c)->as->abi)
+#define ia64_set_abi(c, v) ((c)->as->abi = (v))
+#define ia64_get_abi_marker(c) ((c)->last_abi_marker)
/* XXX should be in glibc: */
#ifndef IA64_SC_FLAG_ONSTACK
diff --git a/src/mi/Gdestroy_addr_space.c b/src/mi/Gdestroy_addr_space.c
index ba50e37..83a01b9 100644
--- a/src/mi/Gdestroy_addr_space.c
+++ b/src/mi/Gdestroy_addr_space.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002 Hewlett-Packard Co
+ Copyright (C) 2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,9 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <stdlib.h>
-
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED void
unw_destroy_addr_space (unw_addr_space_t as)
diff --git a/src/mi/Gdyn-extract.c b/src/mi/Gdyn-extract.c
index 3155983..5258839 100644
--- a/src/mi/Gdyn-extract.c
+++ b/src/mi/Gdyn-extract.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2002 Hewlett-Packard Co
+ Copyright (C) 2001-2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,8 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
HIDDEN int
unwi_extract_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip,
diff --git a/src/mi/Gdyn-remote.c b/src/mi/Gdyn-remote.c
index 6a6252d..917a11d 100644
--- a/src/mi/Gdyn-remote.c
+++ b/src/mi/Gdyn-remote.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2002 Hewlett-Packard Co
+ Copyright (C) 2001-2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -25,9 +25,8 @@
#include <stdlib.h>
-#include "internal.h"
+#include "libunwind_i.h"
#include "remote.h"
-#include "tdep.h"
static void
free_regions (unw_dyn_region_info_t *region)
diff --git a/src/mi/Gfind_dynamic_proc_info.c b/src/mi/Gfind_dynamic_proc_info.c
index 5df946a..24c72ed 100644
--- a/src/mi/Gfind_dynamic_proc_info.c
+++ b/src/mi/Gfind_dynamic_proc_info.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2002 Hewlett-Packard Co
+ Copyright (C) 2001-2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,10 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <stdio.h>
-
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#ifdef UNW_REMOTE_ONLY
diff --git a/src/mi/Gget_accessors.c b/src/mi/Gget_accessors.c
index 1a95ff9..fb256d7 100644
--- a/src/mi/Gget_accessors.c
+++ b/src/mi/Gget_accessors.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002, 2004 Hewlett-Packard Co
+ Copyright (C) 2002, 2004-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED unw_accessors_t *
unw_get_accessors (unw_addr_space_t as)
diff --git a/src/mi/Gget_fpreg.c b/src/mi/Gget_fpreg.c
index 8ff69d2..a9ae9bf 100644
--- a/src/mi/Gget_fpreg.c
+++ b/src/mi/Gget_fpreg.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2004 Hewlett-Packard Co
+ Copyright (C) 2004-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_get_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t *valp)
diff --git a/src/mi/Gget_proc_info_by_ip.c b/src/mi/Gget_proc_info_by_ip.c
index d8b436e..4c9de77 100644
--- a/src/mi/Gget_proc_info_by_ip.c
+++ b/src/mi/Gget_proc_info_by_ip.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
+ Copyright (C) 2003, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,10 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <libunwind.h>
-
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_get_proc_info_by_ip (unw_addr_space_t as, unw_word_t ip,
diff --git a/src/mi/Gget_proc_name.c b/src/mi/Gget_proc_name.c
index c1f3929..7251c59 100644
--- a/src/mi/Gget_proc_name.c
+++ b/src/mi/Gget_proc_name.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2004 Hewlett-Packard Co
+ Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
#include "remote.h"
static inline int
diff --git a/src/mi/Gget_reg.c b/src/mi/Gget_reg.c
index cb95dd6..23b72be 100644
--- a/src/mi/Gget_reg.c
+++ b/src/mi/Gget_reg.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002 Hewlett-Packard Co
+ Copyright (C) 2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
diff --git a/src/mi/Gput_dynamic_unwind_info.c b/src/mi/Gput_dynamic_unwind_info.c
index 92c81ff..13a9c1a 100644
--- a/src/mi/Gput_dynamic_unwind_info.c
+++ b/src/mi/Gput_dynamic_unwind_info.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2002 Hewlett-Packard Co
+ Copyright (C) 2001-2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "internal.h"
+#include "libunwind_i.h"
HIDDEN void
unwi_put_dynamic_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi,
diff --git a/src/mi/Gset_caching_policy.c b/src/mi/Gset_caching_policy.c
index 2da2d8b..52fc7e5 100644
--- a/src/mi/Gset_caching_policy.c
+++ b/src/mi/Gset_caching_policy.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002 Hewlett-Packard Co
+ Copyright (C) 2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_set_caching_policy (unw_addr_space_t as, unw_caching_policy_t policy)
diff --git a/src/mi/Gset_fpreg.c b/src/mi/Gset_fpreg.c
index 05e1c16..d3b202d 100644
--- a/src/mi/Gset_fpreg.c
+++ b/src/mi/Gset_fpreg.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2004 Hewlett-Packard Co
+ Copyright (C) 2004-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_set_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t val)
diff --git a/src/mi/Gset_reg.c b/src/mi/Gset_reg.c
index d9564ab..09fa09a 100644
--- a/src/mi/Gset_reg.c
+++ b/src/mi/Gset_reg.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002 Hewlett-Packard Co
+ Copyright (C) 2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_set_reg (unw_cursor_t *cursor, int regnum, unw_word_t valp)
diff --git a/src/mi/Ldyn-remote.c b/src/mi/Ldyn-remote.c
index e69de29..260722a 100644
--- a/src/mi/Ldyn-remote.c
+++ b/src/mi/Ldyn-remote.c
@@ -0,0 +1,5 @@
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
+#include "Gdyn-remote.c"
+#endif
diff --git a/src/mi/dyn-cancel.c b/src/mi/dyn-cancel.c
index 85a3645..e784317 100644
--- a/src/mi/dyn-cancel.c
+++ b/src/mi/dyn-cancel.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2002 Hewlett-Packard Co
+ Copyright (C) 2001-2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "internal.h"
+#include "libunwind_i.h"
void
_U_dyn_cancel (unw_dyn_info_t *di)
diff --git a/src/mi/dyn-info-list.c b/src/mi/dyn-info-list.c
index 755f583..b06fee4 100644
--- a/src/mi/dyn-info-list.c
+++ b/src/mi/dyn-info-list.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2002 Hewlett-Packard Co
+ Copyright (C) 2001-2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "internal.h"
+#include "libunwind_i.h"
HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
diff --git a/src/mi/dyn-register.c b/src/mi/dyn-register.c
index 5f58136..a62d696 100644
--- a/src/mi/dyn-register.c
+++ b/src/mi/dyn-register.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2002 Hewlett-Packard Co
+ Copyright (C) 2001-2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "internal.h"
+#include "libunwind_i.h"
HIDDEN pthread_mutex_t _U_dyn_info_list_lock = PTHREAD_MUTEX_INITIALIZER;
diff --git a/src/mi/flush_cache.c b/src/mi/flush_cache.c
index 25f869d..15e8950 100644
--- a/src/mi/flush_cache.c
+++ b/src/mi/flush_cache.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,8 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED void
unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi)
diff --git a/src/mi/init.c b/src/mi/init.c
index afd9780..4bf97c4 100644
--- a/src/mi/init.c
+++ b/src/mi/init.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2004 Hewlett-Packard Co
+ Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,13 +23,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <assert.h>
-#include <stdlib.h>
+#include "libunwind_i.h"
-#include "internal.h"
-#include "tdep.h"
-
-HIDDEN sigset_t unwi_full_sigmask;
+HIDDEN intrmask_t unwi_full_mask;
static const char rcsid[] UNUSED =
"$Id: " PACKAGE_STRING " --- report bugs to " PACKAGE_BUGREPORT " $";
diff --git a/src/mi/mempool.c b/src/mi/mempool.c
index c8b7584..ef891bf 100644
--- a/src/mi/mempool.c
+++ b/src/mi/mempool.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2003 Hewlett-Packard Co
+ Copyright (C) 2002-2003, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,18 +23,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/mman.h>
-
-#include "libunwind.h"
-#include "mempool.h"
+#include "libunwind_i.h"
#define MAX_ALIGN (sizeof (long double))
-#define SOS_MEMORY_SIZE 16384
static char sos_memory[SOS_MEMORY_SIZE];
static char *sos_memp;
@@ -57,46 +48,30 @@
mem = (char *) (((unsigned long) old_mem + MAX_ALIGN - 1) & -MAX_ALIGN);
mem += size;
- if (mem >= sos_memory + sizeof (sos_memory))
- abort ();
+ assert (mem < sos_memory + sizeof (sos_memory));
}
while (!cmpxchg_ptr (&sos_memp, old_mem, mem));
#else
- static pthread_mutex_t sos_lock = PTHREAD_MUTEX_INITIALIZER;
- sigset_t saved_sigmask;
+ static define_lock (sos_lock);
+ intrmask_t saved_mask;
size = (size + MAX_ALIGN - 1) & -MAX_ALIGN;
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
- mutex_lock(&sos_lock);
+ lock_acquire (&sos_lock, saved_mask);
{
if (!sos_memp)
sos_memp = sos_memory;
mem = (char *) (((unsigned long) sos_memp + MAX_ALIGN - 1) & -MAX_ALIGN);
mem += size;
- if (mem >= sos_memory + sizeof (sos_memory))
- abort ();
+ assert (mem < sos_memory + sizeof (sos_memory));
sos_memp = mem;
}
- mutex_unlock(&sos_lock);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ lock_release (&sos_lock, saved_mask);
#endif
return mem;
}
-static void *
-alloc_memory (size_t size)
-{
- /* Hopefully, mmap() goes straight through to a system call stub... */
- void *mem = mmap (0, size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (mem == MAP_FAILED)
- return NULL;
-
- return mem;
-}
-
/* Must be called while holding the mempool lock. */
static void
@@ -125,11 +100,11 @@
char *mem;
size = pool->chunk_size;
- mem = alloc_memory (size);
+ GET_MEMORY (mem, size);
if (!mem)
{
size = (pool->obj_size + pg_size - 1) & -pg_size;
- mem = alloc_memory (size);
+ GET_MEMORY (mem, size);
if (!mem)
{
/* last chance: try to allocate one object from the SOS memory */
@@ -148,14 +123,14 @@
memset (pool, 0, sizeof (*pool));
- mutex_init (&pool->lock);
+ lock_init (&pool->lock);
/* round object-size up to integer multiple of MAX_ALIGN */
obj_size = (obj_size + MAX_ALIGN - 1) & -MAX_ALIGN;
if (!reserve)
{
- reserve = pg_size / obj_size / 2;
+ reserve = pg_size / obj_size / 4;
if (!reserve)
reserve = 16;
}
@@ -170,11 +145,10 @@
HIDDEN void *
mempool_alloc (struct mempool *pool)
{
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
struct object *obj;
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
- mutex_lock(&pool->lock);
+ lock_acquire (&pool->lock, saved_mask);
{
if (pool->num_free <= pool->reserve)
expand (pool);
@@ -185,21 +159,18 @@
obj = pool->free_list;
pool->free_list = obj->next;
}
- mutex_unlock(&pool->lock);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ lock_release (&pool->lock, saved_mask);
return obj;
}
HIDDEN void
mempool_free (struct mempool *pool, void *object)
{
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
- mutex_lock(&pool->lock);
+ lock_acquire (&pool->lock, saved_mask);
{
free_object (pool, object);
}
- mutex_unlock(&pool->lock);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ lock_release (&pool->lock, saved_mask);
}
diff --git a/src/mi/strerror.c b/src/mi/strerror.c
index f1512a1..ef64716 100644
--- a/src/mi/strerror.c
+++ b/src/mi/strerror.c
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "internal.h"
+#include "libunwind_i.h"
/* Returns the text corresponding to the given err_code or the
text "invalid error code" if the err_code is invalid. */
diff --git a/src/os-hpux.c b/src/os-hpux.c
index cb6852d..586ace2 100644
--- a/src/os-hpux.c
+++ b/src/os-hpux.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003-2004 Hewlett-Packard Co
+ Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -28,8 +28,7 @@
#include <dlfcn.h>
#include <unistd.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#include "elf64.h"
diff --git a/src/os-linux.c b/src/os-linux.c
index 4395e35..ae37d8f 100644
--- a/src/os-linux.c
+++ b/src/os-linux.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003-2004 Hewlett-Packard Co
+ Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -28,8 +28,7 @@
#include <limits.h>
#include <stdio.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#include "os-linux.h"
PROTECTED int
diff --git a/src/os-linux.h b/src/os-linux.h
index 6a2b7dd..b2c9a8b 100644
--- a/src/os-linux.h
+++ b/src/os-linux.h
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003-2004 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -71,6 +72,7 @@
mi->fd = open (path, O_RDONLY);
mi->offset = 0;
+ mi->buf_size = 0;
cp = NULL;
if (mi->fd >= 0)
@@ -226,19 +228,19 @@
{
/* copy down the remaining bytes, if any */
if (bytes_left > 0)
- memcpy (mi->buf_end - mi->buf_size, mi->buf, bytes_left);
+ memmove (mi->buf_end - mi->buf_size, mi->buf, bytes_left);
mi->buf = mi->buf_end - mi->buf_size;
nread = read (mi->fd, mi->buf + bytes_left,
mi->buf_size - bytes_left);
if (nread <= 0)
return 0;
- else if (nread + bytes_left < mi->buf_size)
+ else if ((size_t) (nread + bytes_left) < mi->buf_size)
{
/* Move contents to the end of the buffer so we
maintain the invariant that all bytes between
mi->buf and mi->buf_end are valid. */
- memcpy (mi->buf_end - nread - bytes_left, mi->buf,
+ memmove (mi->buf_end - nread - bytes_left, mi->buf,
nread + bytes_left);
mi->buf = mi->buf_end - nread - bytes_left;
}
diff --git a/src/hppa/Gget_reg.c b/src/ppc/Gcreate_addr_space.c
similarity index 64%
copy from src/hppa/Gget_reg.c
copy to src/ppc/Gcreate_addr_space.c
index 4553f65..21ec10f 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc/Gcreate_addr_space.c
@@ -1,6 +1,8 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
This file is part of libunwind.
@@ -23,12 +25,30 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+#include <stdlib.h>
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+#include <libunwind_i.h>
+
+PROTECTED unw_addr_space_t
+unw_create_addr_space (unw_accessors_t *a, int byte_order)
{
- struct cursor *c = (struct cursor *) cursor;
+#ifdef UNW_LOCAL_ONLY
+ return NULL;
+#else
+ unw_addr_space_t as = malloc (sizeof (*as));
- return hppa_access_reg (c, regnum, valp, 0);
+ if (!as)
+ return NULL;
+
+ memset (as, 0, sizeof (*as));
+
+ as->acc = *a;
+
+ /*
+ * Linux ppc64 supports only big-endian.
+ */
+ if (byte_order != 0 && byte_order != __BIG_ENDIAN)
+ return NULL;
+ return as;
+#endif
}
diff --git a/src/hppa/Gget_reg.c b/src/ppc/Gget_proc_info.c
similarity index 80%
copy from src/hppa/Gget_reg.c
copy to src/ppc/Gget_proc_info.c
index 4553f65..21be70c 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc/Gget_proc_info.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+
+ Copied from src/x86_64/, modified slightly (or made empty stubs) for
+ building frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
This file is part of libunwind.
@@ -23,12 +24,11 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+#include <libunwind_i.h>
PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi)
{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
+ /* XXX: empty stub. */
+ return 0;
}
diff --git a/src/hppa/Gget_reg.c b/src/ppc/Gget_save_loc.c
similarity index 79%
copy from src/hppa/Gget_reg.c
copy to src/ppc/Gget_save_loc.c
index 4553f65..c5beb81 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc/Gget_save_loc.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+
+ Copied from src/x86_64/, modified slightly (or made empty stubs) for
+ building frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
This file is part of libunwind.
@@ -23,12 +24,11 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+#include <libunwind_i.h>
PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc)
{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
+ /* XXX: empty stub. */
+ return 0;
}
diff --git a/src/ppc/Ginit_local.c b/src/ppc/Ginit_local.c
new file mode 100644
index 0000000..2d9ab2c
--- /dev/null
+++ b/src/ppc/Ginit_local.c
@@ -0,0 +1,65 @@
+/* libunwind - a platform-independent unwind library
+
+ Copied from src/x86_64/, modified slightly (or made empty stubs) for
+ building frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <libunwind_i.h>
+
+#ifdef UNW_TARGET_PPC64
+#include "../ppc64/init.h"
+#else
+#include "../ppc32/init.h"
+#endif
+
+#ifdef UNW_REMOTE_ONLY
+
+PROTECTED int
+unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
+{
+ /* XXX: empty stub. */
+ return -UNW_EINVAL;
+}
+
+#else /* !UNW_REMOTE_ONLY */
+
+PROTECTED int
+unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
+{
+ struct cursor *c = (struct cursor *) cursor;
+
+ if (tdep_needs_initialization)
+ tdep_init ();
+
+ Debug (1, "(cursor=%p)\n", c);
+
+ c->dwarf.as = unw_local_addr_space;
+ c->dwarf.as_arg = uc;
+ #ifdef UNW_TARGET_PPC64
+ return common_init_ppc64 (c);
+ #else
+ return common_init_ppc32 (c);
+ #endif
+}
+
+#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/hppa/Gget_reg.c b/src/ppc/Ginit_remote.c
similarity index 60%
copy from src/hppa/Gget_reg.c
copy to src/ppc/Ginit_remote.c
index 4553f65..66269d2 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc/Ginit_remote.c
@@ -1,6 +1,8 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
This file is part of libunwind.
@@ -23,12 +25,36 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+#include <libunwind_i.h>
+
+#ifdef UNW_TARGET_PPC64
+#include "../ppc64/init.h"
+#else
+#include "../ppc32/init.h"
+#endif
PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg)
{
+#ifdef UNW_LOCAL_ONLY
+ return -UNW_EINVAL;
+#else /* !UNW_LOCAL_ONLY */
struct cursor *c = (struct cursor *) cursor;
- return hppa_access_reg (c, regnum, valp, 0);
+ if (tdep_needs_initialization)
+ tdep_init ();
+
+ Debug (1, "(cursor=%p)\n", c);
+
+ c->dwarf.as = as;
+ c->dwarf.as_arg = as_arg;
+
+ #ifdef UNW_TARGET_PPC64
+ return common_init_ppc64(c);
+ #elif UNW_TARGET_PPC32
+ return common_init_ppc32 (c);
+ #else
+ #error init_remote :: NO VALID PPC ARCH!
+ #endif
+#endif /* !UNW_LOCAL_ONLY */
}
diff --git a/src/ppc/Gis_signal_frame.c b/src/ppc/Gis_signal_frame.c
new file mode 100644
index 0000000..4154429
--- /dev/null
+++ b/src/ppc/Gis_signal_frame.c
@@ -0,0 +1,66 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <libunwind_i.h>
+
+PROTECTED int
+unw_is_signal_frame (unw_cursor_t * cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ unw_word_t w0, w1, ip;
+ unw_addr_space_t as;
+ unw_accessors_t *a;
+ void *arg;
+ int ret;
+
+ as = c->dwarf.as;
+ as->validate = 1; /* Don't trust the ip */
+ arg = c->dwarf.as_arg;
+
+ /* Check if return address points at sigreturn sequence.
+ on ppc64 Linux that is (see libc.so):
+ 0x38210080 addi r1, r1, 128 // pop the stack
+ 0x380000ac li r0, 172 // invoke system service 172
+ 0x44000002 sc
+ */
+
+ ip = c->dwarf.ip;
+ if (ip == 0)
+ return 0;
+
+ /* Read up two 8-byte words at the IP. We are only looking at 3
+ consecutive 32-bit words, so the second 8-byte word needs to be
+ shifted right by 32 bits (think big-endian) */
+
+ a = unw_get_accessors (as);
+ if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
+ || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0)
+ return 0;
+ w1 >>= 32;
+ return (w0 == 0x38210080380000ac && w1 == 0x44000002);
+
+}
diff --git a/src/hppa/Lget_proc_name.c b/src/ppc/Lcreate_addr_space.c
similarity index 76%
copy from src/hppa/Lget_proc_name.c
copy to src/ppc/Lcreate_addr_space.c
index 378097b..0f2dc6b 100644
--- a/src/hppa/Lget_proc_name.c
+++ b/src/ppc/Lcreate_addr_space.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_proc_name.c"
+#include "Gcreate_addr_space.c"
#endif
diff --git a/src/hppa/Lget_proc_name.c b/src/ppc/Lget_proc_info.c
similarity index 79%
rename from src/hppa/Lget_proc_name.c
rename to src/ppc/Lget_proc_info.c
index 378097b..69028b0 100644
--- a/src/hppa/Lget_proc_name.c
+++ b/src/ppc/Lget_proc_info.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_proc_name.c"
+#include "Gget_proc_info.c"
#endif
diff --git a/src/hppa/Lget_proc_name.c b/src/ppc/Lget_save_loc.c
similarity index 79%
copy from src/hppa/Lget_proc_name.c
copy to src/ppc/Lget_save_loc.c
index 378097b..9ea048a 100644
--- a/src/hppa/Lget_proc_name.c
+++ b/src/ppc/Lget_save_loc.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_proc_name.c"
+#include "Gget_save_loc.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc/Linit_local.c
similarity index 80%
copy from src/hppa/Lget_reg.c
copy to src/ppc/Linit_local.c
index effe8a8..68a1687 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc/Linit_local.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Ginit_local.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc/Linit_remote.c
similarity index 80%
copy from src/hppa/Lget_reg.c
copy to src/ppc/Linit_remote.c
index effe8a8..58cb04a 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc/Linit_remote.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Ginit_remote.c"
#endif
diff --git a/src/hppa/Lget_proc_name.c b/src/ppc/Lis_signal_frame.c
similarity index 78%
copy from src/hppa/Lget_proc_name.c
copy to src/ppc/Lis_signal_frame.c
index 378097b..b9a7c4f 100644
--- a/src/hppa/Lget_proc_name.c
+++ b/src/ppc/Lis_signal_frame.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_proc_name.c"
+#include "Gis_signal_frame.c"
#endif
diff --git a/src/hppa/Gget_reg.c b/src/ppc/longjmp.S
similarity index 73%
copy from src/hppa/Gget_reg.c
copy to src/ppc/longjmp.S
index 4553f65..d363aef 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc/longjmp.S
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+
+ Copied from src/x86_64/, modified slightly (or made empty stubs) for
+ building frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
This file is part of libunwind.
@@ -23,12 +24,13 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+ .globl _UI_longjmp_cont
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
+ .type _UI_longjmp_cont, @function
+_UI_longjmp_cont:
+ .size _UI_longjmp_cont, .-_UI_longjmp_cont
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/hppa/Gget_reg.c b/src/ppc/siglongjmp.S
similarity index 80%
copy from src/hppa/Gget_reg.c
copy to src/ppc/siglongjmp.S
index 4553f65..64be36c 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc/siglongjmp.S
@@ -1,6 +1,4 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
This file is part of libunwind.
@@ -23,12 +21,11 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+ .globl _UI_siglongjmp_cont
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
+ _UI_siglongjmp_cont:
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ppc32/Gglobal.c b/src/ppc32/Gglobal.c
new file mode 100644
index 0000000..c2d4604
--- /dev/null
+++ b/src/ppc32/Gglobal.c
@@ -0,0 +1,137 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+#include "dwarf_i.h"
+
+HIDDEN pthread_mutex_t ppc32_lock = PTHREAD_MUTEX_INITIALIZER;
+HIDDEN int tdep_needs_initialization = 1;
+
+/* The API register numbers are exactly the same as the .eh_frame
+ registers, for now at least. */
+uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] =
+ {
+ [UNW_PPC32_R0]=UNW_PPC32_R0,
+ [UNW_PPC32_R1]=UNW_PPC32_R1,
+ [UNW_PPC32_R2]=UNW_PPC32_R2,
+ [UNW_PPC32_R3]=UNW_PPC32_R3,
+ [UNW_PPC32_R4]=UNW_PPC32_R4,
+ [UNW_PPC32_R5]=UNW_PPC32_R5,
+ [UNW_PPC32_R6]=UNW_PPC32_R6,
+ [UNW_PPC32_R7]=UNW_PPC32_R7,
+ [UNW_PPC32_R8]=UNW_PPC32_R8,
+ [UNW_PPC32_R9]=UNW_PPC32_R9,
+ [UNW_PPC32_R10]=UNW_PPC32_R10,
+ [UNW_PPC32_R11]=UNW_PPC32_R11,
+ [UNW_PPC32_R12]=UNW_PPC32_R12,
+ [UNW_PPC32_R13]=UNW_PPC32_R13,
+ [UNW_PPC32_R14]=UNW_PPC32_R14,
+ [UNW_PPC32_R15]=UNW_PPC32_R15,
+ [UNW_PPC32_R16]=UNW_PPC32_R16,
+ [UNW_PPC32_R17]=UNW_PPC32_R17,
+ [UNW_PPC32_R18]=UNW_PPC32_R18,
+ [UNW_PPC32_R19]=UNW_PPC32_R19,
+ [UNW_PPC32_R20]=UNW_PPC32_R20,
+ [UNW_PPC32_R21]=UNW_PPC32_R21,
+ [UNW_PPC32_R22]=UNW_PPC32_R22,
+ [UNW_PPC32_R23]=UNW_PPC32_R23,
+ [UNW_PPC32_R24]=UNW_PPC32_R24,
+ [UNW_PPC32_R25]=UNW_PPC32_R25,
+ [UNW_PPC32_R26]=UNW_PPC32_R26,
+ [UNW_PPC32_R27]=UNW_PPC32_R27,
+ [UNW_PPC32_R28]=UNW_PPC32_R28,
+ [UNW_PPC32_R29]=UNW_PPC32_R29,
+ [UNW_PPC32_R30]=UNW_PPC32_R30,
+ [UNW_PPC32_R31]=UNW_PPC32_R31,
+
+ [UNW_PPC32_CTR]=UNW_PPC32_CTR,
+ [UNW_PPC32_XER]=UNW_PPC32_XER,
+ [UNW_PPC32_CCR]=UNW_PPC32_CCR,
+ [UNW_PPC32_LR]=UNW_PPC32_LR,
+ [UNW_PPC32_FPSCR]=UNW_PPC32_FPSCR,
+
+ [UNW_PPC32_F0]=UNW_PPC32_F0,
+ [UNW_PPC32_F1]=UNW_PPC32_F1,
+ [UNW_PPC32_F2]=UNW_PPC32_F2,
+ [UNW_PPC32_F3]=UNW_PPC32_F3,
+ [UNW_PPC32_F4]=UNW_PPC32_F4,
+ [UNW_PPC32_F5]=UNW_PPC32_F5,
+ [UNW_PPC32_F6]=UNW_PPC32_F6,
+ [UNW_PPC32_F7]=UNW_PPC32_F7,
+ [UNW_PPC32_F8]=UNW_PPC32_F8,
+ [UNW_PPC32_F9]=UNW_PPC32_F9,
+ [UNW_PPC32_F10]=UNW_PPC32_F10,
+ [UNW_PPC32_F11]=UNW_PPC32_F11,
+ [UNW_PPC32_F12]=UNW_PPC32_F12,
+ [UNW_PPC32_F13]=UNW_PPC32_F13,
+ [UNW_PPC32_F14]=UNW_PPC32_F14,
+ [UNW_PPC32_F15]=UNW_PPC32_F15,
+ [UNW_PPC32_F16]=UNW_PPC32_F16,
+ [UNW_PPC32_F17]=UNW_PPC32_F17,
+ [UNW_PPC32_F18]=UNW_PPC32_F18,
+ [UNW_PPC32_F19]=UNW_PPC32_F19,
+ [UNW_PPC32_F20]=UNW_PPC32_F20,
+ [UNW_PPC32_F21]=UNW_PPC32_F21,
+ [UNW_PPC32_F22]=UNW_PPC32_F22,
+ [UNW_PPC32_F23]=UNW_PPC32_F23,
+ [UNW_PPC32_F24]=UNW_PPC32_F24,
+ [UNW_PPC32_F25]=UNW_PPC32_F25,
+ [UNW_PPC32_F26]=UNW_PPC32_F26,
+ [UNW_PPC32_F27]=UNW_PPC32_F27,
+ [UNW_PPC32_F28]=UNW_PPC32_F28,
+ [UNW_PPC32_F29]=UNW_PPC32_F29,
+ [UNW_PPC32_F30]=UNW_PPC32_F30,
+ [UNW_PPC32_F31]=UNW_PPC32_F31,
+};
+
+HIDDEN void
+tdep_init (void)
+{
+ intrmask_t saved_mask;
+
+ sigfillset (&unwi_full_mask);
+
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
+ mutex_lock (&ppc32_lock);
+ {
+ if (!tdep_needs_initialization)
+ /* another thread else beat us to it... */
+ goto out;
+
+ mi_init ();
+
+ dwarf_init ();
+
+#ifndef UNW_REMOTE_ONLY
+ ppc32_local_addr_space_init ();
+#endif
+ tdep_needs_initialization = 0; /* signal that we're initialized... */
+ }
+ out:
+ mutex_unlock (&ppc32_lock);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
+}
diff --git a/src/ppc32/Ginit.c b/src/ppc32/Ginit.c
new file mode 100644
index 0000000..47c66f1
--- /dev/null
+++ b/src/ppc32/Ginit.c
@@ -0,0 +1,221 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ucontext_i.h"
+#include "unwind_i.h"
+
+#ifdef UNW_REMOTE_ONLY
+
+/* unw_local_addr_space is a NULL pointer in this case. */
+PROTECTED unw_addr_space_t unw_local_addr_space;
+
+#else /* !UNW_REMOTE_ONLY */
+
+static struct unw_addr_space local_addr_space;
+
+PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space;
+
+
+#define PAGE_SIZE 4096
+#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
+
+
+static void *
+uc_addr (ucontext_t *uc, int reg)
+{
+ void *addr;
+
+ if ((unsigned) (reg - UNW_PPC32_R0) < 32)
+ addr = &uc->uc_mcontext.uc_regs->gregs[reg - UNW_PPC32_R0];
+
+ else
+ if ( ((unsigned) (reg - UNW_PPC32_F0) < 32) &&
+ ((unsigned) (reg - UNW_PPC32_F0) >= 0) )
+ addr = &uc->uc_mcontext.uc_regs->fpregs.fpregs[reg - UNW_PPC32_F0];
+
+ else
+ {
+ unsigned gregs_idx;
+
+ switch (reg)
+ {
+ case UNW_PPC32_CTR:
+ gregs_idx = CTR_IDX;
+ break;
+ case UNW_PPC32_LR:
+ gregs_idx = LINK_IDX;
+ break;
+ case UNW_PPC32_XER:
+ gregs_idx = XER_IDX;
+ break;
+ case UNW_PPC32_CCR:
+ gregs_idx = CCR_IDX;
+ break;
+ default:
+ return NULL;
+ }
+ addr = &uc->uc_mcontext.uc_regs->gregs[gregs_idx];
+ }
+ return addr;
+}
+
+# ifdef UNW_LOCAL_ONLY
+
+HIDDEN void *
+tdep_uc_addr (ucontext_t *uc, int reg)
+{
+ return uc_addr (uc, reg);
+}
+
+# endif /* UNW_LOCAL_ONLY */
+
+HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
+
+
+static void
+put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
+{
+ /* it's a no-op */
+}
+
+static int
+get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
+ void *arg)
+{
+ *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+ return 0;
+}
+
+static int
+access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
+ void *arg)
+{
+ if (write)
+ {
+ Debug (12, "mem[%lx] <- %lx\n", addr, *val);
+ *(unw_word_t *) addr = *val;
+ }
+ else
+ {
+ *val = *(unw_word_t *) addr;
+ Debug (12, "mem[%lx] -> %lx\n", addr, *val);
+ }
+ return 0;
+}
+
+static int
+access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
+ int write, void *arg)
+{
+ unw_word_t *addr;
+ ucontext_t *uc = arg;
+
+ if ( ((unsigned int) (reg - UNW_PPC32_F0) < 32) &&
+ ((unsigned int) (reg - UNW_PPC32_F0) >= 0))
+ goto badreg;
+
+ addr = uc_addr (uc, reg);
+ if (!addr)
+ goto badreg;
+
+ if (write)
+ {
+ *(unw_word_t *) addr = *val;
+ Debug (12, "%s <- %lx\n", unw_regname (reg), *val);
+ }
+ else
+ {
+ *val = *(unw_word_t *) addr;
+ Debug (12, "%s -> %lx\n", unw_regname (reg), *val);
+ }
+ return 0;
+
+badreg:
+ Debug (1, "bad register number %u\n", reg);
+ return -UNW_EBADREG;
+}
+
+static int
+access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
+ int write, void *arg)
+{
+ ucontext_t *uc = arg;
+ unw_fpreg_t *addr;
+
+ if ((unsigned) (reg - UNW_PPC32_F0) < 0)
+ goto badreg;
+
+ addr = uc_addr (uc, reg);
+ if (!addr)
+ goto badreg;
+
+ if (write)
+ {
+ Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val);
+ *(unw_fpreg_t *) addr = *val;
+ }
+ else
+ {
+ *val = *(unw_fpreg_t *) addr;
+ Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val);
+ }
+ return 0;
+
+badreg:
+ Debug (1, "bad register number %u\n", reg);
+ /* attempt to access a non-preserved register */
+ return -UNW_EBADREG;
+}
+
+static int
+get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
+ char *buf, size_t buf_len, unw_word_t *offp,
+ void *arg)
+{
+ return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
+}
+
+HIDDEN void
+ppc32_local_addr_space_init (void)
+{
+ memset (&local_addr_space, 0, sizeof (local_addr_space));
+ local_addr_space.caching_policy = UNW_CACHE_GLOBAL;
+ local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
+ local_addr_space.acc.put_unwind_info = put_unwind_info;
+ local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
+ local_addr_space.acc.access_mem = access_mem;
+ local_addr_space.acc.access_reg = access_reg;
+ local_addr_space.acc.access_fpreg = access_fpreg;
+ local_addr_space.acc.resume = ppc32_local_resume;
+ local_addr_space.acc.get_proc_name = get_static_proc_name;
+ unw_flush_cache (&local_addr_space, 0, 0);
+}
+
+#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/ppc32/Gregs.c b/src/ppc32/Gregs.c
new file mode 100644
index 0000000..92be321
--- /dev/null
+++ b/src/ppc32/Gregs.c
@@ -0,0 +1,90 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+HIDDEN int
+tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
+ int write)
+{
+ struct dwarf_loc loc;
+
+ switch (reg)
+ {
+ case UNW_TDEP_IP:
+ if (write)
+ {
+ c->dwarf.ip = *valp; /* update the IP cache */
+ if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip
+ || *valp >= c->dwarf.pi.end_ip))
+ c->dwarf.pi_valid = 0; /* new IP outside of current proc */
+ }
+ else
+ *valp = c->dwarf.ip;
+ return 0;
+
+ case UNW_TDEP_SP:
+ if (write)
+ return -UNW_EREADONLYREG;
+ *valp = c->dwarf.cfa;
+ return 0;
+
+
+ default:
+ break;
+ }
+
+ /* make sure it's not an FP or VR register */
+ if ((((unsigned) (reg - UNW_PPC32_F0)) <= 31))
+ return -UNW_EBADREG;
+
+ loc = c->dwarf.loc[reg];
+
+ if (write)
+ return dwarf_put (&c->dwarf, loc, *valp);
+ else
+ return dwarf_get (&c->dwarf, loc, valp);
+}
+
+HIDDEN int
+tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
+ int write)
+{
+ struct dwarf_loc loc;
+
+ if ((unsigned) (reg - UNW_PPC32_F0) < 32)
+ {
+ loc = c->dwarf.loc[reg];
+ if (write)
+ return dwarf_putfp (&c->dwarf, loc, *valp);
+ else
+ return dwarf_getfp (&c->dwarf, loc, valp);
+ }
+
+ return -UNW_EBADREG;
+}
+
diff --git a/src/ppc32/Gresume.c b/src/ppc32/Gresume.c
new file mode 100644
index 0000000..5446c98
--- /dev/null
+++ b/src/ppc32/Gresume.c
@@ -0,0 +1,77 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford cjashfor@us.ibm.com
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <stdlib.h>
+
+#include "unwind_i.h"
+
+#ifndef UNW_REMOTE_ONLY
+
+#include <sys/syscall.h>
+
+/* sigreturn() is a no-op on x86_64 glibc. */
+
+static NORETURN inline long
+my_rt_sigreturn (void *new_sp)
+{
+ /* XXX: empty stub. */
+ abort ();
+}
+
+HIDDEN inline int
+ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
+{
+ /* XXX: empty stub. */
+ return -UNW_EINVAL;
+}
+
+#endif /* !UNW_REMOTE_ONLY */
+
+/* This routine is responsible for copying the register values in
+ cursor C and establishing them as the current machine state. */
+
+static inline int
+establish_machine_state (struct cursor *c)
+{
+ /* XXX: empty stub. */
+ return 0;
+}
+
+PROTECTED int
+unw_resume (unw_cursor_t *cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ int ret;
+
+ Debug (1, "(cursor=%p)\n", c);
+
+ if ((ret = establish_machine_state (c)) < 0)
+ return ret;
+
+ return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c,
+ c->dwarf.as_arg);
+}
diff --git a/src/ppc32/Gstep.c b/src/ppc32/Gstep.c
new file mode 100644
index 0000000..d146e82
--- /dev/null
+++ b/src/ppc32/Gstep.c
@@ -0,0 +1,309 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+#include "ucontext_i.h"
+#include <signal.h>
+
+/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is
+ defined there only when __KERNEL__ is defined. We reproduce it here for
+ our use at the user level in order to locate the ucontext record, which
+ appears to be at this offset relative to the stack pointer when in the
+ context of the signal handler return trampoline code -
+ __kernel_sigtramp_rt64. */
+#define __SIGNAL_FRAMESIZE 128
+
+/* This definition comes from the document "64-bit PowerPC ELF Application
+ Binary Interface Supplement 1.9", section 3.2.2.
+ http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */
+
+typedef struct
+{
+ long unsigned back_chain;
+ long unsigned lr_save;
+ /* many more fields here, but they are unused by this code */
+} stack_frame_t;
+
+
+PROTECTED int
+unw_step (unw_cursor_t * cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ stack_frame_t dummy;
+ unw_word_t back_chain_offset, lr_save_offset;
+ struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc;
+ int ret;
+
+ Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip);
+
+ if (c->dwarf.ip == 0)
+ {
+ /* Unless the cursor or stack is corrupt or uninitialized,
+ we've most likely hit the top of the stack */
+ return 0;
+ }
+
+ /* Try DWARF-based unwinding... */
+
+ ret = dwarf_step (&c->dwarf);
+
+ if (ret < 0 && ret != -UNW_ENOINFO)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+
+ if (unlikely (ret < 0))
+ {
+ if (likely (!unw_is_signal_frame (cursor)))
+ {
+ /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode
+ produces the mandatory level of traceback record in the code, but
+ I get the impression that this is transitory, that eventually gcc
+ will not produce any traceback records at all. So, for now, we
+ won't bother to try to find and use these records.
+
+ We can, however, attempt to unwind the frame by using the callback
+ chain. This is very crude, however, and won't be able to unwind
+ any registers besides the IP, SP, and LR . */
+
+ back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy);
+ lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy);
+
+ back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0);
+
+ if ((ret =
+ dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0)
+ {
+ Debug
+ ("Unable to retrieve CFA from back chain in stack frame - %d\n",
+ ret);
+ return ret;
+ }
+ if (c->dwarf.cfa == 0)
+ /* Unless the cursor or stack is corrupt or uninitialized we've most
+ likely hit the top of the stack */
+ return 0;
+
+ lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0);
+
+ if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0)
+ {
+ Debug
+ ("Unable to retrieve IP from lr save in stack frame - %d\n",
+ ret);
+ return ret;
+ }
+ ret = 1;
+ }
+ else
+ {
+ /* Find the sigcontext record by taking the CFA and adjusting by
+ the dummy signal frame size.
+
+ Note that there isn't any way to determined if SA_SIGINFO was
+ set in the sa_flags parameter to sigaction when the signal
+ handler was established. If it was not set, the ucontext
+ record is not required to be on the stack, in which case the
+ following code will likely cause a seg fault or other crash
+ condition. */
+
+ unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE;
+
+ Debug (1, "signal frame, skip over trampoline\n");
+
+ c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME;
+ c->sigcontext_addr = ucontext;
+
+ sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
+ ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
+
+ ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa);
+ if (ret < 0)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+ ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip);
+ if (ret < 0)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+
+ /* Instead of just restoring the non-volatile registers, do all
+ of the registers for now. This will incur a performance hit,
+ but it's rare enough not to cause too much of a problem, and
+ might be useful in some cases. */
+ c->dwarf.loc[UNW_PPC32_R0] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0);
+ c->dwarf.loc[UNW_PPC32_R1] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
+ c->dwarf.loc[UNW_PPC32_R2] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0);
+ c->dwarf.loc[UNW_PPC32_R3] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0);
+ c->dwarf.loc[UNW_PPC32_R4] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0);
+ c->dwarf.loc[UNW_PPC32_R5] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0);
+ c->dwarf.loc[UNW_PPC32_R6] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0);
+ c->dwarf.loc[UNW_PPC32_R7] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0);
+ c->dwarf.loc[UNW_PPC32_R8] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
+ c->dwarf.loc[UNW_PPC32_R9] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
+ c->dwarf.loc[UNW_PPC32_R10] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
+ c->dwarf.loc[UNW_PPC32_R11] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
+ c->dwarf.loc[UNW_PPC32_R12] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
+ c->dwarf.loc[UNW_PPC32_R13] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
+ c->dwarf.loc[UNW_PPC32_R14] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
+ c->dwarf.loc[UNW_PPC32_R15] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
+ c->dwarf.loc[UNW_PPC32_R16] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0);
+ c->dwarf.loc[UNW_PPC32_R17] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0);
+ c->dwarf.loc[UNW_PPC32_R18] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0);
+ c->dwarf.loc[UNW_PPC32_R19] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0);
+ c->dwarf.loc[UNW_PPC32_R20] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0);
+ c->dwarf.loc[UNW_PPC32_R21] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0);
+ c->dwarf.loc[UNW_PPC32_R22] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0);
+ c->dwarf.loc[UNW_PPC32_R23] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0);
+ c->dwarf.loc[UNW_PPC32_R24] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0);
+ c->dwarf.loc[UNW_PPC32_R25] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0);
+ c->dwarf.loc[UNW_PPC32_R26] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0);
+ c->dwarf.loc[UNW_PPC32_R27] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0);
+ c->dwarf.loc[UNW_PPC32_R28] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0);
+ c->dwarf.loc[UNW_PPC32_R29] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0);
+ c->dwarf.loc[UNW_PPC32_R30] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0);
+ c->dwarf.loc[UNW_PPC32_R31] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0);
+
+ c->dwarf.loc[UNW_PPC32_LR] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
+ c->dwarf.loc[UNW_PPC32_CTR] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0);
+
+ /* This CR0 assignment is probably wrong. There are 8 dwarf columns
+ assigned to the CR registers, but only one CR register in the
+ mcontext structure */
+ c->dwarf.loc[UNW_PPC32_CCR] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0);
+ c->dwarf.loc[UNW_PPC32_XER] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0);
+
+ c->dwarf.loc[UNW_PPC32_F0] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0);
+ c->dwarf.loc[UNW_PPC32_F1] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0);
+ c->dwarf.loc[UNW_PPC32_F2] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0);
+ c->dwarf.loc[UNW_PPC32_F3] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0);
+ c->dwarf.loc[UNW_PPC32_F4] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0);
+ c->dwarf.loc[UNW_PPC32_F5] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0);
+ c->dwarf.loc[UNW_PPC32_F6] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0);
+ c->dwarf.loc[UNW_PPC32_F7] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0);
+ c->dwarf.loc[UNW_PPC32_F8] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0);
+ c->dwarf.loc[UNW_PPC32_F9] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0);
+ c->dwarf.loc[UNW_PPC32_F10] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0);
+ c->dwarf.loc[UNW_PPC32_F11] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0);
+ c->dwarf.loc[UNW_PPC32_F12] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0);
+ c->dwarf.loc[UNW_PPC32_F13] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0);
+ c->dwarf.loc[UNW_PPC32_F14] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0);
+ c->dwarf.loc[UNW_PPC32_F15] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0);
+ c->dwarf.loc[UNW_PPC32_F16] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0);
+ c->dwarf.loc[UNW_PPC32_F17] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0);
+ c->dwarf.loc[UNW_PPC32_F18] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0);
+ c->dwarf.loc[UNW_PPC32_F19] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0);
+ c->dwarf.loc[UNW_PPC32_F20] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0);
+ c->dwarf.loc[UNW_PPC32_F21] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0);
+ c->dwarf.loc[UNW_PPC32_F22] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0);
+ c->dwarf.loc[UNW_PPC32_F23] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0);
+ c->dwarf.loc[UNW_PPC32_F24] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0);
+ c->dwarf.loc[UNW_PPC32_F25] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0);
+ c->dwarf.loc[UNW_PPC32_F26] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0);
+ c->dwarf.loc[UNW_PPC32_F27] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0);
+ c->dwarf.loc[UNW_PPC32_F28] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0);
+ c->dwarf.loc[UNW_PPC32_F29] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0);
+ c->dwarf.loc[UNW_PPC32_F30] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0);
+ c->dwarf.loc[UNW_PPC32_F31] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0);
+
+ ret = 1;
+ }
+ }
+ return ret;
+}
diff --git a/src/hppa/Lget_reg.c b/src/ppc32/Lglobal.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc32/Lglobal.c
index effe8a8..6d7b489 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc32/Lglobal.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gglobal.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc32/Linit.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc32/Linit.c
index effe8a8..e9abfdd 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc32/Linit.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Ginit.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc32/Lregs.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc32/Lregs.c
index effe8a8..2c9c75c 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc32/Lregs.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gregs.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc32/Lresume.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc32/Lresume.c
index effe8a8..41a8cf0 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc32/Lresume.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gresume.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc32/Lstep.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc32/Lstep.c
index effe8a8..c1ac3c7 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc32/Lstep.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gstep.c"
#endif
diff --git a/src/ppc32/Make-arch.in b/src/ppc32/Make-arch.in
new file mode 100644
index 0000000..947dd5f
--- /dev/null
+++ b/src/ppc32/Make-arch.in
@@ -0,0 +1,11 @@
+# Word size.
+ELFW = 64
+# Does use dwarf2 unwind info.
+dwarf_target = true
+
+libunwind_setjmp_OBJS += \
+ $(arch)/longjmp.o \
+ $(arch)/siglongjmp.o
+
+libunwind_OBJS_common += \
+ $(arch)/is_fpreg.o
diff --git a/src/hppa/Gget_reg.c b/src/ppc32/get_func_addr.c
similarity index 77%
copy from src/hppa/Gget_reg.c
copy to src/ppc32/get_func_addr.c
index 4553f65..14797c9 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc32/get_func_addr.c
@@ -1,6 +1,8 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
This file is part of libunwind.
@@ -25,10 +27,10 @@
#include "unwind_i.h"
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+int
+tdep_get_func_addr (unw_addr_space_t as, unw_word_t symbol_val_addr,
+ unw_word_t *real_func_addr)
{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
+ *real_func_addr = symbol_val_addr;
+ return 0;
}
diff --git a/src/ppc32/init.h b/src/ppc32/init.h
new file mode 100644
index 0000000..8badb17
--- /dev/null
+++ b/src/ppc32/init.h
@@ -0,0 +1,71 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+/* Here is the "common" init, for remote and local debuging" */
+
+static inline int
+common_init_ppc32 (struct cursor *c)
+{
+ int ret;
+ int i;
+
+ for (i = UNW_PPC32_R0; i <= UNW_PPC32_R31; i++) {
+ c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i);
+ }
+ for (i = UNW_PPC32_F0; i <= UNW_PPC32_F31; i++) {
+ c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i);
+ }
+
+ c->dwarf.loc[UNW_PPC32_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CTR);
+ c->dwarf.loc[UNW_PPC32_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_XER);
+ c->dwarf.loc[UNW_PPC32_CCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CCR);
+ c->dwarf.loc[UNW_PPC32_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_LR);
+ c->dwarf.loc[UNW_PPC32_FPSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_FPSCR);
+
+ ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC32_LR], &c->dwarf.ip);
+ if (ret < 0)
+ return ret;
+
+ ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC32_R1),
+ &c->dwarf.cfa);
+ if (ret < 0)
+ return ret;
+
+ c->sigcontext_format = PPC_SCF_NONE;
+ c->sigcontext_addr = 0;
+
+ c->dwarf.args_size = 0;
+ c->dwarf.ret_addr_column = 0;
+ c->dwarf.pi_valid = 0;
+ c->dwarf.pi_is_dynamic = 0;
+ c->dwarf.hint = 0;
+ c->dwarf.prev_rs = 0;
+
+ return 0;
+}
diff --git a/src/hppa/Gget_reg.c b/src/ppc32/is_fpreg.c
similarity index 79%
copy from src/hppa/Gget_reg.c
copy to src/ppc32/is_fpreg.c
index 4553f65..cccc511 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc32/is_fpreg.c
@@ -1,6 +1,8 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
This file is part of libunwind.
@@ -23,12 +25,10 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+#include "libunwind_i.h"
PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+unw_is_fpreg (int regnum)
{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
+ return (regnum >= UNW_PPC32_F0 && regnum <= UNW_PPC32_F31);
}
diff --git a/src/ppc32/regname.c b/src/ppc32/regname.c
new file mode 100644
index 0000000..79ba88a
--- /dev/null
+++ b/src/ppc32/regname.c
@@ -0,0 +1,112 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+static const char *regname[] =
+ {
+ [UNW_PPC32_R0]="GPR0",
+ [UNW_PPC32_R1]="GPR1",
+ [UNW_PPC32_R2]="GPR2",
+ [UNW_PPC32_R3]="GPR3",
+ [UNW_PPC32_R4]="GPR4",
+ [UNW_PPC32_R5]="GPR5",
+ [UNW_PPC32_R6]="GPR6",
+ [UNW_PPC32_R7]="GPR7",
+ [UNW_PPC32_R8]="GPR8",
+ [UNW_PPC32_R9]="GPR9",
+ [UNW_PPC32_R10]="GPR10",
+ [UNW_PPC32_R11]="GPR11",
+ [UNW_PPC32_R12]="GPR12",
+ [UNW_PPC32_R13]="GPR13",
+ [UNW_PPC32_R14]="GPR14",
+ [UNW_PPC32_R15]="GPR15",
+ [UNW_PPC32_R16]="GPR16",
+ [UNW_PPC32_R17]="GPR17",
+ [UNW_PPC32_R18]="GPR18",
+ [UNW_PPC32_R19]="GPR19",
+ [UNW_PPC32_R20]="GPR20",
+ [UNW_PPC32_R21]="GPR21",
+ [UNW_PPC32_R22]="GPR22",
+ [UNW_PPC32_R23]="GPR23",
+ [UNW_PPC32_R24]="GPR24",
+ [UNW_PPC32_R25]="GPR25",
+ [UNW_PPC32_R26]="GPR26",
+ [UNW_PPC32_R27]="GPR27",
+ [UNW_PPC32_R28]="GPR28",
+ [UNW_PPC32_R29]="GPR29",
+ [UNW_PPC32_R30]="GPR30",
+ [UNW_PPC32_R31]="GPR31",
+
+ [UNW_PPC32_CTR]="CTR",
+ [UNW_PPC32_XER]="XER",
+ [UNW_PPC32_CCR]="CCR",
+ [UNW_PPC32_LR]="LR",
+ [UNW_PPC32_FPSCR]="FPSCR",
+
+ [UNW_PPC32_F0]="FPR0",
+ [UNW_PPC32_F1]="FPR1",
+ [UNW_PPC32_F2]="FPR2",
+ [UNW_PPC32_F3]="FPR3",
+ [UNW_PPC32_F4]="FPR4",
+ [UNW_PPC32_F5]="FPR5",
+ [UNW_PPC32_F6]="FPR6",
+ [UNW_PPC32_F7]="FPR7",
+ [UNW_PPC32_F8]="FPR8",
+ [UNW_PPC32_F9]="FPR9",
+ [UNW_PPC32_F10]="FPR10",
+ [UNW_PPC32_F11]="FPR11",
+ [UNW_PPC32_F12]="FPR12",
+ [UNW_PPC32_F13]="FPR13",
+ [UNW_PPC32_F14]="FPR14",
+ [UNW_PPC32_F15]="FPR15",
+ [UNW_PPC32_F16]="FPR16",
+ [UNW_PPC32_F17]="FPR17",
+ [UNW_PPC32_F18]="FPR18",
+ [UNW_PPC32_F19]="FPR19",
+ [UNW_PPC32_F20]="FPR20",
+ [UNW_PPC32_F21]="FPR21",
+ [UNW_PPC32_F22]="FPR22",
+ [UNW_PPC32_F23]="FPR23",
+ [UNW_PPC32_F24]="FPR24",
+ [UNW_PPC32_F25]="FPR25",
+ [UNW_PPC32_F26]="FPR26",
+ [UNW_PPC32_F27]="FPR27",
+ [UNW_PPC32_F28]="FPR28",
+ [UNW_PPC32_F29]="FPR29",
+ [UNW_PPC32_F30]="FPR30",
+ [UNW_PPC32_F31]="FPR31"
+};
+
+PROTECTED const char *
+unw_regname (unw_regnum_t reg)
+{
+ if (reg < (unw_regnum_t) ARRAY_SIZE (regname))
+ return regname[reg];
+ else
+ return "???";
+}
diff --git a/src/ppc32/setcontext.S b/src/ppc32/setcontext.S
new file mode 100644
index 0000000..b54378a
--- /dev/null
+++ b/src/ppc32/setcontext.S
@@ -0,0 +1,9 @@
+ .global _UI_setcontext
+
+_UI_setcontext:
+ retq
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ppc32/ucontext_i.h b/src/ppc32/ucontext_i.h
new file mode 100644
index 0000000..52c3dc7
--- /dev/null
+++ b/src/ppc32/ucontext_i.h
@@ -0,0 +1,128 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef ucontext_i_h
+#define ucontext_i_h
+
+#include <ucontext.h>
+
+/* These values were derived by reading
+ /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and
+ /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h
+*/
+
+//#define NIP_IDX 32
+#define CTR_IDX 32
+#define XER_IDX 33
+#define CCR_IDX 34
+#define MSR_IDX 35
+//#define MQ_IDX 36
+#define LINK_IDX 36
+
+/* These are dummy structures used only for obtaining the offsets of the
+ various structure members. */
+static ucontext_t dmy_ctxt;
+static vrregset_t dmy_vrregset;
+
+#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[0] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[1] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[2] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[3] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[4] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[5] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[6] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[7] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[8] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[9] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[10] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[11] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[12] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[13] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[14] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[15] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[16] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[17] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[18] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[19] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[20] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[21] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[22] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[23] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[24] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[25] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[26] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[27] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[28] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[29] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[30] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[31] - (void *)&dmy_ctxt)
+
+#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[MSR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CTR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[LINK_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[XER_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CCR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[SOFTE_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[TRAP_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DAR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DSISR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[RESULT_IDX] - (void *)&dmy_ctxt)
+
+#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[0] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[1] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[2] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[3] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[4] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[5] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[6] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[7] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[8] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[9] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[10] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[11] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[12] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[13] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[14] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[15] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[16] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[17] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[18] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[19] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[20] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[21] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[22] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[23] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[24] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[25] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[26] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[27] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[28] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[29] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[30] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[31] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[32] - (void *)&dmy_ctxt)
+
+#endif
diff --git a/src/hppa/Gget_reg.c b/src/ppc32/unwind_i.h
similarity index 62%
copy from src/hppa/Gget_reg.c
copy to src/ppc32/unwind_i.h
index 4553f65..c3c3a57 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc32/unwind_i.h
@@ -1,6 +1,8 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
This file is part of libunwind.
@@ -23,12 +25,23 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+#ifndef unwind_i_h
+#define unwind_i_h
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
+#include <memory.h>
+#include <stdint.h>
- return hppa_access_reg (c, regnum, valp, 0);
-}
+#include <libunwind-ppc32.h>
+
+#include <libunwind_i.h>
+#include <sys/ucontext.h>
+
+#define ppc32_lock UNW_OBJ(lock)
+#define ppc32_local_resume UNW_OBJ(local_resume)
+#define ppc32_local_addr_space_init UNW_OBJ(local_addr_space_init)
+
+extern void ppc32_local_addr_space_init (void);
+extern int ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
+ void *arg);
+
+#endif /* unwind_i_h */
diff --git a/src/ppc64/Gglobal.c b/src/ppc64/Gglobal.c
new file mode 100644
index 0000000..1506b00
--- /dev/null
+++ b/src/ppc64/Gglobal.c
@@ -0,0 +1,184 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+#include "dwarf_i.h"
+
+HIDDEN pthread_mutex_t ppc64_lock = PTHREAD_MUTEX_INITIALIZER;
+HIDDEN int tdep_needs_initialization = 1;
+
+/* The API register numbers are exactly the same as the .eh_frame
+ registers, for now at least. */
+uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] =
+ {
+ [UNW_PPC64_R0]=UNW_PPC64_R0,
+ [UNW_PPC64_R1]=UNW_PPC64_R1,
+ [UNW_PPC64_R2]=UNW_PPC64_R2,
+ [UNW_PPC64_R3]=UNW_PPC64_R3,
+ [UNW_PPC64_R4]=UNW_PPC64_R4,
+ [UNW_PPC64_R5]=UNW_PPC64_R5,
+ [UNW_PPC64_R6]=UNW_PPC64_R6,
+ [UNW_PPC64_R7]=UNW_PPC64_R7,
+ [UNW_PPC64_R8]=UNW_PPC64_R8,
+ [UNW_PPC64_R9]=UNW_PPC64_R9,
+ [UNW_PPC64_R10]=UNW_PPC64_R10,
+ [UNW_PPC64_R11]=UNW_PPC64_R11,
+ [UNW_PPC64_R12]=UNW_PPC64_R12,
+ [UNW_PPC64_R13]=UNW_PPC64_R13,
+ [UNW_PPC64_R14]=UNW_PPC64_R14,
+ [UNW_PPC64_R15]=UNW_PPC64_R15,
+ [UNW_PPC64_R16]=UNW_PPC64_R16,
+ [UNW_PPC64_R17]=UNW_PPC64_R17,
+ [UNW_PPC64_R18]=UNW_PPC64_R18,
+ [UNW_PPC64_R19]=UNW_PPC64_R19,
+ [UNW_PPC64_R20]=UNW_PPC64_R20,
+ [UNW_PPC64_R21]=UNW_PPC64_R21,
+ [UNW_PPC64_R22]=UNW_PPC64_R22,
+ [UNW_PPC64_R23]=UNW_PPC64_R23,
+ [UNW_PPC64_R24]=UNW_PPC64_R24,
+ [UNW_PPC64_R25]=UNW_PPC64_R25,
+ [UNW_PPC64_R26]=UNW_PPC64_R26,
+ [UNW_PPC64_R27]=UNW_PPC64_R27,
+ [UNW_PPC64_R28]=UNW_PPC64_R28,
+ [UNW_PPC64_R29]=UNW_PPC64_R29,
+ [UNW_PPC64_R30]=UNW_PPC64_R30,
+ [UNW_PPC64_R31]=UNW_PPC64_R31,
+
+ [UNW_PPC64_F0]=UNW_PPC64_F0,
+ [UNW_PPC64_F1]=UNW_PPC64_F1,
+ [UNW_PPC64_F2]=UNW_PPC64_F2,
+ [UNW_PPC64_F3]=UNW_PPC64_F3,
+ [UNW_PPC64_F4]=UNW_PPC64_F4,
+ [UNW_PPC64_F5]=UNW_PPC64_F5,
+ [UNW_PPC64_F6]=UNW_PPC64_F6,
+ [UNW_PPC64_F7]=UNW_PPC64_F7,
+ [UNW_PPC64_F8]=UNW_PPC64_F8,
+ [UNW_PPC64_F9]=UNW_PPC64_F9,
+ [UNW_PPC64_F10]=UNW_PPC64_F10,
+ [UNW_PPC64_F11]=UNW_PPC64_F11,
+ [UNW_PPC64_F12]=UNW_PPC64_F12,
+ [UNW_PPC64_F13]=UNW_PPC64_F13,
+ [UNW_PPC64_F14]=UNW_PPC64_F14,
+ [UNW_PPC64_F15]=UNW_PPC64_F15,
+ [UNW_PPC64_F16]=UNW_PPC64_F16,
+ [UNW_PPC64_F17]=UNW_PPC64_F17,
+ [UNW_PPC64_F18]=UNW_PPC64_F18,
+ [UNW_PPC64_F19]=UNW_PPC64_F19,
+ [UNW_PPC64_F20]=UNW_PPC64_F20,
+ [UNW_PPC64_F21]=UNW_PPC64_F21,
+ [UNW_PPC64_F22]=UNW_PPC64_F22,
+ [UNW_PPC64_F23]=UNW_PPC64_F23,
+ [UNW_PPC64_F24]=UNW_PPC64_F24,
+ [UNW_PPC64_F25]=UNW_PPC64_F25,
+ [UNW_PPC64_F26]=UNW_PPC64_F26,
+ [UNW_PPC64_F27]=UNW_PPC64_F27,
+ [UNW_PPC64_F28]=UNW_PPC64_F28,
+ [UNW_PPC64_F29]=UNW_PPC64_F29,
+ [UNW_PPC64_F30]=UNW_PPC64_F30,
+ [UNW_PPC64_F31]=UNW_PPC64_F31,
+
+ [UNW_PPC64_LR]=UNW_PPC64_LR,
+ [UNW_PPC64_CTR]=UNW_PPC64_CTR,
+ [UNW_PPC64_ARG_POINTER]=UNW_PPC64_ARG_POINTER,
+
+ [UNW_PPC64_CR0]=UNW_PPC64_CR0,
+ [UNW_PPC64_CR1]=UNW_PPC64_CR1,
+ [UNW_PPC64_CR2]=UNW_PPC64_CR2,
+ [UNW_PPC64_CR3]=UNW_PPC64_CR3,
+ [UNW_PPC64_CR4]=UNW_PPC64_CR4,
+ [UNW_PPC64_CR5]=UNW_PPC64_CR5,
+ [UNW_PPC64_CR6]=UNW_PPC64_CR6,
+ [UNW_PPC64_CR7]=UNW_PPC64_CR7,
+
+ [UNW_PPC64_XER]=UNW_PPC64_XER,
+
+ [UNW_PPC64_V0]=UNW_PPC64_V0,
+ [UNW_PPC64_V1]=UNW_PPC64_V1,
+ [UNW_PPC64_V2]=UNW_PPC64_V2,
+ [UNW_PPC64_V3]=UNW_PPC64_V3,
+ [UNW_PPC64_V4]=UNW_PPC64_V4,
+ [UNW_PPC64_V5]=UNW_PPC64_V5,
+ [UNW_PPC64_V6]=UNW_PPC64_V6,
+ [UNW_PPC64_V7]=UNW_PPC64_V7,
+ [UNW_PPC64_V8]=UNW_PPC64_V8,
+ [UNW_PPC64_V9]=UNW_PPC64_V9,
+ [UNW_PPC64_V10]=UNW_PPC64_V10,
+ [UNW_PPC64_V11]=UNW_PPC64_V11,
+ [UNW_PPC64_V12]=UNW_PPC64_V12,
+ [UNW_PPC64_V13]=UNW_PPC64_V13,
+ [UNW_PPC64_V14]=UNW_PPC64_V14,
+ [UNW_PPC64_V15]=UNW_PPC64_V15,
+ [UNW_PPC64_V16]=UNW_PPC64_V16,
+ [UNW_PPC64_V17]=UNW_PPC64_V17,
+ [UNW_PPC64_V18]=UNW_PPC64_V18,
+ [UNW_PPC64_V19]=UNW_PPC64_V19,
+ [UNW_PPC64_V20]=UNW_PPC64_V20,
+ [UNW_PPC64_V21]=UNW_PPC64_V21,
+ [UNW_PPC64_V22]=UNW_PPC64_V22,
+ [UNW_PPC64_V23]=UNW_PPC64_V23,
+ [UNW_PPC64_V24]=UNW_PPC64_V24,
+ [UNW_PPC64_V25]=UNW_PPC64_V25,
+ [UNW_PPC64_V26]=UNW_PPC64_V26,
+ [UNW_PPC64_V27]=UNW_PPC64_V27,
+ [UNW_PPC64_V28]=UNW_PPC64_V28,
+ [UNW_PPC64_V29]=UNW_PPC64_V29,
+ [UNW_PPC64_V30]=UNW_PPC64_V30,
+ [UNW_PPC64_V31]=UNW_PPC64_V31,
+
+ [UNW_PPC64_VRSAVE]=UNW_PPC64_VRSAVE,
+ [UNW_PPC64_VSCR]=UNW_PPC64_VSCR,
+ [UNW_PPC64_SPE_ACC]=UNW_PPC64_SPE_ACC,
+ [UNW_PPC64_SPEFSCR]=UNW_PPC64_SPEFSCR,
+ };
+
+HIDDEN void
+tdep_init (void)
+{
+ intrmask_t saved_mask;
+
+ sigfillset (&unwi_full_mask);
+
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
+ mutex_lock (&ppc64_lock);
+ {
+ if (!tdep_needs_initialization)
+ /* another thread else beat us to it... */
+ goto out;
+
+ mi_init ();
+
+ dwarf_init ();
+
+#ifndef UNW_REMOTE_ONLY
+ ppc64_local_addr_space_init ();
+#endif
+ tdep_needs_initialization = 0; /* signal that we're initialized... */
+ }
+ out:
+ mutex_unlock (&ppc64_lock);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
+}
diff --git a/src/ppc64/Ginit.c b/src/ppc64/Ginit.c
new file mode 100644
index 0000000..97c9d78
--- /dev/null
+++ b/src/ppc64/Ginit.c
@@ -0,0 +1,230 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ucontext_i.h"
+#include "unwind_i.h"
+
+#ifdef UNW_REMOTE_ONLY
+
+/* unw_local_addr_space is a NULL pointer in this case. */
+PROTECTED unw_addr_space_t unw_local_addr_space;
+
+#else /* !UNW_REMOTE_ONLY */
+
+static struct unw_addr_space local_addr_space;
+
+PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space;
+
+
+#define PAGE_SIZE 4096
+#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
+
+
+static void *
+uc_addr (ucontext_t *uc, int reg)
+{
+ void *addr;
+
+ if ((unsigned) (reg - UNW_PPC64_R0) < 32)
+ addr = &uc->uc_mcontext.gp_regs[reg - UNW_PPC64_R0];
+
+ else if ((unsigned) (reg - UNW_PPC64_F0) < 32)
+ addr = &uc->uc_mcontext.fp_regs[reg - UNW_PPC64_F0];
+
+ else if ((unsigned) (reg - UNW_PPC64_V0) < 32)
+ addr = (uc->uc_mcontext.v_regs == 0) ? NULL : &uc->uc_mcontext.v_regs->vrregs[reg - UNW_PPC64_V0][0];
+
+ else
+ {
+ unsigned gregs_idx;
+
+ switch (reg)
+ {
+ case UNW_PPC64_NIP:
+ gregs_idx = NIP_IDX;
+ break;
+ case UNW_PPC64_CTR:
+ gregs_idx = CTR_IDX;
+ break;
+ case UNW_PPC64_LR:
+ gregs_idx = LINK_IDX;
+ break;
+ case UNW_PPC64_XER:
+ gregs_idx = XER_IDX;
+ break;
+ case UNW_PPC64_CR0:
+ gregs_idx = CCR_IDX;
+ break;
+ default:
+ return NULL;
+ }
+ addr = &uc->uc_mcontext.gp_regs[gregs_idx];
+ }
+ return addr;
+}
+
+# ifdef UNW_LOCAL_ONLY
+
+HIDDEN void *
+tdep_uc_addr (ucontext_t *uc, int reg)
+{
+ return uc_addr (uc, reg);
+}
+
+# endif /* UNW_LOCAL_ONLY */
+
+HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
+
+
+static void
+put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
+{
+ /* it's a no-op */
+}
+
+static int
+get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
+ void *arg)
+{
+ *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+ return 0;
+}
+
+static int
+access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
+ void *arg)
+{
+ if (write)
+ {
+ Debug (12, "mem[%lx] <- %lx\n", addr, *val);
+ *(unw_word_t *) addr = *val;
+ }
+ else
+ {
+ *val = *(unw_word_t *) addr;
+ Debug (12, "mem[%lx] -> %lx\n", addr, *val);
+ }
+ return 0;
+}
+
+static int
+access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
+ int write, void *arg)
+{
+ unw_word_t *addr;
+ ucontext_t *uc = arg;
+
+ if ((unsigned int) (reg - UNW_PPC64_F0) < 32)
+ goto badreg;
+ if ((unsigned int) (reg - UNW_PPC64_V0) < 32)
+ goto badreg;
+
+ addr = uc_addr (uc, reg);
+ if (!addr)
+ goto badreg;
+
+ if (write)
+ {
+ *(unw_word_t *) addr = *val;
+ Debug (12, "%s <- %lx\n", unw_regname (reg), *val);
+ }
+ else
+ {
+ *val = *(unw_word_t *) addr;
+ Debug (12, "%s -> %lx\n", unw_regname (reg), *val);
+ }
+ return 0;
+
+badreg:
+ Debug (1, "bad register number %u\n", reg);
+ return -UNW_EBADREG;
+}
+
+static int
+access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
+ int write, void *arg)
+{
+ ucontext_t *uc = arg;
+ unw_fpreg_t *addr;
+
+ if ((unsigned) (reg - UNW_PPC64_F0) < 0)
+ goto badreg;
+
+ if ((unsigned) (reg - UNW_PPC64_V0) >= 32)
+ goto badreg;
+
+
+ addr = uc_addr (uc, reg);
+ if (!addr)
+ goto badreg;
+
+ if (write)
+ {
+ Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val);
+ *(unw_fpreg_t *) addr = *val;
+ }
+ else
+ {
+ *val = *(unw_fpreg_t *) addr;
+ Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val);
+ }
+ return 0;
+
+badreg:
+ Debug (1, "bad register number %u\n", reg);
+ /* attempt to access a non-preserved register */
+ return -UNW_EBADREG;
+}
+
+static int
+get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
+ char *buf, size_t buf_len, unw_word_t *offp,
+ void *arg)
+{
+ return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
+}
+
+HIDDEN void
+ppc64_local_addr_space_init (void)
+{
+ memset (&local_addr_space, 0, sizeof (local_addr_space));
+ local_addr_space.caching_policy = UNW_CACHE_GLOBAL;
+ local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
+ local_addr_space.acc.put_unwind_info = put_unwind_info;
+ local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
+ local_addr_space.acc.access_mem = access_mem;
+ local_addr_space.acc.access_reg = access_reg;
+ local_addr_space.acc.access_fpreg = access_fpreg;
+ local_addr_space.acc.resume = ppc64_local_resume;
+ local_addr_space.acc.get_proc_name = get_static_proc_name;
+ unw_flush_cache (&local_addr_space, 0, 0);
+}
+
+#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/ppc64/Gregs.c b/src/ppc64/Gregs.c
new file mode 100644
index 0000000..b044504
--- /dev/null
+++ b/src/ppc64/Gregs.c
@@ -0,0 +1,100 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+HIDDEN int
+tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
+ int write)
+{
+ struct dwarf_loc loc;
+
+ switch (reg)
+ {
+ case UNW_TDEP_IP:
+ if (write)
+ {
+ c->dwarf.ip = *valp; /* update the IP cache */
+ if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip
+ || *valp >= c->dwarf.pi.end_ip))
+ c->dwarf.pi_valid = 0; /* new IP outside of current proc */
+ }
+ else
+ *valp = c->dwarf.ip;
+ return 0;
+
+ case UNW_TDEP_SP:
+ if (write)
+ return -UNW_EREADONLYREG;
+ *valp = c->dwarf.cfa;
+ return 0;
+
+
+ default:
+ break;
+ }
+
+ /* make sure it's not an FP or VR register */
+ if ((((unsigned) (reg - UNW_PPC64_F0)) <= 31) ||
+ (((unsigned) (reg - UNW_PPC64_V0)) <= 31))
+ return -UNW_EBADREG;
+
+ loc = c->dwarf.loc[reg];
+
+ if (write)
+ return dwarf_put (&c->dwarf, loc, *valp);
+ else
+ return dwarf_get (&c->dwarf, loc, valp);
+}
+
+HIDDEN int
+tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
+ int write)
+{
+ struct dwarf_loc loc;
+
+ if ((unsigned) (reg - UNW_PPC64_F0) < 32)
+ {
+ loc = c->dwarf.loc[reg];
+ if (write)
+ return dwarf_putfp (&c->dwarf, loc, *valp);
+ else
+ return dwarf_getfp (&c->dwarf, loc, valp);
+ }
+ else
+ if ((unsigned) (reg - UNW_PPC64_V0) < 32)
+ {
+ loc = c->dwarf.loc[reg];
+ if (write)
+ return dwarf_putvr (&c->dwarf, loc, *valp);
+ else
+ return dwarf_getvr (&c->dwarf, loc, valp);
+ }
+
+ return -UNW_EBADREG;
+}
+
diff --git a/src/ppc64/Gresume.c b/src/ppc64/Gresume.c
new file mode 100644
index 0000000..893ea63
--- /dev/null
+++ b/src/ppc64/Gresume.c
@@ -0,0 +1,77 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford cjashfor@us.ibm.com
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <stdlib.h>
+
+#include "unwind_i.h"
+
+#ifndef UNW_REMOTE_ONLY
+
+#include <sys/syscall.h>
+
+/* sigreturn() is a no-op on x86_64 glibc. */
+
+static NORETURN inline long
+my_rt_sigreturn (void *new_sp)
+{
+ /* XXX: empty stub. */
+ abort ();
+}
+
+HIDDEN inline int
+ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
+{
+ /* XXX: empty stub. */
+ return -UNW_EINVAL;
+}
+
+#endif /* !UNW_REMOTE_ONLY */
+
+/* This routine is responsible for copying the register values in
+ cursor C and establishing them as the current machine state. */
+
+static inline int
+establish_machine_state (struct cursor *c)
+{
+ /* XXX: empty stub. */
+ return 0;
+}
+
+PROTECTED int
+unw_resume (unw_cursor_t *cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ int ret;
+
+ Debug (1, "(cursor=%p)\n", c);
+
+ if ((ret = establish_machine_state (c)) < 0)
+ return ret;
+
+ return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c,
+ c->dwarf.as_arg);
+}
diff --git a/src/ppc64/Gstep.c b/src/ppc64/Gstep.c
new file mode 100644
index 0000000..20b22b5
--- /dev/null
+++ b/src/ppc64/Gstep.c
@@ -0,0 +1,436 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+#include "ucontext_i.h"
+#include <signal.h>
+
+/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is
+ defined there only when __KERNEL__ is defined. We reproduce it here for
+ our use at the user level in order to locate the ucontext record, which
+ appears to be at this offset relative to the stack pointer when in the
+ context of the signal handler return trampoline code -
+ __kernel_sigtramp_rt64. */
+#define __SIGNAL_FRAMESIZE 128
+
+/* This definition comes from the document "64-bit PowerPC ELF Application
+ Binary Interface Supplement 1.9", section 3.2.2.
+ http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */
+
+typedef struct
+{
+ long unsigned back_chain;
+ long unsigned cr_save;
+ long unsigned lr_save;
+ /* many more fields here, but they are unused by this code */
+} stack_frame_t;
+
+
+PROTECTED int
+unw_step (unw_cursor_t * cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ stack_frame_t dummy;
+ unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr;
+ struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc;
+ int ret;
+
+ Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip);
+
+ if (c->dwarf.ip == 0)
+ {
+ /* Unless the cursor or stack is corrupt or uninitialized,
+ we've most likely hit the top of the stack */
+ return 0;
+ }
+
+ /* Try DWARF-based unwinding... */
+
+ ret = dwarf_step (&c->dwarf);
+
+ if (ret < 0 && ret != -UNW_ENOINFO)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+
+ if (unlikely (ret < 0))
+ {
+ if (likely (!unw_is_signal_frame (cursor)))
+ {
+ /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode
+ produces the mandatory level of traceback record in the code, but
+ I get the impression that this is transitory, that eventually gcc
+ will not produce any traceback records at all. So, for now, we
+ won't bother to try to find and use these records.
+
+ We can, however, attempt to unwind the frame by using the callback
+ chain. This is very crude, however, and won't be able to unwind
+ any registers besides the IP, SP, and LR . */
+
+ back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy);
+ lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy);
+
+ back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0);
+
+ if ((ret =
+ dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0)
+ {
+ Debug
+ ("Unable to retrieve CFA from back chain in stack frame - %d\n",
+ ret);
+ return ret;
+ }
+ if (c->dwarf.cfa == 0)
+ /* Unless the cursor or stack is corrupt or uninitialized we've most
+ likely hit the top of the stack */
+ return 0;
+
+ lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0);
+
+ if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0)
+ {
+ Debug
+ ("Unable to retrieve IP from lr save in stack frame - %d\n",
+ ret);
+ return ret;
+ }
+ ret = 1;
+ }
+ else
+ {
+ /* Find the sigcontext record by taking the CFA and adjusting by
+ the dummy signal frame size.
+
+ Note that there isn't any way to determined if SA_SIGINFO was
+ set in the sa_flags parameter to sigaction when the signal
+ handler was established. If it was not set, the ucontext
+ record is not required to be on the stack, in which case the
+ following code will likely cause a seg fault or other crash
+ condition. */
+
+ unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE;
+
+ Debug (1, "signal frame, skip over trampoline\n");
+
+ c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME;
+ c->sigcontext_addr = ucontext;
+
+ sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
+ ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0);
+
+ ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa);
+ if (ret < 0)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+ ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip);
+ if (ret < 0)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+
+ /* Instead of just restoring the non-volatile registers, do all
+ of the registers for now. This will incur a performance hit,
+ but it's rare enough not to cause too much of a problem, and
+ might be useful in some cases. */
+ c->dwarf.loc[UNW_PPC64_R0] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0);
+ c->dwarf.loc[UNW_PPC64_R1] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
+ c->dwarf.loc[UNW_PPC64_R2] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0);
+ c->dwarf.loc[UNW_PPC64_R3] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0);
+ c->dwarf.loc[UNW_PPC64_R4] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0);
+ c->dwarf.loc[UNW_PPC64_R5] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0);
+ c->dwarf.loc[UNW_PPC64_R6] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0);
+ c->dwarf.loc[UNW_PPC64_R7] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0);
+ c->dwarf.loc[UNW_PPC64_R8] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
+ c->dwarf.loc[UNW_PPC64_R9] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
+ c->dwarf.loc[UNW_PPC64_R10] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
+ c->dwarf.loc[UNW_PPC64_R11] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
+ c->dwarf.loc[UNW_PPC64_R12] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
+ c->dwarf.loc[UNW_PPC64_R13] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
+ c->dwarf.loc[UNW_PPC64_R14] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
+ c->dwarf.loc[UNW_PPC64_R15] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
+ c->dwarf.loc[UNW_PPC64_R16] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0);
+ c->dwarf.loc[UNW_PPC64_R17] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0);
+ c->dwarf.loc[UNW_PPC64_R18] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0);
+ c->dwarf.loc[UNW_PPC64_R19] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0);
+ c->dwarf.loc[UNW_PPC64_R20] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0);
+ c->dwarf.loc[UNW_PPC64_R21] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0);
+ c->dwarf.loc[UNW_PPC64_R22] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0);
+ c->dwarf.loc[UNW_PPC64_R23] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0);
+ c->dwarf.loc[UNW_PPC64_R24] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0);
+ c->dwarf.loc[UNW_PPC64_R25] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0);
+ c->dwarf.loc[UNW_PPC64_R26] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0);
+ c->dwarf.loc[UNW_PPC64_R27] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0);
+ c->dwarf.loc[UNW_PPC64_R28] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0);
+ c->dwarf.loc[UNW_PPC64_R29] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0);
+ c->dwarf.loc[UNW_PPC64_R30] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0);
+ c->dwarf.loc[UNW_PPC64_R31] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0);
+
+ c->dwarf.loc[UNW_PPC64_LR] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
+ c->dwarf.loc[UNW_PPC64_CTR] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0);
+ /* This CR0 assignment is probably wrong. There are 8 dwarf columns
+ assigned to the CR registers, but only one CR register in the
+ mcontext structure */
+ c->dwarf.loc[UNW_PPC64_CR0] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0);
+ c->dwarf.loc[UNW_PPC64_XER] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0);
+ c->dwarf.loc[UNW_PPC64_NIP] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0);
+
+ /* TODO: Is there a way of obtaining the value of the
+ pseudo frame pointer (which is sp + some fixed offset, I
+ assume), based on the contents of the ucontext record
+ structure? For now, set this loc to null. */
+ c->dwarf.loc[UNW_PPC64_FRAME_POINTER] = DWARF_NULL_LOC;
+
+ c->dwarf.loc[UNW_PPC64_F0] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0);
+ c->dwarf.loc[UNW_PPC64_F1] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0);
+ c->dwarf.loc[UNW_PPC64_F2] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0);
+ c->dwarf.loc[UNW_PPC64_F3] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0);
+ c->dwarf.loc[UNW_PPC64_F4] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0);
+ c->dwarf.loc[UNW_PPC64_F5] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0);
+ c->dwarf.loc[UNW_PPC64_F6] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0);
+ c->dwarf.loc[UNW_PPC64_F7] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0);
+ c->dwarf.loc[UNW_PPC64_F8] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0);
+ c->dwarf.loc[UNW_PPC64_F9] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0);
+ c->dwarf.loc[UNW_PPC64_F10] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0);
+ c->dwarf.loc[UNW_PPC64_F11] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0);
+ c->dwarf.loc[UNW_PPC64_F12] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0);
+ c->dwarf.loc[UNW_PPC64_F13] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0);
+ c->dwarf.loc[UNW_PPC64_F14] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0);
+ c->dwarf.loc[UNW_PPC64_F15] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0);
+ c->dwarf.loc[UNW_PPC64_F16] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0);
+ c->dwarf.loc[UNW_PPC64_F17] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0);
+ c->dwarf.loc[UNW_PPC64_F18] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0);
+ c->dwarf.loc[UNW_PPC64_F19] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0);
+ c->dwarf.loc[UNW_PPC64_F20] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0);
+ c->dwarf.loc[UNW_PPC64_F21] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0);
+ c->dwarf.loc[UNW_PPC64_F22] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0);
+ c->dwarf.loc[UNW_PPC64_F23] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0);
+ c->dwarf.loc[UNW_PPC64_F24] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0);
+ c->dwarf.loc[UNW_PPC64_F25] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0);
+ c->dwarf.loc[UNW_PPC64_F26] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0);
+ c->dwarf.loc[UNW_PPC64_F27] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0);
+ c->dwarf.loc[UNW_PPC64_F28] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0);
+ c->dwarf.loc[UNW_PPC64_F29] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0);
+ c->dwarf.loc[UNW_PPC64_F30] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0);
+ c->dwarf.loc[UNW_PPC64_F31] =
+ DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0);
+ /* Note that there is no .eh_section register column for the
+ FPSCR register. I don't know why this is. */
+
+ v_regs_loc = DWARF_LOC (ucontext + UC_MCONTEXT_V_REGS, 0);
+ ret = dwarf_get (&c->dwarf, v_regs_loc, &v_regs_ptr);
+ if (ret < 0)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+ if (v_regs_ptr != 0)
+ {
+ /* The v_regs_ptr is not null. Set all of the AltiVec locs */
+
+ c->dwarf.loc[UNW_PPC64_V0] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R0, 0);
+ c->dwarf.loc[UNW_PPC64_V1] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R1, 0);
+ c->dwarf.loc[UNW_PPC64_V2] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R2, 0);
+ c->dwarf.loc[UNW_PPC64_V3] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R3, 0);
+ c->dwarf.loc[UNW_PPC64_V4] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R4, 0);
+ c->dwarf.loc[UNW_PPC64_V5] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R5, 0);
+ c->dwarf.loc[UNW_PPC64_V6] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R6, 0);
+ c->dwarf.loc[UNW_PPC64_V7] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R7, 0);
+ c->dwarf.loc[UNW_PPC64_V8] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R8, 0);
+ c->dwarf.loc[UNW_PPC64_V9] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R9, 0);
+ c->dwarf.loc[UNW_PPC64_V10] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R10, 0);
+ c->dwarf.loc[UNW_PPC64_V11] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R11, 0);
+ c->dwarf.loc[UNW_PPC64_V12] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R12, 0);
+ c->dwarf.loc[UNW_PPC64_V13] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R13, 0);
+ c->dwarf.loc[UNW_PPC64_V14] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R14, 0);
+ c->dwarf.loc[UNW_PPC64_V15] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R15, 0);
+ c->dwarf.loc[UNW_PPC64_V16] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R16, 0);
+ c->dwarf.loc[UNW_PPC64_V17] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R17, 0);
+ c->dwarf.loc[UNW_PPC64_V18] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R18, 0);
+ c->dwarf.loc[UNW_PPC64_V19] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R19, 0);
+ c->dwarf.loc[UNW_PPC64_V20] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R20, 0);
+ c->dwarf.loc[UNW_PPC64_V21] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R21, 0);
+ c->dwarf.loc[UNW_PPC64_V22] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R22, 0);
+ c->dwarf.loc[UNW_PPC64_V23] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R23, 0);
+ c->dwarf.loc[UNW_PPC64_V24] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R24, 0);
+ c->dwarf.loc[UNW_PPC64_V25] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R25, 0);
+ c->dwarf.loc[UNW_PPC64_V26] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R26, 0);
+ c->dwarf.loc[UNW_PPC64_V27] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R27, 0);
+ c->dwarf.loc[UNW_PPC64_V28] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R28, 0);
+ c->dwarf.loc[UNW_PPC64_V29] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R29, 0);
+ c->dwarf.loc[UNW_PPC64_V30] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R30, 0);
+ c->dwarf.loc[UNW_PPC64_V31] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R31, 0);
+ c->dwarf.loc[UNW_PPC64_VRSAVE] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VRSAVE, 0);
+ c->dwarf.loc[UNW_PPC64_VSCR] =
+ DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VSCR, 0);
+ }
+ else
+ {
+ c->dwarf.loc[UNW_PPC64_V0] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V1] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V2] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V3] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V4] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V5] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V6] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V7] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V8] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V9] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V10] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V11] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V12] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V13] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V14] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V15] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V16] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V17] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V18] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V19] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V20] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V21] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V22] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V23] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V24] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V25] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V26] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V27] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V28] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V29] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V30] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_V31] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_NULL_LOC;
+ c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_NULL_LOC;
+ }
+ ret = 1;
+ }
+ }
+ return ret;
+}
diff --git a/src/hppa/Lget_reg.c b/src/ppc64/Lglobal.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc64/Lglobal.c
index effe8a8..6d7b489 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc64/Lglobal.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gglobal.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc64/Linit.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc64/Linit.c
index effe8a8..e9abfdd 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc64/Linit.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Ginit.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc64/Lregs.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc64/Lregs.c
index effe8a8..2c9c75c 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc64/Lregs.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gregs.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc64/Lresume.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc64/Lresume.c
index effe8a8..41a8cf0 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc64/Lresume.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gresume.c"
#endif
diff --git a/src/hppa/Lget_reg.c b/src/ppc64/Lstep.c
similarity index 82%
copy from src/hppa/Lget_reg.c
copy to src/ppc64/Lstep.c
index effe8a8..c1ac3c7 100644
--- a/src/hppa/Lget_reg.c
+++ b/src/ppc64/Lstep.c
@@ -1,5 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gget_reg.c"
+#include "Gstep.c"
#endif
diff --git a/src/hppa/Gget_reg.c b/src/ppc64/get_func_addr.c
similarity index 64%
copy from src/hppa/Gget_reg.c
copy to src/ppc64/get_func_addr.c
index 4553f65..a9c828d 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc64/get_func_addr.c
@@ -1,6 +1,8 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
This file is part of libunwind.
@@ -25,10 +27,19 @@
#include "unwind_i.h"
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+int
+tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr,
+ unw_word_t *entry_point)
{
- struct cursor *c = (struct cursor *) cursor;
+ unw_accessors_t *a;
+ int ret;
- return hppa_access_reg (c, regnum, valp, 0);
+ a = unw_get_accessors (as);
+ /* Entry-point is stored in the 1st word of the function descriptor.
+ In case that changes in the future, we'd have to update the line
+ below and read the word at addr + offset: */
+ ret = (*a->access_mem) (as, addr, entry_point, 0, NULL);
+ if (ret < 0)
+ return ret;
+ return 0;
}
diff --git a/src/ppc64/init.h b/src/ppc64/init.h
new file mode 100644
index 0000000..886f14c
--- /dev/null
+++ b/src/ppc64/init.h
@@ -0,0 +1,81 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+static inline int
+common_init_ppc64 (struct cursor *c)
+{
+ int ret;
+ int i;
+
+ for (i = UNW_PPC64_R0; i <= UNW_PPC64_R31; i++) {
+ c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i);
+ }
+ for (i = UNW_PPC64_F0; i <= UNW_PPC64_F31; i++) {
+ c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i);
+ }
+ for (i = UNW_PPC64_V0; i <= UNW_PPC64_V31; i++) {
+ c->dwarf.loc[i] = DWARF_VREG_LOC (&c->dwarf, i);
+ }
+
+ for (i = UNW_PPC64_CR0; i <= UNW_PPC64_CR7; i++) {
+ c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i);
+ }
+ c->dwarf.loc[UNW_PPC64_ARG_POINTER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_ARG_POINTER);
+ c->dwarf.loc[UNW_PPC64_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_CTR);
+ c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VSCR);
+
+ c->dwarf.loc[UNW_PPC64_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_XER);
+ c->dwarf.loc[UNW_PPC64_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_LR);
+ c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VRSAVE);
+ c->dwarf.loc[UNW_PPC64_SPEFSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPEFSCR);
+ c->dwarf.loc[UNW_PPC64_SPE_ACC] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPE_ACC);
+
+ c->dwarf.loc[UNW_PPC64_NIP] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_NIP);
+
+ ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC64_NIP], &c->dwarf.ip);
+ if (ret < 0)
+ return ret;
+
+ ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC64_R1),
+ &c->dwarf.cfa);
+ if (ret < 0)
+ return ret;
+
+ c->sigcontext_format = PPC_SCF_NONE;
+ c->sigcontext_addr = 0;
+
+ c->dwarf.args_size = 0;
+ c->dwarf.ret_addr_column = 0;
+ c->dwarf.pi_valid = 0;
+ c->dwarf.pi_is_dynamic = 0;
+ c->dwarf.hint = 0;
+ c->dwarf.prev_rs = 0;
+
+ return 0;
+}
diff --git a/src/hppa/Gget_reg.c b/src/ppc64/is_fpreg.c
similarity index 79%
copy from src/hppa/Gget_reg.c
copy to src/ppc64/is_fpreg.c
index 4553f65..b34bf87 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/ppc64/is_fpreg.c
@@ -1,6 +1,8 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
This file is part of libunwind.
@@ -23,12 +25,10 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+#include "libunwind_i.h"
PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
+unw_is_fpreg (int regnum)
{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
+ return (regnum >= UNW_PPC64_F0 && regnum <= UNW_PPC64_F31);
}
diff --git a/src/ppc64/regname.c b/src/ppc64/regname.c
new file mode 100644
index 0000000..7d64834
--- /dev/null
+++ b/src/ppc64/regname.c
@@ -0,0 +1,161 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "unwind_i.h"
+
+static const char *regname[] =
+ {
+ [UNW_PPC64_R0]="GPR0",
+ [UNW_PPC64_R1]="GPR1",
+ [UNW_PPC64_R2]="GPR2",
+ [UNW_PPC64_R3]="GPR3",
+ [UNW_PPC64_R4]="GPR4",
+ [UNW_PPC64_R5]="GPR5",
+ [UNW_PPC64_R6]="GPR6",
+ [UNW_PPC64_R7]="GPR7",
+ [UNW_PPC64_R8]="GPR8",
+ [UNW_PPC64_R9]="GPR9",
+ [UNW_PPC64_R10]="GPR10",
+ [UNW_PPC64_R11]="GPR11",
+ [UNW_PPC64_R12]="GPR12",
+ [UNW_PPC64_R13]="GPR13",
+ [UNW_PPC64_R14]="GPR14",
+ [UNW_PPC64_R15]="GPR15",
+ [UNW_PPC64_R16]="GPR16",
+ [UNW_PPC64_R17]="GPR17",
+ [UNW_PPC64_R18]="GPR18",
+ [UNW_PPC64_R19]="GPR19",
+ [UNW_PPC64_R20]="GPR20",
+ [UNW_PPC64_R21]="GPR21",
+ [UNW_PPC64_R22]="GPR22",
+ [UNW_PPC64_R23]="GPR23",
+ [UNW_PPC64_R24]="GPR24",
+ [UNW_PPC64_R25]="GPR25",
+ [UNW_PPC64_R26]="GPR26",
+ [UNW_PPC64_R27]="GPR27",
+ [UNW_PPC64_R28]="GPR28",
+ [UNW_PPC64_R29]="GPR29",
+ [UNW_PPC64_R30]="GPR30",
+ [UNW_PPC64_R31]="GPR31",
+
+ [UNW_PPC64_F0]="FPR0",
+ [UNW_PPC64_F1]="FPR1",
+ [UNW_PPC64_F2]="FPR2",
+ [UNW_PPC64_F3]="FPR3",
+ [UNW_PPC64_F4]="FPR4",
+ [UNW_PPC64_F5]="FPR5",
+ [UNW_PPC64_F6]="FPR6",
+ [UNW_PPC64_F7]="FPR7",
+ [UNW_PPC64_F8]="FPR8",
+ [UNW_PPC64_F9]="FPR9",
+ [UNW_PPC64_F10]="FPR10",
+ [UNW_PPC64_F11]="FPR11",
+ [UNW_PPC64_F12]="FPR12",
+ [UNW_PPC64_F13]="FPR13",
+ [UNW_PPC64_F14]="FPR14",
+ [UNW_PPC64_F15]="FPR15",
+ [UNW_PPC64_F16]="FPR16",
+ [UNW_PPC64_F17]="FPR17",
+ [UNW_PPC64_F18]="FPR18",
+ [UNW_PPC64_F19]="FPR19",
+ [UNW_PPC64_F20]="FPR20",
+ [UNW_PPC64_F21]="FPR21",
+ [UNW_PPC64_F22]="FPR22",
+ [UNW_PPC64_F23]="FPR23",
+ [UNW_PPC64_F24]="FPR24",
+ [UNW_PPC64_F25]="FPR25",
+ [UNW_PPC64_F26]="FPR26",
+ [UNW_PPC64_F27]="FPR27",
+ [UNW_PPC64_F28]="FPR28",
+ [UNW_PPC64_F29]="FPR29",
+ [UNW_PPC64_F30]="FPR30",
+ [UNW_PPC64_F31]="FPR31",
+
+ [UNW_PPC64_LR]="LR",
+ [UNW_PPC64_CTR]="CTR",
+ [UNW_PPC64_ARG_POINTER]="ARG_POINTER",
+
+ [UNW_PPC64_CR0]="CR0",
+ [UNW_PPC64_CR1]="CR1",
+ [UNW_PPC64_CR2]="CR2",
+ [UNW_PPC64_CR3]="CR3",
+ [UNW_PPC64_CR4]="CR4",
+ [UNW_PPC64_CR5]="CR5",
+ [UNW_PPC64_CR6]="CR6",
+ [UNW_PPC64_CR7]="CR7",
+
+ [UNW_PPC64_XER]="XER",
+
+ [UNW_PPC64_V0]="VR0",
+ [UNW_PPC64_V1]="VR1",
+ [UNW_PPC64_V2]="VR2",
+ [UNW_PPC64_V3]="VR3",
+ [UNW_PPC64_V4]="VR4",
+ [UNW_PPC64_V5]="VR5",
+ [UNW_PPC64_V6]="VR6",
+ [UNW_PPC64_V7]="VR7",
+ [UNW_PPC64_V8]="VR8",
+ [UNW_PPC64_V9]="VR9",
+ [UNW_PPC64_V10]="VR10",
+ [UNW_PPC64_V11]="VR11",
+ [UNW_PPC64_V12]="VR12",
+ [UNW_PPC64_V13]="VR13",
+ [UNW_PPC64_V14]="VR14",
+ [UNW_PPC64_V15]="VR15",
+ [UNW_PPC64_V16]="VR16",
+ [UNW_PPC64_V17]="VR17",
+ [UNW_PPC64_V18]="VR18",
+ [UNW_PPC64_V19]="VR19",
+ [UNW_PPC64_V20]="VR20",
+ [UNW_PPC64_V21]="VR21",
+ [UNW_PPC64_V22]="VR22",
+ [UNW_PPC64_V23]="VR23",
+ [UNW_PPC64_V24]="VR24",
+ [UNW_PPC64_V25]="VR25",
+ [UNW_PPC64_V26]="VR26",
+ [UNW_PPC64_V27]="VR27",
+ [UNW_PPC64_V28]="VR28",
+ [UNW_PPC64_V29]="VR29",
+ [UNW_PPC64_V30]="VR30",
+ [UNW_PPC64_V31]="VR31",
+
+ [UNW_PPC64_VSCR]="VSCR",
+
+ [UNW_PPC64_VRSAVE]="VRSAVE",
+ [UNW_PPC64_SPE_ACC]="SPE_ACC",
+ [UNW_PPC64_SPEFSCR]="SPEFSCR",
+
+ };
+
+PROTECTED const char *
+unw_regname (unw_regnum_t reg)
+{
+ if (reg < (unw_regnum_t) ARRAY_SIZE (regname))
+ return regname[reg];
+ else
+ return "???";
+}
diff --git a/src/ppc64/setcontext.S b/src/ppc64/setcontext.S
new file mode 100644
index 0000000..b54378a
--- /dev/null
+++ b/src/ppc64/setcontext.S
@@ -0,0 +1,9 @@
+ .global _UI_setcontext
+
+_UI_setcontext:
+ retq
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/ppc64/ucontext_i.h b/src/ppc64/ucontext_i.h
new file mode 100644
index 0000000..245d667
--- /dev/null
+++ b/src/ppc64/ucontext_i.h
@@ -0,0 +1,173 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef ucontext_i_h
+#define ucontext_i_h
+
+#include <ucontext.h>
+
+/* These values were derived by reading
+ /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and
+ /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h
+*/
+
+#define NIP_IDX 32
+#define MSR_IDX 33
+#define ORIG_GPR3_IDX 34
+#define CTR_IDX 35
+#define LINK_IDX 36
+#define XER_IDX 37
+#define CCR_IDX 38
+#define SOFTE_IDX 39
+#define TRAP_IDX 40
+#define DAR_IDX 41
+#define DSISR_IDX 42
+#define RESULT_IDX 43
+
+#define VSCR_IDX 32
+#define VRSAVE_IDX 33
+
+/* These are dummy structures used only for obtaining the offsets of the
+ various structure members. */
+static ucontext_t dmy_ctxt;
+static vrregset_t dmy_vrregset;
+
+#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[0] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[1] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[2] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[3] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[4] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[5] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[6] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[7] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[8] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[9] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[10] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[11] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[12] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[13] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[14] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[15] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[16] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[17] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[18] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[19] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[20] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[21] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[22] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[23] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[24] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[25] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[26] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[27] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[28] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[29] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[30] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[31] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_NIP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[NIP_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[MSR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CTR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.gp_regs[LINK_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.gp_regs[XER_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CCR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.gp_regs[SOFTE_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[TRAP_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DAR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DSISR_IDX] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.gp_regs[RESULT_IDX] - (void *)&dmy_ctxt)
+
+#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[0] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[1] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[2] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[3] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[4] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[5] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[6] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[7] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[8] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[9] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[10] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[11] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[12] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[13] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[14] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[15] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[16] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[17] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[18] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[19] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[20] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[21] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[22] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[23] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[24] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[25] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[26] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[27] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[28] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[29] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[30] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[31] - (void *)&dmy_ctxt)
+#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.fp_regs[32] - (void *)&dmy_ctxt)
+
+#define UC_MCONTEXT_V_REGS ((void *)&dmy_ctxt.uc_mcontext.v_regs - (void *)&dmy_ctxt)
+
+#define UC_MCONTEXT_VREGS_R0 ((void *)&dmy_vrregset.vrregs[0] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R1 ((void *)&dmy_vrregset.vrregs[1] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R2 ((void *)&dmy_vrregset.vrregs[2] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R3 ((void *)&dmy_vrregset.vrregs[3] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R4 ((void *)&dmy_vrregset.vrregs[4] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R5 ((void *)&dmy_vrregset.vrregs[5] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R6 ((void *)&dmy_vrregset.vrregs[6] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R7 ((void *)&dmy_vrregset.vrregs[7] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R8 ((void *)&dmy_vrregset.vrregs[8] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R9 ((void *)&dmy_vrregset.vrregs[9] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R10 ((void *)&dmy_vrregset.vrregs[10] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R11 ((void *)&dmy_vrregset.vrregs[11] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R12 ((void *)&dmy_vrregset.vrregs[12] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R13 ((void *)&dmy_vrregset.vrregs[13] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R14 ((void *)&dmy_vrregset.vrregs[14] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R15 ((void *)&dmy_vrregset.vrregs[15] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R16 ((void *)&dmy_vrregset.vrregs[16] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R17 ((void *)&dmy_vrregset.vrregs[17] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R18 ((void *)&dmy_vrregset.vrregs[18] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R19 ((void *)&dmy_vrregset.vrregs[19] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R20 ((void *)&dmy_vrregset.vrregs[20] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R21 ((void *)&dmy_vrregset.vrregs[21] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R22 ((void *)&dmy_vrregset.vrregs[22] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R23 ((void *)&dmy_vrregset.vrregs[23] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R24 ((void *)&dmy_vrregset.vrregs[24] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R25 ((void *)&dmy_vrregset.vrregs[25] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R26 ((void *)&dmy_vrregset.vrregs[26] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R27 ((void *)&dmy_vrregset.vrregs[27] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R28 ((void *)&dmy_vrregset.vrregs[28] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R29 ((void *)&dmy_vrregset.vrregs[29] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R30 ((void *)&dmy_vrregset.vrregs[30] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_R31 ((void *)&dmy_vrregset.vrregs[31] - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_VSCR ((void *)&dmy_vrregset.vscr - (void *)&dmy_vrregset)
+#define UC_MCONTEXT_VREGS_VRSAVE ((void *)&dmy_vrregset.vrsave - (void *)&dmy_vrregset)
+
+#endif
diff --git a/src/ppc64/unwind_i.h b/src/ppc64/unwind_i.h
new file mode 100644
index 0000000..056dc16
--- /dev/null
+++ b/src/ppc64/unwind_i.h
@@ -0,0 +1,53 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2006-2007 IBM
+ Contributed by
+ Corey Ashford <cjashfor@us.ibm.com>
+ Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef unwind_i_h
+#define unwind_i_h
+
+#include <memory.h>
+#include <stdint.h>
+
+#include <libunwind-ppc64.h>
+
+#include <libunwind_i.h>
+#include <sys/ucontext.h>
+
+#define ppc64_lock UNW_OBJ(lock)
+#define ppc64_local_resume UNW_OBJ(local_resume)
+#define ppc64_local_addr_space_init UNW_OBJ(local_addr_space_init)
+#if 0
+#define ppc64_scratch_loc UNW_OBJ(scratch_loc)
+#endif
+
+extern void ppc64_local_addr_space_init (void);
+extern int ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
+ void *arg);
+#if 0
+extern dwarf_loc_t ppc64_scratch_loc (struct cursor *c, unw_regnum_t reg);
+#endif
+
+#endif /* unwind_i_h */
diff --git a/src/ptrace/_UPT_access_reg.c b/src/ptrace/_UPT_access_reg.c
index 512363d..60e006b 100644
--- a/src/ptrace/_UPT_access_reg.c
+++ b/src/ptrace/_UPT_access_reg.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003-2004 Hewlett-Packard Co
+ Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -30,7 +30,7 @@
# ifdef HAVE_ASM_PTRACE_OFFSETS_H
# include <asm/ptrace_offsets.h>
# endif
-# include "ia64/rse.h"
+# include "tdep-ia64/rse.h"
#endif
int
@@ -152,7 +152,7 @@
if (write)
{
- bsp = ia64_rse_skip_regs (*val, sof);
+ bsp = rse_skip_regs (*val, sof);
#ifdef HAVE_TTRACE
# warning No support for ttrace() yet.
#else
@@ -172,7 +172,7 @@
if (errno)
goto badreg;
#endif
- *val = ia64_rse_skip_regs (bsp, -sof);
+ *val = rse_skip_regs (bsp, -sof);
}
goto out;
}
@@ -197,7 +197,7 @@
new_sof = (*val & 0x7f);
if (old_sof != new_sof)
{
- bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
+ bsp = rse_skip_regs (bsp, -old_sof + new_sof);
#ifdef HAVE_TTRACE
# warning No support for ttrace() yet.
#else
@@ -222,7 +222,10 @@
#endif
if ((unsigned) reg >= sizeof (_UPT_reg_offset) / sizeof (_UPT_reg_offset[0]))
- goto badreg;
+ {
+ errno = EINVAL;
+ goto badreg;
+ }
#ifdef HAVE_TTRACE
# warning No support for ttrace() yet.
@@ -246,6 +249,6 @@
return 0;
badreg:
- Debug (1, "bad register number %u\n", reg);
+ Debug (1, "bad register number %u (error: %s)\n", reg, strerror (errno));
return -UNW_EBADREG;
}
diff --git a/src/ptrace/_UPT_elf.c b/src/ptrace/_UPT_elf.c
new file mode 100644
index 0000000..cf0480f
--- /dev/null
+++ b/src/ptrace/_UPT_elf.c
@@ -0,0 +1,5 @@
+/* We need to get a separate copy of the ELF-code into
+ libunwind-ptrace since it cannot (and must not) have any ELF
+ dependencies on libunwind. */
+#include "libunwind_i.h" /* get ELFCLASS defined */
+#include "../elfxx.c"
diff --git a/src/ptrace/_UPT_find_proc_info.c b/src/ptrace/_UPT_find_proc_info.c
index ceaa2ae..9f4ed38 100644
--- a/src/ptrace/_UPT_find_proc_info.c
+++ b/src/ptrace/_UPT_find_proc_info.c
@@ -145,27 +145,169 @@
return &ui->di_cache;
}
-#elif UNW_TARGET_X86
+#elif UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA || UNW_TARGET_PPC64
+
+#include "dwarf-eh.h"
+#include "dwarf_i.h"
+
+/* We need our own instance of dwarf_read_encoded_pointer() here since
+ the one in dwarf/Gpe.c is not (and should not be) exported. */
+int
+dwarf_read_encoded_pointer (unw_addr_space_t as, unw_accessors_t *a,
+ unw_word_t *addr, unsigned char encoding,
+ const unw_proc_info_t *pi,
+ unw_word_t *valp, void *arg)
+{
+ return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding,
+ pi, valp, arg);
+}
HIDDEN unw_dyn_info_t *
_UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as,
char *path, unw_word_t segbase, unw_word_t mapoff)
{
- /* fix me */
- return NULL;
+ Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL;
+ unw_word_t addr, eh_frame_start, fde_count, load_base;
+ struct dwarf_eh_frame_hdr *hdr;
+ unw_proc_info_t pi;
+ unw_accessors_t *a;
+ Elf_W(Ehdr) *ehdr;
+ int i, ret;
+
+ /* XXX: Much of this code is Linux/LSB-specific. */
+
+ if (!elf_w(valid_object) (&ui->ei))
+ return NULL;
+
+ ehdr = ui->ei.image;
+ phdr = (Elf_W(Phdr) *) ((char *) ui->ei.image + ehdr->e_phoff);
+
+ for (i = 0; i < ehdr->e_phnum; ++i)
+ {
+ switch (phdr[i].p_type)
+ {
+ case PT_LOAD:
+ if (phdr[i].p_offset == mapoff)
+ ptxt = phdr + i;
+ break;
+
+ case PT_GNU_EH_FRAME:
+ peh_hdr = phdr + i;
+ break;
+
+ case PT_DYNAMIC:
+ pdyn = phdr + i;
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (!ptxt || !peh_hdr)
+ return NULL;
+
+ if (pdyn)
+ {
+ /* For dynamicly linked executables and shared libraries,
+ DT_PLTGOT is the value that data-relative addresses are
+ relative to for that object. We call this the "gp". */
+ Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset
+ + (char *) ui->ei.image);
+ for (; dyn->d_tag != DT_NULL; ++dyn)
+ if (dyn->d_tag == DT_PLTGOT)
+ {
+ /* Assume that _DYNAMIC is writable and GLIBC has
+ relocated it (true for x86 at least). */
+ ui->di_cache.gp = dyn->d_un.d_ptr;
+ break;
+ }
+ }
+ else
+ /* Otherwise this is a static executable with no _DYNAMIC. Assume
+ that data-relative addresses are relative to 0, i.e.,
+ absolute. */
+ ui->di_cache.gp = 0;
+
+ hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset
+ + (char *) ui->ei.image);
+ if (hdr->version != DW_EH_VERSION)
+ {
+ Debug (1, "table `%s' has unexpected version %d\n",
+ path, hdr->version);
+ return 0;
+ }
+
+ a = unw_get_accessors (unw_local_addr_space);
+ addr = (unw_word_t) (hdr + 1);
+
+ /* Fill in a dummy proc_info structure. We just need to fill in
+ enough to ensure that dwarf_read_encoded_pointer() can do it's
+ job. Since we don't have a procedure-context at this point, all
+ we have to do is fill in the global-pointer. */
+ memset (&pi, 0, sizeof (pi));
+ pi.gp = ui->di_cache.gp;
+
+ /* (Optionally) read eh_frame_ptr: */
+ if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
+ &addr, hdr->eh_frame_ptr_enc, &pi,
+ &eh_frame_start, NULL)) < 0)
+ return NULL;
+
+ /* (Optionally) read fde_count: */
+ if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
+ &addr, hdr->fde_count_enc, &pi,
+ &fde_count, NULL)) < 0)
+ return NULL;
+
+ if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
+ {
+ abort ();
+#if 0
+ /* If there is no search table or it has an unsupported
+ encoding, fall back on linear search. */
+ if (hdr->table_enc == DW_EH_PE_omit)
+ Debug (4, "table `%s' lacks search table; doing linear search\n",
+ info->dlpi_name);
+ else
+ Debug (4, "table `%s' has encoding 0x%x; doing linear search\n",
+ info->dlpi_name, hdr->table_enc);
+
+ eh_frame_end = max_load_addr; /* XXX can we do better? */
+
+ if (hdr->fde_count_enc == DW_EH_PE_omit)
+ fde_count = ~0UL;
+ if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit)
+ abort ();
+
+ cb_data->single_fde = 1;
+ return linear_search (unw_local_addr_space, ip,
+ eh_frame_start, eh_frame_end, fde_count,
+ pi, need_unwind_info, NULL);
+#endif
+ }
+
+ load_base = segbase - ptxt->p_vaddr;
+
+ ui->di_cache.start_ip = segbase;
+ ui->di_cache.end_ip = ui->di_cache.start_ip + ptxt->p_memsz;
+ ui->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE;
+ ui->di_cache.u.rti.name_ptr = 0;
+ /* two 32-bit values (ip_offset/fde_offset) per table-entry: */
+ ui->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t);
+ ui->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr)
+ + (addr - (unw_word_t) ui->ei.image
+ - peh_hdr->p_offset));
+
+ /* For the binary-search table in the eh_frame_hdr, data-relative
+ means relative to the start of that section... */
+ ui->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr)
+ + ((unw_word_t) hdr - (unw_word_t) ui->ei.image
+ - peh_hdr->p_offset));
+
+ return &ui->di_cache;
}
-#elif UNW_TARGET_X86_64
-
-HIDDEN unw_dyn_info_t *
-_UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as,
- char *path, unw_word_t segbase, unw_word_t mapoff)
-{
- /* fix me */
- return NULL;
-}
-
-#endif /* UNW_TARGET_X86_64 */
+#endif /* UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA*/
static unw_dyn_info_t *
get_unwind_info (struct UPT_info *ui, unw_addr_space_t as, unw_word_t ip)
@@ -198,6 +340,8 @@
if (tdep_get_elf_image (&ui->ei, ui->pid, ip, &segbase, &mapoff) < 0)
return NULL;
+ /* Here, SEGBASE is the starting-address of the (mmap'ped) segment
+ which covers the IP we're looking for. */
di = _UPTi_find_unwind_table (ui, as, path, segbase, mapoff);
if (!di
/* This can happen in corner cases where dynamically generated
@@ -232,14 +376,19 @@
without ill effects. */
int ret = tdep_search_unwind_table (unw_local_addr_space, ip, di, pi,
need_unwind_info, arg);
- if (ret >= 0 && need_unwind_info)
+ if (ret >= 0)
{
- void *mem = malloc (pi->unwind_info_size);
+ if (!need_unwind_info)
+ pi->unwind_info = NULL;
+ else
+ {
+ void *mem = malloc (pi->unwind_info_size);
- if (!mem)
- return -UNW_ENOMEM;
- memcpy (mem, pi->unwind_info, pi->unwind_info_size);
- pi->unwind_info = mem;
+ if (!mem)
+ return -UNW_ENOMEM;
+ memcpy (mem, pi->unwind_info, pi->unwind_info_size);
+ pi->unwind_info = mem;
+ }
}
return ret;
}
diff --git a/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/ptrace/_UPT_get_dyn_info_list_addr.c
index a1b2445..e0ea2f4 100644
--- a/src/ptrace/_UPT_get_dyn_info_list_addr.c
+++ b/src/ptrace/_UPT_get_dyn_info_list_addr.c
@@ -85,6 +85,7 @@
int *countp)
{
# warning Implement get_list_addr(), please.
+ *countp = 0;
return 0;
}
diff --git a/src/ptrace/_UPT_get_proc_name.c b/src/ptrace/_UPT_get_proc_name.c
index ebb7b5f..6ac85a0 100644
--- a/src/ptrace/_UPT_get_proc_name.c
+++ b/src/ptrace/_UPT_get_proc_name.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -32,9 +33,9 @@
struct UPT_info *ui = arg;
#if ELF_CLASS == ELFCLASS64
- return _Uelf64_get_proc_name (ui->pid, ip, buf, buf_len, offp);
+ return _Uelf64_get_proc_name (as, ui->pid, ip, buf, buf_len, offp);
#elif ELF_CLASS == ELFCLASS32
- return _Uelf32_get_proc_name (ui->pid, ip, buf, buf_len, offp);
+ return _Uelf32_get_proc_name (as, ui->pid, ip, buf, buf_len, offp);
#else
return -UNW_ENOINFO;
#endif
diff --git a/src/ptrace/_UPT_internal.h b/src/ptrace/_UPT_internal.h
index 7da9bf0..0577097 100644
--- a/src/ptrace/_UPT_internal.h
+++ b/src/ptrace/_UPT_internal.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
+ Copyright (C) 2003, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -34,8 +34,7 @@
#include <sys/ptrace.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
struct UPT_info
{
diff --git a/src/ptrace/_UPT_reg_offset.c b/src/ptrace/_UPT_reg_offset.c
index 916baae..ae54cd5 100644
--- a/src/ptrace/_UPT_reg_offset.c
+++ b/src/ptrace/_UPT_reg_offset.c
@@ -210,6 +210,42 @@
[UNW_IA64_IP] = PT_CR_IIP
#elif defined(HAVE_TTRACE)
# warning No support for ttrace() yet.
+#elif defined(UNW_TARGET_HPPA)
+ [UNW_HPPA_GR + 0] = 0x000, [UNW_HPPA_GR + 1] = 0x004,
+ [UNW_HPPA_GR + 2] = 0x008, [UNW_HPPA_GR + 3] = 0x00c,
+ [UNW_HPPA_GR + 4] = 0x010, [UNW_HPPA_GR + 5] = 0x014,
+ [UNW_HPPA_GR + 6] = 0x018, [UNW_HPPA_GR + 7] = 0x01c,
+ [UNW_HPPA_GR + 8] = 0x020, [UNW_HPPA_GR + 9] = 0x024,
+ [UNW_HPPA_GR + 10] = 0x028, [UNW_HPPA_GR + 11] = 0x02c,
+ [UNW_HPPA_GR + 12] = 0x030, [UNW_HPPA_GR + 13] = 0x034,
+ [UNW_HPPA_GR + 14] = 0x038, [UNW_HPPA_GR + 15] = 0x03c,
+ [UNW_HPPA_GR + 16] = 0x040, [UNW_HPPA_GR + 17] = 0x044,
+ [UNW_HPPA_GR + 18] = 0x048, [UNW_HPPA_GR + 19] = 0x04c,
+ [UNW_HPPA_GR + 20] = 0x050, [UNW_HPPA_GR + 21] = 0x054,
+ [UNW_HPPA_GR + 22] = 0x058, [UNW_HPPA_GR + 23] = 0x05c,
+ [UNW_HPPA_GR + 24] = 0x060, [UNW_HPPA_GR + 25] = 0x064,
+ [UNW_HPPA_GR + 26] = 0x068, [UNW_HPPA_GR + 27] = 0x06c,
+ [UNW_HPPA_GR + 28] = 0x070, [UNW_HPPA_GR + 29] = 0x074,
+ [UNW_HPPA_GR + 30] = 0x078, [UNW_HPPA_GR + 31] = 0x07c,
+
+ [UNW_HPPA_FR + 0] = 0x080, [UNW_HPPA_FR + 1] = 0x088,
+ [UNW_HPPA_FR + 2] = 0x090, [UNW_HPPA_FR + 3] = 0x098,
+ [UNW_HPPA_FR + 4] = 0x0a0, [UNW_HPPA_FR + 5] = 0x0a8,
+ [UNW_HPPA_FR + 6] = 0x0b0, [UNW_HPPA_FR + 7] = 0x0b8,
+ [UNW_HPPA_FR + 8] = 0x0c0, [UNW_HPPA_FR + 9] = 0x0c8,
+ [UNW_HPPA_FR + 10] = 0x0d0, [UNW_HPPA_FR + 11] = 0x0d8,
+ [UNW_HPPA_FR + 12] = 0x0e0, [UNW_HPPA_FR + 13] = 0x0e8,
+ [UNW_HPPA_FR + 14] = 0x0f0, [UNW_HPPA_FR + 15] = 0x0f8,
+ [UNW_HPPA_FR + 16] = 0x100, [UNW_HPPA_FR + 17] = 0x108,
+ [UNW_HPPA_FR + 18] = 0x110, [UNW_HPPA_FR + 19] = 0x118,
+ [UNW_HPPA_FR + 20] = 0x120, [UNW_HPPA_FR + 21] = 0x128,
+ [UNW_HPPA_FR + 22] = 0x130, [UNW_HPPA_FR + 23] = 0x138,
+ [UNW_HPPA_FR + 24] = 0x140, [UNW_HPPA_FR + 25] = 0x148,
+ [UNW_HPPA_FR + 26] = 0x150, [UNW_HPPA_FR + 27] = 0x158,
+ [UNW_HPPA_FR + 28] = 0x160, [UNW_HPPA_FR + 29] = 0x168,
+ [UNW_HPPA_FR + 30] = 0x170, [UNW_HPPA_FR + 31] = 0x178,
+
+ [UNW_HPPA_IP] = 0x1a8 /* IAOQ[0] */
#elif defined(UNW_TARGET_X86)
[UNW_X86_EAX] = 0x18,
[UNW_X86_EBX] = 0x00,
@@ -235,7 +271,7 @@
[UNW_X86_64_RBX] = 0x28,
[UNW_X86_64_RSI] = 0x68,
[UNW_X86_64_RDI] = 0x70,
- [UNW_X86_64_RBP] = 0x24,
+ [UNW_X86_64_RBP] = 0x20,
[UNW_X86_64_RSP] = 0x98,
[UNW_X86_64_R8] = 0x48,
[UNW_X86_64_R9] = 0x40,
@@ -250,6 +286,8 @@
// [UNW_X86_64_EFLAGS] = 0x90,
// [UNW_X86_64_RSP] = 0x98,
// [UNW_X86_64_SS] = 0xa0
+#elif defined(UNW_TARGET_PPC32)
+#elif defined(UNW_TARGET_PPC64)
#else
# error Fix me.
#endif
diff --git a/src/longjmp.c b/src/setjmp/longjmp.c
similarity index 62%
rename from src/longjmp.c
rename to src/setjmp/longjmp.c
index f99e478..ac31b5b 100644
--- a/src/longjmp.c
+++ b/src/setjmp/longjmp.c
@@ -32,10 +32,7 @@
#include <stdlib.h>
#include "jmpbuf.h"
-
-#if UNW_TARGET_IA64
-# include "ia64/rse.h"
-#endif
+#include "setjmp_i.h"
void
_longjmp (jmp_buf env, int val)
@@ -56,56 +53,17 @@
if (sp != wp[JB_SP])
continue;
-#if UNW_TARGET_IA64
- {
- unw_word_t bsp, pfs, sol;
-
- if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0
- || unw_get_reg (&c, UNW_IA64_AR_PFS, &pfs) < 0)
- abort ();
-
- /* simulate the effect of "br.call setjmp" on ar.bsp: */
- sol = (pfs >> 7) & 0x7f;
- bsp = ia64_rse_skip_regs (bsp, sol);
-
- if (bsp != wp[JB_BSP])
- continue;
-
- if (unlikely (sol == 0))
- {
- unw_word_t prev_sp;
- unw_cursor_t tmp = c;
-
- /* The caller of {sig,}setjmp() cannot have a NULL-frame.
- If we see a NULL-frame, we haven't reached the right
- target yet. To have a NULL-frame, the number of locals
- must be zero and the stack-frame must also be
- empty. */
-
- if (unw_step (&tmp) < 0)
- abort ();
-
- if (unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0)
- abort ();
-
- if (sp == prev_sp)
- /* got a NULL-frame; keep looking... */
- continue;
- }
- }
-#endif
+ if (!bsp_match (&c, wp))
+ continue;
/* found the right frame: */
- if (UNW_NUM_EH_REGS >= 4)
- {
- if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
- || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
- || unw_set_reg (&c, UNW_REG_IP,
- (unw_word_t) &_UI_longjmp_cont))
- abort ();
- }
- else
+ assert (UNW_NUM_EH_REGS >= 2);
+
+ if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
+ || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
+ || unw_set_reg (&c, UNW_REG_IP,
+ (unw_word_t) &_UI_longjmp_cont))
abort ();
unw_resume (&c);
diff --git a/src/setjmp.c b/src/setjmp/setjmp.c
similarity index 100%
rename from src/setjmp.c
rename to src/setjmp/setjmp.c
diff --git a/src/setjmp/setjmp_i.h b/src/setjmp/setjmp_i.h
new file mode 100644
index 0000000..1d7ca15
--- /dev/null
+++ b/src/setjmp/setjmp_i.h
@@ -0,0 +1,118 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003-2005 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#if UNW_TARGET_IA64
+
+#include "libunwind_i.h"
+#include "tdep-ia64/rse.h"
+
+static inline int
+bsp_match (unw_cursor_t *c, unw_word_t *wp)
+{
+ unw_word_t bsp, pfs, sol;
+
+ if (unw_get_reg (c, UNW_IA64_BSP, &bsp) < 0
+ || unw_get_reg (c, UNW_IA64_AR_PFS, &pfs) < 0)
+ abort ();
+
+ /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */
+ sol = (pfs >> 7) & 0x7f;
+ bsp = rse_skip_regs (bsp, sol);
+
+ if (bsp != wp[JB_BSP])
+ return 0;
+
+ if (unlikely (sol == 0))
+ {
+ unw_word_t sp, prev_sp;
+ unw_cursor_t tmp = *c;
+
+ /* The caller of {sig,}setjmp() cannot have a NULL-frame. If we
+ see a NULL-frame, we haven't reached the right target yet.
+ To have a NULL-frame, the number of locals must be zero and
+ the stack-frame must also be empty. */
+
+ if (unw_step (&tmp) < 0)
+ abort ();
+
+ if (unw_get_reg (&tmp, UNW_REG_SP, &sp) < 0
+ || unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0)
+ abort ();
+
+ if (sp == prev_sp)
+ /* got a NULL-frame; keep looking... */
+ return 0;
+ }
+ return 1;
+}
+
+/* On ia64 we cannot always call sigprocmask() at
+ _UI_siglongjmp_cont() because the signal may have switched stacks
+ and the old stack's register-backing store may have overflown,
+ leaving us no space to allocate the stacked registers needed to
+ call sigprocmask(). Fortunately, we can just let unw_resume() (via
+ sigreturn) take care of restoring the signal-mask. That's faster
+ anyhow. */
+static inline int
+resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp)
+{
+ unw_word_t sc_addr = ((struct cursor *) c)->sigcontext_addr;
+ struct sigcontext *sc = (struct sigcontext *) sc_addr;
+ sigset_t current_mask;
+ void *mp;
+
+ if (!sc_addr)
+ return 0;
+
+ /* let unw_resume() install the desired signal mask */
+
+ if (wp[JB_MASK_SAVED])
+ mp = &wp[JB_MASK];
+ else
+ {
+ if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0)
+ abort ();
+ mp = ¤t_mask;
+ }
+ memcpy (&sc->sc_mask, mp, sizeof (sc->sc_mask));
+ return 1;
+}
+
+#else /* !UNW_TARGET_IA64 */
+
+static inline int
+bsp_match (unw_cursor_t *c, unw_word_t *wp)
+{
+ return 1;
+}
+
+static inline int
+resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp)
+{
+ /* We may want to do this analogously as for ia64... */
+ return 0;
+}
+
+#endif /* !UNW_TARGET_IA64 */
diff --git a/src/setjmp/siglongjmp.c b/src/setjmp/siglongjmp.c
new file mode 100644
index 0000000..4257082
--- /dev/null
+++ b/src/setjmp/siglongjmp.c
@@ -0,0 +1,94 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003-2005 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define UNW_LOCAL_ONLY
+
+#include <setjmp.h>
+
+#include "libunwind_i.h"
+#include "jmpbuf.h"
+#include "setjmp_i.h"
+
+void
+siglongjmp (sigjmp_buf env, int val)
+{
+ unw_word_t *wp = (unw_word_t *) env;
+ extern int _UI_siglongjmp_cont;
+ extern int _UI_longjmp_cont;
+ unw_context_t uc;
+ unw_cursor_t c;
+ unw_word_t sp;
+ int *cont;
+
+ if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0)
+ abort ();
+
+ do
+ {
+ if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0)
+ abort ();
+ if (sp != wp[JB_SP])
+ continue;
+
+ if (!bsp_match (&c, wp))
+ continue;
+
+ /* found the right frame: */
+
+ /* default to resuming without restoring signal-mask */
+ cont = &_UI_longjmp_cont;
+
+ /* Order of evaluation is important here: if unw_resume()
+ restores signal mask, we must set it up appropriately, even
+ if wp[JB_MASK_SAVED] is FALSE. */
+ if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED])
+ {
+ /* sigmask was saved */
+ if (UNW_NUM_EH_REGS < 4 || _NSIG >= 16 * sizeof (unw_word_t))
+ /* signal mask doesn't fit into EH arguments and we can't
+ put it on the stack without overwriting something
+ else... */
+ abort ();
+ else
+ if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0
+ || (_NSIG > 8 * sizeof (unw_word_t)
+ && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0))
+ abort ();
+ cont = &_UI_siglongjmp_cont;
+ }
+
+ if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
+ || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
+ || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) cont))
+ abort ();
+
+ unw_resume (&c);
+
+ abort ();
+ }
+ while (unw_step (&c) >= 0);
+
+ abort ();
+}
diff --git a/src/sigsetjmp.c b/src/setjmp/sigsetjmp.c
similarity index 100%
rename from src/sigsetjmp.c
rename to src/setjmp/sigsetjmp.c
diff --git a/src/siglongjmp.c b/src/siglongjmp.c
deleted file mode 100644
index 3f8c9e2..0000000
--- a/src/siglongjmp.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-
-This file is part of libunwind.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#define UNW_LOCAL_ONLY
-
-#include <assert.h>
-#include <libunwind.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stdlib.h>
-
-#include "tdep.h"
-#include "jmpbuf.h"
-
-#if UNW_TARGET_IA64
-# include "ia64/rse.h"
-#endif
-
-void
-siglongjmp (sigjmp_buf env, int val)
-{
- unw_word_t *wp = (unw_word_t *) env;
- extern int _UI_siglongjmp_cont;
- extern int _UI_longjmp_cont;
- unw_context_t uc;
- unw_cursor_t c;
- unw_word_t sp;
- int *cont;
-
- if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0)
- abort ();
-
- do
- {
- if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0)
- abort ();
- if (sp != wp[JB_SP])
- continue;
-
-#if UNW_TARGET_IA64
- {
- unw_word_t bsp, pfs, sol;
-
- if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0
- || unw_get_reg (&c, UNW_IA64_AR_PFS, &pfs) < 0)
- abort ();
-
- /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */
- sol = (pfs >> 7) & 0x7f;
- bsp = ia64_rse_skip_regs (bsp, sol);
-
- if (bsp != wp[JB_BSP])
- continue;
-
- if (unlikely (sol == 0))
- {
- unw_word_t prev_sp;
- unw_cursor_t tmp = c;
-
- /* The caller of {sig,}setjmp() cannot have a NULL-frame.
- If we see a NULL-frame, we haven't reached the right
- target yet. To have a NULL-frame, the number of locals
- must be zero and the stack-frame must also be
- empty. */
-
- if (unw_step (&tmp) < 0)
- abort ();
-
- if (unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0)
- abort ();
-
- if (sp == prev_sp)
- /* got a NULL-frame; keep looking... */
- continue;
- }
- }
-#endif
-
- /* found the right frame: */
-
- assert (UNW_NUM_EH_REGS >= 4 && _NSIG <= 16 * sizeof (unw_word_t));
-
- /* default to continuation without sigprocmask() */
- cont = &_UI_longjmp_cont;
-
-#if UNW_TARGET_IA64
- /* On ia64 we cannot always call sigprocmask() at
- _UI_siglongjmp_cont() because the signal may have switched
- stacks and the old stack's register-backing store may have
- overflown, leaving us no space to allocate the stacked
- registers needed to call sigprocmask(). Fortunately, we can
- just let unw_resume() (via sigreturn) take care of restoring
- the signal-mask. That's faster anyhow.
-
- XXX We probably should do the analogous on all architectures. */
- if (((struct cursor *) &c)->sigcontext_addr)
- {
- /* let unw_resume() install the desired signal mask */
- struct cursor *cp = (struct cursor *) &c;
- struct sigcontext *sc = (struct sigcontext *) cp->sigcontext_addr;
- sigset_t current_mask;
- void *mp;
-
- if (wp[JB_MASK_SAVED])
- mp = &wp[JB_MASK];
- else
- {
- if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0)
- abort ();
- mp = ¤t_mask;
- }
- memcpy (&sc->sc_mask, mp, sizeof (sc->sc_mask));
- }
- else
-#endif
- if (wp[JB_MASK_SAVED])
- {
- /* sigmask was saved */
- if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0
- || (_NSIG > 8 * sizeof (unw_word_t)
- && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0))
- abort ();
- cont = &_UI_siglongjmp_cont;
- }
-
- if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
- || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
- || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) cont))
- abort ();
-
- unw_resume (&c);
-
- abort ();
- }
- while (unw_step (&c) >= 0);
-
- abort ();
-}
diff --git a/src/unwind/unwind-internal.h b/src/unwind/unwind-internal.h
index d410ee3..4db2eda 100644
--- a/src/unwind/unwind-internal.h
+++ b/src/unwind/unwind-internal.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
+ Copyright (C) 2003, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -32,8 +32,7 @@
#include <stdlib.h>
#include <libunwind.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
/* The version of the _Unwind_*() interface implemented by this code. */
#define _U_VERSION 1
@@ -55,7 +54,7 @@
((unw_getcontext (uc) < 0 || unw_init_local (&(context)->cursor, uc) < 0) \
? -1 : 0))
-static inline _Unwind_Reason_Code ALWAYS_INLINE
+static _Unwind_Reason_Code ALWAYS_INLINE
_Unwind_Phase2 (struct _Unwind_Exception *exception_object,
struct _Unwind_Context *context)
{
diff --git a/src/x86/Gglobal.c b/src/x86/Gglobal.c
index 126b38d..e55644c 100644
--- a/src/x86/Gglobal.c
+++ b/src/x86/Gglobal.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -43,11 +43,11 @@
HIDDEN void
tdep_init (void)
{
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
- sigfillset (&unwi_full_sigmask);
+ sigfillset (&unwi_full_mask);
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
mutex_lock (&x86_lock);
{
if (!tdep_needs_initialization)
@@ -65,5 +65,5 @@
}
out:
mutex_unlock (&x86_lock);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
}
diff --git a/src/x86/Ginit.c b/src/x86/Ginit.c
index 555743d..abc9e61 100644
--- a/src/x86/Ginit.c
+++ b/src/x86/Ginit.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2002 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -128,7 +129,6 @@
if (unw_is_fpreg (reg))
goto badreg;
-Debug (16, "reg = %s\n", unw_regname (reg));
if (!(addr = uc_addr (uc, reg)))
goto badreg;
@@ -187,7 +187,7 @@
char *buf, size_t buf_len, unw_word_t *offp,
void *arg)
{
- return _Uelf32_get_proc_name (getpid (), ip, buf, buf_len, offp);
+ return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
}
HIDDEN void
diff --git a/src/x86/Gregs.c b/src/x86/Gregs.c
index fa94cc0..68afd37 100644
--- a/src/x86/Gregs.c
+++ b/src/x86/Gregs.c
@@ -136,6 +136,8 @@
int write)
{
dwarf_loc_t loc = DWARF_NULL_LOC;
+ unsigned int mask;
+ int arg_num;
switch (reg)
{
@@ -147,25 +149,34 @@
break;
case UNW_X86_CFA:
+ case UNW_X86_ESP:
if (write)
return -UNW_EREADONLYREG;
*valp = c->dwarf.cfa;
return 0;
- case UNW_X86_EAX: loc = c->dwarf.loc[EAX]; break;
- case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break;
- case UNW_X86_EDX: loc = c->dwarf.loc[EDX]; break;
- case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break;
- case UNW_X86_ESP:
- if (c->dwarf.cfa_is_sp)
+ case UNW_X86_EAX:
+ case UNW_X86_EDX:
+ arg_num = reg - UNW_X86_EAX;
+ mask = (1 << arg_num);
+ if (write)
{
- if (write)
- return -UNW_EREADONLYREG;
- *valp = c->dwarf.cfa;
+ c->dwarf.eh_args[arg_num] = *valp;
+ c->dwarf.eh_valid_mask |= mask;
return 0;
}
- loc = c->dwarf.loc[ESP];
+ else if ((c->dwarf.eh_valid_mask & mask) != 0)
+ {
+ *valp = c->dwarf.eh_args[arg_num];
+ return 0;
+ }
+ else
+ loc = c->dwarf.loc[(reg == UNW_X86_EAX) ? EAX : EDX];
break;
+
+ case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break;
+ case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break;
+
case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break;
case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break;
case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break;
diff --git a/src/x86/Gresume.c b/src/x86/Gresume.c
index 6f0cf57..6ea9346 100644
--- a/src/x86/Gresume.c
+++ b/src/x86/Gresume.c
@@ -46,44 +46,6 @@
{
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
-#if 0
- /* We're returning to a frame that was (either directly or
- indirectly) interrupted by a signal. We have to restore
- _both_ "preserved" and "scratch" registers. That doesn't
- leave us any registers to work with, and the only way we can
- achieve this is by doing a sigreturn().
-
- Note: it might be tempting to think that we don't have to
- restore the scratch registers when returning to a frame that
- was indirectly interrupted by a signal. However, that is not
- safe because that frame and its descendants could have been
- using a special convention that stores "preserved" state in
- scratch registers. For example, the Linux fsyscall
- convention does this with r11 (to save ar.pfs) and b6 (to
- save "rp"). */
-
- sc->sc_gr[12] = c->psp;
- c->psp = c->sigcontext_addr - c->sigcontext_off;
-
- /* Clear the "in-syscall" flag, because in general we won't be
- returning to the interruption-point and we need all registers
- restored. */
- sc->sc_flags &= ~IA64_SC_FLAG_IN_SYSCALL;
- sc->sc_ip = c->ip;
- sc->sc_cfm = c->cfm & (((unw_word_t) 1 << 38) - 1);
- sc->sc_pr = (c->pr & ~PR_SCRATCH) | (sc->sc_pr & ~PR_PRESERVED);
- if ((ret = ia64_get (c, c->loc[IA64_REG_PFS], &sc->sc_ar_pfs)) < 0
- || (ret = ia64_get (c, c->loc[IA64_REG_FPSR], &sc->sc_ar_fpsr)) < 0
- || (ret = ia64_get (c, c->loc[IA64_REG_UNAT], &sc->sc_ar_unat)) < 0)
- return ret;
-
- sc->sc_gr[1] = c->pi.gp;
- if (c->eh_valid_mask & 0x1) sc->sc_gr[15] = c->eh_args[0];
- if (c->eh_valid_mask & 0x2) sc->sc_gr[16] = c->eh_args[1];
- if (c->eh_valid_mask & 0x4) sc->sc_gr[17] = c->eh_args[2];
- if (c->eh_valid_mask & 0x8) sc->sc_gr[18] = c->eh_args[3];
-#endif
-
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
sigreturn (sc);
}
@@ -121,9 +83,9 @@
Debug (8, "copying out cursor state\n");
- for (reg = 0; reg < UNW_REG_LAST; ++reg)
+ for (reg = 0; reg <= UNW_REG_LAST; ++reg)
{
-Debug (16, "copying %s\n", unw_regname (reg));
+ Debug (16, "copying %s %d\n", unw_regname (reg), reg);
if (unw_is_fpreg (reg))
{
if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
diff --git a/src/x86/Gstep.c b/src/x86/Gstep.c
index 1945c96..e0e681d 100644
--- a/src/x86/Gstep.c
+++ b/src/x86/Gstep.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2003 Hewlett-Packard Co
+ Copyright (C) 2002-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -32,13 +32,16 @@
struct cursor *c = (struct cursor *) cursor;
int ret, i;
- Debug (1, "(cursor=%p)\n", c);
+ Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);
/* Try DWARF-based unwinding... */
ret = dwarf_step (&c->dwarf);
- if (unlikely (ret == -UNW_ESTOPUNWIND))
- return ret;
+ if (ret < 0 && ret != -UNW_ENOINFO)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
if (unlikely (ret < 0))
{
@@ -57,7 +60,7 @@
followed by a struct sigcontext. With SA_SIGINFO, the
arguments consist a signal number, a siginfo *, and a
ucontext *. */
- unw_word_t sigcontext_addr;
+ unw_word_t sc_addr;
unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4;
unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8;
unw_word_t siginfo_ptr, sigcontext_ptr;
@@ -68,7 +71,10 @@
ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr)
| dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr));
if (ret < 0)
- return 0;
+ {
+ Debug (2, "returning 0\n");
+ return 0;
+ }
if (siginfo_ptr < c->dwarf.cfa
|| siginfo_ptr > c->dwarf.cfa + 256
|| sigcontext_ptr < c->dwarf.cfa
@@ -76,7 +82,7 @@
{
/* Not plausible for SA_SIGINFO signal */
c->sigcontext_format = X86_SCF_LINUX_SIGFRAME;
- c->sigcontext_addr = sigcontext_addr = c->dwarf.cfa + 4;
+ c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4;
}
else
{
@@ -87,20 +93,37 @@
up here. */
c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME;
c->sigcontext_addr = sigcontext_ptr;
- sigcontext_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF;
+ sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF;
}
- esp_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_ESP_OFF, 0);
- ebp_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_EBP_OFF, 0);
- eip_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_EIP_OFF, 0);
+ esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0);
+ ebp_loc = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
+ eip_loc = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0);
ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
if (ret < 0)
- return 0;
+ {
+ Debug (2, "returning 0\n");
+ return 0;
+ }
+
+ c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0);
+ c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0);
+ c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0);
+ c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0);
+ c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
+ c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0);
+ c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0);
+ c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC;
+ c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC;
+ c->dwarf.loc[ST0] = DWARF_NULL_LOC;
}
else
{
ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa);
if (ret < 0)
- return ret;
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]),
c->dwarf.cfa);
@@ -108,11 +131,13 @@
ebp_loc = DWARF_LOC (c->dwarf.cfa, 0);
eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0);
c->dwarf.cfa += 8;
+
+ /* Mark all registers unsaved, since we don't know where
+ they are saved (if at all), except for the EBP and
+ EIP. */
+ for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
+ c->dwarf.loc[i] = DWARF_NULL_LOC;
}
- /* Mark all registers unsaved, since we don't know where they
- are saved (if at all), except for the EBP and EIP. */
- for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
- c->dwarf.loc[i] = DWARF_NULL_LOC;
c->dwarf.loc[EBP] = ebp_loc;
c->dwarf.loc[EIP] = eip_loc;
c->dwarf.ret_addr_column = EIP;
@@ -121,10 +146,15 @@
{
ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip);
if (ret < 0)
- return ret;
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
}
else
c->dwarf.ip = 0;
}
- return (c->dwarf.ip == 0) ? 0 : 1;
+ ret = (c->dwarf.ip == 0) ? 0 : 1;
+ Debug (2, "returning %d\n", ret);
+ return ret;
}
diff --git a/src/x86/init.h b/src/x86/init.h
index 0eb9191..675b77e 100644
--- a/src/x86/init.h
+++ b/src/x86/init.h
@@ -36,7 +36,7 @@
c->dwarf.loc[EBX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBX);
c->dwarf.loc[ESP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESP);
c->dwarf.loc[EBP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBP);
- c->dwarf.loc[ESI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDI);
+ c->dwarf.loc[ESI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESI);
c->dwarf.loc[EDI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDI);
c->dwarf.loc[EIP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EIP);
c->dwarf.loc[EFLAGS] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EFLAGS);
@@ -57,5 +57,12 @@
c->sigcontext_format = X86_SCF_NONE;
c->sigcontext_addr = 0;
+ c->dwarf.args_size = 0;
+ c->dwarf.ret_addr_column = 0;
+ c->dwarf.pi_valid = 0;
+ c->dwarf.pi_is_dynamic = 0;
+ c->dwarf.hint = 0;
+ c->dwarf.prev_rs = 0;
+
return 0;
}
diff --git a/src/x86/is_fpreg.c b/src/x86/is_fpreg.c
index a7f81f5..6dc5640 100644
--- a/src/x86/is_fpreg.c
+++ b/src/x86/is_fpreg.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,7 +23,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_is_fpreg (int regnum)
diff --git a/src/hppa/Gget_reg.c b/src/x86/longjmp.S
similarity index 67%
copy from src/hppa/Gget_reg.c
copy to src/x86/longjmp.S
index 4553f65..a89139d 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/x86/longjmp.S
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,12 +23,19 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+ .globl _UI_longjmp_cont
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+ .type _UI_longjmp_cont, @function
+_UI_longjmp_cont:
+ .cfi_startproc
+ .cfi_register 8, 0 /* IP saved in EAX */
+ push %eax /* push target IP as return address */
+ .cfi_restore 8
+ mov %edx, %eax /* set up return-value */
+ ret
+ .cfi_endproc
+ .size _UI_siglongjmp_cont, .-_UI_longjmp_cont
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/x86/regname.c b/src/x86/regname.c
index 5ac7b36..824e213 100644
--- a/src/x86/regname.c
+++ b/src/x86/regname.c
@@ -18,7 +18,7 @@
PROTECTED const char *
unw_regname (unw_regnum_t reg)
{
- if (reg < (unw_regnum_t) NELEMS (regname))
+ if (reg < (unw_regnum_t) ARRAY_SIZE (regname))
return regname[reg];
else
return "???";
diff --git a/src/x86/siglongjmp.S b/src/x86/siglongjmp.S
index c43c984..5aa1784 100644
--- a/src/x86/siglongjmp.S
+++ b/src/x86/siglongjmp.S
@@ -1,10 +1,72 @@
- /* Dummy implementation for now. Libunwind-based setjmp/longjmp
- can't work on x86 until we take advantage of DWARF2 unwind info. */
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
.globl _UI_siglongjmp_cont
- .globl _UI_longjmp_cont
+#define SIG_SETMASK 2
+
+ /* Stack layout at this point:
+
+ +------------+ <- original $esp (at time of setjmp() call)
+ | sigmask[1] |
+ +------------+
+ | sigmask[0] |
+ +------------+
+ */
+
+ .type _UI_siglongjmp_cont, @function
_UI_siglongjmp_cont:
-_UI_longjmp_cont:
-#warning fix me
- ret
+ .cfi_startproc
+ .cfi_register 8, 0 /* IP saved in EAX */
+ .cfi_def_cfa_offset 8
+ mov %esp, %ecx /* pass address of signal mask in 3rd sc arg */
+ push %eax /* save target IP */
+ .cfi_adjust_cfa_offset 4
+ .cfi_offset 8, -12
+ push %edx /* save return value */
+ .cfi_adjust_cfa_offset 4
+ push %ebx /* save %ebx (preserved) */
+ .cfi_adjust_cfa_offset 4
+ .cfi_offset 3, -20
+ mov $SIG_SETMASK, %ebx /* 1st syscall arg (how) */
+ xor %edx, %edx /* pass NULL as 3rd syscall arg (old maskp) */
+ int $0x80
+ pop %ebx /* restore %ebx */
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore 3
+ pop %eax /* fetch return value */
+ .cfi_adjust_cfa_offset -4
+ pop %edx /* pop target IP */
+ .cfi_adjust_cfa_offset -4
+ .cfi_register 8, 2 /* saved IP is now n EDX */
+ lea 8(%esp), %esp /* pop sigmask */
+ .cfi_adjust_cfa_offset -4
+ jmp *%edx
+ .cfi_endproc
+ .size _UI_siglongjmp_cont, .-_UI_siglongjmp_cont
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/x86/unwind_i.h b/src/x86/unwind_i.h
index 637e0eb..6347719 100644
--- a/src/x86/unwind_i.h
+++ b/src/x86/unwind_i.h
@@ -31,8 +31,7 @@
#include <libunwind-x86.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
/* DWARF column numbers: */
#define EAX 0
diff --git a/src/x86_64/Gget_proc_info.c b/src/x86_64/Gget_proc_info.c
index 5130f5a..213666e 100644
--- a/src/x86_64/Gget_proc_info.c
+++ b/src/x86_64/Gget_proc_info.c
@@ -31,11 +31,18 @@
unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi)
{
struct cursor *c = (struct cursor *) cursor;
- int ret;
- if (ret = dwarf_make_proc_info (&c->dwarf))
- return ret;
-
+ if (dwarf_make_proc_info (&c->dwarf) < 0)
+ {
+ /* On x86-64, some key routines such as _start() and _dl_start()
+ are missing DWARF unwind info. We don't want to fail in that
+ case, because those frames are uninteresting and just mark
+ the end of the frame-chain anyhow. */
+ memset (pi, 0, sizeof (*pi));
+ pi->start_ip = c->dwarf.ip;
+ pi->end_ip = c->dwarf.ip + 1;
+ return 0;
+ }
*pi = c->dwarf.pi;
return 0;
}
diff --git a/src/x86_64/Gglobal.c b/src/x86_64/Gglobal.c
index a0ca993..ec14efe 100644
--- a/src/x86_64/Gglobal.c
+++ b/src/x86_64/Gglobal.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@@ -57,11 +57,11 @@
HIDDEN void
tdep_init (void)
{
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
- sigfillset (&unwi_full_sigmask);
+ sigfillset (&unwi_full_mask);
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
mutex_lock (&x86_64_lock);
{
if (!tdep_needs_initialization)
@@ -79,5 +79,5 @@
}
out:
mutex_unlock (&x86_64_lock);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
}
diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c
index 04146b8..026e8d2 100644
--- a/src/x86_64/Ginit.c
+++ b/src/x86_64/Ginit.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2002 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@@ -27,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include "unwind_i.h"
@@ -74,7 +76,7 @@
# ifdef UNW_LOCAL_ONLY
-void *
+HIDDEN void *
tdep_uc_addr (ucontext_t *uc, int reg)
{
return uc_addr (uc, reg);
@@ -103,6 +105,47 @@
return 0;
}
+#define PAGE_SIZE 4096
+#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
+
+/* Cache of already validated addresses */
+#define NLGA 4
+static unw_word_t last_good_addr[NLGA];
+static int lga_victim;
+
+static int
+validate_mem (unw_word_t addr)
+{
+ int i, victim;
+
+ addr = PAGE_START(addr);
+
+ for (i = 0; i < NLGA; i++)
+ {
+ if (last_good_addr[i] && (addr == last_good_addr[i]))
+ return 0;
+ }
+
+ if (msync ((void *) addr, 1, MS_SYNC) == -1)
+ return -1;
+
+ victim = lga_victim;
+ for (i = 0; i < NLGA; i++) {
+ if (!last_good_addr[victim]) {
+ last_good_addr[victim++] = addr;
+ return 0;
+ }
+ victim = (victim + 1) % NLGA;
+ }
+
+ /* All slots full. Evict the victim. */
+ last_good_addr[victim] = addr;
+ victim = (victim + 1) % NLGA;
+ lga_victim = victim;
+
+ return 0;
+}
+
static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
@@ -114,6 +157,9 @@
}
else
{
+ /* validate address */
+ if (as->validate && validate_mem(addr))
+ return -1;
*val = *(unw_word_t *) addr;
Debug (16, "mem[%016lx] -> %lx\n", addr, *val);
}
@@ -188,7 +234,7 @@
char *buf, size_t buf_len, unw_word_t *offp,
void *arg)
{
- return _Uelf64_get_proc_name (getpid (), ip, buf, buf_len, offp);
+ return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
}
HIDDEN void
@@ -205,6 +251,10 @@
local_addr_space.acc.resume = x86_64_local_resume;
local_addr_space.acc.get_proc_name = get_static_proc_name;
unw_flush_cache (&local_addr_space, 0, 0);
+
+ local_addr_space.validate = 0;
+ memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA);
+ lga_victim = 0;
}
#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/x86_64/Gis_signal_frame.c b/src/x86_64/Gis_signal_frame.c
index 221eab8..c9bab90 100644
--- a/src/x86_64/Gis_signal_frame.c
+++ b/src/x86_64/Gis_signal_frame.c
@@ -40,6 +40,7 @@
as = c->dwarf.as;
a = unw_get_accessors (as);
+ as->validate = 1; /* Don't trust the ip */
arg = c->dwarf.as_arg;
/* Check if RIP points at sigreturn sequence.
@@ -52,7 +53,7 @@
ip = c->dwarf.ip;
if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
|| (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0)
- return ret;
+ return 0;
w1 &= 0xffffffff;
return (w0 == 0x0f0000000fc0c748 && w1 == 0x66666605);
}
diff --git a/src/x86_64/Gregs.c b/src/x86_64/Gregs.c
index da04fcb..ddf7b7e 100644
--- a/src/x86_64/Gregs.c
+++ b/src/x86_64/Gregs.c
@@ -62,6 +62,8 @@
int write)
{
dwarf_loc_t loc = DWARF_NULL_LOC;
+ unsigned int mask;
+ int arg_num;
switch (reg)
{
@@ -73,25 +75,34 @@
break;
case UNW_X86_64_CFA:
+ case UNW_X86_64_RSP:
if (write)
return -UNW_EREADONLYREG;
*valp = c->dwarf.cfa;
return 0;
- case UNW_X86_64_RAX: loc = c->dwarf.loc[RAX]; break;
- case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break;
- case UNW_X86_64_RDX: loc = c->dwarf.loc[RDX]; break;
- case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break;
- case UNW_X86_64_RSP:
- if (c->dwarf.cfa_is_sp)
+ case UNW_X86_64_RAX:
+ case UNW_X86_64_RDX:
+ arg_num = reg - UNW_X86_64_RAX;
+ mask = (1 << arg_num);
+ if (write)
{
- if (write)
- return -UNW_EREADONLYREG;
- *valp = c->dwarf.cfa;
+ c->dwarf.eh_args[arg_num] = *valp;
+ c->dwarf.eh_valid_mask |= mask;
return 0;
}
- loc = c->dwarf.loc[RSP];
+ else if ((c->dwarf.eh_valid_mask & mask) != 0)
+ {
+ *valp = c->dwarf.eh_args[arg_num];
+ return 0;
+ }
+ else
+ loc = c->dwarf.loc[(reg == UNW_X86_64_RAX) ? RAX : RDX];
break;
+
+ case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break;
+ case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break;
+
case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break;
case UNW_X86_64_RSI: loc = c->dwarf.loc[RSI]; break;
case UNW_X86_64_RDI: loc = c->dwarf.loc[RDI]; break;
diff --git a/src/x86_64/Gresume.c b/src/x86_64/Gresume.c
index 6967333..4edc4da 100644
--- a/src/x86_64/Gresume.c
+++ b/src/x86_64/Gresume.c
@@ -31,10 +31,52 @@
#ifndef UNW_REMOTE_ONLY
+#include <sys/syscall.h>
+
+/* sigreturn() is a no-op on x86_64 glibc. */
+
+static NORETURN inline long
+my_rt_sigreturn (void *new_sp)
+{
+ __asm__ __volatile__ ("mov %0, %%rsp;"
+ "mov %1, %%rax;"
+ "syscall"
+ :: "r"(new_sp), "i"(SYS_rt_sigreturn)
+ : "memory");
+ abort ();
+}
+
HIDDEN inline int
x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
{
+#if defined(__linux)
+ struct cursor *c = (struct cursor *) cursor;
+ ucontext_t *uc = c->dwarf.as_arg;
+
+ /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to
+ be missing DWARF unwind info. We don't want to fail in that
+ case, because the frame-chain still would let us do a backtrace
+ at least. */
+ dwarf_make_proc_info (&c->dwarf);
+
+ if (unlikely (c->sigcontext_format != X86_64_SCF_NONE))
+ {
+ struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
+
+ Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
+ (unsigned long long) c->dwarf.ip, sc);
+ my_rt_sigreturn (sc);
+ }
+ else
+ {
+ Debug (8, "resuming at ip=%llx via setcontext()\n",
+ (unsigned long long) c->dwarf.ip);
+ _x86_64_setcontext (uc);
+ }
+#else
# warning Implement me!
+#endif
+ return -UNW_EINVAL;
}
#endif /* !UNW_REMOTE_ONLY */
@@ -60,9 +102,9 @@
Debug (8, "copying out cursor state\n");
- for (reg = 0; reg < UNW_REG_LAST; ++reg)
+ for (reg = 0; reg <= UNW_REG_LAST; ++reg)
{
- Debug (8, "copying %s %d\n", unw_regname (reg), reg);
+ Debug (16, "copying %s %d\n", unw_regname (reg), reg);
if (unw_is_fpreg (reg))
{
if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c
index 27fcc08..75f796f 100644
--- a/src/x86_64/Gstep.c
+++ b/src/x86_64/Gstep.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002-2003 Hewlett-Packard Co
+ Copyright (C) 2002-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@@ -35,11 +35,17 @@
struct cursor *c = (struct cursor *) cursor;
int ret, i;
+ Debug (1, "(cursor=%p, ip=0x%016llx)\n",
+ c, (unsigned long long) c->dwarf.ip);
+
/* Try DWARF-based unwinding... */
ret = dwarf_step (&c->dwarf);
- if (unlikely (ret == -UNW_ESTOPUNWIND))
- return ret;
+ if (ret < 0 && ret != -UNW_ENOINFO)
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
if (likely (ret >= 0))
{
@@ -50,8 +56,19 @@
}
else
{
- /* DWARF failed, let's see if we can follow the frame-chain
- or skip over the signal trampoline. */
+ /* DWARF failed. There isn't much of a usable frame-chain on x86-64,
+ but we do need to handle two special-cases:
+
+ (i) signal trampoline: Old kernels and older libcs don't
+ export the vDSO needed to get proper unwind info for the
+ trampoline. Recognize that case by looking at the code
+ and filling in things by hand.
+
+ (ii) PLT (shared-library) call-stubs: PLT stubs are invoked
+ via CALLQ. Try this for all non-signal trampoline
+ code. */
+
+ unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa;
struct dwarf_loc rbp_loc, rsp_loc, rip_loc;
Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
@@ -71,28 +88,69 @@
ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa);
if (ret < 0)
- return ret;
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
+
+ c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0);
+ c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0);
+ c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0);
+ c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0);
+ c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0);
+ c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0);
+ c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0);
+ c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
+ c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
+ c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
+ c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
+ c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
+ c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
+ c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
+ c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
+ c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0);
}
else
{
- ret = dwarf_get (&c->dwarf, c->dwarf.loc[RBP], &c->dwarf.cfa);
+ unw_word_t rbp;
+
+ ret = dwarf_get (&c->dwarf, c->dwarf.loc[RBP], &rbp);
if (ret < 0)
- return ret;
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
- Debug (13, "[RBP=0x%Lx] = 0x%Lx\n",
- (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RBP]),
- (unsigned long long) c->dwarf.cfa);
+ if (!rbp)
+ {
+ /* Looks like we may have reached the end of the call-chain. */
+ rbp_loc = DWARF_NULL_LOC;
+ rsp_loc = DWARF_NULL_LOC;
+ rip_loc = DWARF_NULL_LOC;
+ }
+ else
+ {
+ unw_word_t rbp1;
+ Debug (1, "[RBP=0x%Lx] = 0x%Lx (cfa = 0x%Lx)\n",
+ (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RBP]),
+ (unsigned long long) rbp,
+ (unsigned long long) c->dwarf.cfa);
- rbp_loc = DWARF_LOC (c->dwarf.cfa, 0);
- rsp_loc = DWARF_NULL_LOC;
- rip_loc = DWARF_LOC (c->dwarf.cfa + 8, 0);
- c->dwarf.cfa += 16;
+ rbp_loc = DWARF_LOC(rbp, 0);
+ rsp_loc = DWARF_NULL_LOC;
+ rip_loc = DWARF_LOC (rbp + 8, 0);
+ /* Heuristic to recognize a bogus frame pointer */
+ ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1);
+ if (ret || ((rbp1 - rbp) > 0x4000))
+ rbp_loc = DWARF_NULL_LOC;
+ c->dwarf.cfa += 16;
+ }
+
+ /* Mark all registers unsaved */
+ for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
+ c->dwarf.loc[i] = DWARF_NULL_LOC;
}
- /* Mark all registers unsaved */
- for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
- c->dwarf.loc[i] = DWARF_NULL_LOC;
-
c->dwarf.loc[RBP] = rbp_loc;
c->dwarf.loc[RSP] = rsp_loc;
c->dwarf.loc[RIP] = rip_loc;
@@ -101,11 +159,22 @@
if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]))
{
ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip);
+ Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n",
+ (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]),
+ (unsigned long long) c->dwarf.ip);
if (ret < 0)
- return ret;
+ {
+ Debug (2, "returning %d\n", ret);
+ return ret;
+ }
}
else
c->dwarf.ip = 0;
+
+ if (c->dwarf.ip == prev_ip && c->dwarf.cfa == prev_cfa)
+ return -UNW_EBADFRAME;
}
- return (c->dwarf.ip == 0) ? 0 : 1;
+ ret = (c->dwarf.ip == 0) ? 0 : 1;
+ Debug (2, "returning %d\n", ret);
+ return ret;
}
diff --git a/src/x86_64/init.h b/src/x86_64/init.h
index aad3cc2..ae108b2 100644
--- a/src/x86_64/init.h
+++ b/src/x86_64/init.h
@@ -58,5 +58,16 @@
&c->dwarf.cfa);
if (ret < 0)
return ret;
+
+ c->sigcontext_format = X86_64_SCF_NONE;
+ c->sigcontext_addr = 0;
+
+ c->dwarf.args_size = 0;
+ c->dwarf.ret_addr_column = RIP;
+ c->dwarf.pi_valid = 0;
+ c->dwarf.pi_is_dynamic = 0;
+ c->dwarf.hint = 0;
+ c->dwarf.prev_rs = 0;
+
return 0;
}
diff --git a/src/x86_64/is_fpreg.c b/src/x86_64/is_fpreg.c
index 3c6e9f0..030dd71 100644
--- a/src/x86_64/is_fpreg.c
+++ b/src/x86_64/is_fpreg.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@@ -25,7 +25,7 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "tdep.h"
+#include "libunwind_i.h"
PROTECTED int
unw_is_fpreg (int regnum)
diff --git a/src/hppa/Gget_reg.c b/src/x86_64/longjmp.S
similarity index 71%
copy from src/hppa/Gget_reg.c
copy to src/x86_64/longjmp.S
index 4553f65..bda9d06 100644
--- a/src/hppa/Gget_reg.c
+++ b/src/x86_64/longjmp.S
@@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by ...
+ Copyright (C) 2004-2005 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,12 +23,15 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "unwind_i.h"
+ .globl _UI_longjmp_cont
-PROTECTED int
-unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
-{
- struct cursor *c = (struct cursor *) cursor;
-
- return hppa_access_reg (c, regnum, valp, 0);
-}
+ .type _UI_longjmp_cont, @function
+_UI_longjmp_cont:
+ push %rax /* push target IP as return address */
+ mov %rdx, %rax /* set up return-value */
+ retq
+ .size _UI_longjmp_cont, .-_UI_longjmp_cont
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/x86_64/offsets.h b/src/x86_64/offsets.h
new file mode 100644
index 0000000..56ead69
--- /dev/null
+++ b/src/x86_64/offsets.h
@@ -0,0 +1,29 @@
+/* This used to be a generated file. But then it breaks cross compilation.
+ * So use the method used by other architectures.
+ */
+#ifndef OFFSETS_H
+#define OFFSETS_H
+
+#define REG_OFFSET_RAX 144
+#define REG_OFFSET_RBX 128
+#define REG_OFFSET_RCX 152
+#define REG_OFFSET_RDX 136
+#define REG_OFFSET_RDI 104
+#define REG_OFFSET_RSI 112
+#define REG_OFFSET_RSP 160
+#define REG_OFFSET_RBP 120
+#define REG_OFFSET_R8 40
+#define REG_OFFSET_R9 48
+#define REG_OFFSET_R10 56
+#define REG_OFFSET_R11 64
+#define REG_OFFSET_R12 72
+#define REG_OFFSET_R13 80
+#define REG_OFFSET_R14 88
+#define REG_OFFSET_R15 96
+#define REG_OFFSET_R15 96
+#define REG_OFFSET_R15 96
+#define REG_OFFSET_RIP 168
+#define REG_OFFSET_FPREGS_PTR 224
+#define FPREG_OFFSET_MXCR 24
+
+#endif /* OFFSETS_H */
diff --git a/src/x86_64/regname.c b/src/x86_64/regname.c
index 5962392..6c0e2f3 100644
--- a/src/x86_64/regname.c
+++ b/src/x86_64/regname.c
@@ -49,7 +49,7 @@
PROTECTED const char *
unw_regname (unw_regnum_t reg)
{
- if (reg < (unw_regnum_t) NELEMS (regname))
+ if (reg < (unw_regnum_t) ARRAY_SIZE (regname))
return regname[reg];
else
return "???";
diff --git a/src/x86_64/setcontext.S b/src/x86_64/setcontext.S
new file mode 100644
index 0000000..9eeb1b8
--- /dev/null
+++ b/src/x86_64/setcontext.S
@@ -0,0 +1,63 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2007 Google, Inc
+ Contributed by Arun Sharma <arun.sharma@google.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "offsets.h"
+
+ .global _x86_64_setcontext
+
+_x86_64_setcontext:
+
+ /* restore fp state */
+ mov REG_OFFSET_FPREGS_PTR(%rdi),%r8
+ fldenv (%r8)
+ ldmxcsr FPREG_OFFSET_MXCR(%r8)
+
+ /* restore the rest of the state */
+ mov REG_OFFSET_R8(%rdi),%r8
+ mov REG_OFFSET_R9(%rdi),%r9
+ mov REG_OFFSET_RBX(%rdi),%rbx
+ mov REG_OFFSET_RBP(%rdi),%rbp
+ mov REG_OFFSET_R12(%rdi),%r12
+ mov REG_OFFSET_R13(%rdi),%r13
+ mov REG_OFFSET_R14(%rdi),%r14
+ mov REG_OFFSET_R15(%rdi),%r15
+ mov REG_OFFSET_RSI(%rdi),%rsi
+ mov REG_OFFSET_RDX(%rdi),%rdx
+ mov REG_OFFSET_RAX(%rdi),%rax
+ mov REG_OFFSET_RCX(%rdi),%rcx
+ mov REG_OFFSET_RSP(%rdi),%rsp
+
+ /* push the return address on the stack */
+ mov REG_OFFSET_RIP(%rdi),%rcx
+ push %rcx
+
+ mov REG_OFFSET_RCX(%rdi),%rcx
+ mov REG_OFFSET_RDI(%rdi),%rdi
+ retq
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/x86_64/siglongjmp.S b/src/x86_64/siglongjmp.S
index c43c984..8ca7968 100644
--- a/src/x86_64/siglongjmp.S
+++ b/src/x86_64/siglongjmp.S
@@ -1,10 +1,33 @@
- /* Dummy implementation for now. Libunwind-based setjmp/longjmp
- can't work on x86 until we take advantage of DWARF2 unwind info. */
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
.globl _UI_siglongjmp_cont
- .globl _UI_longjmp_cont
_UI_siglongjmp_cont:
-_UI_longjmp_cont:
-#warning fix me
- ret
+ retq
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/src/x86_64/ucontext_i.h b/src/x86_64/ucontext_i.h
index 377bcb9..dfd93bc 100644
--- a/src/x86_64/ucontext_i.h
+++ b/src/x86_64/ucontext_i.h
@@ -22,6 +22,20 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#define UC_MCONTEXT_GREGS_R8 0x28
+#define UC_MCONTEXT_GREGS_R9 0x30
+#define UC_MCONTEXT_GREGS_R10 0x38
+#define UC_MCONTEXT_GREGS_R11 0x40
+#define UC_MCONTEXT_GREGS_R12 0x48
+#define UC_MCONTEXT_GREGS_R13 0x50
+#define UC_MCONTEXT_GREGS_R14 0x58
+#define UC_MCONTEXT_GREGS_R15 0x60
+#define UC_MCONTEXT_GREGS_RDI 0x68
+#define UC_MCONTEXT_GREGS_RSI 0x70
#define UC_MCONTEXT_GREGS_RBP 0x78
+#define UC_MCONTEXT_GREGS_RBX 0x80
+#define UC_MCONTEXT_GREGS_RDX 0x88
+#define UC_MCONTEXT_GREGS_RAX 0x90
+#define UC_MCONTEXT_GREGS_RCX 0x98
#define UC_MCONTEXT_GREGS_RSP 0xa0
#define UC_MCONTEXT_GREGS_RIP 0xa8
diff --git a/src/x86_64/unwind_i.h b/src/x86_64/unwind_i.h
index a749174..af779bb 100644
--- a/src/x86_64/unwind_i.h
+++ b/src/x86_64/unwind_i.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2002 Hewlett-Packard Co
+ Copyright (C) 2002, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@@ -33,8 +33,7 @@
#include <libunwind-x86_64.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#include <sys/ucontext.h>
/* DWARF column numbers for x86_64: */
diff --git a/tests/Gia64-test-nat.c b/tests/Gia64-test-nat.c
index 47d7ad6..1e9e939 100644
--- a/tests/Gia64-test-nat.c
+++ b/tests/Gia64-test-nat.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2004 Hewlett-Packard Co
+ Copyright (C) 2004-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -36,7 +36,9 @@
# include <sys/uc_access.h>
#endif
-#include "ia64/rse.h"
+#include "tdep-ia64/rse.h"
+
+#define ARRAY_SIZE(a) ((int) (sizeof (a) / sizeof ((a)[0])))
#define NUM_RUNS 1024
//#define NUM_RUNS 1
@@ -82,6 +84,9 @@
extern save_func_t rotate_regs;
static check_func_t check_rotate_regs;
+extern save_func_t save_pr;
+static check_func_t check_pr;
+
static int verbose;
static int nerrors;
@@ -106,9 +111,21 @@
{ save_static_to_mem4, check_static_to_mem4 },
{ save_static_to_mem5, check_static_to_mem5 },
{ save_static_to_scratch, check_static_to_scratch },
+ { save_pr, check_pr },
{ rotate_regs, check_rotate_regs },
};
+static unw_word_t
+random_word (void)
+{
+ unw_word_t val = random ();
+
+ if (sizeof (unw_word_t) > 4)
+ val |= ((unw_word_t) random ()) << 32;
+
+ return val;
+}
+
void
sighandler (int signal, void *siginfo, void *context)
{
@@ -125,8 +142,7 @@
printf ("sighandler: signal %d sp=%p nat=%08lx pr=%lx\n",
signal, &sp, uc->uc_mcontext.sc_nat, uc->uc_mcontext.sc_pr);
sof = uc->uc_mcontext.sc_cfm & 0x7f;
- bsp = (unsigned long *) ia64_rse_skip_regs (uc->uc_mcontext.sc_ar_bsp,
- -sof);
+ bsp = (unsigned long *) rse_skip_regs (uc->uc_mcontext.sc_ar_bsp, -sof);
}
#elif defined(__hpux)
if (__uc_get_ar (uc, UNW_IA64_AR_BSP - UNW_IA64_AR, &bsp) != 0)
@@ -138,7 +154,7 @@
flushrs ();
arg0 = (save_func_t **) *bsp;
- bsp = (unsigned long *) ia64_rse_skip_regs ((uint64_t) bsp, 1);
+ bsp = (unsigned long *) rse_skip_regs ((uint64_t) bsp, 1);
arg1 = (unsigned long *) *bsp;
(*arg0[0]) (arg0 + 1, arg1);
@@ -406,7 +422,7 @@
static unw_word_t *
check_static_to_scratch (unw_cursor_t *c, unw_word_t *vals)
{
- unw_word_t r[4], nat[4];
+ unw_word_t r[4], nat[4], ec, expected;
unw_fpreg_t f4;
int i, ret;
@@ -470,6 +486,53 @@
panic ("%s: f4=%016lx.%016lx instead of %lx!\n",
__FUNCTION__, f4.raw.bits[1], f4.raw.bits[0], r[0]);
}
+
+ if ((unw_get_reg (c, UNW_IA64_AR_EC, &ec)) < 0)
+ panic ("%s: failed to read register ar.ec, error=%d\n", __FUNCTION__, ret);
+
+ expected = vals[0] & 0x3f;
+ if (ec != expected)
+ panic ("%s: ar.ec=%016lx instead of %016lx!\n",
+ __FUNCTION__, ec, expected);
+
+ return vals;
+}
+
+static unw_word_t *
+check_pr (unw_cursor_t *c, unw_word_t *vals)
+{
+ unw_word_t pr, expected;
+ int ret;
+# define BIT(n) ((unw_word_t) 1 << (n))
+# define DONTCARE (BIT( 6) | BIT( 7) | BIT( 8) | BIT( 9) | BIT(10) \
+ | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15))
+
+ if (verbose)
+ printf (" %s()\n", __FUNCTION__);
+
+ vals -= 1;
+
+ if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0)
+ panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret);
+
+ pr &= ~DONTCARE;
+ expected = (vals[0] & ~DONTCARE) | 1;
+
+ if (verbose)
+ printf (" pr = %016lx (expected %016lx)\n", pr, expected);
+
+ if (pr != expected)
+ panic ("%s: pr=%lx instead of %lx!\n", __FUNCTION__, pr, expected);
+
+ if ((ret = unw_set_reg (c, UNW_IA64_PR, vals[0])) < 0)
+ panic ("%s: failed to write register pr, error=%d\n", __FUNCTION__, ret);
+
+ if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0)
+ panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret);
+
+ if (pr != vals[0])
+ panic ("%s: secondary pr=%lx instead of %lx!\n",
+ __FUNCTION__, pr, vals[0]);
return vals;
}
@@ -478,7 +541,7 @@
{
if (verbose)
printf (" %s()\n", __FUNCTION__);
- return vals - 1;
+ return check_pr (c, vals - 1);
}
static void
@@ -519,15 +582,15 @@
num_checks = (random () % MAX_CHECKS) + 1;
for (i = 0; i < num_checks * MAX_VALUES_PER_FUNC; ++i)
- values[i] = random ();
+ values[i] = random_word ();
for (i = 0; i < num_checks; ++i)
{
if (test == 1)
/* Make first test once go through each test... */
- index = i % NELEMS (all_funcs);
+ index = i % ARRAY_SIZE (all_funcs);
else
- index = random () % NELEMS (all_funcs);
+ index = random () % ARRAY_SIZE (all_funcs);
funcs[i] = all_funcs[index].func;
checks[i] = all_funcs[index].check;
}
diff --git a/tests/Gia64-test-rbs.c b/tests/Gia64-test-rbs.c
index f84dbea..ba89f88 100644
--- a/tests/Gia64-test-rbs.c
+++ b/tests/Gia64-test-rbs.c
@@ -38,7 +38,7 @@
#define panic(args...) \
do { fprintf (stderr, args); ++nerrors; return -9999; } while (0)
-#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
+#define ARRAY_SIZE(a) ((int) (sizeof (a) / sizeof ((a)[0])))
/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64
implementations to at most 2048 physical stacked registers
@@ -138,7 +138,7 @@
/* First, generate a set of 88 random values which loadup() will load
into loc2-loc89 (r37-r124). */
- for (i = 0; i < NELEMS (reg_values); ++i)
+ for (i = 0; i < ARRAY_SIZE (reg_values); ++i)
{
reg_values[i] = random ();
/* Generate NaTs with a reasonably probability (1/16th): */
@@ -150,7 +150,7 @@
nfuncs = 0;
do
{
- n = random () % NELEMS (spill_funcs);
+ n = random () % ARRAY_SIZE (spill_funcs);
func[nfuncs++] = spill_funcs[n];
nspills += 2 + n;
}
diff --git a/tests/Gperf-simple.c b/tests/Gperf-simple.c
index 7c2cc99..239ad26 100644
--- a/tests/Gperf-simple.c
+++ b/tests/Gperf-simple.c
@@ -53,7 +53,7 @@
return tv.tv_sec + 1e-6*tv.tv_usec;
}
-static int
+static int __attribute__((noinline))
measure_unwind (int maxlevel, double *step)
{
double stop, start;
@@ -79,15 +79,17 @@
stop = gettime ();
if (level <= maxlevel)
- panic ("Unwound only %d levels, expected at least %d levels",
+ panic ("Unwound only %d levels, expected at least %d levels\n",
level, maxlevel);
*step = (stop - start) / (double) level;
return 0;
}
-static int
-f1 (int level, int maxlevel, double *step)
+static int f1 (int, int, double *);
+
+static int __attribute__((noinline))
+g1 (int level, int maxlevel, double *step)
{
if (level == maxlevel)
return measure_unwind (maxlevel, step);
@@ -96,6 +98,16 @@
return f1 (level + 1, maxlevel, step) + level;
}
+static int __attribute__((noinline))
+f1 (int level, int maxlevel, double *step)
+{
+ if (level == maxlevel)
+ return measure_unwind (maxlevel, step);
+ else
+ /* defeat last-call/sibcall optimization */
+ return g1 (level + 1, maxlevel, step) + level;
+}
+
static void
doit (const char *label)
{
diff --git a/tests/Gtest-bt.c b/tests/Gtest-bt.c
index c844779..1256512 100644
--- a/tests/Gtest-bt.c
+++ b/tests/Gtest-bt.c
@@ -38,8 +38,8 @@
#include <unistd.h>
#include <libunwind.h>
-#if UNW_TARGET_X86
-# define STACK_SIZE (128*1024) /* On x86, SIGSTKSZ is too small */
+#if UNW_TARGET_X86 || UNW_TARGET_X86_64
+# define STACK_SIZE (128*1024) /* On x86/-64, SIGSTKSZ is too small */
#else
# define STACK_SIZE SIGSTKSZ
#endif
@@ -64,6 +64,9 @@
unw_context_t uc;
int ret;
+ if (verbose)
+ printf ("\texplicit backtrace:\n");
+
unw_getcontext (&uc);
if (unw_init_local (&cursor, &uc) < 0)
panic ("unw_init_local failed!\n");
@@ -110,24 +113,24 @@
}
}
while (ret > 0);
+
+ {
+ void *buffer[20];
+ int i, n;
+
+ if (verbose)
+ printf ("\n\tvia backtrace():\n");
+ n = backtrace (buffer, 20);
+ if (verbose)
+ for (i = 0; i < n; ++i)
+ printf ("[%d] ip=%p\n", i, buffer[i]);
+ }
}
void
foo (long val)
{
- void *buffer[20];
- int i, n;
-
- if (verbose)
- printf ("\texplicit backtrace:\n");
do_backtrace ();
-
- if (verbose)
- printf ("\n\tvia backtrace():\n");
- n = backtrace (buffer, 20);
- if (verbose)
- for (i = 0; i < n; ++i)
- printf ("[%d] ip=%p\n", i, buffer[i]);
}
void
diff --git a/tests/Gtest-concurrent.c b/tests/Gtest-concurrent.c
index 638ad34..8166fc5 100644
--- a/tests/Gtest-concurrent.c
+++ b/tests/Gtest-concurrent.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003-2004 Hewlett-Packard Co
+ Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Permission is hereby granted, free of charge, to any person obtaining
@@ -28,6 +28,7 @@
#endif
#include <libunwind.h>
+#include <limits.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
@@ -81,10 +82,20 @@
doit (void)
{
pthread_t th[NTHREADS];
+ pthread_attr_t attr;
int i;
+ pthread_attr_init (&attr);
+ pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN + 64*1024);
+
for (i = 0; i < NTHREADS; ++i)
- pthread_create (th + i, NULL, worker, NULL);
+ if (pthread_create (th + i, &attr, worker, NULL))
+ {
+ fprintf (stderr, "FAILURE: Failed to create %u threads "
+ "(after %u threads)\n",
+ NTHREADS, i);
+ exit (-1);
+ }
for (i = 0; i < NTHREADS; ++i)
pthread_join (th[i], NULL);
@@ -110,7 +121,10 @@
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
if (nerrors)
- fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
+ {
+ fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
+ exit (-1);
+ }
if (verbose)
printf ("SUCCESS\n");
diff --git a/tests/Gtest-dyn1.c b/tests/Gtest-dyn1.c
index 5e3f1a3..2faa1f7 100644
--- a/tests/Gtest-dyn1.c
+++ b/tests/Gtest-dyn1.c
@@ -87,7 +87,7 @@
char name[128], off[32];
unw_word_t ip, offset;
unw_context_t uc;
- int count = 0;
+ int count;
if (verbose)
printf ("caught signal %d\n", signal);
@@ -95,11 +95,21 @@
unw_getcontext (&uc);
unw_init_local (&cursor, &uc);
+ count = 0;
while (!unw_is_signal_frame (&cursor))
- if (unw_step (&cursor) < 0)
- panic ("failed to find signal frame!\n");
+ {
+ if (unw_step (&cursor) < 0)
+ panic ("failed to find signal frame!\n");
+
+ if (count++ > 20)
+ {
+ panic ("Too many steps to the signal frame (%d)\n", count);
+ break;
+ }
+ }
unw_step (&cursor);
+ count = 0;
do
{
unw_get_reg (&cursor, UNW_REG_IP, &ip);
@@ -111,6 +121,13 @@
if (verbose)
printf ("ip = %lx <%s%s>\n", (long) ip, name, off);
++count;
+
+ if (count > 20)
+ {
+ panic ("Too many steps (%d)\n", count);
+ break;
+ }
+
}
while (unw_step (&cursor) > 0);
diff --git a/tests/Gtest-exc.c b/tests/Gtest-exc.c
index 18d4990..44b837d 100644
--- a/tests/Gtest-exc.c
+++ b/tests/Gtest-exc.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2001-2003 Hewlett-Packard Co
+ Copyright (C) 2001-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Permission is hereby granted, free of charge, to any person obtaining
@@ -24,18 +24,27 @@
/* This illustrates the basics of using the unwind interface for
exception handling. */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libunwind.h>
+#ifdef HAVE_IA64INTRIN_H
+# include <ia64intrin.h>
+#endif
+
#define panic(args...) \
{ ++nerrors; fprintf (stderr, args); }
int nerrors = 0;
int verbose = 0;
int depth = 13;
+volatile int got_here = 0;
extern void b (int);
@@ -53,15 +62,8 @@
return;
}
- /* unwind to frame b(): */
- if (unw_step (&cursor) < 0)
- {
- panic ("unw_step() failed!\n");
- return;
- }
-
- /* unwind to top-most frame a(): */
- for (i = 0; i < depth - 1; ++i)
+ /* unwind to top-most frame a(), skipping over b() and raise_exception(): */
+ for (i = 0; i < depth + 2; ++i)
if (unw_step (&cursor) < 0)
{
panic ("unw_step() failed!\n");
@@ -70,42 +72,50 @@
unw_resume (&cursor); /* transfer control to exception handler */
}
-#if !UNW_TARGET_IA64 || defined(__INTEL_COMPILER)
-
-void *
-__builtin_ia64_bsp (void)
+uintptr_t
+get_bsp (void)
{
- return NULL;
-}
-
+#if UNW_TARGET_IA64
+# ifdef __INTEL_COMPILER
+ return __getReg (_IA64_REG_AR_BSP);
+# else
+ return (uintptr_t) __builtin_ia64_bsp ();
+# endif
+#else
+ return 0;
#endif
+}
int
a (int n)
{
long stack;
+ int result = 99;
if (verbose)
- printf ("a(n=%d)\n", n);
+ printf ("a(n=%d): sp=%p bsp=0x%lx\n",
+ n, &stack, (unsigned long) get_bsp ());
if (n > 0)
- return a (n - 1);
-
- if (verbose)
- printf ("a: sp=%p bsp=%p\n", &stack, __builtin_ia64_bsp ());
-
- b (16);
+ a (n - 1) + 1;
+ else
+ b (16);
if (verbose)
{
- printf ("exception handler: here we go (sp=%p, bsp=%p)...\n",
- &stack, __builtin_ia64_bsp ());
+ printf ("exception handler: here we go (sp=%p, bsp=0x%lx)...\n",
+ &stack, (unsigned long) get_bsp ());
/* This call works around a bug in gcc (up-to pre3.4) which
causes invalid assembly code to be generated when
__builtin_ia64_bsp() gets predicated. */
getpid ();
}
- return 0;
+ if (n == depth)
+ {
+ result = 0;
+ got_here = 1;
+ }
+ return result;
}
void
@@ -123,15 +133,26 @@
int
main (int argc, char **argv)
{
+ int result;
+
if (argc > 1)
{
++verbose;
depth = atol (argv[1]);
+ if (depth < 1)
+ {
+ fprintf (stderr, "Usage: %s depth\n"
+ " depth must be >= 1\n", argv[0]);
+ exit (-1);
+ }
}
- if (a (depth) != 0 || nerrors > 0)
+ result = a (depth);
+ if (result != 0 || !got_here || nerrors > 0)
{
- fprintf (stderr, "FAILURE: test failed; try again?\n");
+ fprintf (stderr,
+ "FAILURE: test failed: result=%d got_here=%d nerrors=%d\n",
+ result, got_here, nerrors);
exit (-1);
}
diff --git a/tests/Gtest-resume-sig.c b/tests/Gtest-resume-sig.c
index fb28ac1..0f0a6f9 100644
--- a/tests/Gtest-resume-sig.c
+++ b/tests/Gtest-resume-sig.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
+ Copyright (C) 2003-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Permission is hereby granted, free of charge, to any person obtaining
@@ -45,6 +45,20 @@
int got_usr1, got_usr2;
char *sigusr1_sp;
+uintptr_t
+get_bsp (void)
+{
+#if UNW_TARGET_IA64
+# ifdef __INTEL_COMPILER
+ return __getReg (_IA64_REG_AR_BSP);
+# else
+ return (uintptr_t) __builtin_ia64_bsp ();
+# endif
+#else
+ return 0;
+#endif
+}
+
void
handler (int sig)
{
@@ -53,15 +67,11 @@
unw_context_t uc;
unw_cursor_t c;
char foo;
+ int ret;
#if UNW_TARGET_IA64
-# ifdef __ECC
- void *bsp = (void *) __getReg(_IA64_REG_AR_BSP);
-# else
- void *bsp = __builtin_ia64_bsp ();
-#endif
if (verbose)
- printf ("bsp = %p\n", bsp);
+ printf ("bsp = %llx\n", (unsigned long long) get_bsp ());
#endif
if (verbose)
@@ -80,15 +90,23 @@
signal (SIGUSR1, SIG_IGN);
signal (SIGUSR2, handler);
- unw_getcontext(&uc);
- unw_init_local(&c, &uc);
- unw_step(&c); /* step to signal trampoline */
- unw_step(&c); /* step to signaller frame (main ()) */
- unw_get_reg(&c, UNW_REG_IP, &ip);
+ if ((ret = unw_getcontext (&uc)) < 0)
+ panic ("unw_getcontext() failed: ret=%d\n", ret);
+ if ((ret = unw_init_local (&c, &uc)) < 0)
+ panic ("unw_init_local() failed: ret=%d\n", ret);
+
+ if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */
+ panic ("unw_step(1) failed: ret=%d\n", ret);
+
+ if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */
+ panic ("unw_step(2) failed: ret=%d\n", ret);
+
+ if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0)
+ panic ("unw_get_reg(IP) failed: ret=%d\n", ret);
if (verbose)
printf ("resuming at 0x%lx, with SIGUSR2 pending\n",
(unsigned long) ip);
- unw_resume(&c);
+ unw_resume (&c);
}
else if (sig == SIGUSR2)
{
@@ -110,17 +128,37 @@
int
main (int argc, char **argv)
{
+ float d = 1.0;
+ int n = 0;
+
if (argc > 1)
verbose = 1;
signal (SIGUSR1, handler);
+ /* Use the FPU a bit; otherwise we get spurious errors should the
+ signal handler need to use the FPU for any reason. This seems to
+ happen on x86-64. */
+ while (d > 0.0)
+ {
+ d /= 2.0;
+ ++n;
+ }
+ if (n > 9999)
+ return -1; /* can't happen, but don't tell the compiler... */
+
if (verbose)
printf ("sending SIGUSR1\n");
kill (getpid (), SIGUSR1);
+ if (!got_usr2)
+ panic ("failed to get SIGUSR2\n");
+
if (nerrors)
- fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
+ {
+ fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
+ exit (-1);
+ }
if (verbose)
printf ("SUCCESS\n");
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6bbaa91..073a33c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -16,6 +16,7 @@
perf:
else
+ LIBUNWIND_local = ../src/libunwind.la
if ARCH_IA64
noinst_PROGRAMS_arch = ia64-test-dyn1
check_SCRIPTS_arch = run-ia64-test-dyn1
@@ -24,7 +25,14 @@
Gia64-test-rbs Lia64-test-rbs \
Gia64-test-readonly Lia64-test-readonly \
ia64-test-setjmp ia64-test-sig
-endif
+else
+if ARCH_PPC64
+if USE_ALTIVEC
+ noinst_PROGRAMS_arch_altivec = ppc64-test-altivec ppc64-test-wchar
+endif #USE_ALTIVEC
+ noinst_PROGRAMS_arch = $(noinst_PROGRAMS_arch_altivec) ppc64-test-wchar
+endif #ARCH_PPC64
+endif #ARCH_IA64
check_SCRIPTS_cdep = run-ptrace-mapper run-ptrace-misc
check_PROGRAMS_cdep = Gtest-bt Ltest-bt Gtest-exc Ltest-exc \
Gtest-init Ltest-init \
@@ -68,6 +76,8 @@
Lia64_test_nat_SOURCES = Lia64-test-nat.c ia64-test-nat-asm.S
Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S
ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S
+ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c
+ppc64_test_wchar_SOURCES = ppc64-test-wchar.c
Gtest_init_SOURCES = Gtest-init.cxx
Ltest_init_SOURCES = Ltest-init.cxx
Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S
@@ -79,11 +89,11 @@
Ltest_bt_SOURCES = Ltest-bt.c ident.c
test_ptrace_misc_SOURCES = test-ptrace-misc.c ident.c
-LIBUNWIND = ../src/libunwind-$(arch).la
+LIBUNWIND = ../src/libunwind-$(arch).la $(LIBUNWIND_local)
LDADD = $(LIBUNWIND)
-test_setjmp_LDADD = ../src/libunwind-setjmp.la
-ia64_test_setjmp_LDADD = ../src/libunwind-setjmp.la
+test_setjmp_LDADD = ../src/libunwind-setjmp.la $(LIBUNWIND_local)
+ia64_test_setjmp_LDADD = ../src/libunwind-setjmp.la $(LIBUNWIND_local)
test_ptrace_LDADD = ../src/libunwind-ptrace.a $(LIBUNWIND)
Ltest_concurrent_LDADD = $(LIBUNWIND) -lpthread
Gtest_concurrent_LDADD = $(LIBUNWIND) -lpthread
diff --git a/tests/Makefile.in b/tests/Makefile.in
index a08932c..7ca5277 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -38,7 +38,7 @@
host_triplet = @host@
target_triplet = @target@
check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
-noinst_PROGRAMS = $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6)
+noinst_PROGRAMS = $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_7)
subdir = tests
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/check-namespace.sh.in
@@ -81,168 +81,184 @@
@REMOTE_ONLY_FALSE@ test-varargs$(EXEEXT) Gperf-simple$(EXEEXT) \
@REMOTE_ONLY_FALSE@ Lperf-simple$(EXEEXT)
@REMOTE_ONLY_TRUE@am__EXEEXT_5 = $(am__EXEEXT_4)
-@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@am__EXEEXT_6 = \
+@ARCH_IA64_FALSE@@ARCH_PPC64_TRUE@@REMOTE_ONLY_FALSE@@USE_ALTIVEC_TRUE@am__EXEEXT_6 = ppc64-test-altivec$(EXEEXT) \
+@ARCH_IA64_FALSE@@ARCH_PPC64_TRUE@@REMOTE_ONLY_FALSE@@USE_ALTIVEC_TRUE@ ppc64-test-wchar$(EXEEXT)
+@ARCH_IA64_FALSE@@ARCH_PPC64_TRUE@@REMOTE_ONLY_FALSE@am__EXEEXT_7 = $(am__EXEEXT_6) \
+@ARCH_IA64_FALSE@@ARCH_PPC64_TRUE@@REMOTE_ONLY_FALSE@ ppc64-test-wchar$(EXEEXT)
+@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@am__EXEEXT_7 = \
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@ ia64-test-dyn1$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
am_Gia64_test_nat_OBJECTS = Gia64-test-nat.$(OBJEXT) \
ia64-test-nat-asm.$(OBJEXT)
Gia64_test_nat_OBJECTS = $(am_Gia64_test_nat_OBJECTS)
Gia64_test_nat_LDADD = $(LDADD)
-am__DEPENDENCIES_1 = ../src/libunwind-$(arch).la
-Gia64_test_nat_DEPENDENCIES = $(am__DEPENDENCIES_1)
+@REMOTE_ONLY_FALSE@am__DEPENDENCIES_1 = ../src/libunwind.la
+am__DEPENDENCIES_2 = ../src/libunwind-$(arch).la $(am__DEPENDENCIES_1)
+Gia64_test_nat_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Gia64_test_rbs_OBJECTS = Gia64-test-rbs.$(OBJEXT) \
ia64-test-rbs-asm.$(OBJEXT)
Gia64_test_rbs_OBJECTS = $(am_Gia64_test_rbs_OBJECTS)
Gia64_test_rbs_LDADD = $(LDADD)
-Gia64_test_rbs_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gia64_test_rbs_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Gia64_test_readonly_OBJECTS = Gia64-test-readonly.$(OBJEXT) \
ia64-test-readonly-asm.$(OBJEXT)
Gia64_test_readonly_OBJECTS = $(am_Gia64_test_readonly_OBJECTS)
Gia64_test_readonly_LDADD = $(LDADD)
-Gia64_test_readonly_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gia64_test_readonly_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Gia64_test_stack_OBJECTS = Gia64-test-stack.$(OBJEXT) \
ia64-test-stack-asm.$(OBJEXT)
Gia64_test_stack_OBJECTS = $(am_Gia64_test_stack_OBJECTS)
Gia64_test_stack_LDADD = $(LDADD)
-Gia64_test_stack_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gia64_test_stack_DEPENDENCIES = $(am__DEPENDENCIES_2)
Gperf_simple_SOURCES = Gperf-simple.c
Gperf_simple_OBJECTS = Gperf-simple.$(OBJEXT)
Gperf_simple_LDADD = $(LDADD)
-Gperf_simple_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gperf_simple_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Gtest_bt_OBJECTS = Gtest-bt.$(OBJEXT) ident.$(OBJEXT)
Gtest_bt_OBJECTS = $(am_Gtest_bt_OBJECTS)
Gtest_bt_LDADD = $(LDADD)
-Gtest_bt_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gtest_bt_DEPENDENCIES = $(am__DEPENDENCIES_2)
Gtest_concurrent_SOURCES = Gtest-concurrent.c
Gtest_concurrent_OBJECTS = Gtest-concurrent.$(OBJEXT)
-Gtest_concurrent_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gtest_concurrent_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Gtest_dyn1_OBJECTS = Gtest-dyn1.$(OBJEXT) flush-cache.$(OBJEXT)
Gtest_dyn1_OBJECTS = $(am_Gtest_dyn1_OBJECTS)
Gtest_dyn1_LDADD = $(LDADD)
-Gtest_dyn1_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gtest_dyn1_DEPENDENCIES = $(am__DEPENDENCIES_2)
Gtest_exc_SOURCES = Gtest-exc.c
Gtest_exc_OBJECTS = Gtest-exc.$(OBJEXT)
Gtest_exc_LDADD = $(LDADD)
-Gtest_exc_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gtest_exc_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Gtest_init_OBJECTS = Gtest-init.$(OBJEXT)
Gtest_init_OBJECTS = $(am_Gtest_init_OBJECTS)
Gtest_init_LDADD = $(LDADD)
-Gtest_init_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gtest_init_DEPENDENCIES = $(am__DEPENDENCIES_2)
Gtest_resume_sig_SOURCES = Gtest-resume-sig.c
Gtest_resume_sig_OBJECTS = Gtest-resume-sig.$(OBJEXT)
Gtest_resume_sig_LDADD = $(LDADD)
-Gtest_resume_sig_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Gtest_resume_sig_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Lia64_test_nat_OBJECTS = Lia64-test-nat.$(OBJEXT) \
ia64-test-nat-asm.$(OBJEXT)
Lia64_test_nat_OBJECTS = $(am_Lia64_test_nat_OBJECTS)
Lia64_test_nat_LDADD = $(LDADD)
-Lia64_test_nat_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Lia64_test_nat_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Lia64_test_rbs_OBJECTS = Lia64-test-rbs.$(OBJEXT) \
ia64-test-rbs-asm.$(OBJEXT)
Lia64_test_rbs_OBJECTS = $(am_Lia64_test_rbs_OBJECTS)
Lia64_test_rbs_LDADD = $(LDADD)
-Lia64_test_rbs_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Lia64_test_rbs_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Lia64_test_readonly_OBJECTS = Lia64-test-readonly.$(OBJEXT) \
ia64-test-readonly-asm.$(OBJEXT)
Lia64_test_readonly_OBJECTS = $(am_Lia64_test_readonly_OBJECTS)
Lia64_test_readonly_LDADD = $(LDADD)
-Lia64_test_readonly_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Lia64_test_readonly_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Lia64_test_stack_OBJECTS = Lia64-test-stack.$(OBJEXT) \
ia64-test-stack-asm.$(OBJEXT)
Lia64_test_stack_OBJECTS = $(am_Lia64_test_stack_OBJECTS)
Lia64_test_stack_LDADD = $(LDADD)
-Lia64_test_stack_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Lia64_test_stack_DEPENDENCIES = $(am__DEPENDENCIES_2)
Lperf_simple_SOURCES = Lperf-simple.c
Lperf_simple_OBJECTS = Lperf-simple.$(OBJEXT)
Lperf_simple_LDADD = $(LDADD)
-Lperf_simple_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Lperf_simple_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Ltest_bt_OBJECTS = Ltest-bt.$(OBJEXT) ident.$(OBJEXT)
Ltest_bt_OBJECTS = $(am_Ltest_bt_OBJECTS)
Ltest_bt_LDADD = $(LDADD)
-Ltest_bt_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Ltest_bt_DEPENDENCIES = $(am__DEPENDENCIES_2)
Ltest_concurrent_SOURCES = Ltest-concurrent.c
Ltest_concurrent_OBJECTS = Ltest-concurrent.$(OBJEXT)
-Ltest_concurrent_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Ltest_concurrent_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Ltest_dyn1_OBJECTS = Ltest-dyn1.$(OBJEXT) flush-cache.$(OBJEXT)
Ltest_dyn1_OBJECTS = $(am_Ltest_dyn1_OBJECTS)
Ltest_dyn1_LDADD = $(LDADD)
-Ltest_dyn1_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Ltest_dyn1_DEPENDENCIES = $(am__DEPENDENCIES_2)
Ltest_exc_SOURCES = Ltest-exc.c
Ltest_exc_OBJECTS = Ltest-exc.$(OBJEXT)
Ltest_exc_LDADD = $(LDADD)
-Ltest_exc_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Ltest_exc_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_Ltest_init_OBJECTS = Ltest-init.$(OBJEXT)
Ltest_init_OBJECTS = $(am_Ltest_init_OBJECTS)
Ltest_init_LDADD = $(LDADD)
-Ltest_init_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Ltest_init_DEPENDENCIES = $(am__DEPENDENCIES_2)
Ltest_resume_sig_SOURCES = Ltest-resume-sig.c
Ltest_resume_sig_OBJECTS = Ltest-resume-sig.$(OBJEXT)
Ltest_resume_sig_LDADD = $(LDADD)
-Ltest_resume_sig_DEPENDENCIES = $(am__DEPENDENCIES_1)
+Ltest_resume_sig_DEPENDENCIES = $(am__DEPENDENCIES_2)
forker_SOURCES = forker.c
forker_OBJECTS = forker.$(OBJEXT)
forker_LDADD = $(LDADD)
-forker_DEPENDENCIES = $(am__DEPENDENCIES_1)
+forker_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_ia64_test_dyn1_OBJECTS = ia64-test-dyn1.$(OBJEXT) \
ia64-dyn-asm.$(OBJEXT) flush-cache.$(OBJEXT)
ia64_test_dyn1_OBJECTS = $(am_ia64_test_dyn1_OBJECTS)
ia64_test_dyn1_LDADD = $(LDADD)
-ia64_test_dyn1_DEPENDENCIES = $(am__DEPENDENCIES_1)
+ia64_test_dyn1_DEPENDENCIES = $(am__DEPENDENCIES_2)
ia64_test_setjmp_SOURCES = ia64-test-setjmp.c
ia64_test_setjmp_OBJECTS = ia64-test-setjmp.$(OBJEXT)
-ia64_test_setjmp_DEPENDENCIES = ../src/libunwind-setjmp.la
+ia64_test_setjmp_DEPENDENCIES = ../src/libunwind-setjmp.la \
+ $(am__DEPENDENCIES_1)
ia64_test_sig_SOURCES = ia64-test-sig.c
ia64_test_sig_OBJECTS = ia64-test-sig.$(OBJEXT)
ia64_test_sig_LDADD = $(LDADD)
-ia64_test_sig_DEPENDENCIES = $(am__DEPENDENCIES_1)
+ia64_test_sig_DEPENDENCIES = $(am__DEPENDENCIES_2)
mapper_SOURCES = mapper.c
mapper_OBJECTS = mapper.$(OBJEXT)
mapper_LDADD = $(LDADD)
-mapper_DEPENDENCIES = $(am__DEPENDENCIES_1)
+mapper_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_ppc64_test_altivec_OBJECTS = ppc64-test-altivec.$(OBJEXT) \
+ ppc64-test-altivec-utils.$(OBJEXT)
+ppc64_test_altivec_OBJECTS = $(am_ppc64_test_altivec_OBJECTS)
+ppc64_test_altivec_LDADD = $(LDADD)
+ppc64_test_altivec_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_ppc64_test_wchar_OBJECTS = ppc64-test-wchar.$(OBJEXT)
+ppc64_test_wchar_OBJECTS = $(am_ppc64_test_wchar_OBJECTS)
+ppc64_test_wchar_LDADD = $(LDADD)
+ppc64_test_wchar_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_async_sig_SOURCES = test-async-sig.c
test_async_sig_OBJECTS = test-async-sig.$(OBJEXT)
-test_async_sig_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_async_sig_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_flush_cache_SOURCES = test-flush-cache.c
test_flush_cache_OBJECTS = test-flush-cache.$(OBJEXT)
test_flush_cache_LDADD = $(LDADD)
-test_flush_cache_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_flush_cache_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_init_remote_SOURCES = test-init-remote.c
test_init_remote_OBJECTS = test-init-remote.$(OBJEXT)
test_init_remote_LDADD = $(LDADD)
-test_init_remote_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_init_remote_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_mem_SOURCES = test-mem.c
test_mem_OBJECTS = test-mem.$(OBJEXT)
test_mem_LDADD = $(LDADD)
-test_mem_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_mem_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_proc_info_SOURCES = test-proc-info.c
test_proc_info_OBJECTS = test-proc-info.$(OBJEXT)
test_proc_info_LDADD = $(LDADD)
-test_proc_info_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_proc_info_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_ptrace_SOURCES = test-ptrace.c
test_ptrace_OBJECTS = test-ptrace.$(OBJEXT)
test_ptrace_DEPENDENCIES = ../src/libunwind-ptrace.a \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_2)
am_test_ptrace_misc_OBJECTS = test-ptrace-misc.$(OBJEXT) \
ident.$(OBJEXT)
test_ptrace_misc_OBJECTS = $(am_test_ptrace_misc_OBJECTS)
test_ptrace_misc_LDADD = $(LDADD)
-test_ptrace_misc_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_ptrace_misc_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_setjmp_SOURCES = test-setjmp.c
test_setjmp_OBJECTS = test-setjmp.$(OBJEXT)
-test_setjmp_DEPENDENCIES = ../src/libunwind-setjmp.la
+test_setjmp_DEPENDENCIES = ../src/libunwind-setjmp.la \
+ $(am__DEPENDENCIES_1)
am_test_static_link_OBJECTS = test-static-link-loc.$(OBJEXT) \
test-static-link-gen.$(OBJEXT)
test_static_link_OBJECTS = $(am_test_static_link_OBJECTS)
test_static_link_LDADD = $(LDADD)
-test_static_link_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_static_link_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_strerror_SOURCES = test-strerror.c
test_strerror_OBJECTS = test-strerror.$(OBJEXT)
test_strerror_LDADD = $(LDADD)
-test_strerror_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_strerror_DEPENDENCIES = $(am__DEPENDENCIES_2)
test_varargs_SOURCES = test-varargs.c
test_varargs_OBJECTS = test-varargs.$(OBJEXT)
test_varargs_LDADD = $(LDADD)
-test_varargs_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test_varargs_DEPENDENCIES = $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
@@ -275,10 +291,12 @@
Ltest-concurrent.c $(Ltest_dyn1_SOURCES) Ltest-exc.c \
$(Ltest_init_SOURCES) Ltest-resume-sig.c forker.c \
$(ia64_test_dyn1_SOURCES) ia64-test-setjmp.c ia64-test-sig.c \
- mapper.c test-async-sig.c test-flush-cache.c \
- test-init-remote.c test-mem.c test-proc-info.c test-ptrace.c \
- $(test_ptrace_misc_SOURCES) test-setjmp.c \
- $(test_static_link_SOURCES) test-strerror.c test-varargs.c
+ mapper.c $(ppc64_test_altivec_SOURCES) \
+ $(ppc64_test_wchar_SOURCES) test-async-sig.c \
+ test-flush-cache.c test-init-remote.c test-mem.c \
+ test-proc-info.c test-ptrace.c $(test_ptrace_misc_SOURCES) \
+ test-setjmp.c $(test_static_link_SOURCES) test-strerror.c \
+ test-varargs.c
DIST_SOURCES = $(Gia64_test_nat_SOURCES) $(Gia64_test_rbs_SOURCES) \
$(Gia64_test_readonly_SOURCES) $(Gia64_test_stack_SOURCES) \
Gperf-simple.c $(Gtest_bt_SOURCES) Gtest-concurrent.c \
@@ -289,10 +307,12 @@
Ltest-concurrent.c $(Ltest_dyn1_SOURCES) Ltest-exc.c \
$(Ltest_init_SOURCES) Ltest-resume-sig.c forker.c \
$(ia64_test_dyn1_SOURCES) ia64-test-setjmp.c ia64-test-sig.c \
- mapper.c test-async-sig.c test-flush-cache.c \
- test-init-remote.c test-mem.c test-proc-info.c test-ptrace.c \
- $(test_ptrace_misc_SOURCES) test-setjmp.c \
- $(test_static_link_SOURCES) test-strerror.c test-varargs.c
+ mapper.c $(ppc64_test_altivec_SOURCES) \
+ $(ppc64_test_wchar_SOURCES) test-async-sig.c \
+ test-flush-cache.c test-init-remote.c test-mem.c \
+ test-proc-info.c test-ptrace.c $(test_ptrace_misc_SOURCES) \
+ test-setjmp.c $(test_static_link_SOURCES) test-strerror.c \
+ test-varargs.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -306,6 +326,10 @@
ARCH_HPPA_TRUE = @ARCH_HPPA_TRUE@
ARCH_IA64_FALSE = @ARCH_IA64_FALSE@
ARCH_IA64_TRUE = @ARCH_IA64_TRUE@
+ARCH_PPC32_FALSE = @ARCH_PPC32_FALSE@
+ARCH_PPC32_TRUE = @ARCH_PPC32_TRUE@
+ARCH_PPC64_FALSE = @ARCH_PPC64_FALSE@
+ARCH_PPC64_TRUE = @ARCH_PPC64_TRUE@
ARCH_X86_64_FALSE = @ARCH_X86_64_FALSE@
ARCH_X86_64_TRUE = @ARCH_X86_64_TRUE@
ARCH_X86_FALSE = @ARCH_X86_FALSE@
@@ -375,6 +399,8 @@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+USE_ALTIVEC_FALSE = @USE_ALTIVEC_FALSE@
+USE_ALTIVEC_TRUE = @USE_ALTIVEC_TRUE@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
@@ -453,6 +479,8 @@
@REMOTE_ONLY_FALSE@ Gperf-simple Lperf-simple
@REMOTE_ONLY_TRUE@noinst_PROGRAMS_cdep = $(noinst_PROGRAMS_common)
+@REMOTE_ONLY_FALSE@LIBUNWIND_local = ../src/libunwind.la
+@ARCH_IA64_FALSE@@ARCH_PPC64_TRUE@@REMOTE_ONLY_FALSE@noinst_PROGRAMS_arch = $(noinst_PROGRAMS_arch_altivec) ppc64-test-wchar
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@noinst_PROGRAMS_arch = ia64-test-dyn1
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@check_SCRIPTS_arch = run-ia64-test-dyn1
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@check_PROGRAMS_arch = Gia64-test-stack Lia64-test-stack \
@@ -461,6 +489,7 @@
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@ Gia64-test-readonly Lia64-test-readonly \
@ARCH_IA64_TRUE@@REMOTE_ONLY_FALSE@ ia64-test-setjmp ia64-test-sig
+@ARCH_IA64_FALSE@@ARCH_PPC64_TRUE@@REMOTE_ONLY_FALSE@@USE_ALTIVEC_TRUE@noinst_PROGRAMS_arch_altivec = ppc64-test-altivec ppc64-test-wchar
check_SCRIPTS = $(check_SCRIPTS_common) $(check_SCRIPTS_cdep) \
$(check_SCRIPTS_arch)
@@ -478,6 +507,8 @@
Lia64_test_nat_SOURCES = Lia64-test-nat.c ia64-test-nat-asm.S
Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S
ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S
+ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c
+ppc64_test_wchar_SOURCES = ppc64-test-wchar.c
Gtest_init_SOURCES = Gtest-init.cxx
Ltest_init_SOURCES = Ltest-init.cxx
Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S
@@ -488,10 +519,10 @@
Gtest_bt_SOURCES = Gtest-bt.c ident.c
Ltest_bt_SOURCES = Ltest-bt.c ident.c
test_ptrace_misc_SOURCES = test-ptrace-misc.c ident.c
-LIBUNWIND = ../src/libunwind-$(arch).la
+LIBUNWIND = ../src/libunwind-$(arch).la $(LIBUNWIND_local)
LDADD = $(LIBUNWIND)
-test_setjmp_LDADD = ../src/libunwind-setjmp.la
-ia64_test_setjmp_LDADD = ../src/libunwind-setjmp.la
+test_setjmp_LDADD = ../src/libunwind-setjmp.la $(LIBUNWIND_local)
+ia64_test_setjmp_LDADD = ../src/libunwind-setjmp.la $(LIBUNWIND_local)
test_ptrace_LDADD = ../src/libunwind-ptrace.a $(LIBUNWIND)
Ltest_concurrent_LDADD = $(LIBUNWIND) -lpthread
Gtest_concurrent_LDADD = $(LIBUNWIND) -lpthread
@@ -626,6 +657,12 @@
mapper$(EXEEXT): $(mapper_OBJECTS) $(mapper_DEPENDENCIES)
@rm -f mapper$(EXEEXT)
$(LINK) $(mapper_LDFLAGS) $(mapper_OBJECTS) $(mapper_LDADD) $(LIBS)
+ppc64-test-altivec$(EXEEXT): $(ppc64_test_altivec_OBJECTS) $(ppc64_test_altivec_DEPENDENCIES)
+ @rm -f ppc64-test-altivec$(EXEEXT)
+ $(LINK) $(ppc64_test_altivec_LDFLAGS) $(ppc64_test_altivec_OBJECTS) $(ppc64_test_altivec_LDADD) $(LIBS)
+ppc64-test-wchar$(EXEEXT): $(ppc64_test_wchar_OBJECTS) $(ppc64_test_wchar_DEPENDENCIES)
+ @rm -f ppc64-test-wchar$(EXEEXT)
+ $(LINK) $(ppc64_test_wchar_LDFLAGS) $(ppc64_test_wchar_OBJECTS) $(ppc64_test_wchar_LDADD) $(LIBS)
test-async-sig$(EXEEXT): $(test_async_sig_OBJECTS) $(test_async_sig_DEPENDENCIES)
@rm -f test-async-sig$(EXEEXT)
$(LINK) $(test_async_sig_LDFLAGS) $(test_async_sig_OBJECTS) $(test_async_sig_LDADD) $(LIBS)
@@ -694,6 +731,9 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64-test-sig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ident.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mapper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64-test-altivec-utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64-test-altivec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64-test-wchar.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-async-sig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-flush-cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-init-remote.Po@am__quote@
diff --git a/tests/check-namespace.sh.in b/tests/check-namespace.sh.in
index 791b3e7..253f709 100644
--- a/tests/check-namespace.sh.in
+++ b/tests/check-namespace.sh.in
@@ -103,6 +103,11 @@
match backtrace
case ${plat} in
+ hppa)
+ match _UL${plat}_dwarf_search_unwind_table
+ match _U${plat}_get_elf_image
+ match _U${plat}_setcontext
+ ;;
ia64)
match _UL${plat}_search_unwind_table
match _U${plat}_get_elf_image
@@ -112,6 +117,11 @@
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
;;
+ x86_64)
+ match _U${plat}_get_elf_image
+ match _U${plat}_is_fpreg
+ match _UL${plat}_dwarf_search_unwind_table
+ ;;
*)
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
@@ -143,6 +153,10 @@
match _U${plat}_strerror
case ${plat} in
+ hppa)
+ match _U${plat}_dwarf_search_unwind_table
+ match _U${plat}_get_elf_image
+ ;;
ia64)
match _U${plat}_search_unwind_table
match _U${plat}_find_dyn_list
@@ -160,6 +174,11 @@
match _U${plat}_is_fpreg
match _U${plat}_dwarf_search_unwind_table
;;
+ x86_64)
+ match _U${plat}_get_elf_image
+ match _U${plat}_is_fpreg
+ match _U${plat}_dwarf_search_unwind_table
+ ;;
*)
match _U${plat}_is_fpreg
match _U${plat}_dwarf_search_unwind_table
diff --git a/tests/flush-cache.S b/tests/flush-cache.S
index d8f28c8..d996492 100644
--- a/tests/flush-cache.S
+++ b/tests/flush-cache.S
@@ -36,6 +36,41 @@
flush_cache:
ret
+#elif defined(__hppa__)
+
+# warning FIX ME!!
+
+ .globl flush_cache
+flush_cache:
+ .proc
+ .callinfo
+ bv %r0(%rp)
+ .procend
+#elif defined(__powerpc64__)
+# warning IMPLEMENT ME FOR PPC64!!
+ .globl flush_cache
+flush_cache:
+ lwz 11, 0(1) ;
+ lwz 0, 4(11) ;
+ mtlr 0 ;
+ lwz 31, -4(11) ;
+ mr 1, 11 ;
+ blr
+#elif defined(__powerpc__)
+# warning IMPLEMENT ME FOR PPC32!!
+ .globl flush_cache
+flush_cache:
+ lwz 11, 0(1) ;
+ lwz 0, 4(11) ;
+ mtlr 0 ;
+ lwz 31, -4(11) ;
+ mr 1, 11 ;
+ blr
#else
# error Need flush_cache code for this architecture.
#endif
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/tests/ia64-dyn-asm.S b/tests/ia64-dyn-asm.S
index bc69852..79582e9 100644
--- a/tests/ia64-dyn-asm.S
+++ b/tests/ia64-dyn-asm.S
@@ -95,3 +95,8 @@
}
func_vframe_end:
.endp func_vframe
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/tests/ia64-test-nat-asm.S b/tests/ia64-test-nat-asm.S
index e435eef..eea5ac2 100644
--- a/tests/ia64-test-nat-asm.S
+++ b/tests/ia64-test-nat-asm.S
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2004 Hewlett-Packard Co
+ Copyright (C) 2004-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -394,6 +394,10 @@
mov f6 = f4;;
.body
+ ld8 r2 = [in1]
+ ;;
+ mov ar.ec = r2
+
LOAD_VAL(r4)
LOAD_VAL(r5)
LOAD_VAL(r6)
@@ -443,12 +447,23 @@
mov loc4 = r4
ld8 r2 = [in1], 8;;
+ mov pr = r2, -1
+
+ ld8 r2 = [in1], 8;;
mov r8 = in0
mov r9 = in1
and r2 = 127, r2;;
mov ar.ec = 0
mov ar.lc = r2;;
-1: br.ctop.dptk.few 1b;;
+
+ // use p6 to preserve p63 as it gets rotated into p16:
+(p16) cmp.eq.unc p6,p0 = r0,r0;;
+1:
+(p6) cmp.eq.unc p16,p0 = r0,r0
+(p63) cmp.eq.unc p6,p0 = r0,r0
+ br.ctop.dptk.few 1b;;
+
+(p6) cmp.eq.unc p63,p0 = r0,r0
CALL_NEXT_PTR(r4, r8, r9)
@@ -462,3 +477,32 @@
br.ret.sptk.many rp
.endp rotate_regs
+
+ .global save_pr
+ .proc save_pr
+save_pr:
+ .prologue
+ .regstk 2, 4, 2, 0
+ .save ar.pfs, loc0
+ alloc loc0 = ar.pfs, 2, 4, 2, 0
+ .save rp, loc1
+ mov loc1 = rp
+ .save pr, loc2
+ mov loc2 = pr
+
+ ld8 r2 = [in1], 8;;
+ mov pr = r2, -1
+
+ CALL_NEXT(loc3)
+
+ mov ar.pfs = loc0
+ mov rp = loc1
+ mov pr = loc2, -1
+ br.ret.sptk.many rp
+
+ .endp save_pr
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/tests/ia64-test-rbs-asm.S b/tests/ia64-test-rbs-asm.S
index dc532d9..9a6d33f 100644
--- a/tests/ia64-test-rbs-asm.S
+++ b/tests/ia64-test-rbs-asm.S
@@ -268,3 +268,8 @@
;;
br.cond.sptk.many b6
.endp resumption_point
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/tests/ia64-test-readonly-asm.S b/tests/ia64-test-readonly-asm.S
index 94a4dd7..acd3ada 100644
--- a/tests/ia64-test-readonly-asm.S
+++ b/tests/ia64-test-readonly-asm.S
@@ -48,3 +48,8 @@
br.ret.sptk.many rp
.endp test_func
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/tests/ia64-test-setjmp.c b/tests/ia64-test-setjmp.c
index a32557a..be487b6 100644
--- a/tests/ia64-test-setjmp.c
+++ b/tests/ia64-test-setjmp.c
@@ -34,6 +34,7 @@
#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
@@ -69,10 +70,16 @@
siglongjmp (env, 1);
}
+/* Direct call of doit () at the end of doit () would get optimized by GCC to
+ a branch. */
+static void doit (int n);
+static volatile void (*doit_pointer) (int n) = doit;
+
static void
doit (int n)
{
uintptr_t guard_page_addr, bsp = get_bsp ();
+ void *ret;
if (n == 0)
{
@@ -81,10 +88,15 @@
guard_page_addr = (bsp + page_size - 1) & -page_size;
if (verbose)
printf ("guard_page_addr = 0x%lx\n", (unsigned long) guard_page_addr);
- if (mmap ((void *) guard_page_addr, page_size, PROT_NONE,
- MAP_SHARED | MAP_ANONYMOUS, -1, 0) != (void *) guard_page_addr)
+ ret = mmap ((void *) guard_page_addr, page_size, PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (ret != (void *) guard_page_addr)
{
- perror ("mmap");
+ if (ret == MAP_FAILED)
+ perror ("mmap");
+ else
+ fprintf (stderr, "mmap() returned %p, expected 0x%lx\n",
+ ret, guard_page_addr);
exit (EXIT_FAILURE);
}
}
@@ -95,7 +107,7 @@
return_bsp = bsp;
}
else
- doit (n + 1);
+ (*doit_pointer) (n + 1);
}
int
diff --git a/tests/ia64-test-stack-asm.S b/tests/ia64-test-stack-asm.S
index 0194774..0aea33a 100644
--- a/tests/ia64-test-stack-asm.S
+++ b/tests/ia64-test-stack-asm.S
@@ -176,3 +176,8 @@
mov ar.pfs = loc1
br.ret.sptk.many rp
.endp touch_all
+
+#ifdef __linux__
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/tests/mapper.c b/tests/mapper.c
index 49ff620..1006a8c 100644
--- a/tests/mapper.c
+++ b/tests/mapper.c
@@ -56,7 +56,7 @@
}
}
- alarm (30); /* die if we don't finish in 30 seconds */
+ alarm (80); /* die if we don't finish in 80 seconds */
printf ("Turning on single-stepping...\n");
kill (getpid (), SIGUSR1); /* tell test-ptrace to start single-stepping */
diff --git a/tests/perf-startup b/tests/perf-startup
index e69de29..c370748 100755
--- a/tests/perf-startup
+++ b/tests/perf-startup
@@ -0,0 +1,19 @@
+#!/bin/sh
+platform=$1
+LIBUNWIND=../src/.libs/libunwind.so
+LIBUNWIND_PLAT=../src/.libs/libunwind-$platform.so
+warmup=$(./forker 2000 /bin/true | cut -f1 -d' ')
+
+nsec1=$(./forker 2000 /bin/true | cut -f1 -d' ')
+echo -e \"/bin/true\""\t\t\t\t\t\t": $nsec1 nsec/execution
+
+nsec2=$(LD_PRELOAD=$LIBUNWIND ./forker 2000 /bin/true | cut -f1 -d' ')
+echo -e \"LD_PRELOAD=$LIBUNWIND /bin/true\""\t": $nsec2 nsec/execution
+
+nsec3=$(LD_PRELOAD=$LIBUNWIND_PLAT ./forker 2000 /bin/true | cut -f1 -d' ')
+echo -e \"LD_PRELOAD=$LIBUNWIND_PLAT /bin/true\""\t": $nsec3 nsec/execution
+
+echo
+
+echo -e "Overhead of preloading $LIBUNWIND\t: " $(($nsec2 - $nsec1)) nsec
+echo -e "Overhead of preloading $LIBUNWIND_PLAT\t: " $(($nsec3 - $nsec1)) nsec
diff --git a/tests/ppc64-test-altivec-utils.c b/tests/ppc64-test-altivec-utils.c
new file mode 100644
index 0000000..bd67ff7
--- /dev/null
+++ b/tests/ppc64-test-altivec-utils.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <altivec.h>
+
+union si_overlay
+{
+ vector signed int v;
+ int ints[4];
+};
+
+vector signed int
+vec_init ()
+{
+ vector signed int v;
+ static int count = 1;
+
+ ((union si_overlay *) &v)->ints[0] = count++;
+ ((union si_overlay *) &v)->ints[1] = count++;
+ ((union si_overlay *) &v)->ints[2] = count++;
+ ((union si_overlay *) &v)->ints[3] = count++;
+ return v;
+}
+
+void
+vec_print (vector signed int v)
+{
+ printf ("%08x %08x %08x %08x",
+ ((union si_overlay *) &v)->ints[0],
+ ((union si_overlay *) &v)->ints[1],
+ ((union si_overlay *) &v)->ints[2],
+ ((union si_overlay *) &v)->ints[3]);
+}
+
diff --git a/tests/ppc64-test-altivec.c b/tests/ppc64-test-altivec.c
new file mode 100644
index 0000000..a3e95ee
--- /dev/null
+++ b/tests/ppc64-test-altivec.c
@@ -0,0 +1,177 @@
+
+
+#include <libunwind.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <altivec.h>
+
+#include <sys/resource.h>
+
+#define panic(args...) { fprintf (stderr, args); abort(); }
+
+extern vector signed int vec_init ();
+extern void vec_print (vector signed int v);
+
+vector signed int vec_stack (int count);
+
+int
+main ()
+{
+ printf ("&vec_stack = %016lx\n", (unsigned long) vec_stack);
+ vec_stack (3);
+ return 0;
+}
+
+
+vector signed int
+vec_stack (int count)
+{
+ register vector signed int v1;
+ register vector signed int v2;
+ register vector signed int v3;
+ register vector signed int v4;
+ register vector signed int v5;
+ register vector signed int v6;
+ register vector signed int v7;
+ register vector signed int v8;
+ register vector signed int v9;
+
+ unw_fpreg_t vr;
+
+ unw_cursor_t cursor;
+ unw_word_t ip, sp;
+ unw_context_t uc;
+ int ret;
+ int verbose = 1;
+
+ /* if (count == 0) return vec_init(); */
+
+ if (count == 0)
+ {
+ unw_getcontext (&uc);
+ if (unw_init_local (&cursor, &uc) < 0)
+ {
+ panic ("unw_init_local failed!\n");
+ }
+ else
+ {
+ do
+ {
+ if ((ret = unw_get_reg (&cursor, UNW_REG_IP, &ip)) < 0)
+ {
+ panic ("FAILURE: unw_get_reg returned %d for UNW_REG_IP\n",
+ ret);
+ }
+ if ((ret = unw_get_reg (&cursor, UNW_REG_SP, &sp)) < 0)
+ {
+ panic ("FAILURE: unw_get_reg returned %d for UNW_REG_SP\n",
+ ret);
+ }
+ if ((ret = unw_get_fpreg (&cursor, UNW_PPC64_V30, &vr)) < 0)
+ {
+ panic
+ ("FAILURE: unw_get_vreg returned %d for UNW_PPC64_V30\n",
+ ret);
+ }
+
+
+ if (verbose)
+ {
+ const char *regname = unw_regname (UNW_PPC64_V30);
+ char proc_name_buffer[256];
+ unw_word_t offset;
+ unsigned int * vec_half1, * vec_half2;
+ vec_half1 = (unsigned int *)&vr;
+ vec_half2 = vec_half1 + 1;
+ printf ("ip = %016lx, sp=%016lx\n", (long) ip, (long) sp);
+ printf ("vr30 = %08x %08x %08x %08x\n",
+ (unsigned int) (*vec_half1 >> 16),
+ (unsigned int) (*vec_half1 & 0xffffffff),
+ (unsigned int) (*vec_half2 >> 16),
+ (unsigned int) (*vec_half2 & 0xffffffff));
+ ret =
+ unw_get_proc_name (&cursor, proc_name_buffer,
+ sizeof (proc_name_buffer), &offset);
+ if (ret == 0)
+ {
+ printf ("proc name = %s, offset = %lx\n",
+ proc_name_buffer, offset);
+ }
+ else
+ {
+ panic ("unw_get_proc_name returned %d\n", ret);
+ }
+ printf ("unw_regname(UNW_PPC_V30) = %s\n\n", regname);
+ }
+
+ ret = unw_step (&cursor);
+ if (ret < 0)
+ {
+ unw_get_reg (&cursor, UNW_REG_IP, &ip);
+ panic ("FAILURE: unw_step() returned %d for ip=%lx\n", ret,
+ (long) ip);
+ }
+ }
+ while (ret > 0);
+ }
+ }
+
+ v1 = vec_init ();
+ v2 = vec_init ();
+ v3 = vec_init ();
+ v4 = vec_init ();
+ v5 = vec_init ();
+ v6 = vec_init ();
+
+ /* make use of all of the registers in some calculation */
+ v7 =
+ vec_nor (v1, vec_add (v2, vec_sub (v3, vec_and (v4, vec_or (v5, v6)))));
+
+ /*
+ * "force" the registers to be non-volatile by making a call and also
+ * using the registers after the call.
+ */
+ v8 = vec_stack (count - 1);
+
+ /*
+ * Use the result from the previous call, plus all of the non-volatile
+ * registers in another calculation.
+ */
+ v9 =
+ vec_nor (v1,
+ vec_add (v2,
+ vec_sub (v3,
+ vec_and (v4, vec_or (v5, vec_xor (v6, v8))))));
+
+ printf ("v1 - ");
+ vec_print (v1);
+ printf ("\n");
+ printf ("v2 - ");
+ vec_print (v2);
+ printf ("\n");
+ printf ("v3 - ");
+ vec_print (v3);
+ printf ("\n");
+ printf ("v4 - ");
+ vec_print (v4);
+ printf ("\n");
+ printf ("v5 - ");
+ vec_print (v5);
+ printf ("\n");
+ printf ("v6 - ");
+ vec_print (v6);
+ printf ("\n");
+ printf ("v7 - ");
+ vec_print (v7);
+ printf ("\n");
+ printf ("v8 - ");
+ vec_print (v8);
+ printf ("\n");
+ printf ("v9 - ");
+ vec_print (v9);
+ printf ("\n");
+
+ return v9;
+}
diff --git a/tests/ppc64-test-wchar.c b/tests/ppc64-test-wchar.c
new file mode 100644
index 0000000..01d637c
--- /dev/null
+++ b/tests/ppc64-test-wchar.c
@@ -0,0 +1,20 @@
+#include <wchar.h>
+#include <stdio.h>
+main ()
+{
+ wchar_t *wstring =
+ L"Now is the time for all good men to come to the aid of their country";
+ int i;
+ int ret;
+
+ printf("wcslen(wstring) = %d\n", wcslen(wstring));
+ for (i = 0; i < wcslen (wstring); i++)
+ {
+ ret = printf ("%lc", wstring[i]);
+ if (ret != 1) {
+ printf("printf returned: %d\n", ret);
+ perror("Linux says");
+ }
+ }
+ printf("\n");
+}
diff --git a/tests/test-async-sig.c b/tests/test-async-sig.c
index a114bff..9309076 100644
--- a/tests/test-async-sig.c
+++ b/tests/test-async-sig.c
@@ -33,6 +33,8 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
+static const int nerrors_max = 100;
+
struct itimerval interval =
{
.it_interval = { .tv_sec = 0, .tv_usec = 0 },
@@ -54,6 +56,7 @@
unw_word_t ip, sp, off;
unw_context_t uc;
int ret;
+ int depth = 0;
unw_getcontext (&uc);
if (unw_init_local (&cursor, &uc) < 0)
@@ -92,6 +95,11 @@
panic ("FAILURE: unw_step() returned %d for ip=%lx\n",
ret, (long) ip);
}
+ if (depth++ > 100)
+ {
+ panic ("FAILURE: unw_step() looping over %d iterations\n", depth);
+ break;
+ }
}
while (ret > 0);
}
@@ -110,8 +118,10 @@
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL);
else if (sigcount == 200)
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
- else if (sigcount == 300)
+ else if (sigcount == 300 || nerrors > nerrors_max)
{
+ if (nerrors > nerrors_max)
+ panic ("Too many errors (%d)\n", nerrors);
if (nerrors)
{
fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
@@ -147,5 +157,10 @@
if (0 && verbose)
printf ("%s: starting backtrace\n", __FUNCTION__);
do_backtrace (0, (i++ % 100) == 0);
+ if (nerrors > nerrors_max)
+ {
+ panic ("Too many errors (%d)\n", nerrors);
+ exit (-1);
+ }
}
}
diff --git a/tests/test-mem.c b/tests/test-mem.c
index e1fcb2b..4f7e58c 100644
--- a/tests/test-mem.c
+++ b/tests/test-mem.c
@@ -28,6 +28,7 @@
#include <libunwind.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
@@ -69,12 +70,27 @@
}
int
+consume_some_stack_space (void)
+{
+ unw_cursor_t cursor;
+ unw_context_t uc;
+ char string[1024];
+
+ memset (&cursor, 0, sizeof (cursor));
+ memset (&uc, 0, sizeof (uc));
+ return sprintf (string, "hello %p %p\n", &cursor, &uc);
+}
+
+int
main (int argc, char **argv)
{
struct rlimit rlim;
verbose = argc > 1;
+ if (consume_some_stack_space () > 9999)
+ exit (-1); /* can't happen, but don't let the compiler know... */
+
rlim.rlim_cur = 0;
rlim.rlim_max = RLIM_INFINITY;
setrlimit (RLIMIT_DATA, &rlim);
diff --git a/tests/test-proc-info.c b/tests/test-proc-info.c
index db69bd3..9e039c6 100644
--- a/tests/test-proc-info.c
+++ b/tests/test-proc-info.c
@@ -110,7 +110,7 @@
int ret, verbose = 0;
unw_cursor_t c;
- if (argc > 1 && strcmp (argv[0], "-v") == 0)
+ if (argc > 1 && strcmp (argv[1], "-v") == 0)
verbose = 1;
memset (&acc, 0, sizeof (acc));
diff --git a/tests/test-ptrace-misc.c b/tests/test-ptrace-misc.c
index 2160548..562636a 100644
--- a/tests/test-ptrace-misc.c
+++ b/tests/test-ptrace-misc.c
@@ -67,7 +67,7 @@
bar (int v)
{
extern long f (long);
- int arr[1];
+ int arr[1] = { v };
uintptr_t r;
/* This is a vain attempt to use up lots of registers to force
diff --git a/tests/test-ptrace.c b/tests/test-ptrace.c
index 73409db..1f46f7d 100644
--- a/tests/test-ptrace.c
+++ b/tests/test-ptrace.c
@@ -47,6 +47,8 @@
#include <sys/ptrace.h>
#include <sys/wait.h>
+static const int nerrors_max = 100;
+
int nerrors;
int verbose;
int print_names = 1;
@@ -65,14 +67,17 @@
static unw_addr_space_t as;
static struct UPT_info *ui;
+static int killed;
+
void
do_backtrace (pid_t target_pid)
{
+ unw_word_t ip, sp, start_ip = 0, off;
int n = 0, ret;
unw_proc_info_t pi;
- unw_word_t ip, sp, start_ip;
unw_cursor_t c;
char buf[512];
+ size_t len;
ret = unw_init_remote (&c, as, ui);
if (ret < 0)
@@ -89,13 +94,22 @@
buf[0] = '\0';
if (print_names)
- unw_get_proc_name (&c, buf, sizeof (buf), NULL);
+ unw_get_proc_name (&c, buf, sizeof (buf), &off);
if (verbose)
- printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp);
+ {
+ if (off)
+ {
+ len = strlen (buf);
+ if (len >= sizeof (buf) - 32)
+ len = sizeof (buf) - 32;
+ sprintf (buf + len, "+0x%lx", (unsigned long) off);
+ }
+ printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp);
+ }
if ((ret = unw_get_proc_info (&c, &pi)) < 0)
- panic ("unw_get_proc_info() failed: ret=%d\n", ret);
+ panic ("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret);
else if (verbose)
printf ("\tproc=%016lx-%016lx\n\thandler=%lx lsda=%lx",
(long) pi.start_ip, (long) pi.end_ip,
@@ -122,10 +136,16 @@
ret, (long) ip, (long) start_ip);
}
- if (++n > 32)
+ if (++n > 64)
{
/* guard against bad unwind info in old libraries... */
- panic ("too deeply nested---assuming bogus unwind\n");
+ panic ("too deeply nested---assuming bogus unwind (start ip=%lx)\n",
+ (long) start_ip);
+ break;
+ }
+ if (nerrors > nerrors_max)
+ {
+ panic ("Too many errors (%d)!\n", nerrors);
break;
}
}
@@ -138,11 +158,16 @@
printf ("================\n\n");
}
+static pid_t target_pid;
+static void target_pid_kill (void)
+{
+ kill (target_pid, SIGKILL);
+}
+
int
main (int argc, char **argv)
{
int status, pid, pending_sig, optind = 1, state = 1;
- pid_t target_pid;
as = unw_create_addr_space (&_UPT_accessors, 0);
if (!as)
@@ -188,10 +213,11 @@
execve (argv[optind], argv + optind, environ);
_exit (-1);
}
+ atexit (target_pid_kill);
ui = _UPT_create (target_pid);
- while (1)
+ while (nerrors <= nerrors_max)
{
pid = wait4 (-1, &status, 0, 0);
if (pid == -1)
@@ -213,12 +239,16 @@
}
else if (WIFSIGNALED (status))
{
- panic ("child terminated by signal %d\n", WTERMSIG (status));
+ if (!killed)
+ panic ("child terminated by signal %d\n", WTERMSIG (status));
break;
}
else
{
pending_sig = WSTOPSIG (status);
+ /* Avoid deadlock: */
+ if (WSTOPSIG (status) == SIGKILL)
+ break;
if (trace_mode == TRIGGER)
{
if (WSTOPSIG (status) == SIGUSR1)
@@ -226,6 +256,17 @@
else if (WSTOPSIG (status) == SIGUSR2)
state = 1;
}
+ if (WSTOPSIG (status) != SIGUSR1 && WSTOPSIG (status) != SIGUSR2)
+ {
+ static int count = 0;
+
+ if (count++ > 100)
+ {
+ panic ("Too many child unexpected signals (now %d)\n",
+ WSTOPSIG (status));
+ killed = 1;
+ }
+ }
}
}
@@ -253,6 +294,8 @@
ptrace (PTRACE_SINGLESTEP, target_pid, 0, pending_sig);
break;
}
+ if (killed)
+ kill (target_pid, SIGKILL);
}
_UPT_destroy (ui);