This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Backport unwind-libunwind.c to 3.3 branch
- From: "Zack Weinberg" <zack at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 09 Aug 2003 16:15:19 -0700
- Subject: Backport unwind-libunwind.c to 3.3 branch
This patch backports complete support for libunwind-based exception
handling from mainline to the 3.3 branch. This cannot be said to fix
a regression, however, C++ on ia64-hpux targets is basically useless
without it, and it is low risk for other targets.
On an ia64-hp-hpux11.23 box:
=== g++ Summary ===
before after
# of expected passes 6401 7751
# of unexpected failures 1188 137
# of unexpected successes 6 8
# of expected failures 254 90
# of unresolved testcases 47 21
# of untested testcases 23 23
# of unsupported tests 27 27
=== libstdc++-v3 Summary ===
before after
# of expected passes 95 414
# of unexpected failures 201 4
# of expected failures 1 17
# of unsupported tests 6 6
The patch consists entirely of bringing over changes from the
mainline. I had to leave one bit of DMT's original patches out:
* unwind.h (_Unwind_GetTextRelBase): Mark _C argument with
attribute "unused".
It's not strictly necessary and the 3.3 C++ parser can't handle the
syntax. That is the only change relative to the mainline patchset.
OK for branch?
zw
Backport the following changes from mainline:
2003-05-08 David Mosberger <davidm@hpl.hp.com>
* unwind-libunwind.c (_Unwind_FindEnclosingFunction): New.
2003-04-03 Richard Henderson <rth@redhat.com>
* unwind-libunwind.c (_Unwind_GetCFA): New.
2003-03-27 David Mosberger <davidm@hpl.hp.com>
* unwind-libunwind.c (uw_frame_state_for): Adjust for libunwind
v0.9 API change: replace read of UNW_REG_HANDLER with
unw_get_proc_info().
(_Unwind_GetLanguageSpecificData): Replace read of UNW_REG_LSDA
with unw_get_proc_info().
(_Unwind_GetRegionStart): Replace UNW_REG_PROC_START with
unw_get_proc_info().
2003-03-13 Nathanael Nerode <neroden@gcc.gnu.org>
* unwind-libunwind.c: Replace "GNU CC" with "GCC".
2002-10-02 David Mosberger-Tang <David.Mosberger@acm.org>
* config/t-libunwind: Mention unwind-sjlj.c.
* unwind-libunwind.c: Change #ifdef __USING_LIBUNWIND_EXCEPTIONS__
to #ifndef __USING_SJLJ_EXCEPTIONS__.
* configure.in: Move sjlj-exceptions and --enable-libunwind-exceptions
before inclusion of config.gcc, but after configuring the compiler etc.
Determine default value for --enable-libunwind-exceptions based on
whether the host has a libunwind library (not guaranteed to be correct,
but it's a reasonable first guess and can always be overridden with an
explicit --enable/disable-libunwind-exceptions.
* config.gcc: For target ia64*-*-linux*, mention t-libunwind as a
tmake_file when $use_libunwind_exceptions is enabled.
* Makefile.in: Update comment: LIB2ADDEH is updated not just by
ia64 (e.g., config/t-linux also updates it).
* gcc.c (init_spec) [USE_LIBUNWIND_EXCEPTIONS]: Mention -lunwind
along with the shared version of libgcc since the latter requires
the former.
* unwind-libunwind.c: New file.
* config/t-libunwind: Ditto.
===================================================================
Index: Makefile.in
--- Makefile.in 3 Aug 2003 15:48:36 -0000 1.958.2.14
+++ Makefile.in 9 Aug 2003 17:57:14 -0000
@@ -401,7 +401,7 @@ CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(IN
-finhibit-size-directive -fno-inline-functions -fno-exceptions \
-fno-zero-initialized-in-bss
-# Additional sources to handle exceptions; overridden on ia64.
+# Additional sources to handle exceptions; overridden by targets as needed.
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h
===================================================================
Index: config.gcc
--- config.gcc 9 Aug 2003 06:51:04 -0000 1.266.2.12
+++ config.gcc 9 Aug 2003 17:57:14 -0000
@@ -1484,6 +1484,9 @@ ia64*-*-linux*)
tmake_file="t-slibgcc-elf-ver t-linux ia64/t-ia64 ia64/t-glibc"
target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtfastmath.o"
+ if test x"$use_libunwind_exceptions" = xyes; then
+ tmake_file="$tmake_file t-libunwind"
+ fi
;;
ia64*-*-hpux*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h ia64/sysv4.h ia64/hpux.h ia64/hpux_longdouble.h"
===================================================================
Index: configure.in
--- configure.in 25 Jun 2003 23:14:55 -0000 1.627.2.13
+++ configure.in 9 Aug 2003 17:57:14 -0000
@@ -797,6 +797,25 @@ objext='.o'
AC_SUBST(manext)
AC_SUBST(objext)
+# With Setjmp/Longjmp based exception handling.
+AC_ARG_ENABLE(sjlj-exceptions,
+[ --enable-sjlj-exceptions
+ arrange to use setjmp/longjmp exception handling],
+[sjlj=`if test $enableval = yes; then echo 1; else echo 0; fi`
+AC_DEFINE_UNQUOTED(CONFIG_SJLJ_EXCEPTIONS, $sjlj,
+ [Define 0/1 to force the choice for exception handling model.])])
+
+AC_CHECK_LIB(unwind, main, use_libunwind_default=yes, use_libunwind_default=no)
+# Use libunwind based exception handling.
+AC_ARG_ENABLE(libunwind-exceptions,
+[ --enable-libunwind-exceptions force use libunwind for exceptions],
+use_libunwind_exceptions=$enableval,
+use_libunwind_exceptions=$use_libunwind_default)
+if test x"$use_libunwind_exceptions" = xyes; then
+ AC_DEFINE(USE_LIBUNWIND_EXCEPTIONS, 1,
+ [Define if gcc should use -lunwind.])
+fi
+
target_gtfiles=
build_xm_file=
build_xm_defines=
@@ -2580,24 +2599,6 @@ else
MAINT='#'
fi
AC_SUBST(MAINT)dnl
-
-# With Setjmp/Longjmp based exception handling.
-AC_ARG_ENABLE(sjlj-exceptions,
-[ --enable-sjlj-exceptions
- arrange to use setjmp/longjmp exception handling],
-[sjlj=`if test $enableval = yes; then echo 1; else echo 0; fi`
-AC_DEFINE_UNQUOTED(CONFIG_SJLJ_EXCEPTIONS, $sjlj,
- [Define 0/1 to force the choice for exception handling model.])])
-
-# Use libunwind based exception handling.
-AC_ARG_ENABLE(libunwind-exceptions,
-[ --enable-libunwind-exceptions force use libunwind for exceptions],
-use_libunwind_exceptions=$enableval,
-use_libunwind_exceptions=no)
-if test x"$use_libunwind_exceptions" = xyes; then
- AC_DEFINE(USE_LIBUNWIND_EXCEPTIONS, 1,
- [Define if gcc should use -lunwind.])
-fi
# Make empty files to contain the specs and options for each language.
# Then add #include lines to for a compiler that has specs and/or options.
===================================================================
Index: gcc.c
--- gcc.c 7 May 2003 06:02:07 -0000 1.350.2.4
+++ gcc.c 9 Aug 2003 17:57:14 -0000
@@ -1556,6 +1556,9 @@ init_spec ()
#else
"-lgcc_s%M"
#endif
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+ " -lunwind"
+#endif
,
"-lgcc",
"-lgcc_eh");
===================================================================
Index: unwind-libunwind.c
--- unwind-libunwind.c 1 Jan 1970 00:00:00 -0000
+++ unwind-libunwind.c 9 Aug 2003 17:57:14 -0000
@@ -0,0 +1,172 @@
+/* Subroutines needed for unwinding stack frames via the libunwind API.
+ Copyright (C) 2002, 2003
+ Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ This file is part of GCC.
+
+ GCC 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.
+
+ GCC 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 GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "unwind.h"
+
+#ifndef __USING_SJLJ_EXCEPTIONS__
+
+#define UNW_LOCAL_ONLY
+
+#include <libunwind.h>
+
+typedef struct {
+ _Unwind_Personality_Fn personality;
+} _Unwind_FrameState;
+
+struct _Unwind_Context {
+ unw_cursor_t cursor;
+};
+
+
+/* First come the helper-routines that are needed by unwind.inc. */
+
+static _Unwind_Reason_Code
+uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+ unw_proc_info_t pi;
+
+ if (unw_step (&context->cursor) <= 0)
+ return _URC_END_OF_STACK;
+
+ unw_get_proc_info(&context->cursor, &pi);
+ fs->personality = (_Unwind_Personality_Fn) pi.handler;
+
+ return _URC_NO_REASON;
+}
+
+#define uw_update_context(context,fs) do { ; } while (0)
+
+static inline _Unwind_Ptr
+uw_identify_context (struct _Unwind_Context *context)
+{
+ unw_word_t ip;
+ unw_get_reg (&context->cursor, UNW_REG_IP, &ip);
+ return (_Unwind_Ptr) ip;
+}
+
+#define uw_init_context(context) \
+do \
+ { \
+ unw_context_t uc; \
+ unw_getcontext (&uc); \
+ unw_init_local (&(context)->cursor, &uc); \
+ } \
+while (0)
+
+static inline void __attribute__ ((noreturn))
+uw_install_context (struct _Unwind_Context *current __attribute__ ((unused)),
+ struct _Unwind_Context *target)
+{
+ unw_resume (&(target)->cursor);
+ abort ();
+}
+
+
+/* Now come the helper-routines which may be called from an exception
+ handler. The interface for these routines are defined by the C++
+ ABI. See: http://www.codesourcery.com/cxx-abi/abi-eh.html */
+
+_Unwind_Word
+_Unwind_GetGR (struct _Unwind_Context *context, int index)
+{
+ unw_word_t ret;
+
+ /* Note: here we depend on the fact that general registers are
+ expected to start with register number 0! */
+ unw_get_reg (&context->cursor, index, &ret);
+ return ret;
+}
+
+/* Get the value of the CFA as saved in CONTEXT. */
+
+_Unwind_Word
+_Unwind_GetCFA (struct _Unwind_Context *context)
+{
+ /* ??? Is there any way to get this information? */
+ return NULL;
+}
+
+/* Overwrite the saved value for register REG in CONTEXT with VAL. */
+
+void
+_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
+{
+ /* Note: here we depend on the fact that general registers are
+ expected to start with register number 0! */
+ unw_set_reg (&context->cursor, index, val);
+}
+
+/* Retrieve the return address for CONTEXT. */
+
+inline _Unwind_Ptr
+_Unwind_GetIP (struct _Unwind_Context *context)
+{
+ unw_word_t ret;
+
+ unw_get_reg (&context->cursor, UNW_REG_IP, &ret);
+ return ret;
+}
+
+/* Overwrite the return address for CONTEXT with VAL. */
+
+inline void
+_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
+{
+ unw_set_reg (&context->cursor, UNW_REG_IP, val);
+}
+
+void *
+_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
+{
+ unw_proc_info_t pi;
+
+ unw_get_proc_info(&context->cursor, &pi);
+ return (void *) pi.lsda;
+}
+
+_Unwind_Ptr
+_Unwind_GetRegionStart (struct _Unwind_Context *context)
+{
+ unw_proc_info_t pi;
+
+ unw_get_proc_info(&context->cursor, &pi);
+ return (_Unwind_Ptr) pi.start_ip;
+}
+
+void *
+_Unwind_FindEnclosingFunction (void *pc)
+{
+ return NULL;
+}
+
+#include "unwind.inc"
+
+#endif /* !__USING_SJLJ_EXCEPTIONS__ */
===================================================================
Index: config/t-libunwind
--- config/t-libunwind 1 Jan 1970 00:00:00 -0000
+++ config/t-libunwind 9 Aug 2003 17:57:14 -0000
@@ -0,0 +1 @@
+LIB2ADDEH = $(srcdir)/unwind-libunwind.c $(srcdir)/unwind-sjlj.c