diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e254b46923f..e4ea83a62a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2003-05-03 Richard Henderson + + * builtins.c (expand_builtin) : Remove. + : 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 * config/rs6000/rs6000.c (constant_pool_expr_p): Make static and diff --git a/gcc/builtins.c b/gcc/builtins.c index 969162b8922..c3e14779e50 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4703,8 +4703,8 @@ expand_builtin (exp, target, subtarget, mode, ignore) case BUILT_IN_DWARF_CFA: return virtual_cfa_rtx; #ifdef DWARF2_UNWIND_INFO - case BUILT_IN_DWARF_FP_REGNUM: - return expand_builtin_dwarf_fp_regnum (); + case BUILT_IN_DWARF_SP_COLUMN: + return expand_builtin_dwarf_sp_column (); case BUILT_IN_INIT_DWARF_REG_SIZES: expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist)); return const0_rtx; diff --git a/gcc/builtins.def b/gcc/builtins.def index 13aad964f02..a74673196a6 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -881,8 +881,8 @@ DEF_GCC_BUILTIN(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa", BT_FN_PTR, ATTR_NULL) -DEF_GCC_BUILTIN(BUILT_IN_DWARF_FP_REGNUM, - "__builtin_dwarf_fp_regnum", +DEF_GCC_BUILTIN(BUILT_IN_DWARF_SP_COLUMN, + "__builtin_dwarf_sp_column", BT_FN_UNSIGNED, ATTR_NULL) DEF_GCC_BUILTIN(BUILT_IN_INIT_DWARF_REG_SIZES, diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 6338f99a7d1..66e5eaf2244 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -414,9 +414,9 @@ static void def_cfa_1 PARAMS ((const char *, /* Hook used by __throw. */ rtx -expand_builtin_dwarf_fp_regnum () +expand_builtin_dwarf_sp_column () { - return GEN_INT (DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM)); + return GEN_INT (DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM)); } /* Return a pointer to a copy of the section string name S with all diff --git a/gcc/except.h b/gcc/except.h index 40d16767943..d8e7acec8c4 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -114,7 +114,7 @@ extern rtx expand_builtin_eh_return_data_regno PARAMS ((tree)); extern rtx expand_builtin_extract_return_addr PARAMS ((tree)); extern void expand_builtin_init_dwarf_reg_sizes PARAMS ((tree)); extern rtx expand_builtin_frob_return_addr PARAMS ((tree)); -extern rtx expand_builtin_dwarf_fp_regnum PARAMS ((void)); +extern rtx expand_builtin_dwarf_sp_column PARAMS ((void)); extern void expand_builtin_eh_return PARAMS ((tree, tree)); extern void expand_eh_return PARAMS ((void)); extern rtx get_exception_pointer PARAMS ((struct function *)); diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index 6ffda3f7ead..7596ef07c9c 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -726,7 +726,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end, /* 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:; } @@ -878,17 +878,17 @@ execute_cfa_program (const unsigned char *insn_ptr, 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; @@ -1076,37 +1076,41 @@ static void 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; } @@ -1121,14 +1125,18 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) { 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; @@ -1190,7 +1198,7 @@ uw_init_context_1 (struct _Unwind_Context *context, /* 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);