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..636a4e4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,16 +28,18 @@
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
-DISTCLEANFILES = include/libunwind.h include/tdep.h
+DISTCLEANFILES = include/libunwind.h include/tdep
diff --git a/Makefile.in b/Makefile.in
index 50c155b..15fd32c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004 Free Software Foundation, Inc.
+# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -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 \
@@ -234,19 +234,21 @@
@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
-DISTCLEANFILES = include/libunwind.h include/tdep.h
+DISTCLEANFILES = include/libunwind.h include/tdep
all: all-recursive
.SUFFIXES:
@@ -354,7 +356,13 @@
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @set fnord $$MAKEFLAGS; amf=$$2; \
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -366,7 +374,7 @@
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ || eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
@@ -374,7 +382,13 @@
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
- @set fnord $$MAKEFLAGS; amf=$$2; \
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
@@ -395,7 +409,7 @@
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ || eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -470,7 +484,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-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/README b/README
index f119fec..5f7fdb7 100644
--- a/README
+++ b/README
@@ -1,21 +1,14 @@
-*- 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.
-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
@@ -60,6 +53,7 @@
that member, variables of type unw_context_t won't be aligned
properly.
+
* Building on HP-UX
For the time being, libunwind must be built with GCC on HP-UX.
@@ -83,6 +77,7 @@
GCC v3.3.2 or later have been fixed and do not require this
workaround.
+
* Regression Testing
After building the library, you can run a set of regression tests with:
@@ -114,10 +109,56 @@
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-bt (see http://sources.redhat.com/bugzilla/show_bug.cgi?id=595)
+ Ltest-bt (likewise)
+ Gtest-resume-sig (likewise)
+ 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)
+
+In addition, the following are failing on Debian (Sarge):
+
+ Gtest-init (lack of unwind info for __libc_start_main,
+ libc ought to be compiled without
+ -fno-frame-pointer or with -fexceptions)
+ Ltest-init (likewise)
+ test-ptrace (likewise?)
+
+** 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
diff --git a/aclocal.m4 b/aclocal.m4
index 509d10c..4540518 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.9.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.9.5 -*- Autoconf -*-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -5927,23 +5927,11 @@
AC_MSG_RESULT([$SED])
])
-# -*- Autoconf -*-
-# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-# Generated from amversion.in; do not edit by hand.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
@@ -5956,28 +5944,17 @@
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
- [AM_AUTOMAKE_VERSION([1.9.3])])
+ [AM_AUTOMAKE_VERSION([1.9.5])])
-# Figure out how to run the assembler. -*- Autoconf -*-
+# Figure out how to run the assembler. -*- Autoconf -*-
-# serial 3
+# Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# serial 4
# AM_PROG_AS
# ----------
@@ -5990,24 +5967,13 @@
AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])
])
-# AM_AUX_DIR_EXPAND
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
@@ -6054,26 +6020,16 @@
am_aux_dir=`cd $ac_aux_dir && pwd`
])
-# AM_CONDITIONAL -*- Autoconf -*-
+# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 6
+# serial 7
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
@@ -6097,26 +6053,15 @@
Usually this means the macro was only invoked conditionally.]])
fi])])
-# serial 7 -*- Autoconf -*-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
+# serial 8
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
@@ -6125,7 +6070,6 @@
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
@@ -6265,27 +6209,16 @@
AC_SUBST([AMDEPBACKSLASH])
])
-# Generate code to set up dependency tracking. -*- Autoconf -*-
+# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
-# Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-#serial 2
+#serial 3
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
@@ -6344,54 +6277,31 @@
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
-# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 7
+# serial 8
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-# Do all the work for Automake. -*- Autoconf -*-
+# Do all the work for Automake. -*- Autoconf -*-
-# This macro actually does too much some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
+# serial 12
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 11
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
@@ -6493,51 +6403,27 @@
done
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
-# -*- Autoconf -*-
-# Copyright (C) 2003 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 1
+# serial 2
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
@@ -6552,28 +6438,17 @@
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
-# Add --enable-maintainer-mode option to configure.
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 3
+# serial 4
AC_DEFUN([AM_MAINTAINER_MODE],
[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
@@ -6592,26 +6467,15 @@
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-# Check to see how 'make' treats includes. -*- Autoconf -*-
+# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 2
+# serial 3
# AM_MAKE_INCLUDE()
# -----------------
@@ -6655,29 +6519,17 @@
rm -f confinc confmf
])
-# serial 2
+# Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
# AM_PROG_CC_C_O
# --------------
# Like AC_PROG_CC_C_O, but changed for automake.
-
-# Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
AC_DEFUN([AM_PROG_CC_C_O],
[AC_REQUIRE([AC_PROG_CC_C_O])dnl
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
@@ -6695,27 +6547,16 @@
fi
])
-# -*- Autoconf -*-
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 3
+# serial 4
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
@@ -6741,27 +6582,16 @@
fi
])
+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
# AM_PROG_MKDIR_P
# ---------------
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
-
-# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
+#
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
# created by `make install' are always world readable, even if the
# installer happens to have an overly restrictive umask (e.g. 077).
@@ -6815,26 +6645,15 @@
fi
AC_SUBST([mkdir_p])])
-# Helper functions for option handling. -*- Autoconf -*-
+# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 2
+# serial 3
# _AM_MANGLE_OPTION(NAME)
# -----------------------
@@ -6859,28 +6678,16 @@
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
#
-# Check to make sure that the build environment is sane.
-#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 3
+# serial 4
# AM_SANITY_CHECK
# ---------------
@@ -6923,25 +6730,14 @@
fi
AC_MSG_RESULT(yes)])
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
# AM_PROG_INSTALL_STRIP
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
+# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
@@ -6964,25 +6760,13 @@
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 1
-
+# serial 2
# _AM_PROG_TAR(FORMAT)
# --------------------
diff --git a/configure b/configure
index cd2a291..e286821 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.59 for libunwind 0.98.5.
+# Generated by GNU Autoconf 2.59 for libunwind 0.99-alpha.
#
# Report bugs to <libunwind@linux.hpl.hp.com>.
#
@@ -423,8 +423,8 @@
# Identity of this package.
PACKAGE_NAME='libunwind'
PACKAGE_TARNAME='libunwind'
-PACKAGE_VERSION='0.98.5'
-PACKAGE_STRING='libunwind 0.98.5'
+PACKAGE_VERSION='0.99-alpha'
+PACKAGE_STRING='libunwind 0.99-alpha'
PACKAGE_BUGREPORT='libunwind@linux.hpl.hp.com'
ac_unique_file="src/mi/backtrace.c"
@@ -962,7 +962,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.5 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]...
@@ -1029,7 +1029,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libunwind 0.98.5:";;
+ short | recursive ) echo "Configuration of libunwind 0.99-alpha:";;
esac
cat <<\_ACEOF
@@ -1173,7 +1173,7 @@
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-libunwind configure 0.98.5
+libunwind configure 0.99-alpha
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1187,7 +1187,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.5, which was
+It was created by libunwind $as_me 0.99-alpha, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1913,7 +1913,7 @@
# Define the identity of the package.
PACKAGE='libunwind'
- VERSION='0.98.5'
+ VERSION='0.99-alpha'
cat >>confdefs.h <<_ACEOF
@@ -20727,7 +20727,7 @@
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 or --disable-debug was given.
@@ -20868,7 +20868,7 @@
rm -f 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
@@ -20878,8 +20878,8 @@
ARCH=`echo $target_arch | tr a-z A-Z`
PKG_MAJOR=0
-PKG_MINOR=98
-PKG_EXTRA=.5
+PKG_MINOR=99
+PKG_EXTRA=-alpha
PKG_MAINTAINER=libunwind@linux.hpl.hp.com
@@ -21334,7 +21334,7 @@
} >&5
cat >&5 <<_CSEOF
-This file was extended by libunwind $as_me 0.98.5, which was
+This file was extended by libunwind $as_me 0.99-alpha, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -21400,7 +21400,7 @@
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-libunwind config.status 0.98.5
+libunwind config.status 0.99-alpha
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
@@ -21518,7 +21518,7 @@
"doc/common.tex" ) CONFIG_FILES="$CONFIG_FILES doc/common.tex" ;;
"include/libunwind-common.h" ) CONFIG_FILES="$CONFIG_FILES include/libunwind-common.h" ;;
"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" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
diff --git a/configure.in b/configure.in
index 7e00572..ef9137c 100644
--- a/configure.in
+++ b/configure.in
@@ -1,6 +1,6 @@
define(pkg_major, 0)
-define(pkg_minor, 98)
-define(pkg_extra, .5)
+define(pkg_minor, 99)
+define(pkg_extra, -alpha)
define(pkg_maintainer, libunwind@linux.hpl.hp.com)
define(mkvers, $1.$2$3)
dnl Process this file with autoconf to produce a configure script.
@@ -80,7 +80,7 @@
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 +101,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.in b/doc/Makefile.in
index e591131..1458635 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004 Free Software Foundation, Inc.
+# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
diff --git a/doc/libunwind-ia64.man b/doc/libunwind-ia64.man
index a8bce6a..58b105e 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 Fri May 20 08:11:38 PDT 2005
.\" 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" "20 May 2005" "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
diff --git a/doc/libunwind-ia64.tex b/doc/libunwind-ia64.tex
index b3dd45d..d085b97 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}
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..ac70c6b 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,7 @@
#ifndef dwarf_h
#define dwarf_h
-#include "internal.h"
-#include "mempool.h"
+#include <libunwind.h>
struct dwarf_cursor; /* forward-declaration */
@@ -145,7 +144,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 +198,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 +234,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 +280,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 +328,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 +350,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 +364,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-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 80%
rename from include/internal.h
rename to include/libunwind_i.h
index 73a1191..7309234 100644
--- a/include/internal.h
+++ b/include/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,8 +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 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 +49,7 @@
#include <libunwind.h>
#include <pthread.h>
#include <signal.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -65,7 +70,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 +102,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 +162,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 +245,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 +264,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 +283,6 @@
size_t size; /* (file-) size of the image */
};
-#endif /* internal_h */
+#include "tdep/libunwind_i.h"
+
+#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/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%
rename from src/hppa/Gget_reg.c
rename 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%
copy from src/hppa/Gget_reg.c
copy 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..e351452 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,21 @@
#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;
};
struct cursor
@@ -67,49 +73,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 +94,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 +111,6 @@
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
-//# warning fix me
abort ();
}
@@ -149,10 +120,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 +134,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 +142,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 +156,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 +185,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..9a2321b 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,14 @@
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:
@@ -86,7 +84,6 @@
libunwind_la_SOURCES_os_hpux = os-hpux.c
dwarf_SOURCES_common = \
- dwarf/dwarf-eh.h \
dwarf/global.c
dwarf_SOURCES_local = \
@@ -97,6 +94,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 +103,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 +120,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,13 +178,14 @@
# 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/setcontext.S \
x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h \
x86_64/is_fpreg.c x86_64/regname.c
# 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/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \
@@ -268,14 +283,19 @@
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 \
diff --git a/src/Makefile.in b/src/Makefile.in
index 990fb3e..32291c1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004 Free Software Foundation, Inc.
+# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -66,7 +66,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) \
@@ -80,17 +81,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 \
@@ -101,55 +141,44 @@
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)
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 \
+am__libunwind_setjmp_la_SOURCES_DIST = setjmp/setjmp_i.h \
+ setjmp/longjmp.c setjmp/siglongjmp.c 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_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__objects_12 = setjmp/longjmp.lo setjmp/siglongjmp.lo
+am__objects_13 = x86_64/longjmp.lo x86_64/siglongjmp.lo
+am__objects_14 = x86/longjmp.lo x86/siglongjmp.lo
+am__objects_15 = hppa/siglongjmp.lo
+am__objects_16 = 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_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_12) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_64_TRUE@@ARCH_X86_FALSE@ $(am__objects_13)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_12) \
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@ $(am__objects_14)
@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_12) \
+@ARCH_HPPA_TRUE@@ARCH_IA64_FALSE@ $(am__objects_15)
+@ARCH_IA64_TRUE@am_libunwind_setjmp_la_OBJECTS = $(am__objects_12) \
+@ARCH_IA64_TRUE@ $(am__objects_16)
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 \
@@ -162,17 +191,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_17 = $(am__objects_4) $(am__objects_5) elf32.lo \
+ x86/is_fpreg.lo x86/regname.lo
+am__objects_18 = $(am__objects_17) $(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_18)
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 \
@@ -180,29 +206,30 @@
@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 \
- 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 x86_64/Gcreate_addr_space.c \
- x86_64/Gget_save_loc.c x86_64/Gglobal.c x86_64/Ginit.c \
- 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) \
+ dwarf/global.c elf64.c elf64.h x86_64/setcontext.S \
+ 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 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 \
+ x86_64/Gcreate_addr_space.c x86_64/Gget_save_loc.c \
+ x86_64/Gglobal.c x86_64/Ginit.c 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_19 = $(am__objects_4) $(am__objects_5) elf64.lo \
+ x86_64/setcontext.lo x86_64/is_fpreg.lo x86_64/regname.lo
+am__objects_20 = $(am__objects_19) $(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_20)
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)
@@ -210,51 +237,51 @@
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/global.c elf64.c elf64.h x86_64/setcontext.S \
+ 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 dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c \
dwarf/Lpe.c dwarf/Lstep.c dwarf/Lfind_proc_info-lsb.c \
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_64/Lstep.c elf32.c elf32.h x86/init.h x86/offsets.h \
+ x86/unwind_i.h 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/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/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_21 = mi/_ReadULEB.lo mi/_ReadSLEB.lo
+@OS_LINUX_TRUE@am__objects_22 = $(am__objects_21)
+am__objects_23 = $(am__objects_22) 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 \
@@ -268,28 +295,27 @@
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_24 = 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 \
- 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_25 = $(am__objects_19) $(am__objects_23) $(am__objects_24) \
+ dwarf/Lfind_proc_info-lsb.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_26 = $(am__objects_17) $(am__objects_23) $(am__objects_24) \
+ 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_27 = $(am__objects_6) $(am__objects_23) hppa/getcontext.lo \
+ hppa/setcontext.lo $(am__objects_24) \
+ 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_28 = $(am__objects_10) $(am__objects_23) \
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 \
@@ -297,11 +323,11 @@
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_X86_64_TRUE@@ARCH_X86_FALSE@am_libunwind_la_OBJECTS = $(am__objects_25)
+@ARCH_HPPA_FALSE@@ARCH_IA64_FALSE@@ARCH_X86_TRUE@am_libunwind_la_OBJECTS = $(am__objects_26)
@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_27)
+@ARCH_IA64_TRUE@am_libunwind_la_OBJECTS = $(am__objects_28)
libunwind_la_OBJECTS = $(am_libunwind_la_OBJECTS)
@REMOTE_ONLY_FALSE@am_libunwind_la_rpath = -rpath $(libdir)
PROGRAMS = $(noinst_PROGRAMS)
@@ -335,7 +361,7 @@
$(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_setjmp_la_SOURCES_DIST) \
$(am__libunwind_x86_la_SOURCES_DIST) \
@@ -477,13 +503,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
@@ -493,6 +515,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 \
@@ -507,17 +530,16 @@
-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:
@@ -565,7 +587,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 = \
@@ -577,6 +598,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
@@ -586,8 +608,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 \
@@ -606,20 +626,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
@@ -627,7 +669,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 \
@@ -650,6 +691,8 @@
# 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/setcontext.S \
x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h \
x86_64/is_fpreg.c x86_64/regname.c
@@ -657,7 +700,6 @@
# 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/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \
@@ -715,13 +757,20 @@
@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)
+
+#
+# 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) \
@@ -812,6 +861,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) \
@@ -867,8 +918,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)
@@ -879,13 +928,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) \
@@ -904,6 +960,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) \
@@ -929,12 +1019,24 @@
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)
+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)
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):
@@ -943,13 +1045,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)
@@ -959,23 +1056,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) \
@@ -993,6 +1075,8 @@
x86/Gstep.lo: x86/$(am__dirstamp) x86/$(DEPDIR)/$(am__dirstamp)
libunwind-x86.la: $(libunwind_x86_la_OBJECTS) $(libunwind_x86_la_DEPENDENCIES)
$(LINK) $(am_libunwind_x86_la_rpath) $(libunwind_x86_la_LDFLAGS) $(libunwind_x86_la_OBJECTS) $(libunwind_x86_la_LIBADD) $(LIBS)
+x86_64/setcontext.lo: x86_64/$(am__dirstamp) \
+ x86_64/$(DEPDIR)/$(am__dirstamp)
x86_64/is_fpreg.lo: x86_64/$(am__dirstamp) \
x86_64/$(DEPDIR)/$(am__dirstamp)
x86_64/regname.lo: x86_64/$(am__dirstamp) \
@@ -1129,27 +1213,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)
@@ -1226,40 +1309,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)
@@ -1416,12 +1517,17 @@
-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)
@@ -1502,6 +1608,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)
@@ -1552,8 +1660,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
@@ -1562,12 +1674,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@
@@ -1581,22 +1689,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@
@@ -1671,12 +1786,15 @@
@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@
@@ -1785,6 +1903,7 @@
-rm -rf hppa/.libs hppa/_libs
-rm -rf ia64/.libs ia64/_libs
-rm -rf mi/.libs mi/_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
@@ -1842,7 +1961,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)/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 \
@@ -1908,6 +2027,8 @@
-rm -f mi/$(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)
@@ -1925,7 +2046,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) 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
@@ -1953,7 +2074,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) 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..3edd51b 100644
--- a/src/dwarf/Gparser.c
+++ b/src/dwarf/Gparser.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -23,10 +23,9 @@
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include <string.h>
-
+#include <stddef.h>
#include "dwarf_i.h"
-#include "tdep.h"
+#include "libunwind_i.h"
#define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool))
#define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs))
@@ -60,7 +59,7 @@
static int
run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
unw_word_t ip, unw_word_t *addr, unw_word_t end_addr,
- unw_dyn_dwarf_fde_info_t *dfi)
+ struct dwarf_cie_info *dci)
{
unw_word_t curr_ip, operand = 0, regnum, val, len, fde_encoding;
dwarf_reg_state_t *rs_stack = NULL, *new_rs, *old_rs;
@@ -90,28 +89,28 @@
switch ((dwarf_cfa_t) op)
{
case DW_CFA_advance_loc:
- curr_ip += operand * dfi->code_align;
+ curr_ip += operand * dci->code_align;
Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip);
break;
case DW_CFA_advance_loc1:
if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0)
goto fail;
- curr_ip += u8 * dfi->code_align;
+ curr_ip += u8 * dci->code_align;
Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip);
break;
case DW_CFA_advance_loc2:
if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0)
goto fail;
- curr_ip += u16 * dfi->code_align;
+ curr_ip += u16 * dci->code_align;
Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip);
break;
case DW_CFA_advance_loc4:
if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0)
goto fail;
- curr_ip += u32 * dfi->code_align;
+ curr_ip += u32 * dci->code_align;
Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip);
break;
@@ -122,7 +121,7 @@
if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0)
goto fail;
- curr_ip += u64 * dfi->code_align;
+ curr_ip += u64 * dci->code_align;
Debug (15, "CFA_MIPS_advance_loc8\n");
break;
}
@@ -143,27 +142,27 @@
}
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dfi->data_align);
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset r%lu at cfa+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_offset_extended:
if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dfi->data_align);
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_offset_extended_sf:
if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
|| ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0))
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dfi->data_align);
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_restore:
@@ -197,7 +196,7 @@
break;
case DW_CFA_set_loc:
- fde_encoding = dfi->flags & UNW_DYN_DFI_FLAG_FDE_PE_MASK;
+ fde_encoding = dci->fde_encoding;
if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding,
&c->pi, &curr_ip,
arg)) < 0)
@@ -271,9 +270,9 @@
goto fail;
set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum);
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0,
- val * dfi->data_align); /* factored! */
+ val * dci->data_align); /* factored! */
Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n",
- (long) regnum, (long) (val * dfi->data_align));
+ (long) regnum, (long) (val * dci->data_align));
break;
case DW_CFA_def_cfa_register:
@@ -287,16 +286,16 @@
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
goto fail;
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */
- Debug (15, "CFA_def_cfa_offsets 0x%lx\n", (long) val);
+ Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val);
break;
case DW_CFA_def_cfa_offset_sf:
if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)
goto fail;
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0,
- val * dfi->data_align); /* factored! */
- Debug (15, "CFA_def_cfa_offsets_sf 0x%lx\n",
- (long) (val * dfi->data_align));
+ val * dci->data_align); /* factored! */
+ Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n",
+ (long) (val * dci->data_align));
break;
case DW_CFA_def_cfa_expression:
@@ -311,7 +310,7 @@
*addr += len;
break;
- case DW_CFA_CFA_expression:
+ case DW_CFA_expression:
if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
goto fail;
@@ -340,9 +339,9 @@
if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail;
- set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dfi->data_align));
- Debug (15, "CFA_GNU_negative_offsets_extended cfa+0x%lx\n",
- (long) -(val * dfi->data_align));
+ set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align));
+ Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n",
+ (long) -(val * dci->data_align));
break;
case DW_CFA_GNU_window_save:
@@ -359,7 +358,7 @@
#endif
case DW_CFA_lo_user:
case DW_CFA_hi_user:
- Debug (1, "Unexpected CFA opcode 0x%x", op);
+ Debug (1, "Unexpected CFA opcode 0x%x\n", op);
ret = -UNW_EINVAL;
goto fail;
}
@@ -382,9 +381,13 @@
{
int ret, dynamic = 1;
+ --ip;
+
if (c->pi_valid && !need_unwind_info)
return 0;
+ memset (&c->pi, 0, sizeof (c->pi));
+
/* check dynamic info first --- it overrides everything else */
ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info,
c->as_arg);
@@ -419,32 +422,216 @@
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___THREAD
+ if (as->caching_policy == UNW_CACHE_PER_THREAD)
+ cache = &dwarf_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", __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 >> 4) * magic >> (64 - 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 +640,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 +655,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 +689,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 +716,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 +734,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 +766,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 +801,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..7b13506 100644
--- a/src/elfxx.c
+++ b/src/elfxx.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.
@@ -24,14 +24,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)
@@ -137,7 +133,7 @@
sped up greatly, but until an application materializes that's
sensitive to the performance of this routine, why bother... */
-PROTECTED int
+HIDDEN int
elf_w (get_proc_name) (pid_t pid, unw_word_t ip, char *buf, size_t buf_len,
unw_word_t *offp)
{
diff --git a/src/elfxx.h b/src/elfxx.h
index 694c03d..a12375b 100644
--- a/src/elfxx.h
+++ b/src/elfxx.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.
@@ -30,7 +30,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
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..6826d4a 100644
--- a/src/hppa/Ginit.c
+++ b/src/hppa/Ginit.c
@@ -44,28 +44,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 +90,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 +108,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 +118,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 +136,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 +148,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 +164,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 (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%
rename from src/hppa/Lget_reg.c
rename 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%
rename from src/hppa/Lget_proc_name.c
rename 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%
copy from src/hppa/Lget_reg.c
copy 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..ae48537
--- /dev/null
+++ b/src/hppa/getcontext.S
@@ -0,0 +1,70 @@
+/* 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
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..4eba4cd
--- /dev/null
+++ b/src/hppa/setcontext.S
@@ -0,0 +1,73 @@
+/* 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
diff --git a/src/hppa/siglongjmp.S b/src/hppa/siglongjmp.S
index 194f205..16cfcc6 100644
--- a/src/hppa/siglongjmp.S
+++ b/src/hppa/siglongjmp.S
@@ -1 +1,12 @@
-# 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
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 9a7859c..24596b0 100644
--- a/src/ia64/Ginit.c
+++ b/src/ia64/Ginit.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,52 +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. */
-#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. */
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/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/Lregs.c~ b/src/ia64/Lregs.c~
deleted file mode 100644
index e69de29..0000000
--- a/src/ia64/Lregs.c~
+++ /dev/null
diff --git a/src/ia64/Lscript.c~ b/src/ia64/Lscript.c~
deleted file mode 100644
index e69de29..0000000
--- a/src/ia64/Lscript.c~
+++ /dev/null
diff --git a/src/ia64/Lunw_get_reg.c~ b/src/ia64/Lunw_get_reg.c~
deleted file mode 100644
index e69de29..0000000
--- a/src/ia64/Lunw_get_reg.c~
+++ /dev/null
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/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/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/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..ce73b01 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
+
+#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_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..8956231 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,
diff --git a/src/longjmp.c b/src/setjmp/longjmp.c
similarity index 62%
rename from src/longjmp.c
rename to src/setjmp/longjmp.c
index f99e478..ac31b5b 100644
--- a/src/longjmp.c
+++ b/src/setjmp/longjmp.c
@@ -32,10 +32,7 @@
#include <stdlib.h>
#include "jmpbuf.h"
-
-#if UNW_TARGET_IA64
-# include "ia64/rse.h"
-#endif
+#include "setjmp_i.h"
void
_longjmp (jmp_buf env, int val)
@@ -56,56 +53,17 @@
if (sp != wp[JB_SP])
continue;
-#if UNW_TARGET_IA64
- {
- unw_word_t bsp, pfs, sol;
-
- if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0
- || unw_get_reg (&c, UNW_IA64_AR_PFS, &pfs) < 0)
- abort ();
-
- /* simulate the effect of "br.call setjmp" on ar.bsp: */
- sol = (pfs >> 7) & 0x7f;
- bsp = ia64_rse_skip_regs (bsp, sol);
-
- if (bsp != wp[JB_BSP])
- continue;
-
- if (unlikely (sol == 0))
- {
- unw_word_t prev_sp;
- unw_cursor_t tmp = c;
-
- /* The caller of {sig,}setjmp() cannot have a NULL-frame.
- If we see a NULL-frame, we haven't reached the right
- target yet. To have a NULL-frame, the number of locals
- must be zero and the stack-frame must also be
- empty. */
-
- if (unw_step (&tmp) < 0)
- abort ();
-
- if (unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0)
- abort ();
-
- if (sp == prev_sp)
- /* got a NULL-frame; keep looking... */
- continue;
- }
- }
-#endif
+ if (!bsp_match (&c, wp))
+ continue;
/* found the right frame: */
- if (UNW_NUM_EH_REGS >= 4)
- {
- if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
- || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
- || unw_set_reg (&c, UNW_REG_IP,
- (unw_word_t) &_UI_longjmp_cont))
- abort ();
- }
- else
+ assert (UNW_NUM_EH_REGS >= 2);
+
+ if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
+ || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
+ || unw_set_reg (&c, UNW_REG_IP,
+ (unw_word_t) &_UI_longjmp_cont))
abort ();
unw_resume (&c);
diff --git a/src/setjmp.c b/src/setjmp/setjmp.c
similarity index 100%
rename from src/setjmp.c
rename to src/setjmp/setjmp.c
diff --git a/src/setjmp/setjmp_i.h b/src/setjmp/setjmp_i.h
new file mode 100644
index 0000000..1d7ca15
--- /dev/null
+++ b/src/setjmp/setjmp_i.h
@@ -0,0 +1,118 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003-2005 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#if UNW_TARGET_IA64
+
+#include "libunwind_i.h"
+#include "tdep-ia64/rse.h"
+
+static inline int
+bsp_match (unw_cursor_t *c, unw_word_t *wp)
+{
+ unw_word_t bsp, pfs, sol;
+
+ if (unw_get_reg (c, UNW_IA64_BSP, &bsp) < 0
+ || unw_get_reg (c, UNW_IA64_AR_PFS, &pfs) < 0)
+ abort ();
+
+ /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */
+ sol = (pfs >> 7) & 0x7f;
+ bsp = rse_skip_regs (bsp, sol);
+
+ if (bsp != wp[JB_BSP])
+ return 0;
+
+ if (unlikely (sol == 0))
+ {
+ unw_word_t sp, prev_sp;
+ unw_cursor_t tmp = *c;
+
+ /* The caller of {sig,}setjmp() cannot have a NULL-frame. If we
+ see a NULL-frame, we haven't reached the right target yet.
+ To have a NULL-frame, the number of locals must be zero and
+ the stack-frame must also be empty. */
+
+ if (unw_step (&tmp) < 0)
+ abort ();
+
+ if (unw_get_reg (&tmp, UNW_REG_SP, &sp) < 0
+ || unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0)
+ abort ();
+
+ if (sp == prev_sp)
+ /* got a NULL-frame; keep looking... */
+ return 0;
+ }
+ return 1;
+}
+
+/* On ia64 we cannot always call sigprocmask() at
+ _UI_siglongjmp_cont() because the signal may have switched stacks
+ and the old stack's register-backing store may have overflown,
+ leaving us no space to allocate the stacked registers needed to
+ call sigprocmask(). Fortunately, we can just let unw_resume() (via
+ sigreturn) take care of restoring the signal-mask. That's faster
+ anyhow. */
+static inline int
+resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp)
+{
+ unw_word_t sc_addr = ((struct cursor *) c)->sigcontext_addr;
+ struct sigcontext *sc = (struct sigcontext *) sc_addr;
+ sigset_t current_mask;
+ void *mp;
+
+ if (!sc_addr)
+ return 0;
+
+ /* let unw_resume() install the desired signal mask */
+
+ if (wp[JB_MASK_SAVED])
+ mp = &wp[JB_MASK];
+ else
+ {
+ if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0)
+ abort ();
+ mp = ¤t_mask;
+ }
+ memcpy (&sc->sc_mask, mp, sizeof (sc->sc_mask));
+ return 1;
+}
+
+#else /* !UNW_TARGET_IA64 */
+
+static inline int
+bsp_match (unw_cursor_t *c, unw_word_t *wp)
+{
+ return 1;
+}
+
+static inline int
+resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp)
+{
+ /* We may want to do this analogously as for ia64... */
+ return 0;
+}
+
+#endif /* !UNW_TARGET_IA64 */
diff --git a/src/setjmp/siglongjmp.c b/src/setjmp/siglongjmp.c
new file mode 100644
index 0000000..4257082
--- /dev/null
+++ b/src/setjmp/siglongjmp.c
@@ -0,0 +1,94 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003-2005 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define UNW_LOCAL_ONLY
+
+#include <setjmp.h>
+
+#include "libunwind_i.h"
+#include "jmpbuf.h"
+#include "setjmp_i.h"
+
+void
+siglongjmp (sigjmp_buf env, int val)
+{
+ unw_word_t *wp = (unw_word_t *) env;
+ extern int _UI_siglongjmp_cont;
+ extern int _UI_longjmp_cont;
+ unw_context_t uc;
+ unw_cursor_t c;
+ unw_word_t sp;
+ int *cont;
+
+ if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0)
+ abort ();
+
+ do
+ {
+ if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0)
+ abort ();
+ if (sp != wp[JB_SP])
+ continue;
+
+ if (!bsp_match (&c, wp))
+ continue;
+
+ /* found the right frame: */
+
+ /* default to resuming without restoring signal-mask */
+ cont = &_UI_longjmp_cont;
+
+ /* Order of evaluation is important here: if unw_resume()
+ restores signal mask, we must set it up appropriately, even
+ if wp[JB_MASK_SAVED] is FALSE. */
+ if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED])
+ {
+ /* sigmask was saved */
+ if (UNW_NUM_EH_REGS < 4 || _NSIG >= 16 * sizeof (unw_word_t))
+ /* signal mask doesn't fit into EH arguments and we can't
+ put it on the stack without overwriting something
+ else... */
+ abort ();
+ else
+ if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0
+ || (_NSIG > 8 * sizeof (unw_word_t)
+ && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0))
+ abort ();
+ cont = &_UI_siglongjmp_cont;
+ }
+
+ if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
+ || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
+ || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) cont))
+ abort ();
+
+ unw_resume (&c);
+
+ abort ();
+ }
+ while (unw_step (&c) >= 0);
+
+ abort ();
+}
diff --git a/src/sigsetjmp.c b/src/setjmp/sigsetjmp.c
similarity index 100%
rename from src/sigsetjmp.c
rename to src/setjmp/sigsetjmp.c
diff --git a/src/siglongjmp.c b/src/siglongjmp.c
deleted file mode 100644
index 3f8c9e2..0000000
--- a/src/siglongjmp.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-
-This file is part of libunwind.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#define UNW_LOCAL_ONLY
-
-#include <assert.h>
-#include <libunwind.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stdlib.h>
-
-#include "tdep.h"
-#include "jmpbuf.h"
-
-#if UNW_TARGET_IA64
-# include "ia64/rse.h"
-#endif
-
-void
-siglongjmp (sigjmp_buf env, int val)
-{
- unw_word_t *wp = (unw_word_t *) env;
- extern int _UI_siglongjmp_cont;
- extern int _UI_longjmp_cont;
- unw_context_t uc;
- unw_cursor_t c;
- unw_word_t sp;
- int *cont;
-
- if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0)
- abort ();
-
- do
- {
- if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0)
- abort ();
- if (sp != wp[JB_SP])
- continue;
-
-#if UNW_TARGET_IA64
- {
- unw_word_t bsp, pfs, sol;
-
- if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0
- || unw_get_reg (&c, UNW_IA64_AR_PFS, &pfs) < 0)
- abort ();
-
- /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */
- sol = (pfs >> 7) & 0x7f;
- bsp = ia64_rse_skip_regs (bsp, sol);
-
- if (bsp != wp[JB_BSP])
- continue;
-
- if (unlikely (sol == 0))
- {
- unw_word_t prev_sp;
- unw_cursor_t tmp = c;
-
- /* The caller of {sig,}setjmp() cannot have a NULL-frame.
- If we see a NULL-frame, we haven't reached the right
- target yet. To have a NULL-frame, the number of locals
- must be zero and the stack-frame must also be
- empty. */
-
- if (unw_step (&tmp) < 0)
- abort ();
-
- if (unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0)
- abort ();
-
- if (sp == prev_sp)
- /* got a NULL-frame; keep looking... */
- continue;
- }
- }
-#endif
-
- /* found the right frame: */
-
- assert (UNW_NUM_EH_REGS >= 4 && _NSIG <= 16 * sizeof (unw_word_t));
-
- /* default to continuation without sigprocmask() */
- cont = &_UI_longjmp_cont;
-
-#if UNW_TARGET_IA64
- /* On ia64 we cannot always call sigprocmask() at
- _UI_siglongjmp_cont() because the signal may have switched
- stacks and the old stack's register-backing store may have
- overflown, leaving us no space to allocate the stacked
- registers needed to call sigprocmask(). Fortunately, we can
- just let unw_resume() (via sigreturn) take care of restoring
- the signal-mask. That's faster anyhow.
-
- XXX We probably should do the analogous on all architectures. */
- if (((struct cursor *) &c)->sigcontext_addr)
- {
- /* let unw_resume() install the desired signal mask */
- struct cursor *cp = (struct cursor *) &c;
- struct sigcontext *sc = (struct sigcontext *) cp->sigcontext_addr;
- sigset_t current_mask;
- void *mp;
-
- if (wp[JB_MASK_SAVED])
- mp = &wp[JB_MASK];
- else
- {
- if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0)
- abort ();
- mp = ¤t_mask;
- }
- memcpy (&sc->sc_mask, mp, sizeof (sc->sc_mask));
- }
- else
-#endif
- if (wp[JB_MASK_SAVED])
- {
- /* sigmask was saved */
- if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0
- || (_NSIG > 8 * sizeof (unw_word_t)
- && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0))
- abort ();
- cont = &_UI_siglongjmp_cont;
- }
-
- if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
- || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
- || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) cont))
- abort ();
-
- unw_resume (&c);
-
- abort ();
- }
- while (unw_step (&c) >= 0);
-
- abort ();
-}
diff --git a/src/unwind/unwind-internal.h b/src/unwind/unwind-internal.h
index d410ee3..4db2eda 100644
--- a/src/unwind/unwind-internal.h
+++ b/src/unwind/unwind-internal.h
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (C) 2003 Hewlett-Packard Co
+ Copyright (C) 2003, 2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -32,8 +32,7 @@
#include <stdlib.h>
#include <libunwind.h>
-#include "internal.h"
-#include "tdep.h"
+#include "libunwind_i.h"
/* The version of the _Unwind_*() interface implemented by this code. */
#define _U_VERSION 1
@@ -55,7 +54,7 @@
((unw_getcontext (uc) < 0 || unw_init_local (&(context)->cursor, uc) < 0) \
? -1 : 0))
-static inline _Unwind_Reason_Code ALWAYS_INLINE
+static _Unwind_Reason_Code ALWAYS_INLINE
_Unwind_Phase2 (struct _Unwind_Exception *exception_object,
struct _Unwind_Context *context)
{
diff --git a/src/x86/Gglobal.c b/src/x86/Gglobal.c
index 126b38d..e55644c 100644
--- a/src/x86/Gglobal.c
+++ b/src/x86/Gglobal.c
@@ -1,5 +1,5 @@
/* libunwind - a platform-independent unwind library
- Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
@@ -43,11 +43,11 @@
HIDDEN void
tdep_init (void)
{
- sigset_t saved_sigmask;
+ intrmask_t saved_mask;
- sigfillset (&unwi_full_sigmask);
+ sigfillset (&unwi_full_mask);
- sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
+ sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
mutex_lock (&x86_lock);
{
if (!tdep_needs_initialization)
@@ -65,5 +65,5 @@
}
out:
mutex_unlock (&x86_lock);
- sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
+ sigprocmask (SIG_SETMASK, &saved_mask, NULL);
}
diff --git a/src/x86/Ginit.c b/src/x86/Ginit.c
index 555743d..3b206a3 100644
--- a/src/x86/Ginit.c
+++ b/src/x86/Ginit.c
@@ -128,7 +128,6 @@
if (unw_is_fpreg (reg))
goto badreg;
-Debug (16, "reg = %s\n", unw_regname (reg));
if (!(addr = uc_addr (uc, reg)))
goto badreg;
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..61a2f02 100644
--- a/src/x86/init.h
+++ b/src/x86/init.h
@@ -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 72%
copy from src/hppa/Gget_reg.c
copy to src/x86/longjmp.S
index 4553f65..ce8d4b2 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,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:
+ .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
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..51bbb50 100644
--- a/src/x86/siglongjmp.S
+++ b/src/x86/siglongjmp.S
@@ -1,10 +1,68 @@
- /* 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
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..7bf01fb 100644
--- a/src/x86_64/Ginit.c
+++ b/src/x86_64/Ginit.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include "unwind_i.h"
@@ -74,7 +75,7 @@
# ifdef UNW_LOCAL_ONLY
-void *
+HIDDEN void *
tdep_uc_addr (ucontext_t *uc, int reg)
{
return uc_addr (uc, reg);
@@ -103,6 +104,9 @@
return 0;
}
+#define PAGE_SIZE 4096
+#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
+
static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
@@ -114,6 +118,9 @@
}
else
{
+ /* validate address */
+ if (msync(PAGE_START(addr), 1, MS_SYNC) == -1)
+ return -1;
*val = *(unw_word_t *) addr;
Debug (16, "mem[%016lx] -> %lx\n", addr, *val);
}
diff --git a/src/x86_64/Gis_signal_frame.c b/src/x86_64/Gis_signal_frame.c
index 221eab8..67eab27 100644
--- a/src/x86_64/Gis_signal_frame.c
+++ b/src/x86_64/Gis_signal_frame.c
@@ -52,7 +52,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..2fc51aa 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);
+ 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 76%
copy from src/hppa/Gget_reg.c
copy to src/x86_64/longjmp.S
index 4553f65..192b8bc 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,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_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
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..d164d8d
--- /dev/null
+++ b/src/x86_64/setcontext.S
@@ -0,0 +1,4 @@
+ .global _UI_setcontext
+
+_UI_setcontext:
+ retq
diff --git a/src/x86_64/siglongjmp.S b/src/x86_64/siglongjmp.S
index c43c984..9846932 100644
--- a/src/x86_64/siglongjmp.S
+++ b/src/x86_64/siglongjmp.S
@@ -1,10 +1,29 @@
- /* 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
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-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..ff15328 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
@@ -79,11 +80,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 90468c7..27a3048 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004 Free Software Foundation, Inc.
+# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -90,161 +90,164 @@
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)
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
@@ -450,6 +453,7 @@
@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_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 \
@@ -485,10 +489,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
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..d856a23 100644
--- a/tests/flush-cache.S
+++ b/tests/flush-cache.S
@@ -36,6 +36,17 @@
flush_cache:
ret
+#elif defined(__hppa__)
+
+# warning FIX ME!!
+
+ .globl flush_cache
+flush_cache:
+ .proc
+ .callinfo
+ bv %r0(%rp)
+ .procend
+
#else
# error Need flush_cache code for this architecture.
#endif
diff --git a/tests/ia64-test-nat-asm.S b/tests/ia64-test-nat-asm.S
index e435eef..8482c35 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,27 @@
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
diff --git a/tests/ia64-test-setjmp.c b/tests/ia64-test-setjmp.c
index a32557a..74bb4b4 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>
diff --git a/tests/perf-startup b/tests/perf-startup
index e69de29..c370748 100644
--- 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/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..2bbbee2 100644
--- a/tests/test-ptrace.c
+++ b/tests/test-ptrace.c
@@ -68,11 +68,12 @@
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 +90,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", 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 +132,11 @@
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;
}
}