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];
};
static inline unsigned long
read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
\f
+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;
+}
+\f
/* Get the value of register INDEX as saved in CONTEXT. */
inline _Unwind_Word
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. */
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;
_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];
}
_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;
}
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;
}
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;
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)
{
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)
break;
}
- context->signal_frame = fs->signal_frame;
+ _Unwind_SetSignalFrame (context, fs->signal_frame);
#ifdef MD_FROB_UPDATE_CONTEXT
MD_FROB_UPDATE_CONTEXT (context, fs);
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);