Commit cca2207a by H.J. Lu Committed by H.J. Lu

Fix Dwarf unwind library for UNITS_PER_WORD > sizeof (void *)

gcc/

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

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

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

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

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

libgcc/

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

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

From-SVN: r177563
parent b6ee5bef
2011-08-08 H.J. Lu <hongjiu.lu@intel.com>
PR other/48007
* config.gcc (libgcc_tm_file): Add i386/value-unwind.h for
Linux/x86.
* system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned.
(ASSUME_EXTENDED_UNWIND_CONTEXT): Likewise.
* unwind-dw2.c (ASSUME_EXTENDED_UNWIND_CONTEXT): New.
(_Unwind_Context_Reg_Val): Likewise.
(_Unwind_Get_Unwind_Word): Likewise.
(_Unwind_Get_Unwind_Context_Reg_Val): Likewise.
(_Unwind_Context): Use _Unwind_Context_Reg_Val on the reg field.
(_Unwind_IsExtendedContext): Check ASSUME_EXTENDED_UNWIND_CONTEXT
for EXTENDED_CONTEXT_BIT.
(__frame_state_for): Likewise.
(uw_init_context_1): Likewise.
(_Unwind_GetGR): Updated.
(_Unwind_SetGR): Likewise.
(_Unwind_GetGRPtr): Likewise.
(_Unwind_SetGRPtr): Likewise.
(_Unwind_SetGRValue): Likewise.
(_Unwind_GRByValue): Likewise.
(uw_install_context_1): Likewise.
* doc/tm.texi.in: Document REG_VALUE_IN_UNWIND_CONTEXT and
ASSUME_EXTENDED_UNWIND_CONTEXT.
* doc/tm.texi: Regenerated.
2011-08-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2011-08-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* Makefile.in (gengtype$(exeext)): Add $(LDFLAGS). * Makefile.in (gengtype$(exeext)): Add $(LDFLAGS).
......
...@@ -2663,6 +2663,7 @@ esac ...@@ -2663,6 +2663,7 @@ esac
case ${target} in case ${target} in
i[34567]86-*-linux* | x86_64-*-linux*) i[34567]86-*-linux* | x86_64-*-linux*)
tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386" 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-*-*) i[34567]86-*-* | x86_64-*-*)
tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386" tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
......
...@@ -3725,6 +3725,24 @@ return @code{@var{regno}}. ...@@ -3725,6 +3725,24 @@ return @code{@var{regno}}.
@end defmac @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 @node Elimination
@subsection Eliminating Frame Pointer and Arg Pointer @subsection Eliminating Frame Pointer and Arg Pointer
......
...@@ -3711,6 +3711,24 @@ return @code{@var{regno}}. ...@@ -3711,6 +3711,24 @@ return @code{@var{regno}}.
@end defmac @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 @node Elimination
@subsection Eliminating Frame Pointer and Arg Pointer @subsection Eliminating Frame Pointer and Arg Pointer
......
...@@ -802,7 +802,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; ...@@ -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 /* Target macros only used for code built for the target, that have
moved to libgcc-tm.h or have never been present elsewhere. */ moved to libgcc-tm.h or have never been present elsewhere. */
#pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX \ #pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX \
MD_UNWIND_SUPPORT MD_FROB_UPDATE_CONTEXT ENABLE_EXECUTE_STACK MD_UNWIND_SUPPORT MD_FROB_UPDATE_CONTEXT ENABLE_EXECUTE_STACK \
REG_VALUE_IN_UNWIND_CONTEXT ASSUME_EXTENDED_UNWIND_CONTEXT
/* Other obsolete target macros, or macros that used to be in target /* 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 headers and were not used, and may be obsolete or may never have
......
2011-08-08 H.J. Lu <hongjiu.lu@intel.com>
PR other/48007
* config/i386/value-unwind.h: New.
2011-08-06 Richard Sandiford <rdsandiford@googlemail.com> 2011-08-06 Richard Sandiford <rdsandiford@googlemail.com>
* config.host (*-*-darwin*, *-*-freebsd*, *-*-linux*, frv-*-*linux*) * config.host (*-*-darwin*, *-*-freebsd*, *-*-linux*, frv-*-*linux*)
......
/* 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
...@@ -59,12 +59,50 @@ ...@@ -59,12 +59,50 @@
#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO) #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
#endif #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 /* This is the register and unwind state for a particular frame. This
provides the information necessary to unwind up past a frame and return provides the information necessary to unwind up past a frame and return
to its caller. */ to its caller. */
struct _Unwind_Context struct _Unwind_Context
{ {
void *reg[DWARF_FRAME_REGISTERS+1]; _Unwind_Context_Reg_Val reg[DWARF_FRAME_REGISTERS+1];
void *cfa; void *cfa;
void *ra; void *ra;
void *lsda; void *lsda;
...@@ -147,7 +185,8 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val) ...@@ -147,7 +185,8 @@ _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
static inline _Unwind_Word static inline _Unwind_Word
_Unwind_IsExtendedContext (struct _Unwind_Context *context) _Unwind_IsExtendedContext (struct _Unwind_Context *context)
{ {
return context->flags & EXTENDED_CONTEXT_BIT; return (ASSUME_EXTENDED_UNWIND_CONTEXT
|| (context->flags & EXTENDED_CONTEXT_BIT));
} }
/* Get the value of register INDEX as saved in CONTEXT. */ /* Get the value of register INDEX as saved in CONTEXT. */
...@@ -156,7 +195,7 @@ inline _Unwind_Word ...@@ -156,7 +195,7 @@ inline _Unwind_Word
_Unwind_GetGR (struct _Unwind_Context *context, int index) _Unwind_GetGR (struct _Unwind_Context *context, int index)
{ {
int size; int size;
void *ptr; _Unwind_Context_Reg_Val val;
#ifdef DWARF_ZERO_REG #ifdef DWARF_ZERO_REG
if (index == DWARF_ZERO_REG) if (index == DWARF_ZERO_REG)
...@@ -166,18 +205,18 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) ...@@ -166,18 +205,18 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
index = DWARF_REG_TO_UNWIND_COLUMN (index); index = DWARF_REG_TO_UNWIND_COLUMN (index);
gcc_assert (index < (int) sizeof(dwarf_reg_size_table)); gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
size = dwarf_reg_size_table[index]; size = dwarf_reg_size_table[index];
ptr = context->reg[index]; val = context->reg[index];
if (_Unwind_IsExtendedContext (context) && context->by_value[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. */ /* This will segfault if the register hasn't been saved. */
if (size == sizeof(_Unwind_Ptr)) if (size == sizeof(_Unwind_Ptr))
return * (_Unwind_Ptr *) ptr; return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
else else
{ {
gcc_assert (size == sizeof(_Unwind_Word)); 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) ...@@ -209,11 +248,11 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
if (_Unwind_IsExtendedContext (context) && context->by_value[index]) 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; return;
} }
ptr = context->reg[index]; ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
if (size == sizeof(_Unwind_Ptr)) if (size == sizeof(_Unwind_Ptr))
* (_Unwind_Ptr *) ptr = val; * (_Unwind_Ptr *) ptr = val;
...@@ -232,7 +271,7 @@ _Unwind_GetGRPtr (struct _Unwind_Context *context, int index) ...@@ -232,7 +271,7 @@ _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
index = DWARF_REG_TO_UNWIND_COLUMN (index); index = DWARF_REG_TO_UNWIND_COLUMN (index);
if (_Unwind_IsExtendedContext (context) && context->by_value[index]) if (_Unwind_IsExtendedContext (context) && context->by_value[index])
return &context->reg[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. */ /* 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) ...@@ -243,7 +282,7 @@ _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
index = DWARF_REG_TO_UNWIND_COLUMN (index); index = DWARF_REG_TO_UNWIND_COLUMN (index);
if (_Unwind_IsExtendedContext (context)) if (_Unwind_IsExtendedContext (context))
context->by_value[index] = 0; 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. */ /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
...@@ -254,10 +293,10 @@ _Unwind_SetGRValue (struct _Unwind_Context *context, int index, ...@@ -254,10 +293,10 @@ _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
{ {
index = DWARF_REG_TO_UNWIND_COLUMN (index); index = DWARF_REG_TO_UNWIND_COLUMN (index);
gcc_assert (index < (int) sizeof(dwarf_reg_size_table)); 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->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 /* Return nonzero if register INDEX is stored by value rather than
...@@ -1215,6 +1254,7 @@ __frame_state_for (void *pc_target, struct frame_state *state_in) ...@@ -1215,6 +1254,7 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
int reg; int reg;
memset (&context, 0, sizeof (struct _Unwind_Context)); memset (&context, 0, sizeof (struct _Unwind_Context));
if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
context.flags = EXTENDED_CONTEXT_BIT; context.flags = EXTENDED_CONTEXT_BIT;
context.ra = pc_target + 1; context.ra = pc_target + 1;
...@@ -1453,6 +1493,7 @@ uw_init_context_1 (struct _Unwind_Context *context, ...@@ -1453,6 +1493,7 @@ uw_init_context_1 (struct _Unwind_Context *context,
memset (context, 0, sizeof (struct _Unwind_Context)); memset (context, 0, sizeof (struct _Unwind_Context));
context->ra = ra; context->ra = ra;
if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
context->flags = EXTENDED_CONTEXT_BIT; context->flags = EXTENDED_CONTEXT_BIT;
code = uw_frame_state_for (context, &fs); code = uw_frame_state_for (context, &fs);
...@@ -1532,8 +1573,8 @@ uw_install_context_1 (struct _Unwind_Context *current, ...@@ -1532,8 +1573,8 @@ uw_install_context_1 (struct _Unwind_Context *current,
for (i = 0; i < DWARF_FRAME_REGISTERS; ++i) for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
{ {
void *c = current->reg[i]; void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
void *t = target->reg[i]; void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
gcc_assert (current->by_value[i] == 0); gcc_assert (current->by_value[i] == 0);
if (target->by_value[i] && c) if (target->by_value[i] && c)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment