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);