* 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] != ¤t->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] != ¤t->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] != ¤t->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 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
* 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
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).