On Wed, Jun 25, 2008 at 10:02:40AM +0800, Joey Ye wrote:
> Daniel,
>
> We generate following DWARF2 instructions for stack alignment prologue.
> Basically we use expression to calculate CFA. But it run into some
> segfault in libmudflap and libjava. Do you have any hints what's wrong?
>
> DW_CFA_def_cfa: r4 (esp) ofs 4
> DW_CFA_offset: r8 (eip) at cfa-4
> DW_CFA_nop
> DW_CFA_nop
>
> 0000001c 0000002c 00000020 FDE cie=00000000 pc=00000000..00000083
> DW_CFA_advance_loc: 1 to 00000001
> DW_CFA_def_cfa_offset: 8
> DW_CFA_offset: r7 (edi) at cfa-8
> DW_CFA_advance_loc: 4 to 00000005
> DW_CFA_def_cfa: r7 (edi) ofs 0
> DW_CFA_advance_loc: 7 to 0000000c
> DW_CFA_expression: r5 (ebp) (DW_OP_breg5: 0)
> DW_CFA_advance_loc: 37 to 00000031
> DW_CFA_def_cfa_expression (DW_OP_breg5: -4; DW_OP_deref)
> DW_CFA_expression: r6 (esi) (DW_OP_breg5: -8)
> DW_CFA_expression: r3 (ebx) (DW_OP_breg5: -12)
>
> 00000000 <_Z3bariii>:
> 0: 57 push %edi
> 1: 8d 7c 24 08 lea 0x8(%esp),%edi
> 5: 83 e4 e0 and $0xffffffe0,%esp
> 8: ff 77 fc pushl -0x4(%edi)
> b: 55 push %ebp
> c: 89 e5 mov %esp,%ebp
> e: 81 ec 88 00 00 00 sub $0x88,%esp
> 14: 89 45 c4 mov %eax,-0x3c(%ebp)
> 17: 89 c8 mov %ecx,%eax
> 19: 83 c0 1e add $0x1e,%eax
> 1c: 83 e0 f0 and $0xfffffff0,%eax
> 1f: 89 5c 24 7c mov %ebx,0x7c(%esp)
> 23: 89 b4 24 80 00 00 00 mov %esi,0x80(%esp)
> 2a: 89 bc 24 84 00 00 00 mov %edi,0x84(%esp)
> 31: 29 c4 sub %eax,%esp
>
I think the problem is in uw_update_context_1. REG_SAVED_EXP
and REG_SAVED_VAL_EXP may use other registers as shown above:
DW_CFA_expression: r6 (esi) (DW_OP_breg5: -8)
They should be handle last. I am testing this patch. Does it
make senses?
Joey, Xuepeng, please check out our stack branch.
Thanks.
H.J.
---
2008-06-24 H.J. Lu <[EMAIL PROTECTED]>
* unwind-dw2.c (uw_update_context_1): Handle REG_SAVED_EXP and
REG_SAVED_VAL_EXP after other registers.
Index: gcc/unwind-dw2.c
===================================================================
--- gcc/unwind-dw2.c (revision 3051)
+++ gcc/unwind-dw2.c (working copy)
@@ -1258,6 +1258,7 @@ uw_update_context_1 (struct _Unwind_Cont
struct _Unwind_Context orig_context = *context;
void *cfa;
long i;
+ long j, nexps, exps[DWARF_FRAME_REGISTERS + 1];
#ifdef EH_RETURN_STACKADJ_RTX
/* Special handling here: Many machines do not use a frame pointer,
@@ -1307,12 +1308,21 @@ uw_update_context_1 (struct _Unwind_Cont
context->cfa = cfa;
/* Compute the addresses of all registers saved in this frame. */
+ nexps = 0;
for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
switch (fs->regs.reg[i].how)
{
case REG_UNSAVED:
break;
+ case REG_SAVED_EXP:
+ case REG_SAVED_VAL_EXP:
+ /* Handle registers saved with REG_SAVED_EXP and
+ REG_SAVED_VAL_EXP last since they may use other
+ registers. */
+ exps[nexps++] = i;
+ break;
+
case REG_SAVED_OFFSET:
_Unwind_SetGRPtr (context, i,
(void *) (cfa + fs->regs.reg[i].loc.offset));
@@ -1329,38 +1339,42 @@ uw_update_context_1 (struct _Unwind_Cont
fs->regs.reg[i].loc.reg));
break;
- case REG_SAVED_EXP:
- {
- const unsigned char *exp = fs->regs.reg[i].loc.exp;
- _uleb128_t len;
- _Unwind_Ptr val;
-
- exp = read_uleb128 (exp, &len);
- val = execute_stack_op (exp, exp + len, &orig_context,
- (_Unwind_Ptr) cfa);
- _Unwind_SetGRPtr (context, i, (void *) val);
- }
- break;
-
case REG_SAVED_VAL_OFFSET:
_Unwind_SetGRValue (context, i,
(_Unwind_Internal_Ptr)
(cfa + fs->regs.reg[i].loc.offset));
break;
+ }
- case REG_SAVED_VAL_EXP:
+ if (nexps)
+ {
+ const unsigned char *exp;
+ _uleb128_t len;
+ _Unwind_Ptr val;
+
+ /* Compute the addresses of registers saved with REG_SAVED_EXP
+ and REG_SAVED_VAL_EXP. They may use other registers. */
+ orig_context = *context;
+ for (j = 0; j < nexps; ++j)
{
- const unsigned char *exp = fs->regs.reg[i].loc.exp;
- _uleb128_t len;
- _Unwind_Ptr val;
-
+ i = exps[j];
+ exp = fs->regs.reg[i].loc.exp;
exp = read_uleb128 (exp, &len);
val = execute_stack_op (exp, exp + len, &orig_context,
(_Unwind_Ptr) cfa);
- _Unwind_SetGRValue (context, i, val);
+ switch (fs->regs.reg[i].how)
+ {
+ case REG_SAVED_EXP:
+ _Unwind_SetGRPtr (context, i, (void *) val);
+ break;
+ case REG_SAVED_VAL_EXP:
+ _Unwind_SetGRValue (context, i, val);
+ break;
+ default:
+ gcc_unreachable ();
+ }
}
- break;
- }
+ }
_Unwind_SetSignalFrame (context, fs->signal_frame);