Fix Dwarf unwind library for UNITS_PER_WORD > sizeof (void *)
authorH.J. Lu <hongjiu.lu@intel.com>
Mon, 8 Aug 2011 13:26:06 +0000 (13:26 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Mon, 8 Aug 2011 13:26:06 +0000 (06:26 -0700)
gcc/

2011-08-08  H.J. Lu  <hongjiu.lu@intel.com>

PR other/48007
* config.gcc (libgcc_tm_file): Add i386/value-unwind.h for
Linux/x86.

* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.
(ASSUME_EXTENDED_UNWIND_CONTEXT): Likewise.

* unwind-dw2.c (ASSUME_EXTENDED_UNWIND_CONTEXT): New.
(_Unwind_Context_Reg_Val): Likewise.
(_Unwind_Get_Unwind_Word): Likewise.
(_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
(_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
(_Unwind_IsExtendedContext): Check ASSUME_EXTENDED_UNWIND_CONTEXT
for EXTENDED_CONTEXT_BIT.
(__frame_state_for): Likewise.
(uw_init_context_1): Likewise.
(_Unwind_GetGR): Updated.
(_Unwind_SetGR): Likewise.
(_Unwind_GetGRPtr): Likewise.
(_Unwind_SetGRPtr): Likewise.
(_Unwind_SetGRValue): Likewise.
(_Unwind_GRByValue): Likewise.
(uw_install_context_1): Likewise.

* doc/tm.texi.in: Document REG_VALUE_IN_UNWIND_CONTEXT and
ASSUME_EXTENDED_UNWIND_CONTEXT.
* doc/tm.texi: Regenerated.

libgcc/

2011-08-08  H.J. Lu  <hongjiu.lu@intel.com>

PR other/48007
* config/i386/value-unwind.h: New.

From-SVN: r177563

gcc/ChangeLog
gcc/config.gcc
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/system.h
libgcc/ChangeLog
libgcc/config/i386/value-unwind.h [new file with mode: 0644]
libgcc/unwind-dw2.c

index ac35dd681155d705a8501cb607daa4fb8f5ee757..d1371d2b25d95be27003299d9ec255515d825432 100644 (file)
@@ -1,3 +1,33 @@
+2011-08-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR other/48007
+       * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for
+       Linux/x86.
+
+       * system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.
+       (ASSUME_EXTENDED_UNWIND_CONTEXT): Likewise.
+
+       * unwind-dw2.c (ASSUME_EXTENDED_UNWIND_CONTEXT): New.
+       (_Unwind_Context_Reg_Val): Likewise.
+       (_Unwind_Get_Unwind_Word): Likewise.
+       (_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
+       (_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
+       (_Unwind_IsExtendedContext): Check ASSUME_EXTENDED_UNWIND_CONTEXT
+       for EXTENDED_CONTEXT_BIT.
+       (__frame_state_for): Likewise.
+       (uw_init_context_1): Likewise.
+       (_Unwind_GetGR): Updated.
+       (_Unwind_SetGR): Likewise.
+       (_Unwind_GetGRPtr): Likewise.
+       (_Unwind_SetGRPtr): Likewise.
+       (_Unwind_SetGRValue): Likewise.
+       (_Unwind_GRByValue): Likewise.
+       (uw_install_context_1): Likewise.
+
+       * doc/tm.texi.in: Document REG_VALUE_IN_UNWIND_CONTEXT and
+       ASSUME_EXTENDED_UNWIND_CONTEXT.
+       * doc/tm.texi: Regenerated.
+
 2011-08-08  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * Makefile.in (gengtype$(exeext)): Add $(LDFLAGS).
index 716fa224b2a98e3a460f82df18c677267f7dbcb9..ec13d93b3d5b8e84843264e24cfd8dce4dc91045 100644 (file)
@@ -2663,6 +2663,7 @@ esac
 case ${target} in
 i[34567]86-*-linux* | x86_64-*-linux*)
        tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
+       libgcc_tm_file="${libgcc_tm_file} i386/value-unwind.h"
        ;;
 i[34567]86-*-* | x86_64-*-*)
        tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
index 097531f7f6ba034310be4ba39768afe265c5ab07..74a232412d12df3453b2739f9fead9dbc8ac6da1 100644 (file)
@@ -3725,6 +3725,24 @@ return @code{@var{regno}}.
 
 @end defmac
 
+@defmac REG_VALUE_IN_UNWIND_CONTEXT
+
+Define this macro if the target stores register values as
+@code{_Unwind_Word} type in unwind context.  It should be defined if
+target register size is larger than the size of @code{void *}.  The
+default is to store register values as @code{void *} type.
+
+@end defmac
+
+@defmac ASSUME_EXTENDED_UNWIND_CONTEXT
+
+Define this macro to be 1 if the target always uses extended unwind
+context with version, args_size and by_value fields.  If it is undefined,
+it will be defined to 1 when @code{REG_VALUE_IN_UNWIND_CONTEXT} is
+defined and 0 otherwise.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
index 01beeb47920e7d01d693c489041e6f9a82444906..f63fe4a0c2b16946ee9b4bdc9b5463af9918af0b 100644 (file)
@@ -3711,6 +3711,24 @@ return @code{@var{regno}}.
 
 @end defmac
 
+@defmac REG_VALUE_IN_UNWIND_CONTEXT
+
+Define this macro if the target stores register values as
+@code{_Unwind_Word} type in unwind context.  It should be defined if
+target register size is larger than the size of @code{void *}.  The
+default is to store register values as @code{void *} type.
+
+@end defmac
+
+@defmac ASSUME_EXTENDED_UNWIND_CONTEXT
+
+Define this macro to be 1 if the target always uses extended unwind
+context with version, args_size and by_value fields.  If it is undefined,
+it will be defined to 1 when @code{REG_VALUE_IN_UNWIND_CONTEXT} is
+defined and 0 otherwise.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
index a7db6f58f851bad9cc8356540e805a7b803aac5e..9698c613f3506216b4f47c0808b7af5939a17cea 100644 (file)
@@ -802,7 +802,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
  #pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX         \
-       MD_UNWIND_SUPPORT MD_FROB_UPDATE_CONTEXT ENABLE_EXECUTE_STACK
+       MD_UNWIND_SUPPORT MD_FROB_UPDATE_CONTEXT ENABLE_EXECUTE_STACK   \
+       REG_VALUE_IN_UNWIND_CONTEXT ASSUME_EXTENDED_UNWIND_CONTEXT
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
index 79020025415bf18852b2a91f85eed9ea91021090..9148c9badc20e20560ce534ae362a5f5ff3a5e2e 100644 (file)
@@ -1,3 +1,8 @@
+2011-08-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR other/48007
+       * config/i386/value-unwind.h: New.
+
 2011-08-06  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * config.host (*-*-darwin*, *-*-freebsd*, *-*-linux*, frv-*-*linux*)
diff --git a/libgcc/config/i386/value-unwind.h b/libgcc/config/i386/value-unwind.h
new file mode 100644 (file)
index 0000000..0dceb5c
--- /dev/null
@@ -0,0 +1,26 @@
+/* Store register values as _Unwind_Word type in DWARF2 EH unwind context.
+   Copyright (C) 2011
+   Free Software Foundation, Inc.
+
+   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 3, 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 and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define this macro if the target stores register values as _Unwind_Word
+   type in unwind context.  Only enable it for x32.  */
+#if defined __x86_64 && !defined __LP64__
+# define REG_VALUE_IN_UNWIND_CONTEXT
+#endif
index 19da29982b69d47a22360cc9f0f5768c37b1503b..92aa233eb26538fbd86b7634469ac93d268217c6 100644 (file)
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
 #endif
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+typedef _Unwind_Word _Unwind_Context_Reg_Val;
+
+#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
+#define ASSUME_EXTENDED_UNWIND_CONTEXT 1
+#endif
+
+static inline _Unwind_Word
+_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
+{
+  return val;
+}
+
+static inline _Unwind_Context_Reg_Val
+_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
+{
+  return val;
+}
+#else
+typedef void *_Unwind_Context_Reg_Val;
+
+static inline _Unwind_Word
+_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
+{
+  return (_Unwind_Word) (_Unwind_Internal_Ptr) val;
+}
+
+static inline _Unwind_Context_Reg_Val
+_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
+{
+  return (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) val;
+}
+#endif
+
+#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
+#define ASSUME_EXTENDED_UNWIND_CONTEXT 0
+#endif
+
 /* This is the register and unwind state for a particular frame.  This
    provides the information necessary to unwind up past a frame and return
    to its caller.  */
 struct _Unwind_Context
 {
-  void *reg[DWARF_FRAME_REGISTERS+1];
+  _Unwind_Context_Reg_Val reg[DWARF_FRAME_REGISTERS+1];
   void *cfa;
   void *ra;
   void *lsda;
@@ -147,7 +185,8 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
 static inline _Unwind_Word
 _Unwind_IsExtendedContext (struct _Unwind_Context *context)
 {
-  return context->flags & EXTENDED_CONTEXT_BIT;
+  return (ASSUME_EXTENDED_UNWIND_CONTEXT
+         || (context->flags & EXTENDED_CONTEXT_BIT));
 }
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
@@ -156,7 +195,7 @@ inline _Unwind_Word
 _Unwind_GetGR (struct _Unwind_Context *context, int index)
 {
   int size;
-  void *ptr;
+  _Unwind_Context_Reg_Val val;
 
 #ifdef DWARF_ZERO_REG
   if (index == DWARF_ZERO_REG)
@@ -166,18 +205,18 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
   size = dwarf_reg_size_table[index];
-  ptr = context->reg[index];
+  val = context->reg[index];
 
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
-    return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
+    return _Unwind_Get_Unwind_Word (val);
 
   /* This will segfault if the register hasn't been saved.  */
   if (size == sizeof(_Unwind_Ptr))
-    return * (_Unwind_Ptr *) ptr;
+    return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
   else
     {
       gcc_assert (size == sizeof(_Unwind_Word));
-      return * (_Unwind_Word *) ptr;
+      return * (_Unwind_Word *) (_Unwind_Internal_Ptr) val;
     }
 }
 
@@ -209,11 +248,11 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
 
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     {
-      context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
+      context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
       return;
     }
 
-  ptr = context->reg[index];
+  ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
 
   if (size == sizeof(_Unwind_Ptr))
     * (_Unwind_Ptr *) ptr = val;
@@ -232,7 +271,7 @@ _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     return &context->reg[index];
-  return context->reg[index];
+  return (void *) (_Unwind_Internal_Ptr) context->reg[index];
 }
 
 /* Set the pointer to a register INDEX as saved in CONTEXT.  */
@@ -243,7 +282,7 @@ _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
   if (_Unwind_IsExtendedContext (context))
     context->by_value[index] = 0;
-  context->reg[index] = p;
+  context->reg[index] = (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) p;
 }
 
 /* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
@@ -254,10 +293,10 @@ _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
-  gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
+  gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Context_Reg_Val));
 
   context->by_value[index] = 1;
-  context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
+  context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
 }
 
 /* Return nonzero if register INDEX is stored by value rather than
@@ -1215,7 +1254,8 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
-  context.flags = EXTENDED_CONTEXT_BIT;
+  if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
+    context.flags = EXTENDED_CONTEXT_BIT;
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1453,7 +1493,8 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
-  context->flags = EXTENDED_CONTEXT_BIT;
+  if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
+    context->flags = EXTENDED_CONTEXT_BIT;
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1532,8 +1573,8 @@ uw_install_context_1 (struct _Unwind_Context *current,
 
   for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
     {
-      void *c = current->reg[i];
-      void *t = target->reg[i];
+      void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
+      void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
 
       gcc_assert (current->by_value[i] == 0);
       if (target->by_value[i] && c)