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, &regnum, 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, &regnum, 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, &regnum, arg)) < 0)
 	    goto fail;
 
@@ -340,9 +339,9 @@
 	  if (((ret = read_regnum (as, a, addr, &regnum, 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, &current_mask) < 0)
+	abort ();
+      mp = &current_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, &current_mask) < 0)
-		abort ();
-	      mp = &current_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);