From 5032e5f8188169c7051ab89c4dd15d4280e50de4 Mon Sep 17 00:00:00 2001 From: jakub Date: Wed, 3 Jan 2007 23:45:47 +0000 Subject: [PATCH] * unwind-dw2.c (SIGNAL_FRAME_BIT, EXTENDED_CONTEXT_BIT): Define. (struct _Unwind_Context): Rename args_size to flags, remove signal_frame field, add a new args_size field and version field. (_Unwind_IsSignalFrame, _Unwind_SetSignalFrame, _Unwind_IsExtendedContext): New inline functions. (_Unwind_GetGR, _Unwind_SetGR, _Unwind_GetGRPtr, _Unwind_SetGRPtr): Assume by_value array is only present if _Unwind_IsExtendedContext. (_Unwind_GetIPInfo, execute_cfa_program, uw_frame_state_for): Use _Unwind_IsSignalFrame. (__frame_state_for): Initialize context.flags to EXTENDED_CONTEXT_BIT. (uw_update_context_1): Use _Unwind_SetSignalFrame. (uw_init_context_1): Initialize context->flags to EXTENDED_CONTEXT_BIT. * config/rs6000/linux-unwind.h (frob_update_context): Use _Unwind_SetSignalFrame. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120406 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 18 +++++++++++++++ gcc/config/rs6000/linux-unwind.h | 4 ++-- gcc/unwind-dw2.c | 50 ++++++++++++++++++++++++++++++++-------- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1361073..db31113 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2007-01-03 Jakub Jelinek + + * unwind-dw2.c (SIGNAL_FRAME_BIT, EXTENDED_CONTEXT_BIT): Define. + (struct _Unwind_Context): Rename args_size to flags, remove + signal_frame field, add a new args_size field and version field. + (_Unwind_IsSignalFrame, _Unwind_SetSignalFrame, + _Unwind_IsExtendedContext): New inline functions. + (_Unwind_GetGR, _Unwind_SetGR, _Unwind_GetGRPtr, _Unwind_SetGRPtr): + Assume by_value array is only present if _Unwind_IsExtendedContext. + (_Unwind_GetIPInfo, execute_cfa_program, uw_frame_state_for): Use + _Unwind_IsSignalFrame. + (__frame_state_for): Initialize context.flags to EXTENDED_CONTEXT_BIT. + (uw_update_context_1): Use _Unwind_SetSignalFrame. + (uw_init_context_1): Initialize context->flags to + EXTENDED_CONTEXT_BIT. + * config/rs6000/linux-unwind.h (frob_update_context): Use + _Unwind_SetSignalFrame. + 2007-01-03 Andrew Pinski PR middle-end/30353 diff --git a/gcc/config/rs6000/linux-unwind.h b/gcc/config/rs6000/linux-unwind.h index 2758cbc..182bb6d 100644 --- a/gcc/config/rs6000/linux-unwind.h +++ b/gcc/config/rs6000/linux-unwind.h @@ -319,7 +319,7 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT if (pc[0] == 0x38210000 + SIGNAL_FRAMESIZE && (pc[1] == 0x38000077 || pc[1] == 0x380000AC) && pc[2] == 0x44000002) - context->signal_frame = 1; + _Unwind_SetSignalFrame (context, 1); #else /* li r0, 0x7777; sc (sigreturn old) */ /* li r0, 0x0077; sc (sigreturn new) */ @@ -328,7 +328,7 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT if ((pc[0] == 0x38007777 || pc[0] == 0x38000077 || pc[0] == 0x38006666 || pc[0] == 0x380000AC) && pc[1] == 0x44000002) - context->signal_frame = 1; + _Unwind_SetSignalFrame (context, 1); #endif #ifdef __powerpc64__ diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index 9cc4e28..da8289f 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -70,8 +70,15 @@ struct _Unwind_Context 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. */ + _Unwind_Word version; _Unwind_Word args_size; - char signal_frame; char by_value[DWARF_FRAME_REGISTERS+1]; }; @@ -123,6 +130,27 @@ read_8u (const void *p) { const union unaligned *up = p; return up->u8; } static inline unsigned long read_8s (const void *p) { const union unaligned *up = p; return up->s8; } +static inline _Unwind_Word +_Unwind_IsSignalFrame (struct _Unwind_Context *context) +{ + return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0; +} + +static inline void +_Unwind_SetSignalFrame (struct _Unwind_Context *context, int val) +{ + if (val) + context->flags |= SIGNAL_FRAME_BIT; + else + context->flags &= ~SIGNAL_FRAME_BIT; +} + +static inline _Unwind_Word +_Unwind_IsExtendedContext (struct _Unwind_Context *context) +{ + return context->flags & EXTENDED_CONTEXT_BIT; +} + /* Get the value of register INDEX as saved in CONTEXT. */ inline _Unwind_Word @@ -141,7 +169,7 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) size = dwarf_reg_size_table[index]; ptr = context->reg[index]; - if (context->by_value[index]) + if (_Unwind_IsExtendedContext (context) && context->by_value[index]) return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr; /* This will segfault if the register hasn't been saved. */ @@ -180,7 +208,7 @@ _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]; - if (context->by_value[index]) + if (_Unwind_IsExtendedContext (context) && context->by_value[index]) { context->reg[index] = (void *) (_Unwind_Internal_Ptr) val; return; @@ -203,7 +231,7 @@ static inline void * _Unwind_GetGRPtr (struct _Unwind_Context *context, int index) { index = DWARF_REG_TO_UNWIND_COLUMN (index); - if (context->by_value[index]) + if (_Unwind_IsExtendedContext (context) && context->by_value[index]) return &context->reg[index]; return context->reg[index]; } @@ -214,7 +242,8 @@ static inline void _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p) { index = DWARF_REG_TO_UNWIND_COLUMN (index); - context->by_value[index] = 0; + if (_Unwind_IsExtendedContext (context)) + context->by_value[index] = 0; context->reg[index] = p; } @@ -256,7 +285,7 @@ _Unwind_GetIP (struct _Unwind_Context *context) inline _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) { - *ip_before_insn = context->signal_frame != 0; + *ip_before_insn = _Unwind_IsSignalFrame (context); return (_Unwind_Ptr) context->ra; } @@ -824,7 +853,8 @@ execute_cfa_program (const unsigned char *insn_ptr, reflected at the point immediately before the call insn. In signal frames, return address is after last completed instruction, so we add 1 to return address to make the comparison <=. */ - while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame) + while (insn_ptr < insn_end + && fs->pc < context->ra + _Unwind_IsSignalFrame (context)) { unsigned char insn = *insn_ptr++; _Unwind_Word reg, utmp; @@ -1063,7 +1093,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) if (context->ra == 0) return _URC_END_OF_STACK; - fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1, + fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1, &context->bases); if (fde == NULL) { @@ -1142,6 +1172,7 @@ __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; context.ra = pc_target + 1; if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON) @@ -1306,7 +1337,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) break; } - context->signal_frame = fs->signal_frame; + _Unwind_SetSignalFrame (context, fs->signal_frame); #ifdef MD_FROB_UPDATE_CONTEXT MD_FROB_UPDATE_CONTEXT (context, fs); @@ -1366,6 +1397,7 @@ uw_init_context_1 (struct _Unwind_Context *context, memset (context, 0, sizeof (struct _Unwind_Context)); context->ra = ra; + context->flags = EXTENDED_CONTEXT_BIT; code = uw_frame_state_for (context, &fs); gcc_assert (code == _URC_NO_REASON); -- 2.7.4