+2003-05-03 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin) <BUILT_IN_DWARF_FP_REGNUM>: Remove.
+ <BUILT_IN_DWARF_SP_COLUMN>: New.
+ * builtins.def (BUILT_IN_DWARF_FP_REGNUM): Remove.
+ (BUILT_IN_DWARF_SP_COLUMN): New.
+ * dwarf2out.c (expand_builtin_dwarf_fp_regnum): Remove.
+ (expand_builtin_dwarf_sp_column): New.
+ * except.h: Update to match.
+ * unwind-dw2.c (execute_stack_op): Correct stack push typo.
+ (execute_cfa_program): Record location expression address
+ before extracting length.
+ (uw_update_context_1): Install old CFA into stack pointer column.
+ (uw_init_context_1): Set cfa_reg to stack pointer column.
+
2003-05-03 Richard Henderson <rth@redhat.com>
* config/rs6000/rs6000.c (constant_pool_expr_p): Make static and
/* Most things push a result value. */
if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
abort ();
- stack[++stack_elt] = result;
+ stack[stack_elt++] = result;
no_push:;
}
break;
case DW_CFA_def_cfa_expression:
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->cfa_exp = insn_ptr;
fs->cfa_how = CFA_EXP;
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
insn_ptr += utmp;
break;
case DW_CFA_expression:
insn_ptr = read_uleb128 (insn_ptr, ®);
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
insn_ptr += utmp;
break;
uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
struct _Unwind_Context orig_context = *context;
+ _Unwind_Word tmp_sp;
void *cfa;
long i;
+ /* Special handling here: Many machines do not use a frame pointer,
+ and track the CFA only through offsets from the stack pointer from
+ one frame to the next. In this case, the stack pointer is never
+ stored, so it has no saved address in the context. What we do
+ have is the CFA from the previous stack frame.
+
+ In very special situations (such as unwind info for signal return),
+ there may be location expressions that use the stack pointer as well.
+
+ Given that other unwind mechanisms generally won't work if you try
+ to represent stack pointer saves and restores directly, we don't
+ bother conditionalizing this at all. */
+ tmp_sp = (_Unwind_Ptr) context->cfa;
+ _Unwind_SetGRPtr (&orig_context, __builtin_dwarf_sp_column (), &tmp_sp);
+
/* Compute this frame's CFA. */
switch (fs->cfa_how)
{
case CFA_REG_OFFSET:
- /* Special handling here: Many machines do not use a frame pointer,
- and track the CFA only through offsets from the stack pointer from
- one frame to the next. In this case, the stack pointer is never
- stored, so it has no saved address in the context. What we do
- have is the CFA from the previous stack frame. */
- if (_Unwind_GetGRPtr (context, fs->cfa_reg) == NULL)
- cfa = context->cfa;
- else
- cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
+ cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
cfa += fs->cfa_offset;
break;
case CFA_EXP:
- /* ??? No way of knowing what register number is the stack pointer
- to do the same sort of handling as above. Assume that if the
- CFA calculation is so complicated as to require a stack program
- that this will not be a problem. */
{
const unsigned char *exp = fs->cfa_exp;
_Unwind_Word len;
exp = read_uleb128 (exp, &len);
cfa = (void *) (_Unwind_Ptr)
- execute_stack_op (exp, exp + len, context, 0);
+ execute_stack_op (exp, exp + len, &orig_context, 0);
break;
}
{
case REG_UNSAVED:
break;
+
case REG_SAVED_OFFSET:
- _Unwind_SetGRPtr (context, i, (void *) (cfa + fs->regs.reg[i].loc.offset));
+ _Unwind_SetGRPtr (context, i,
+ (void *) (cfa + fs->regs.reg[i].loc.offset));
break;
+
case REG_SAVED_REG:
_Unwind_SetGRPtr
(context, i,
_Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
break;
+
case REG_SAVED_EXP:
{
const unsigned char *exp = fs->regs.reg[i].loc.exp;
/* Force the frame state to use the known cfa value. */
context->cfa = outer_cfa;
fs.cfa_how = CFA_REG_OFFSET;
- fs.cfa_reg = 0;
+ fs.cfa_reg = __builtin_dwarf_sp_column ();
fs.cfa_offset = 0;
uw_update_context_1 (context, &fs);