This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

unwind fixes for location expressions


This code has never before been tested, clearly.  Now tested with
linux kernel changes that expose unwind info for the signal frame
directly to userland.

I'll install it for 3.3.1, but it's not important enough for 3.3.0.


r~


        * 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.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.194
diff -c -p -d -u -r1.194 builtins.c
--- builtins.c	3 May 2003 14:25:20 -0000	1.194
+++ builtins.c	4 May 2003 05:17:25 -0000
@@ -4703,8 +4703,8 @@ expand_builtin (exp, target, subtarget, 
     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;
Index: builtins.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.def,v
retrieving revision 1.50
diff -c -p -d -u -r1.50 builtins.def
--- builtins.def	1 May 2003 01:27:48 -0000	1.50
+++ builtins.def	4 May 2003 05:17:25 -0000
@@ -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,
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.424
diff -c -p -d -u -r1.424 dwarf2out.c
--- dwarf2out.c	1 May 2003 13:45:35 -0000	1.424
+++ dwarf2out.c	4 May 2003 05:17:28 -0000
@@ -414,9 +414,9 @@ static void def_cfa_1		 	PARAMS ((const 
 /* 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
Index: except.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.h,v
retrieving revision 1.67
diff -c -p -d -u -r1.67 except.h
--- except.h	22 Apr 2003 05:44:05 -0000	1.67
+++ except.h	4 May 2003 05:17:28 -0000
@@ -114,7 +114,7 @@ extern rtx expand_builtin_eh_return_data
 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 *));
Index: unwind-dw2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unwind-dw2.c,v
retrieving revision 1.27
diff -c -p -d -u -r1.27 unwind-dw2.c
--- unwind-dw2.c	19 Apr 2003 21:23:19 -0000	1.27
+++ unwind-dw2.c	4 May 2003 05:17:28 -0000
@@ -726,7 +726,7 @@ execute_stack_op (const unsigned char *o
       /* 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
 	  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, &reg);
-	  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_Cont
       {
       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_Contex
   /* 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]