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

Reply via email to