public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
@ 2011-06-25 17:02 H.J. Lu
  2011-06-25 23:34 ` Joseph S. Myers
  2011-06-26 20:06 ` Jason Merrill
  0 siblings, 2 replies; 34+ messages in thread
From: H.J. Lu @ 2011-06-25 17:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill, Richard Henderson

Hi,

This patch introduces UNIQUE_UNWIND_CONTEXT and properly saves/stores
registers with UNITS_PER_WORD > sizeof (void *) as suggested in

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01526.html

OK for trunk?

Thanks.

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

	PR other/48007
	* unwind-dw2.c (UNIQUE_UNWIND_CONTEXT): New.
	(_Unwind_Context): If UNIQUE_UNWIND_CONTEXT is defined, add
	dwarf_reg_size_table and value, remove version and by_value.
	(EXTENDED_CONTEXT_BIT): Don't define if UNIQUE_UNWIND_CONTEXT
	is defined.
	(_Unwind_IsExtendedContext): Likewise.
	(_Unwind_GetGR): Support UNIQUE_UNWIND_CONTEXT.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Initialize dwarf_reg_size_table field if
	UNIQUE_UNWIND_CONTEXT is defined.
	(uw_install_context_1): Likewise.  Support UNIQUE_UNWIND_CONTEXT.

diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 25990b4..5fa2723 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -59,6 +59,12 @@
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
 #endif
 
+#ifndef UNIQUE_UNWIND_CONTEXT
+#if defined __x86_64 && !defined __LP64__
+# define UNIQUE_UNWIND_CONTEXT
+#endif
+#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.  */
@@ -69,6 +75,15 @@ struct _Unwind_Context
   void *ra;
   void *lsda;
   struct dwarf_eh_bases bases;
+#ifdef UNIQUE_UNWIND_CONTEXT
+  /* Used to check for unique _Unwind_Context.  */
+  void *dwarf_reg_size_table;
+  /* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
+  _Unwind_Word flags;
+  _Unwind_Word args_size;
+  _Unwind_Word value[DWARF_FRAME_REGISTERS+1];
+#else
   /* Signal frame context.  */
 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
   /* Context which has version/args_size/by_value fields.  */
@@ -79,6 +94,7 @@ struct _Unwind_Context
   _Unwind_Word version;
   _Unwind_Word args_size;
   char by_value[DWARF_FRAME_REGISTERS+1];
+#endif
 };
 
 /* Byte size of every register managed by these routines.  */
@@ -144,11 +160,13 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
     context->flags &= ~SIGNAL_FRAME_BIT;
 }
 
+#ifndef UNIQUE_UNWIND_CONTEXT
 static inline _Unwind_Word
 _Unwind_IsExtendedContext (struct _Unwind_Context *context)
 {
   return context->flags & EXTENDED_CONTEXT_BIT;
 }
+#endif
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
@@ -168,8 +186,14 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
   size = dwarf_reg_size_table[index];
   ptr = context->reg[index];
 
+#ifdef UNIQUE_UNWIND_CONTEXT
+  gcc_assert (context->dwarf_reg_size_table == &dwarf_reg_size_table);
+  if (context->reg[index] == &context->value[index])
+    return context->value[index];
+#else
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
+#endif
 
   /* This will segfault if the register hasn't been saved.  */
   if (size == sizeof(_Unwind_Ptr))
@@ -207,11 +231,20 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
   size = dwarf_reg_size_table[index];
 
+#ifdef UNIQUE_UNWIND_CONTEXT
+  gcc_assert (context->dwarf_reg_size_table == &dwarf_reg_size_table);
+  if (context->reg[index] == &context->value[index])
+    {
+      context->value[index] = val;
+      return;
+    }
+#else
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     {
       context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
       return;
     }
+#endif
 
   ptr = context->reg[index];
 
@@ -230,8 +263,10 @@ static inline void *
 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifndef UNIQUE_UNWIND_CONTEXT
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     return &context->reg[index];
+#endif
   return context->reg[index];
 }
 
@@ -241,8 +276,10 @@ static inline void
 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifndef UNIQUE_UNWIND_CONTEXT
   if (_Unwind_IsExtendedContext (context))
     context->by_value[index] = 0;
+#endif
   context->reg[index] = p;
 }
 
@@ -254,10 +291,15 @@ _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
+#ifdef UNIQUE_UNWIND_CONTEXT
+  gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Word));
+  context->value[index] = val;
+  context->reg[index] = &context->value[index];
+#else
   gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
-
   context->by_value[index] = 1;
   context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
+#endif
 }
 
 /* Return nonzero if register INDEX is stored by value rather than
@@ -267,7 +309,11 @@ static inline int
 _Unwind_GRByValue (struct _Unwind_Context *context, int index)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifdef UNIQUE_UNWIND_CONTEXT
+  return context->reg[index] == &context->value[index];
+#else
   return context->by_value[index];
+#endif
 }
 
 /* Retrieve the return address for CONTEXT.  */
@@ -1217,7 +1263,11 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
+#ifdef UNIQUE_UNWIND_CONTEXT
+  context.dwarf_reg_size_table = &dwarf_reg_size_table;
+#else
   context.flags = EXTENDED_CONTEXT_BIT;
+#endif
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1455,7 +1505,11 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
+#ifdef UNIQUE_UNWIND_CONTEXT
+  context->dwarf_reg_size_table = &dwarf_reg_size_table;
+#else
   context->flags = EXTENDED_CONTEXT_BIT;
+#endif
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1537,8 +1591,13 @@ uw_install_context_1 (struct _Unwind_Context *current,
       void *c = current->reg[i];
       void *t = target->reg[i];
 
+#ifdef UNIQUE_UNWIND_CONTEXT
+      gcc_assert (current->reg[i] != &current->value[i]);
+      if (target->reg[i] == &target->value[i] && c)
+#else
       gcc_assert (current->by_value[i] == 0);
       if (target->by_value[i] && c)
+#endif
 	{
 	  _Unwind_Word w;
 	  _Unwind_Ptr p;

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-25 17:02 PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *) H.J. Lu
@ 2011-06-25 23:34 ` Joseph S. Myers
  2011-06-25 23:36   ` H.J. Lu
  2011-06-26 20:06 ` Jason Merrill
  1 sibling, 1 reply; 34+ messages in thread
From: Joseph S. Myers @ 2011-06-25 23:34 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches, Jason Merrill, Richard Henderson

On Sat, 25 Jun 2011, H.J. Lu wrote:

> +#ifndef UNIQUE_UNWIND_CONTEXT

The use of #ifndef seems to imply that this is a target macro, to be 
defined in libgcc_tm.h.  In that case it should be documented, and 
poisoned in system.h under the "only used for code built for the target" 
case, and this:

> +#if defined __x86_64 && !defined __LP64__

is inappropriate since you should instead put it in an appropriate header 
in libgcc/config/, rather than hardcoding an architecture-specific #if in 
an architecture-independent file.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-25 23:34 ` Joseph S. Myers
@ 2011-06-25 23:36   ` H.J. Lu
  0 siblings, 0 replies; 34+ messages in thread
From: H.J. Lu @ 2011-06-25 23:36 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches, Jason Merrill, Richard Henderson

[-- Attachment #1: Type: text/plain, Size: 1749 bytes --]

On Sat, Jun 25, 2011 at 1:19 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> On Sat, 25 Jun 2011, H.J. Lu wrote:
>
>> +#ifndef UNIQUE_UNWIND_CONTEXT
>
> The use of #ifndef seems to imply that this is a target macro, to be
> defined in libgcc_tm.h.  In that case it should be documented, and
> poisoned in system.h under the "only used for code built for the target"
> case, and this:
>
>> +#if defined __x86_64 && !defined __LP64__
>
> is inappropriate since you should instead put it in an appropriate header
> in libgcc/config/, rather than hardcoding an architecture-specific #if in
> an architecture-independent file.
>

Here is the updated patch.  OK for trunk?

Thanks.


-- 
H.J.
---
gcc/

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

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

	* system.h (UNIQUE_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context): If UNIQUE_UNWIND_CONTEXT is
	defined, add dwarf_reg_size_table and value, remove version and
	by_value.
	(EXTENDED_CONTEXT_BIT): Don't define if UNIQUE_UNWIND_CONTEXT
	is defined.
	(_Unwind_IsExtendedContext): Likewise.
	(_Unwind_GetGR): Support UNIQUE_UNWIND_CONTEXT.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Initialize dwarf_reg_size_table field if
	UNIQUE_UNWIND_CONTEXT is defined.
	(uw_install_context_1): Likewise.  Support UNIQUE_UNWIND_CONTEXT.

	* doc/tm.texi.in: Document UNIQUE_UNWIND_CONTEXT.
	* doc/tm.texi: Regenerated.

libgcc/

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

	* config/i386/unique-unwind.h: New file.

[-- Attachment #2: gcc-x32-pr48007-2.patch --]
[-- Type: text/plain, Size: 9596 bytes --]

gcc/

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

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

	* system.h (UNIQUE_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context): If UNIQUE_UNWIND_CONTEXT is
	defined, add dwarf_reg_size_table and value, remove version and
	by_value.
	(EXTENDED_CONTEXT_BIT): Don't define if UNIQUE_UNWIND_CONTEXT
	is defined.
	(_Unwind_IsExtendedContext): Likewise.
	(_Unwind_GetGR): Support UNIQUE_UNWIND_CONTEXT.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Initialize dwarf_reg_size_table field if
	UNIQUE_UNWIND_CONTEXT is defined.
	(uw_install_context_1): Likewise.  Support UNIQUE_UNWIND_CONTEXT.

	* doc/tm.texi.in: Document UNIQUE_UNWIND_CONTEXT.
	* doc/tm.texi: Regenerated.

libgcc/

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

	* config/i386/unique-unwind.h: New file.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index a1dbd1a..cdcabac 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2627,6 +2648,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/unique-unwind.h"
 	;;
 i[34567]86-*-* | x86_64-*-*)
 	tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 341628b..ad8543d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3701,6 +3701,13 @@ return @code{@var{regno}}.
 
 @end defmac
 
+@defmac UNIQUE_UNWIND_CONTEXT
+
+Define this macro if the target only supports single unqiue unwind
+context.  The default is to support multiple unwind contexts.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f7c16e9..9847014 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3687,6 +3687,13 @@ return @code{@var{regno}}.
 
 @end defmac
 
+@defmac UNIQUE_UNWIND_CONTEXT
+
+Define this macro if the target only supports single unqiue unwind
+context.  The default is to support multiple unwind contexts.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/system.h b/gcc/system.h
index e02cbcd..e9771af 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ 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 ENABLE_EXECUTE_STACK
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK UNIQUE_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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 19da299..ed6d15f 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -69,6 +69,15 @@ struct _Unwind_Context
   void *ra;
   void *lsda;
   struct dwarf_eh_bases bases;
+#ifdef UNIQUE_UNWIND_CONTEXT
+  /* Used to check for unique _Unwind_Context.  */
+  void *dwarf_reg_size_table;
+  /* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
+  _Unwind_Word flags;
+  _Unwind_Word args_size;
+  _Unwind_Word value[DWARF_FRAME_REGISTERS+1];
+#else
   /* Signal frame context.  */
 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
   /* Context which has version/args_size/by_value fields.  */
@@ -79,6 +88,7 @@ struct _Unwind_Context
   _Unwind_Word version;
   _Unwind_Word args_size;
   char by_value[DWARF_FRAME_REGISTERS+1];
+#endif
 };
 
 /* Byte size of every register managed by these routines.  */
@@ -144,11 +154,13 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
     context->flags &= ~SIGNAL_FRAME_BIT;
 }
 
+#ifndef UNIQUE_UNWIND_CONTEXT
 static inline _Unwind_Word
 _Unwind_IsExtendedContext (struct _Unwind_Context *context)
 {
   return context->flags & EXTENDED_CONTEXT_BIT;
 }
+#endif
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
@@ -168,8 +180,14 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
   size = dwarf_reg_size_table[index];
   ptr = context->reg[index];
 
+#ifdef UNIQUE_UNWIND_CONTEXT
+  gcc_assert (context->dwarf_reg_size_table == &dwarf_reg_size_table);
+  if (context->reg[index] == &context->value[index])
+    return context->value[index];
+#else
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
+#endif
 
   /* This will segfault if the register hasn't been saved.  */
   if (size == sizeof(_Unwind_Ptr))
@@ -207,11 +225,20 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
   size = dwarf_reg_size_table[index];
 
+#ifdef UNIQUE_UNWIND_CONTEXT
+  gcc_assert (context->dwarf_reg_size_table == &dwarf_reg_size_table);
+  if (context->reg[index] == &context->value[index])
+    {
+      context->value[index] = val;
+      return;
+    }
+#else
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     {
       context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
       return;
     }
+#endif
 
   ptr = context->reg[index];
 
@@ -230,8 +257,10 @@ static inline void *
 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifndef UNIQUE_UNWIND_CONTEXT
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     return &context->reg[index];
+#endif
   return context->reg[index];
 }
 
@@ -241,8 +270,10 @@ static inline void
 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifndef UNIQUE_UNWIND_CONTEXT
   if (_Unwind_IsExtendedContext (context))
     context->by_value[index] = 0;
+#endif
   context->reg[index] = p;
 }
 
@@ -254,10 +285,15 @@ _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
+#ifdef UNIQUE_UNWIND_CONTEXT
+  gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Word));
+  context->value[index] = val;
+  context->reg[index] = &context->value[index];
+#else
   gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
-
   context->by_value[index] = 1;
   context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
+#endif
 }
 
 /* Return nonzero if register INDEX is stored by value rather than
@@ -267,7 +303,11 @@ static inline int
 _Unwind_GRByValue (struct _Unwind_Context *context, int index)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifdef UNIQUE_UNWIND_CONTEXT
+  return context->reg[index] == &context->value[index];
+#else
   return context->by_value[index];
+#endif
 }
 
 /* Retrieve the return address for CONTEXT.  */
@@ -1215,7 +1255,11 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
+#ifdef UNIQUE_UNWIND_CONTEXT
+  context.dwarf_reg_size_table = &dwarf_reg_size_table;
+#else
   context.flags = EXTENDED_CONTEXT_BIT;
+#endif
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1453,7 +1497,11 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
+#ifdef UNIQUE_UNWIND_CONTEXT
+  context->dwarf_reg_size_table = &dwarf_reg_size_table;
+#else
   context->flags = EXTENDED_CONTEXT_BIT;
+#endif
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1535,8 +1583,13 @@ uw_install_context_1 (struct _Unwind_Context *current,
       void *c = current->reg[i];
       void *t = target->reg[i];
 
+#ifdef UNIQUE_UNWIND_CONTEXT
+      gcc_assert (current->reg[i] != &current->value[i]);
+      if (target->reg[i] == &target->value[i] && c)
+#else
       gcc_assert (current->by_value[i] == 0);
       if (target->by_value[i] && c)
+#endif
 	{
 	  _Unwind_Word w;
 	  _Unwind_Ptr p;
diff --git a/libgcc/config/i386/unique-unwind.h b/libgcc/config/i386/unique-unwind.h
new file mode 100644
index 0000000..7b11a9a
--- /dev/null
+++ b/libgcc/config/i386/unique-unwind.h
@@ -0,0 +1,26 @@
+/* Support DWARF2 EH unwind with single unqiue 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 only supports single unqiue unwind
+   context.  Only enable it for x32.  */
+#if defined __x86_64 && !defined __LP64__
+# define UNIQUE_UNWIND_CONTEXT
+#endif

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-25 17:02 PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *) H.J. Lu
  2011-06-25 23:34 ` Joseph S. Myers
@ 2011-06-26 20:06 ` Jason Merrill
  2011-06-26 20:22   ` Jason Merrill
  2011-06-26 21:45   ` H.J. Lu
  1 sibling, 2 replies; 34+ messages in thread
From: Jason Merrill @ 2011-06-26 20:06 UTC (permalink / raw)
  To: H.J. Lu; +Cc: H.J. Lu, gcc-patches, Richard Henderson

On 06/25/2011 12:13 PM, H.J. Lu wrote:
> This patch introduces UNIQUE_UNWIND_CONTEXT

Where is this documented?  The ABI document doesn't seem to say anything 
about it.

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-26 20:06 ` Jason Merrill
@ 2011-06-26 20:22   ` Jason Merrill
  2011-06-26 21:45   ` H.J. Lu
  1 sibling, 0 replies; 34+ messages in thread
From: Jason Merrill @ 2011-06-26 20:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: H.J. Lu, gcc-patches, Richard Henderson

On 06/25/2011 12:13 PM, H.J. Lu wrote:
> This patch introduces UNIQUE_UNWIND_CONTEXT

Where is this documented?  The ABI document doesn't seem to say anything 
about it.

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-26 20:06 ` Jason Merrill
  2011-06-26 20:22   ` Jason Merrill
@ 2011-06-26 21:45   ` H.J. Lu
  2011-06-27  2:12     ` Jason Merrill
  1 sibling, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-26 21:45 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Richard Henderson

On Sun, Jun 26, 2011 at 12:54 PM, Jason Merrill <jason@redhat.com> wrote:
> On 06/25/2011 12:13 PM, H.J. Lu wrote:
>>
>> This patch introduces UNIQUE_UNWIND_CONTEXT
>
> Where is this documented?  The ABI document doesn't seem to say anything
> about it.
>

I added a short paragraph in the updated patch:

http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01922.html

+@defmac UNIQUE_UNWIND_CONTEXT
+
+Define this macro if the target only supports single unqiue unwind
+context.  The default is to support multiple unwind contexts.
+
+@end defmac

This is the implementation detail and isn't required by the ABI.
With the unique unwind context, we can update the unwind
context format without breaking binary compatibility.

Thanks.


-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-26 21:45   ` H.J. Lu
@ 2011-06-27  2:12     ` Jason Merrill
  2011-06-27  3:17       ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Jason Merrill @ 2011-06-27  2:12 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches, Richard Henderson

On 06/26/2011 04:06 PM, H.J. Lu wrote:
> I added a short paragraph in the updated patch:
>
> +@defmac UNIQUE_UNWIND_CONTEXT
> +
> +Define this macro if the target only supports single unqiue unwind
> +context.  The default is to support multiple unwind contexts.

I saw that.  I don't know what it means.

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-27  2:12     ` Jason Merrill
@ 2011-06-27  3:17       ` H.J. Lu
  2011-06-27 15:16         ` Jason Merrill
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-27  3:17 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Richard Henderson

On Sun, Jun 26, 2011 at 2:45 PM, Jason Merrill <jason@redhat.com> wrote:
> On 06/26/2011 04:06 PM, H.J. Lu wrote:
>>
>> I added a short paragraph in the updated patch:
>>
>> +@defmac UNIQUE_UNWIND_CONTEXT
>> +
>> +Define this macro if the target only supports single unqiue unwind
>> +context.  The default is to support multiple unwind contexts.
>
> I saw that.  I don't know what it means.
>

The current unwind library scheme provides only one unwind
context and is backward compatible with multiple different unwind
contexts from multiple unwind libraries:

http://gcc.gnu.org/ml/gcc-patches/2006-12/msg01769.html

My patch fixes UNITS_PER_WORD > sizeof (void *) and
enforces single unwind context when backward compatibility
isn't needed.


-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-27  3:17       ` H.J. Lu
@ 2011-06-27 15:16         ` Jason Merrill
  2011-06-28 19:25           ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Jason Merrill @ 2011-06-27 15:16 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

On 06/26/2011 05:58 PM, H.J. Lu wrote:
> The current unwind library scheme provides only one unwind
> context and is backward compatible with multiple different unwind
> contexts from multiple unwind libraries:
>
> http://gcc.gnu.org/ml/gcc-patches/2006-12/msg01769.html
>
> My patch fixes UNITS_PER_WORD > sizeof (void *) and
> enforces single unwind context when backward compatibility
> isn't needed.

OK, there seem to be two things going on in this patch:

1) Handle registers larger than pointers.
2) Require that all code share a single copy of the unwinder.

For #2, how are you avoiding the issues Jakub describes in that message? 
  Isn't his scenario 2 still possible?  Are you deciding that it's 
better to abort at run-time in that case?

It seems to me that for targets newer than Jakub's patch we can 
hard-wire _Unwind_IsExtendedContext to true, but making further 
assumptions would be a mistake.

Then, if we're still trying to handle versioning, I think your earlier 
patch for #1 (r170716) that just changes the type of the reg array is a 
better way to go.  But that change should be dependent on a target macro 
to avoid ABI changes for existing targets.

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-27 15:16         ` Jason Merrill
@ 2011-06-28 19:25           ` H.J. Lu
  2011-06-30 14:46             ` Jason Merrill
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-28 19:25 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 2841 bytes --]

On Mon, Jun 27, 2011 at 7:58 AM, Jason Merrill <jason@redhat.com> wrote:
> On 06/26/2011 05:58 PM, H.J. Lu wrote:
>>
>> The current unwind library scheme provides only one unwind
>> context and is backward compatible with multiple different unwind
>> contexts from multiple unwind libraries:
>>
>> http://gcc.gnu.org/ml/gcc-patches/2006-12/msg01769.html
>>
>> My patch fixes UNITS_PER_WORD > sizeof (void *) and
>> enforces single unwind context when backward compatibility
>> isn't needed.
>
> OK, there seem to be two things going on in this patch:
>
> 1) Handle registers larger than pointers.
> 2) Require that all code share a single copy of the unwinder.
>
> For #2, how are you avoiding the issues Jakub describes in that message?
>  Isn't his scenario 2 still possible?  Are you deciding that it's better to
> abort at run-time in that case?
>
> It seems to me that for targets newer than Jakub's patch we can hard-wire
> _Unwind_IsExtendedContext to true, but making further assumptions would be a
> mistake.
>
> Then, if we're still trying to handle versioning, I think your earlier patch
> for #1 (r170716) that just changes the type of the reg array is a better way
> to go.  But that change should be dependent on a target macro to avoid ABI
> changes for existing targets.
>

This updated patch.  It allows multiple unwind contexts.  It replaces

char by_value[DWARF_FRAME_REGISTERS+1];

with

_Unwind_Word value[DWARF_FRAME_REGISTERS+1];

The code is cleaner than conditionally replacing

void *reg[DWARF_FRAME_REGISTERS+1];

with

_Unwind_Word reg[DWARF_FRAME_REGISTERS+1];

with a bigger unwind context.  But it is more flexible if we
want to extend unwind context later, like saving/restoring
128bit or vector registers which may be bigger than the current
_Unwind_Word.

Thanks.

-- 
H.J.
----
gcc/

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

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context): If REG_VALUE_IN_UNWIND_CONTEXT
	is defined, add value and remove by_value.
	(SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
	defined.
	(EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
	is defined.
	(_Unwind_IsExtendedContext): Likewise.
	(_Unwind_GetGR): Support REG_VALUE_IN_UNWIND_CONTEXT.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

libgcc/

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

	* config/i386/value-unwind.h: New.

[-- Attachment #2: gcc-x32-pr48007-3.patch --]
[-- Type: text/plain, Size: 9525 bytes --]

gcc/

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

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context): If REG_VALUE_IN_UNWIND_CONTEXT
	is defined, add value and remove by_value.
	(SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
	defined.
	(EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
	is defined.
	(_Unwind_IsExtendedContext): Likewise.
	(_Unwind_GetGR): Support REG_VALUE_IN_UNWIND_CONTEXT.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

libgcc/

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

	* config/i386/value-unwind.h: New.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index a1dbd1a..c9867a2 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2627,6 +2648,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"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 341628b..2666716 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3701,6 +3701,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f7c16e9..690fa52 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3687,6 +3687,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/system.h b/gcc/system.h
index e02cbcd..ed39d93 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ 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 ENABLE_EXECUTE_STACK
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK REG_VALUE_IN_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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 19da299..8014a1b 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -69,16 +69,25 @@ struct _Unwind_Context
   void *ra;
   void *lsda;
   struct dwarf_eh_bases bases;
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+  /* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
+#else
   /* Signal frame context.  */
 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
   /* Context which has version/args_size/by_value fields.  */
 #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
+#endif
   _Unwind_Word flags;
   /* 0 for now, can be increased when further fields are added to
      struct _Unwind_Context.  */
   _Unwind_Word version;
   _Unwind_Word args_size;
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+  _Unwind_Word value[DWARF_FRAME_REGISTERS+1];
+#else
   char by_value[DWARF_FRAME_REGISTERS+1];
+#endif
 };
 
 /* Byte size of every register managed by these routines.  */
@@ -144,11 +153,13 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
     context->flags &= ~SIGNAL_FRAME_BIT;
 }
 
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
 static inline _Unwind_Word
 _Unwind_IsExtendedContext (struct _Unwind_Context *context)
 {
   return context->flags & EXTENDED_CONTEXT_BIT;
 }
+#endif
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
@@ -168,8 +179,13 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
   size = dwarf_reg_size_table[index];
   ptr = context->reg[index];
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+  if (context->reg[index] == &context->value[index])
+    return context->value[index];
+#else
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
+#endif
 
   /* This will segfault if the register hasn't been saved.  */
   if (size == sizeof(_Unwind_Ptr))
@@ -207,11 +223,19 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
   size = dwarf_reg_size_table[index];
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+  if (context->reg[index] == &context->value[index])
+    {
+      context->value[index] = val;
+      return;
+    }
+#else
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     {
       context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
       return;
     }
+#endif
 
   ptr = context->reg[index];
 
@@ -230,8 +254,10 @@ static inline void *
 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
     return &context->reg[index];
+#endif
   return context->reg[index];
 }
 
@@ -241,8 +267,10 @@ static inline void
 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   if (_Unwind_IsExtendedContext (context))
     context->by_value[index] = 0;
+#endif
   context->reg[index] = p;
 }
 
@@ -254,10 +282,15 @@ _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+  gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Word));
+  context->value[index] = val;
+  context->reg[index] = &context->value[index];
+#else
   gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
-
   context->by_value[index] = 1;
   context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
+#endif
 }
 
 /* Return nonzero if register INDEX is stored by value rather than
@@ -267,7 +300,11 @@ static inline int
 _Unwind_GRByValue (struct _Unwind_Context *context, int index)
 {
   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+  return context->reg[index] == &context->value[index];
+#else
   return context->by_value[index];
+#endif
 }
 
 /* Retrieve the return address for CONTEXT.  */
@@ -1215,7 +1252,9 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context.flags = EXTENDED_CONTEXT_BIT;
+#endif
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1453,7 +1492,9 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context->flags = EXTENDED_CONTEXT_BIT;
+#endif
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1535,8 +1576,13 @@ uw_install_context_1 (struct _Unwind_Context *current,
       void *c = current->reg[i];
       void *t = target->reg[i];
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+      gcc_assert (current->reg[i] != &current->value[i]);
+      if (target->reg[i] == &target->value[i] && c)
+#else
       gcc_assert (current->by_value[i] == 0);
       if (target->by_value[i] && c)
+#endif
 	{
 	  _Unwind_Word w;
 	  _Unwind_Ptr p;
diff --git a/libgcc/config/i386/value-unwind.h b/libgcc/config/i386/value-unwind.h
new file mode 100644
index 0000000..0dceb5c
--- /dev/null
+++ b/libgcc/config/i386/value-unwind.h
@@ -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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-28 19:25           ` H.J. Lu
@ 2011-06-30 14:46             ` Jason Merrill
  2011-06-30 14:53               ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Jason Merrill @ 2011-06-30 14:46 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

On 06/28/2011 02:53 PM, H.J. Lu wrote:
> This updated patch.  It allows multiple unwind contexts.  It replaces
>
> char by_value[DWARF_FRAME_REGISTERS+1];
>
> with
>
> _Unwind_Word value[DWARF_FRAME_REGISTERS+1];
>
> The code is cleaner than conditionally replacing
>
> void *reg[DWARF_FRAME_REGISTERS+1];
>
> with
>
> _Unwind_Word reg[DWARF_FRAME_REGISTERS+1];
>
> with a bigger unwind context.

It doesn't seem cleaner to me.

> But it is more flexible if we
> want to extend unwind context later, like saving/restoring
> 128bit or vector registers which may be bigger than the current
> _Unwind_Word.

I don't see that, either; with either approach, supporting larger 
registers would require a change to the the unwind context.

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 14:46             ` Jason Merrill
@ 2011-06-30 14:53               ` H.J. Lu
  2011-06-30 15:26                 ` Jason Merrill
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 14:53 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

On Thu, Jun 30, 2011 at 7:08 AM, Jason Merrill <jason@redhat.com> wrote:
> On 06/28/2011 02:53 PM, H.J. Lu wrote:
>>
>> This updated patch.  It allows multiple unwind contexts.  It replaces
>>
>> char by_value[DWARF_FRAME_REGISTERS+1];
>>
>> with
>>
>> _Unwind_Word value[DWARF_FRAME_REGISTERS+1];
>>
>> The code is cleaner than conditionally replacing
>>
>> void *reg[DWARF_FRAME_REGISTERS+1];
>>
>> with
>>
>> _Unwind_Word reg[DWARF_FRAME_REGISTERS+1];
>>
>> with a bigger unwind context.
>
> It doesn't seem cleaner to me.

Register may be saved/restored either by address or value. My patch
doesn't change the reg field.  The other way will be

#ifdef USE_UNWIND_WORD
    _Unwind_Word reg[DWARF_FRAME_REGISTERS+1];
#else
     void *reg[DWARF_FRAME_REGISTERS+1];
#endif

We need it so that we are binary compatible with the existing
unwind context.  Once we do that we need many

#ifdef USE_UNWIND_WORD
#endif

whenever the reg field is accessed since the reg field is changed.

-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 14:53               ` H.J. Lu
@ 2011-06-30 15:26                 ` Jason Merrill
  2011-06-30 16:36                   ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Jason Merrill @ 2011-06-30 15:26 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

On 06/30/2011 10:42 AM, H.J. Lu wrote:
> Register may be saved/restored either by address or value. My patch
> doesn't change the reg field.  The other way will be
>
> #ifdef USE_UNWIND_WORD
>      _Unwind_Word reg[DWARF_FRAME_REGISTERS+1];
> #else
>       void *reg[DWARF_FRAME_REGISTERS+1];
> #endif
>
> We need it so that we are binary compatible with the existing
> unwind context.  Once we do that we need many
>
> #ifdef USE_UNWIND_WORD
> #endif
>
> whenever the reg field is accessed since the reg field is changed.

But your patch already changes all but one place where reg is accessed. 
  And we can avoid lots of ifdefs by abstraction with macros/inlines so 
there's one interface.

Also, why change SIGNAL_FRAME_BIT?

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 15:26                 ` Jason Merrill
@ 2011-06-30 16:36                   ` H.J. Lu
  2011-06-30 17:57                     ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 16:36 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

On Thu, Jun 30, 2011 at 8:03 AM, Jason Merrill <jason@redhat.com> wrote:
> On 06/30/2011 10:42 AM, H.J. Lu wrote:
>>
>> Register may be saved/restored either by address or value. My patch
>> doesn't change the reg field.  The other way will be
>>
>> #ifdef USE_UNWIND_WORD
>>     _Unwind_Word reg[DWARF_FRAME_REGISTERS+1];
>> #else
>>      void *reg[DWARF_FRAME_REGISTERS+1];
>> #endif
>>
>> We need it so that we are binary compatible with the existing
>> unwind context.  Once we do that we need many
>>
>> #ifdef USE_UNWIND_WORD
>> #endif
>>
>> whenever the reg field is accessed since the reg field is changed.
>
> But your patch already changes all but one place where reg is accessed.  And
> we can avoid lots of ifdefs by abstraction with macros/inlines so there's
> one interface.

I can do that.

> Also, why change SIGNAL_FRAME_BIT?
>

The current one is

  /* Signal frame context.  */
#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)

It is defined such a strange way to be binary backward compatible.
Since there is no such a problem with if REG_VALUE_IN_UNWIND_CONTEXT
is defined, I simply define it as

  /* Signal frame context.  */
#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 16:36                   ` H.J. Lu
@ 2011-06-30 17:57                     ` H.J. Lu
  2011-06-30 18:01                       ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 17:57 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 2504 bytes --]

On Thu, Jun 30, 2011 at 9:08 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Jun 30, 2011 at 8:03 AM, Jason Merrill <jason@redhat.com> wrote:
>> On 06/30/2011 10:42 AM, H.J. Lu wrote:
>>>
>>> Register may be saved/restored either by address or value. My patch
>>> doesn't change the reg field.  The other way will be
>>>
>>> #ifdef USE_UNWIND_WORD
>>>     _Unwind_Word reg[DWARF_FRAME_REGISTERS+1];
>>> #else
>>>      void *reg[DWARF_FRAME_REGISTERS+1];
>>> #endif
>>>
>>> We need it so that we are binary compatible with the existing
>>> unwind context.  Once we do that we need many
>>>
>>> #ifdef USE_UNWIND_WORD
>>> #endif
>>>
>>> whenever the reg field is accessed since the reg field is changed.
>>
>> But your patch already changes all but one place where reg is accessed.  And
>> we can avoid lots of ifdefs by abstraction with macros/inlines so there's
>> one interface.
>
> I can do that.
>
>> Also, why change SIGNAL_FRAME_BIT?
>>
>
> The current one is
>
>  /* Signal frame context.  */
> #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
>
> It is defined such a strange way to be binary backward compatible.
> Since there is no such a problem with if REG_VALUE_IN_UNWIND_CONTEXT
> is defined, I simply define it as
>
>  /* Signal frame context.  */
> #define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
>

Here is the updated patch.  OK for trunk if there are no regressions?

Thanks.

-- 
H.J.
---
gcc/

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

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context_Reg_Val): New.
	(_Unwind_Get_Unwind_Word): Likewise.
	(_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
	(_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
	(SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
	defined.
	(_Unwind_IsExtendedContext): Likewise.
	(EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
	is defined.
	(_Unwind_GetGR): Updated.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

libgcc/

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

	* config/i386/value-unwind.h: New.

[-- Attachment #2: gcc-x32-pr48007-4.patch --]
[-- Type: text/plain, Size: 11120 bytes --]

gcc/

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

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context_Reg_Val): New.
	(_Unwind_Get_Unwind_Word): Likewise.
	(_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
	(_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
	(SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
	defined.
	(_Unwind_IsExtendedContext): Likewise.
	(EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
	is defined.
	(_Unwind_GetGR): Updated.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

libgcc/

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

	* config/i386/value-unwind.h: New.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 73c47d7..2702df2 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1277,7 +1277,17 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/gnu-user64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64"
+			case x${enable_x32}${enable_ia32} in
+			xyesyes)
+				tmake_file="${tmake_file} i386/t-linux-x32"
+				;;
+			xyesno)
+				tmake_file="${tmake_file} i386/t-linux64-x32"
+				;;
+			*)
+				tmake_file="${tmake_file} i386/t-linux64"
+				;;
+			esac
 			need_64bit_hwint=yes
 			need_64bit_isa=yes
 			case X"${with_cpu}" in
@@ -1315,7 +1325,18 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h i386/kfreebsd-gnu64.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
+	case x${enable_x32}${enable_ia32} in
+	xyesyes)
+		tmake_file="${tmake_file} i386/t-linux-x32"
+		;;
+	xyesno)
+		tmake_file="${tmake_file} i386/t-linux64-x32"
+		;;
+	*)
+		tmake_file="${tmake_file} i386/t-linux64"
+		;;
+	esac
+	tmake_file="${tmake_file} i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-pc-msdosdjgpp*)
 	xm_file=i386/xm-djgpp.h
@@ -2630,6 +2651,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"
diff --git a/gcc/system.h b/gcc/system.h
index e02cbcd..ed39d93 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ 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 ENABLE_EXECUTE_STACK
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK REG_VALUE_IN_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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 19da299..c77265c 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -59,20 +59,56 @@
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
 #endif
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+typedef _Unwind_Word _Unwind_Context_Reg_Val;
+/* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
+
+#define _Unwind_IsExtendedContext(c) 1
+
+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;
+/* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
+/* Context which has version/args_size/by_value fields.  */
+#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
+
+#define _Unwind_IsExtendedContext(c) ((c)->flags & EXTENDED_CONTEXT_BIT)
+
+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
+
 /* 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;
   struct dwarf_eh_bases bases;
-  /* Signal frame context.  */
-#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
-  /* Context which has version/args_size/by_value fields.  */
-#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
   _Unwind_Word flags;
   /* 0 for now, can be increased when further fields are added to
      struct _Unwind_Context.  */
@@ -143,12 +179,6 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
   else
     context->flags &= ~SIGNAL_FRAME_BIT;
 }
-
-static inline _Unwind_Word
-_Unwind_IsExtendedContext (struct _Unwind_Context *context)
-{
-  return context->flags & EXTENDED_CONTEXT_BIT;
-}
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
@@ -156,7 +186,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 +196,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 +239,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 +262,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 +273,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 +284,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 +1245,9 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context.flags = EXTENDED_CONTEXT_BIT;
+#endif
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1453,7 +1485,9 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context->flags = EXTENDED_CONTEXT_BIT;
+#endif
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1532,8 +1566,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)
diff --git a/libgcc/config/i386/value-unwind.h b/libgcc/config/i386/value-unwind.h
new file mode 100644
index 0000000..0dceb5c
--- /dev/null
+++ b/libgcc/config/i386/value-unwind.h
@@ -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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 17:57                     ` H.J. Lu
@ 2011-06-30 18:01                       ` H.J. Lu
  2011-06-30 18:10                         ` Rainer Orth
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 18:01 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Richard Henderson, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 2955 bytes --]

On Thu, Jun 30, 2011 at 10:37 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Jun 30, 2011 at 9:08 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Thu, Jun 30, 2011 at 8:03 AM, Jason Merrill <jason@redhat.com> wrote:
>>> On 06/30/2011 10:42 AM, H.J. Lu wrote:
>>>>
>>>> Register may be saved/restored either by address or value. My patch
>>>> doesn't change the reg field.  The other way will be
>>>>
>>>> #ifdef USE_UNWIND_WORD
>>>>     _Unwind_Word reg[DWARF_FRAME_REGISTERS+1];
>>>> #else
>>>>      void *reg[DWARF_FRAME_REGISTERS+1];
>>>> #endif
>>>>
>>>> We need it so that we are binary compatible with the existing
>>>> unwind context.  Once we do that we need many
>>>>
>>>> #ifdef USE_UNWIND_WORD
>>>> #endif
>>>>
>>>> whenever the reg field is accessed since the reg field is changed.
>>>
>>> But your patch already changes all but one place where reg is accessed.  And
>>> we can avoid lots of ifdefs by abstraction with macros/inlines so there's
>>> one interface.
>>
>> I can do that.
>>
>>> Also, why change SIGNAL_FRAME_BIT?
>>>
>>
>> The current one is
>>
>>  /* Signal frame context.  */
>> #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
>>
>> It is defined such a strange way to be binary backward compatible.
>> Since there is no such a problem with if REG_VALUE_IN_UNWIND_CONTEXT
>> is defined, I simply define it as
>>
>>  /* Signal frame context.  */
>> #define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
>>
>
> Here is the updated patch.  OK for trunk if there are no regressions?
>
> Thanks.
>
> --
> H.J.
> ---
> gcc/
>
> 2011-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>
>        * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for
>        Linux/x86.
>
>        * system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.
>
>        * unwind-dw2.c (_Unwind_Context_Reg_Val): New.
>        (_Unwind_Get_Unwind_Word): Likewise.
>        (_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
>        (_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
>        (SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
>        defined.
>        (_Unwind_IsExtendedContext): Likewise.
>        (EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
>        is defined.
>        (_Unwind_GetGR): Updated.
>        (_Unwind_SetGR): Likewise.
>        (_Unwind_GetGRPtr): Likewise.
>        (_Unwind_SetGRPtr): Likewise.
>        (_Unwind_SetGRValue): Likewise.
>        (_Unwind_GRByValue): Likewise.
>        (__frame_state_for): Likewise.
>        (uw_install_context_1): Likewise.
>
>        * doc/tm.texi.in: Document REG_VALUE_IN_UNWIND_CONTEXT.
>        * doc/tm.texi: Regenerated.
>
> libgcc/
>
> 2011-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>
>        * config/i386/value-unwind.h: New.
>

config.gcc has some extra changes for x32 and missed doc changes.
This one fixed them.  Sorry for that.

-- 
H.J.

[-- Attachment #2: gcc-x32-pr48007-4.patch --]
[-- Type: text/plain, Size: 10756 bytes --]

gcc/

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

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context_Reg_Val): New.
	(_Unwind_Get_Unwind_Word): Likewise.
	(_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
	(_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
	(SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
	defined.
	(_Unwind_IsExtendedContext): Likewise.
	(EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
	is defined.
	(_Unwind_GetGR): Updated.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

libgcc/

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

	* config/i386/value-unwind.h: New.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 73c47d7..2702df2 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2630,6 +2651,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"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 341628b..2666716 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3701,6 +3701,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f7c16e9..690fa52 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3687,6 +3687,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/system.h b/gcc/system.h
index e02cbcd..ed39d93 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ 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 ENABLE_EXECUTE_STACK
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK REG_VALUE_IN_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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 19da299..c77265c 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -59,20 +59,56 @@
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
 #endif
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+typedef _Unwind_Word _Unwind_Context_Reg_Val;
+/* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
+
+#define _Unwind_IsExtendedContext(c) 1
+
+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;
+/* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
+/* Context which has version/args_size/by_value fields.  */
+#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
+
+#define _Unwind_IsExtendedContext(c) ((c)->flags & EXTENDED_CONTEXT_BIT)
+
+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
+
 /* 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;
   struct dwarf_eh_bases bases;
-  /* Signal frame context.  */
-#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
-  /* Context which has version/args_size/by_value fields.  */
-#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
   _Unwind_Word flags;
   /* 0 for now, can be increased when further fields are added to
      struct _Unwind_Context.  */
@@ -143,12 +179,6 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
   else
     context->flags &= ~SIGNAL_FRAME_BIT;
 }
-
-static inline _Unwind_Word
-_Unwind_IsExtendedContext (struct _Unwind_Context *context)
-{
-  return context->flags & EXTENDED_CONTEXT_BIT;
-}
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
@@ -156,7 +186,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 +196,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 +239,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 +262,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 +273,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 +284,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 +1245,9 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context.flags = EXTENDED_CONTEXT_BIT;
+#endif
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1453,7 +1485,9 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context->flags = EXTENDED_CONTEXT_BIT;
+#endif
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1532,8 +1566,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)
diff --git a/libgcc/config/i386/value-unwind.h b/libgcc/config/i386/value-unwind.h
new file mode 100644
index 0000000..0dceb5c
--- /dev/null
+++ b/libgcc/config/i386/value-unwind.h
@@ -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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 18:01                       ` H.J. Lu
@ 2011-06-30 18:10                         ` Rainer Orth
  2011-06-30 18:19                           ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Rainer Orth @ 2011-06-30 18:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jason Merrill, gcc-patches, Richard Henderson, Jakub Jelinek

"H.J. Lu" <hjl.tools@gmail.com> writes:

>> gcc/
>>
>> 2011-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>        * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for
>>        Linux/x86.
>>
>>        * system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.
>>
>>        * unwind-dw2.c (_Unwind_Context_Reg_Val): New.
>>        (_Unwind_Get_Unwind_Word): Likewise.
>>        (_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
>>        (_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
>>        (SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
>>        defined.
>>        (_Unwind_IsExtendedContext): Likewise.
>>        (EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
>>        is defined.
>>        (_Unwind_GetGR): Updated.
>>        (_Unwind_SetGR): Likewise.
>>        (_Unwind_GetGRPtr): Likewise.
>>        (_Unwind_SetGRPtr): Likewise.
>>        (_Unwind_SetGRValue): Likewise.
>>        (_Unwind_GRByValue): Likewise.
>>        (__frame_state_for): Likewise.
>>        (uw_install_context_1): Likewise.
>>
>>        * doc/tm.texi.in: Document REG_VALUE_IN_UNWIND_CONTEXT.
>>        * doc/tm.texi: Regenerated.
>>
>> libgcc/
>>
>> 2011-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>        * config/i386/value-unwind.h: New.

Why all those contortions with i386/value-unwind.h?  It seems far
simpler to me to put this into libgcc/config/i386/linux-unwind.h and be
done with it.

The unwinder are on their way to libgcc, and I don't want to keep some
gcc-side configuration behind.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 18:10                         ` Rainer Orth
@ 2011-06-30 18:19                           ` H.J. Lu
  2011-06-30 18:42                             ` Rainer Orth
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 18:19 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Jason Merrill, gcc-patches, Richard Henderson, Jakub Jelinek

On Thu, Jun 30, 2011 at 11:03 AM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>>> gcc/
>>>
>>> 2011-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>        * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for
>>>        Linux/x86.
>>>
>>>        * system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.
>>>
>>>        * unwind-dw2.c (_Unwind_Context_Reg_Val): New.
>>>        (_Unwind_Get_Unwind_Word): Likewise.
>>>        (_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
>>>        (_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
>>>        (SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
>>>        defined.
>>>        (_Unwind_IsExtendedContext): Likewise.
>>>        (EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
>>>        is defined.
>>>        (_Unwind_GetGR): Updated.
>>>        (_Unwind_SetGR): Likewise.
>>>        (_Unwind_GetGRPtr): Likewise.
>>>        (_Unwind_SetGRPtr): Likewise.
>>>        (_Unwind_SetGRValue): Likewise.
>>>        (_Unwind_GRByValue): Likewise.
>>>        (__frame_state_for): Likewise.
>>>        (uw_install_context_1): Likewise.
>>>
>>>        * doc/tm.texi.in: Document REG_VALUE_IN_UNWIND_CONTEXT.
>>>        * doc/tm.texi: Regenerated.
>>>
>>> libgcc/
>>>
>>> 2011-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>        * config/i386/value-unwind.h: New.
>
> Why all those contortions with i386/value-unwind.h?  It seems far
> simpler to me to put this into libgcc/config/i386/linux-unwind.h and be
> done with it.
>

I did it this way so that other non-Linux x32 targets can use it.

-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 18:19                           ` H.J. Lu
@ 2011-06-30 18:42                             ` Rainer Orth
  2011-06-30 20:14                               ` H.J. Lu
  2011-06-30 20:59                               ` H.J. Lu
  0 siblings, 2 replies; 34+ messages in thread
From: Rainer Orth @ 2011-06-30 18:42 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jason Merrill, gcc-patches, Richard Henderson, Jakub Jelinek

"H.J. Lu" <hjl.tools@gmail.com> writes:

>> Why all those contortions with i386/value-unwind.h?  It seems far
>> simpler to me to put this into libgcc/config/i386/linux-unwind.h and be
>> done with it.
>
> I did it this way so that other non-Linux x32 targets can use it.

Such as?  Currently, only Linux, Windows and Solaris have i386/*-unwind.h
implementations.  I'm pretty sure the latter two are highly unlikely to
develop an x32 port, so let's cross that bridge when we get there.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 18:42                             ` Rainer Orth
@ 2011-06-30 20:14                               ` H.J. Lu
  2011-06-30 20:24                                 ` Richard Henderson
  2011-06-30 20:59                               ` H.J. Lu
  1 sibling, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 20:14 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Jason Merrill, gcc-patches, Richard Henderson, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 1563 bytes --]

On Thu, Jun 30, 2011 at 11:09 AM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>>> Why all those contortions with i386/value-unwind.h?  It seems far
>>> simpler to me to put this into libgcc/config/i386/linux-unwind.h and be
>>> done with it.
>>
>> I did it this way so that other non-Linux x32 targets can use it.
>
> Such as?  Currently, only Linux, Windows and Solaris have i386/*-unwind.h
> implementations.  I'm pretty sure the latter two are highly unlikely to
> develop an x32 port, so let's cross that bridge when we get there.
>

Here is the updated patch without config/i386/value-unwind.h.
OK for trunk?

Thanks.

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context_Reg_Val): New.
	(_Unwind_Get_Unwind_Word): Likewise.
	(_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
	(_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
	(SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
	defined.
	(_Unwind_IsExtendedContext): Likewise.
	(EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
	is defined.
	(_Unwind_GetGR): Updated.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

[-- Attachment #2: gcc-x32-pr48007-5.patch --]
[-- Type: text/plain, Size: 8846 bytes --]

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context_Reg_Val): New.
	(_Unwind_Get_Unwind_Word): Likewise.
	(_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
	(_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
	(SIGNAL_FRAME_BIT): Define if REG_VALUE_IN_UNWIND_CONTEXT is
	defined.
	(_Unwind_IsExtendedContext): Likewise.
	(EXTENDED_CONTEXT_BIT): Don't define if REG_VALUE_IN_UNWIND_CONTEXT
	is defined.
	(_Unwind_GetGR): Updated.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 341628b..2666716 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3701,6 +3701,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f7c16e9..690fa52 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3687,6 +3687,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/system.h b/gcc/system.h
index e02cbcd..ed39d93 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ 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 ENABLE_EXECUTE_STACK
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK REG_VALUE_IN_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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 19da299..c77265c 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -59,20 +59,56 @@
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
 #endif
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+typedef _Unwind_Word _Unwind_Context_Reg_Val;
+/* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
+
+#define _Unwind_IsExtendedContext(c) 1
+
+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;
+/* Signal frame context.  */
+#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
+/* Context which has version/args_size/by_value fields.  */
+#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
+
+#define _Unwind_IsExtendedContext(c) ((c)->flags & EXTENDED_CONTEXT_BIT)
+
+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
+
 /* 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;
   struct dwarf_eh_bases bases;
-  /* Signal frame context.  */
-#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
-  /* Context which has version/args_size/by_value fields.  */
-#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
   _Unwind_Word flags;
   /* 0 for now, can be increased when further fields are added to
      struct _Unwind_Context.  */
@@ -143,12 +179,6 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
   else
     context->flags &= ~SIGNAL_FRAME_BIT;
 }
-
-static inline _Unwind_Word
-_Unwind_IsExtendedContext (struct _Unwind_Context *context)
-{
-  return context->flags & EXTENDED_CONTEXT_BIT;
-}
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
@@ -156,7 +186,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 +196,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 +239,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 +262,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 +273,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 +284,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 +1245,9 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context.flags = EXTENDED_CONTEXT_BIT;
+#endif
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1453,7 +1485,9 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context->flags = EXTENDED_CONTEXT_BIT;
+#endif
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1532,8 +1566,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)

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 20:14                               ` H.J. Lu
@ 2011-06-30 20:24                                 ` Richard Henderson
  2011-06-30 21:51                                   ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Richard Henderson @ 2011-06-30 20:24 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Rainer Orth, Jason Merrill, gcc-patches, Jakub Jelinek

On 06/30/2011 11:23 AM, H.J. Lu wrote:
> +#ifdef REG_VALUE_IN_UNWIND_CONTEXT
> +typedef _Unwind_Word _Unwind_Context_Reg_Val;
> +/* Signal frame context.  */
> +#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)

There's absolutely no reason to re-define this.
So what if the value is most-significant-bit set?

Nor do I see any reason not to continue setting E_C_B.

> +#define _Unwind_IsExtendedContext(c) 1

Why is this not still an inline function?

> +
> +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;
> +}

I cannot believe this actually works.  I see nowhere that 
you copy the by-address slot out of the stack frame and
place it into the by-value slot in the unwind context.

>    /* 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;
>      }

Indeed, this section is both wrong and belies the change
you purport to make.

You didn't even test this, did you?


r~

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 18:42                             ` Rainer Orth
  2011-06-30 20:14                               ` H.J. Lu
@ 2011-06-30 20:59                               ` H.J. Lu
  1 sibling, 0 replies; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 20:59 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Jason Merrill, gcc-patches, Richard Henderson, Jakub Jelinek

On Thu, Jun 30, 2011 at 11:09 AM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>>> Why all those contortions with i386/value-unwind.h?  It seems far
>>> simpler to me to put this into libgcc/config/i386/linux-unwind.h and be
>>> done with it.
>>
>> I did it this way so that other non-Linux x32 targets can use it.
>
> Such as?  Currently, only Linux, Windows and Solaris have i386/*-unwind.h
> implementations.  I'm pretty sure the latter two are highly unlikely to
> develop an x32 port, so let's cross that bridge when we get there.
>

It doesn't work since md-unwind-support.h was included much too late.

-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 20:24                                 ` Richard Henderson
@ 2011-06-30 21:51                                   ` H.J. Lu
  2011-07-01  9:03                                     ` Rainer Orth
  2011-08-02 21:02                                     ` Jason Merrill
  0 siblings, 2 replies; 34+ messages in thread
From: H.J. Lu @ 2011-06-30 21:51 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Rainer Orth, Jason Merrill, gcc-patches, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 2968 bytes --]

On Thu, Jun 30, 2011 at 12:02 PM, Richard Henderson <rth@redhat.com> wrote:
> On 06/30/2011 11:23 AM, H.J. Lu wrote:
>> +#ifdef REG_VALUE_IN_UNWIND_CONTEXT
>> +typedef _Unwind_Word _Unwind_Context_Reg_Val;
>> +/* Signal frame context.  */
>> +#define SIGNAL_FRAME_BIT ((_Unwind_Word) 1 >> 0)
>
> There's absolutely no reason to re-define this.
> So what if the value is most-significant-bit set?
>
> Nor do I see any reason not to continue setting E_C_B.

Done.

>> +#define _Unwind_IsExtendedContext(c) 1
>
> Why is this not still an inline function?

It is defined before _Unwind_Context is declared.  I used
macros so that there can be one less "#ifdef".

>> +
>> +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;
>> +}
>
> I cannot believe this actually works.  I see nowhere that
> you copy the by-address slot out of the stack frame and
> place it into the by-value slot in the unwind context.

I changed the implantation based on the feedback from
Jason.  Now I use the same reg field for both value and
address.

>>    /* 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;
>>      }
>
> Indeed, this section is both wrong and belies the change
> you purport to make.
>
> You didn't even test this, did you?
>

Here is the updated patch.  It works on simple tests.
I am running full tests.  I kept config/i386/value-unwind.h
since libgcc/md-unwind-support.h is included too late
in unwind-dw2.c and I don't want to move it to be on
the safe side.

OK for trunk?

Thanks.

-- 
H.J.
---
gcc/

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

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context_Reg_Val): New.
	(_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): Defined as macro.
	(_Unwind_GetGR): Updated.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

libgcc/

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

	* config/i386/value-unwind.h: New.

[-- Attachment #2: gcc-x32-pr48007-6.patch --]
[-- Type: text/plain, Size: 9952 bytes --]

gcc/

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

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

	* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.

	* unwind-dw2.c (_Unwind_Context_Reg_Val): New.
	(_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): Defined as macro.
	(_Unwind_GetGR): Updated.
	(_Unwind_SetGR): Likewise.
	(_Unwind_GetGRPtr): Likewise.
	(_Unwind_SetGRPtr): Likewise.
	(_Unwind_SetGRValue): Likewise.
	(_Unwind_GRByValue): Likewise.
	(__frame_state_for): Likewise.
	(uw_install_context_1): Likewise.

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

libgcc/

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

	* config/i386/value-unwind.h: New.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 73c47d7..2702df2 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2630,6 +2651,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"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 341628b..2666716 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3701,6 +3701,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f7c16e9..690fa52 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3687,6 +3687,14 @@ 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.  The default is to
+store register values as @code{void *} type.
+
+@end defmac
+
 @node Elimination
 @subsection Eliminating Frame Pointer and Arg Pointer
 
diff --git a/gcc/system.h b/gcc/system.h
index e02cbcd..ed39d93 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ 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 ENABLE_EXECUTE_STACK
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK REG_VALUE_IN_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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 19da299..2114b8b 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -59,12 +59,46 @@
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
 #endif
 
+#ifdef REG_VALUE_IN_UNWIND_CONTEXT
+typedef _Unwind_Word _Unwind_Context_Reg_Val;
+
+#define _Unwind_IsExtendedContext(c) 1
+
+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;
+
+#define _Unwind_IsExtendedContext(c) ((c)->flags & EXTENDED_CONTEXT_BIT)
+
+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
+
 /* 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;
@@ -143,12 +177,6 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
   else
     context->flags &= ~SIGNAL_FRAME_BIT;
 }
-
-static inline _Unwind_Word
-_Unwind_IsExtendedContext (struct _Unwind_Context *context)
-{
-  return context->flags & EXTENDED_CONTEXT_BIT;
-}
 \f
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
@@ -156,7 +184,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 +194,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 +237,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 +260,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 +271,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 +282,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 +1243,9 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   int reg;
 
   memset (&context, 0, sizeof (struct _Unwind_Context));
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context.flags = EXTENDED_CONTEXT_BIT;
+#endif
   context.ra = pc_target + 1;
 
   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
@@ -1453,7 +1483,9 @@ uw_init_context_1 (struct _Unwind_Context *context,
 
   memset (context, 0, sizeof (struct _Unwind_Context));
   context->ra = ra;
+#ifndef REG_VALUE_IN_UNWIND_CONTEXT
   context->flags = EXTENDED_CONTEXT_BIT;
+#endif
 
   code = uw_frame_state_for (context, &fs);
   gcc_assert (code == _URC_NO_REASON);
@@ -1532,8 +1564,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)
diff --git a/libgcc/config/i386/value-unwind.h b/libgcc/config/i386/value-unwind.h
new file mode 100644
index 0000000..0dceb5c
--- /dev/null
+++ b/libgcc/config/i386/value-unwind.h
@@ -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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 21:51                                   ` H.J. Lu
@ 2011-07-01  9:03                                     ` Rainer Orth
  2011-07-01 12:51                                       ` H.J. Lu
  2011-08-02 21:02                                     ` Jason Merrill
  1 sibling, 1 reply; 34+ messages in thread
From: Rainer Orth @ 2011-07-01  9:03 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

"H.J. Lu" <hjl.tools@gmail.com> writes:

> Here is the updated patch.  It works on simple tests.
> I am running full tests.  I kept config/i386/value-unwind.h
> since libgcc/md-unwind-support.h is included too late
> in unwind-dw2.c and I don't want to move it to be on
> the safe side.

Oh please, don't pile hack upon hack to avoid proper testing.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-07-01  9:03                                     ` Rainer Orth
@ 2011-07-01 12:51                                       ` H.J. Lu
  2011-07-01 13:37                                         ` Rainer Orth
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-07-01 12:51 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

On Fri, Jul 1, 2011 at 2:02 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> Here is the updated patch.  It works on simple tests.
>> I am running full tests.  I kept config/i386/value-unwind.h
>> since libgcc/md-unwind-support.h is included too late
>> in unwind-dw2.c and I don't want to move it to be on
>> the safe side.
>
> Oh please, don't pile hack upon hack to avoid proper testing.
>

What is your suggestion?


-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-07-01 12:51                                       ` H.J. Lu
@ 2011-07-01 13:37                                         ` Rainer Orth
  2011-07-01 13:42                                           ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Rainer Orth @ 2011-07-01 13:37 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

"H.J. Lu" <hjl.tools@gmail.com> writes:

> On Fri, Jul 1, 2011 at 2:02 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>
>>> Here is the updated patch.  It works on simple tests.
>>> I am running full tests.  I kept config/i386/value-unwind.h
>>> since libgcc/md-unwind-support.h is included too late
>>> in unwind-dw2.c and I don't want to move it to be on
>>> the safe side.
>>
>> Oh please, don't pile hack upon hack to avoid proper testing.
>>
>
> What is your suggestion?

How about moving the md-unwind-support.h include up to the rest of the
includes?  The headers usually only define MD_FALLBACK_FRAME_STATE_FOR
and perhaps MD_FROB_UPDATE_CONTEXT, everything else is an internal
helper macro, so order shouldn't matter.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-07-01 13:37                                         ` Rainer Orth
@ 2011-07-01 13:42                                           ` H.J. Lu
  2011-07-01 14:03                                             ` Rainer Orth
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-07-01 13:42 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

On Fri, Jul 1, 2011 at 6:37 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> On Fri, Jul 1, 2011 at 2:02 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>>
>>>> Here is the updated patch.  It works on simple tests.
>>>> I am running full tests.  I kept config/i386/value-unwind.h
>>>> since libgcc/md-unwind-support.h is included too late
>>>> in unwind-dw2.c and I don't want to move it to be on
>>>> the safe side.
>>>
>>> Oh please, don't pile hack upon hack to avoid proper testing.
>>>
>>
>> What is your suggestion?
>
> How about moving the md-unwind-support.h include up to the rest of the
> includes?  The headers usually only define MD_FALLBACK_FRAME_STATE_FOR
> and perhaps MD_FROB_UPDATE_CONTEXT, everything else is an internal
> helper macro, so order shouldn't matter.
>

It doesn't work on Linux/x86-64:

In file included from
/export/gnu/import/git/gcc/libgcc/../gcc/unwind-dw2.c:39:0:
./md-unwind-support.h: In function \u2018x86_fallback_frame_state\u2019:
./md-unwind-support.h:121:30: error: dereferencing pointer to incomplete type
./md-unwind-support.h:129:17: error: dereferencing pointer to incomplete type
./md-unwind-support.h:141:23: error: dereferencing pointer to incomplete type
./md-unwind-support.h:153:49: error: dereferencing pointer to incomplete type
./md-unwind-support.h: In function \u2018x86_frob_update_context\u2019:
./md-unwind-support.h:185:30: error: dereferencing pointer to incomplete type
./md-unwind-support.h:192:5: warning: implicit declaration of function
\u2018_Unwind_SetSignalFrame\u2019 [-Wimplicit-function-declaration]
/export/gnu/import/git/gcc/libgcc/../gcc/unwind-dw2.c: At top level:
/export/gnu/import/git/gcc/libgcc/../gcc/unwind-dw2.c:140:1: warning:
conflicting types for \u2018_Unwind_SetSignalFrame\u2019 [enabled by
default]
/export/gnu/import/git/gcc/libgcc/../gcc/unwind-dw2.c:140:1: error:
static declaration of \u2018_Unwind_SetSignalFrame\u2019 follows
non-static declaration
./md-unwind-support.h:192:5: note: previous implicit declaration of
\u2018_Unwind_SetSignalFrame\u2019 was here


-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-07-01 13:42                                           ` H.J. Lu
@ 2011-07-01 14:03                                             ` Rainer Orth
  2011-07-01 14:06                                               ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Rainer Orth @ 2011-07-01 14:03 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

"H.J. Lu" <hjl.tools@gmail.com> writes:

>>> What is your suggestion?
>>
>> How about moving the md-unwind-support.h include up to the rest of the
>> includes?  The headers usually only define MD_FALLBACK_FRAME_STATE_FOR
>> and perhaps MD_FROB_UPDATE_CONTEXT, everything else is an internal
>> helper macro, so order shouldn't matter.
>>
>
> It doesn't work on Linux/x86-64:
>
> In file included from
> /export/gnu/import/git/gcc/libgcc/../gcc/unwind-dw2.c:39:0:
> ./md-unwind-support.h: In function \u2018x86_fallback_frame_state\u2019:
> ./md-unwind-support.h:121:30: error: dereferencing pointer to incomplete type

Then move it below the definition of struct _Unwind_Context with a
comment explaining why it has to be there.  I thought you aspired to
become Linux maintainer?

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-07-01 14:03                                             ` Rainer Orth
@ 2011-07-01 14:06                                               ` H.J. Lu
  2011-07-01 14:25                                                 ` Rainer Orth
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-07-01 14:06 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

On Fri, Jul 1, 2011 at 7:02 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>>>> What is your suggestion?
>>>
>>> How about moving the md-unwind-support.h include up to the rest of the
>>> includes?  The headers usually only define MD_FALLBACK_FRAME_STATE_FOR
>>> and perhaps MD_FROB_UPDATE_CONTEXT, everything else is an internal
>>> helper macro, so order shouldn't matter.
>>>
>>
>> It doesn't work on Linux/x86-64:
>>
>> In file included from
>> /export/gnu/import/git/gcc/libgcc/../gcc/unwind-dw2.c:39:0:
>> ./md-unwind-support.h: In function \u2018x86_fallback_frame_state\u2019:
>> ./md-unwind-support.h:121:30: error: dereferencing pointer to incomplete type
>
> Then move it below the definition of struct _Unwind_Context with a

It won't work since I need to define a macro before struct _Unwind_Context.

> comment explaining why it has to be there.  I thought you aspired to
> become Linux maintainer?
>

Yes, not by breaking working codes.


-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-07-01 14:06                                               ` H.J. Lu
@ 2011-07-01 14:25                                                 ` Rainer Orth
  2011-07-01 14:55                                                   ` H.J. Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Rainer Orth @ 2011-07-01 14:25 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

"H.J. Lu" <hjl.tools@gmail.com> writes:

>> Then move it below the definition of struct _Unwind_Context with a
>
> It won't work since I need to define a macro before struct _Unwind_Context.

Then this does seem to be a case for libgcc_tm_file indeed.  Ugly that
the unwinder configuration has to be split between two different files
this way, but unavoidable, it seems.  At least when libgcc_tm_file moves
to libgcc/config.host, it won't any longer be split between gcc and libgcc.

>> comment explaining why it has to be there.  I thought you aspired to
>> become Linux maintainer?
>
> Yes, not by breaking working codes.

Anyway, thanks for trying.  I'd really have liked to avoid this split.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-07-01 14:25                                                 ` Rainer Orth
@ 2011-07-01 14:55                                                   ` H.J. Lu
  0 siblings, 0 replies; 34+ messages in thread
From: H.J. Lu @ 2011-07-01 14:55 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Richard Henderson, Jason Merrill, gcc-patches, Jakub Jelinek

On Fri, Jul 1, 2011 at 7:25 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>>> Then move it below the definition of struct _Unwind_Context with a
>>
>> It won't work since I need to define a macro before struct _Unwind_Context.
>
> Then this does seem to be a case for libgcc_tm_file indeed.  Ugly that
> the unwinder configuration has to be split between two different files
> this way, but unavoidable, it seems.  At least when libgcc_tm_file moves
> to libgcc/config.host, it won't any longer be split between gcc and libgcc.
>

We need target support for unwind:

1. Target configuration.
2. Target implementation.

Unfortunately, they can't be put in the same file.  If we really want to use
the same file, we can add some macros like:

UNWIND_CONFIGURE
UNWIND_IMPLEMENT

and we can include the same file twice.


-- 
H.J.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-06-30 21:51                                   ` H.J. Lu
  2011-07-01  9:03                                     ` Rainer Orth
@ 2011-08-02 21:02                                     ` Jason Merrill
  2011-08-02 22:27                                       ` H.J. Lu
  1 sibling, 1 reply; 34+ messages in thread
From: Jason Merrill @ 2011-08-02 21:02 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, Rainer Orth, gcc-patches, Jakub Jelinek

On 06/30/2011 04:47 PM, H.J. Lu wrote:
> +@defmac REG_VALUE_IN_UNWIND_CONTEXT
> +
> +Define this macro if the target stores register values as
> +@code{_Unwind_Word} type in unwind context.  The default is to
> +store register values as @code{void *} type.
> +
> +@end defmac

This ought to suggest why a port would need to do this, namely if 
registers can be larger than void*.

> +#ifdef REG_VALUE_IN_UNWIND_CONTEXT
> +typedef _Unwind_Word _Unwind_Context_Reg_Val;
> +
> +#define _Unwind_IsExtendedContext(c) 1

I still think that assuming extended context should be a separate target 
macro which is implied by REG_VALUE_IN_UNWIND_CONTEXT, but can also be 
defined separately by new ports.

Otherwise it looks good to me.

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-08-02 21:02                                     ` Jason Merrill
@ 2011-08-02 22:27                                       ` H.J. Lu
  2011-08-03 21:47                                         ` Jason Merrill
  0 siblings, 1 reply; 34+ messages in thread
From: H.J. Lu @ 2011-08-02 22:27 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Richard Henderson, Rainer Orth, gcc-patches, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 2129 bytes --]

On Tue, Aug 2, 2011 at 2:02 PM, Jason Merrill <jason@redhat.com> wrote:
> On 06/30/2011 04:47 PM, H.J. Lu wrote:
>>
>> +@defmac REG_VALUE_IN_UNWIND_CONTEXT
>> +
>> +Define this macro if the target stores register values as
>> +@code{_Unwind_Word} type in unwind context.  The default is to
>> +store register values as @code{void *} type.
>> +
>> +@end defmac
>
> This ought to suggest why a port would need to do this, namely if registers
> can be larger than void*.
>
>> +#ifdef REG_VALUE_IN_UNWIND_CONTEXT
>> +typedef _Unwind_Word _Unwind_Context_Reg_Val;
>> +
>> +#define _Unwind_IsExtendedContext(c) 1
>
> I still think that assuming extended context should be a separate target
> macro which is implied by REG_VALUE_IN_UNWIND_CONTEXT, but can also be
> defined separately by new ports.
>
> Otherwise it looks good to me.
>
> Jason
>

Here is the updated patch.  I updated REG_VALUE_IN_UNWIND_CONTEXT
document and added ASSUME_EXTENDED_UNWIND_CONTEXT.  OK for
trunk?

Thanks.


-- 
H.J.
-gcc/

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

	* 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-02  H.J. Lu  <hongjiu.lu@intel.com>

	* config/i386/value-unwind.h: New.
---

[-- Attachment #2: gcc-x32-pr48007-7.patch --]
[-- Type: text/x-diff, Size: 11139 bytes --]

gcc/

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

	* 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-02  H.J. Lu  <hongjiu.lu@intel.com>

	* config/i386/value-unwind.h: New.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 94f15d8..1ccd5f1 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2671,6 +2671,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"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 097531f..74a2324 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 01beeb4..f63fe4a 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -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
 
diff --git a/gcc/system.h b/gcc/system.h
index 7ac9859..783101d 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -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 ENABLE_EXECUTE_STACK
+	MD_UNWIND_SUPPORT 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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 19da299..92aa233 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -59,12 +59,50 @@
 #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)
diff --git a/libgcc/config/i386/value-unwind.h b/libgcc/config/i386/value-unwind.h
new file mode 100644
index 0000000..0dceb5c
--- /dev/null
+++ b/libgcc/config/i386/value-unwind.h
@@ -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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
  2011-08-02 22:27                                       ` H.J. Lu
@ 2011-08-03 21:47                                         ` Jason Merrill
  0 siblings, 0 replies; 34+ messages in thread
From: Jason Merrill @ 2011-08-03 21:47 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, Rainer Orth, gcc-patches, Jakub Jelinek

On 08/02/2011 06:27 PM, H.J. Lu wrote:
> Here is the updated patch.  I updated REG_VALUE_IN_UNWIND_CONTEXT
> document and added ASSUME_EXTENDED_UNWIND_CONTEXT.  OK for
> trunk?

Let's say OK on Monday if nobody objects before then.

Jason

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2011-08-03 21:47 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-25 17:02 PATCH [8/n]: Prepare x32: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *) H.J. Lu
2011-06-25 23:34 ` Joseph S. Myers
2011-06-25 23:36   ` H.J. Lu
2011-06-26 20:06 ` Jason Merrill
2011-06-26 20:22   ` Jason Merrill
2011-06-26 21:45   ` H.J. Lu
2011-06-27  2:12     ` Jason Merrill
2011-06-27  3:17       ` H.J. Lu
2011-06-27 15:16         ` Jason Merrill
2011-06-28 19:25           ` H.J. Lu
2011-06-30 14:46             ` Jason Merrill
2011-06-30 14:53               ` H.J. Lu
2011-06-30 15:26                 ` Jason Merrill
2011-06-30 16:36                   ` H.J. Lu
2011-06-30 17:57                     ` H.J. Lu
2011-06-30 18:01                       ` H.J. Lu
2011-06-30 18:10                         ` Rainer Orth
2011-06-30 18:19                           ` H.J. Lu
2011-06-30 18:42                             ` Rainer Orth
2011-06-30 20:14                               ` H.J. Lu
2011-06-30 20:24                                 ` Richard Henderson
2011-06-30 21:51                                   ` H.J. Lu
2011-07-01  9:03                                     ` Rainer Orth
2011-07-01 12:51                                       ` H.J. Lu
2011-07-01 13:37                                         ` Rainer Orth
2011-07-01 13:42                                           ` H.J. Lu
2011-07-01 14:03                                             ` Rainer Orth
2011-07-01 14:06                                               ` H.J. Lu
2011-07-01 14:25                                                 ` Rainer Orth
2011-07-01 14:55                                                   ` H.J. Lu
2011-08-02 21:02                                     ` Jason Merrill
2011-08-02 22:27                                       ` H.J. Lu
2011-08-03 21:47                                         ` Jason Merrill
2011-06-30 20:59                               ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).