This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB 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]

[offbyone] Merge with mainline


FYI,

I've committed the attached. It merges that branch with the mainline.

Andrew
2003-03-05  Andrew Cagney  <cagney at redhat dot com>

	* dummy-frame.c (dummy_frame_id_unwind): Abort if called.
	(cached_find_dummy_frame): Add hack to obtain this thread's id
	without calling id unwind.
	* frame.h: Merge with mainline.
	* d10v-tdep.c: Merge with mainline.
	* frame.c: Merge with mainline.

Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.80.2.2
diff -u -r1.80.2.2 d10v-tdep.c
--- d10v-tdep.c	5 Mar 2003 05:00:03 -0000	1.80.2.2
+++ d10v-tdep.c	6 Mar 2003 00:56:23 -0000
@@ -616,8 +616,11 @@
   CORE_ADDR base;
   int size;
   CORE_ADDR *saved_regs;
-  LONGEST next_addr;
-  LONGEST r11_addr;
+  /* How far the SP and r11 (FP) have been offset from the start of
+     the stack frame (as defined by the previous frame's stack
+     pointer).  */
+  LONGEST sp_offset;
+  LONGEST r11_offset;
   int uses_frame;
   void **regs;
 };
@@ -632,8 +635,8 @@
   if ((op & 0x7E1F) == 0x6C1F)
     {
       n = (op & 0x1E0) >> 5;
-      info->next_addr -= 2;
-      info->saved_regs[n] = info->next_addr;
+      info->sp_offset -= 2;
+      info->saved_regs[n] = info->sp_offset;
       return 1;
     }
 
@@ -641,9 +644,9 @@
   else if ((op & 0x7E3F) == 0x6E1F)
     {
       n = (op & 0x1E0) >> 5;
-      info->next_addr -= 4;
-      info->saved_regs[n] = info->next_addr;
-      info->saved_regs[n + 1] = info->next_addr + 2;
+      info->sp_offset -= 4;
+      info->saved_regs[n] = info->sp_offset;
+      info->saved_regs[n + 1] = info->sp_offset + 2;
       return 1;
     }
 
@@ -653,7 +656,7 @@
       n = (op & 0x1E) >> 1;
       if (n == 0)
 	n = 16;
-      info->next_addr -= n;
+      info->sp_offset -= n;
       return 1;
     }
 
@@ -661,7 +664,7 @@
   if (op == 0x417E)
     {
       info->uses_frame = 1;
-      info->r11_addr = info->next_addr;
+      info->r11_offset = info->sp_offset;
       return 1;
     }
 
@@ -669,7 +672,7 @@
   if ((op & 0x7E1F) == 0x6816)
     {
       n = (op & 0x1E0) >> 5;
-      info->saved_regs[n] = info->r11_addr;
+      info->saved_regs[n] = info->r11_offset;
       return 1;
     }
 
@@ -681,7 +684,7 @@
   if ((op & 0x7E1F) == 0x681E)
     {
       n = (op & 0x1E0) >> 5;
-      info->saved_regs[n] = info->next_addr;
+      info->saved_regs[n] = info->sp_offset;
       return 1;
     }
 
@@ -689,8 +692,8 @@
   if ((op & 0x7E3F) == 0x3A1E)
     {
       n = (op & 0x1E0) >> 5;
-      info->saved_regs[n] = info->next_addr;
-      info->saved_regs[n + 1] = info->next_addr + 2;
+      info->saved_regs[n] = info->sp_offset;
+      info->saved_regs[n + 1] = info->sp_offset + 2;
       return 1;
     }
 
@@ -708,8 +711,8 @@
 			 void **this_cache)
 {
   CORE_ADDR pc;
-  ULONGEST sp;
-  ULONGEST base;
+  ULONGEST prev_sp;
+  ULONGEST this_base;
   unsigned long op;
   unsigned short op1, op2;
   int i;
@@ -724,7 +727,7 @@
 
   info->size = 0;
 
-  info->next_addr = 0;
+  info->sp_offset = 0;
 
   pc = get_pc_function_start (frame_pc_unwind (next_frame));
 
@@ -739,22 +742,22 @@
 	    {
 	      /* add3 sp,sp,n */
 	      short n = op & 0xFFFF;
-	      info->next_addr += n;
+	      info->sp_offset += n;
 	    }
 	  else if ((op & 0x3F0F0000) == 0x340F0000)
 	    {
 	      /* st  rn, @(offset,sp) */
 	      short offset = op & 0xFFFF;
 	      short n = (op >> 20) & 0xF;
-	      info->saved_regs[n] = info->next_addr + offset;
+	      info->saved_regs[n] = info->sp_offset + offset;
 	    }
 	  else if ((op & 0x3F1F0000) == 0x350F0000)
 	    {
 	      /* st2w  rn, @(offset,sp) */
 	      short offset = op & 0xFFFF;
 	      short n = (op >> 20) & 0xF;
-	      info->saved_regs[n] = info->next_addr + offset;
-	      info->saved_regs[n + 1] = info->next_addr + offset + 2;
+	      info->saved_regs[n] = info->sp_offset + offset;
+	      info->saved_regs[n + 1] = info->sp_offset + offset + 2;
 	    }
 	  else
 	    break;
@@ -779,52 +782,50 @@
       pc += 4;
     }
 
-  info->size = -info->next_addr;
+  info->size = -info->sp_offset;
 
-  /* Compute the frame's base.  */
+  /* Compute the frame's base, and the previous frame's SP.  */
   if (info->uses_frame)
     {
-      /* The SP was moved into the FP.  This indicates that a new
-         frame was created.  Get THIS frame's FP value by unwinding it
-         from the next frame.  */
-      frame_unwind_unsigned_register (next_frame, FP_REGNUM, &base);
+      /* The SP was moved to the FP.  This indicates that a new frame
+         was created.  Get THIS frame's FP value by unwinding it from
+         the next frame.  */
+      frame_unwind_unsigned_register (next_frame, FP_REGNUM, &this_base);
       /* The FP points at the last saved register.  Adjust the FP back
          to before the first saved register giving the SP.  */
-      sp = base + info->size;
+      prev_sp = this_base + info->size;
     }
   else if (info->saved_regs[SP_REGNUM])
     {
       /* The SP was saved (which is very unusual), the frame base is
 	 just the PREV's frame's TOP-OF-STACK.  */
-      base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM], 
-					   register_size (current_gdbarch,
-							  SP_REGNUM));
-      sp = base;
+      this_base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM], 
+						register_size (current_gdbarch,
+							       SP_REGNUM));
+      prev_sp = this_base;
     }
   else
     {
       /* Assume that the FP is this frame's SP but with that pushed
          stack space added back.  */
-      frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
-      sp = base + info->size;
+      frame_unwind_unsigned_register (next_frame, SP_REGNUM, &this_base);
+      prev_sp = this_base + info->size;
     }
 
-  info->base = d10v_make_daddr (base);
-  sp = d10v_make_daddr (sp);
+  info->base = d10v_make_daddr (this_base);
+  prev_sp = d10v_make_daddr (prev_sp);
 
   /* Adjust all the saved registers so that they contain addresses and
      not offsets.  */
   for (i = 0; i < NUM_REGS - 1; i++)
-    {
-      if (info->saved_regs[i])
-	{
-	  info->saved_regs[i] = (sp + info->saved_regs[i]);
-	}
-    }
+    if (info->saved_regs[i])
+      {
+	info->saved_regs[i] = (prev_sp + info->saved_regs[i]);
+      }
 
   /* The SP_REGNUM is special.  Instead of the address of the SP, the
      previous frame's SP value is saved.  */
-  info->saved_regs[SP_REGNUM] = sp;
+  info->saved_regs[SP_REGNUM] = prev_sp;
 
   return info;
 }
@@ -1587,18 +1588,6 @@
 			 lvalp, addrp, realnump, bufferp);
 }
 
-
-static struct frame_id
-d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  ULONGEST base;
-  struct frame_id id;
-  id.pc = frame_pc_unwind (next_frame);
-  frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
-  id.base = d10v_make_daddr (base);
-  return id;
-}
-
 static void
 d10v_frame_pop (struct frame_info *next_frame, void **this_cache,
 		struct regcache *regcache)
@@ -1646,6 +1635,22 @@
   return &d10v_frame_unwind;
 }
 
+/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
+   dummy frame.  The frame ID's base needs to match the TOS value
+   saved by save_dummy_frame_tos(), and the PC match the dummy frame's
+   breakpoint.  */
+
+static struct frame_id
+d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  ULONGEST base;
+  struct frame_id id;
+  id.pc = frame_pc_unwind (next_frame);
+  frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
+  id.base = d10v_make_daddr (base);
+  return id;
+}
+
 static gdbarch_init_ftype d10v_gdbarch_init;
 
 static struct gdbarch *
@@ -1782,6 +1787,8 @@
   set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info);
 
   frame_unwind_append_predicate (gdbarch, d10v_frame_p);
+
+  /* Methods for saving / extracting a dummy frame's ID.  */
   set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);
   set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
 
Index: dummy-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dummy-frame.c,v
retrieving revision 1.10.4.1
diff -u -r1.10.4.1 dummy-frame.c
--- dummy-frame.c	4 Mar 2003 23:15:23 -0000	1.10.4.1
+++ dummy-frame.c	6 Mar 2003 00:56:23 -0000
@@ -108,8 +108,13 @@
 cached_find_dummy_frame (struct frame_info *next_frame, void **this_cache)
 {
   if ((*this_cache) == NULL)
-    (*this_cache) = find_dummy_frame (frame_pc_unwind (next_frame),
-				      frame_id_unwind (next_frame).base);
+    {
+      /* FIXME: hack to find the frame ID of this frame.  Need to do
+	 this better.  */
+      gdb_assert (next_frame->prev != NULL);
+      (*this_cache) = find_dummy_frame (frame_pc_unwind (next_frame),
+					next_frame->prev->frame);
+    }
   return (*this_cache);
 }
 
@@ -396,6 +401,7 @@
 		       void **this_cache,
 		       struct frame_id *this_id)
 {
+#if 0
   struct dummy_frame *dummy = cached_find_dummy_frame (next_frame, this_cache);
   /* Oops!  In a dummy-frame but can't find the stack dummy.  Pretend
      that the frame doesn't unwind.  Should this function instead
@@ -404,6 +410,14 @@
     (*this_id) = null_frame_id;
   else
     (*this_id) = dummy->id;
+#else
+  /* FIXME - with all the frames shuffled by one, it becomes possible
+     to move the dummy frame unwind code to here.  This is because,
+     unlike the mainline, this function is called when determining the
+     ID of the dummy, and not the ID of the dummy's caller.  For the
+     moment, this function is never called.  */
+  internal_error (__FILE__, __LINE__, "dummy_frame_pc_unwind called");
+#endif
 }
 
 static struct frame_unwind dummy_frame_unwind =
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.71.2.3
diff -u -r1.71.2.3 frame.c
--- frame.c	5 Mar 2003 05:00:03 -0000	1.71.2.3
+++ frame.c	6 Mar 2003 00:56:23 -0000
@@ -146,18 +146,6 @@
   return this_frame->pc_unwind_cache;
 }
 
-struct frame_id
-frame_id_unwind (struct frame_info *this_frame)
-{
-  if (!this_frame->id_unwind_cache_p)
-    {
-      this_frame->unwind->id (this_frame->next, &this_frame->unwind_cache,
-			      &this_frame->id_unwind_cache);
-      this_frame->id_unwind_cache_p = 1;
-    }
-  return this_frame->id_unwind_cache;
-}
-
 void
 frame_pop (struct frame_info *frame)
 {
@@ -1346,83 +1334,87 @@
 						prev_frame->pc);
 
   /* Find the prev's frame's ID.  */
-  {
-    switch (prev_frame->type)
-      {
-      case DUMMY_FRAME:
-	/* A dummy doesn't have anything resembling either a sane
-	   frame or PC.  The PC is sitting in the entry code and the
-	   stack, which has nothing to do with that entry address, is
-	   a down right mess.  Trying to use the standard frame ID
-	   unwind code to get the previous frame ID is just asking for
-	   trouble.  */
-	if (gdbarch_unwind_dummy_id_p (current_gdbarch))
-	  {
-	    /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
-               previously saved the dummy ID that is being obtained
-               here.  Things only work if the two match.  */
-	    gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
-	    /* Use an architecture specific method to extract the
-	       prev's dummy ID from the next frame.  Note that this
-	       method typically uses frame_register_unwind to obtain
-	       register values needed to determine the dummy ID.  */
-	    next_frame->id_unwind_cache =
-	      gdbarch_unwind_dummy_id (current_gdbarch, next_frame);
-	  }
-	else if (next_frame->level == 0)
-	  {
-	    /* We're `unwinding' the sentinel frame.  Just fake up the
-               ID the same way that the traditional hacks did it.  */
-	    next_frame->id_unwind_cache.pc = read_pc ();
-	    next_frame->id_unwind_cache.pc = read_fp ();
-	  }
-	else
-	  {
-	    /* Outch!  We're not on the innermost frame yet we're
-               trying to unwind to a dummy.  The architecture must
-               provide the unwind_dummy_id() method.  */
-	    internal_error (__FILE__, __LINE__,
+  switch (prev_frame->type)
+    {
+    case DUMMY_FRAME:
+      /* When unwinding a normal frame, the stack structure is
+	 determined by analyzing the frame's function's code (be it
+	 using brute force prologue analysis, or the dwarf2 CFI).  In
+	 the case of a dummy frame, that simply isn't possible.  The
+	 The PC is either the program entry point, or some random
+	 address on the stack.  Trying to use that PC to apply
+	 standard frame ID unwind techniques is just asking for
+	 trouble.  */
+      if (gdbarch_unwind_dummy_id_p (current_gdbarch))
+	{
+	  /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
+	     previously saved the dummy frame's ID.  Things only work
+	     if the two return the same value.  */
+	  gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
+	  /* Use an architecture specific method to extract the prev's
+	     dummy ID from the next frame.  Note that this method uses
+	     frame_register_unwind to obtain the register values
+	     needed to determine the dummy frame's ID.  */
+	  prev_frame->id = gdbarch_unwind_dummy_id (current_gdbarch,
+						    next_frame);
+	}
+      else if (next_frame->level < 0)
+	{
+	  /* We're unwinding a sentinel frame, the PC of which is
+	     pointing at a stack dummy.  Fake up the dummy frame's ID
+	     using the same sequence as is found a traditional
+	     unwinder.  Once all architectures supply the
+	     unwind_dummy_id method, this code can go away.  */
+	  prev_frame->id.base = read_fp ();
+	  prev_frame->id.pc = read_pc ();
+	}
+      else
+	{
+	  /* Outch!  We're not on the innermost frame yet we're trying
+	     to unwind to a dummy.  The architecture must provide the
+	     unwind_dummy_id() method.  Abandon the unwind process but
+	     only after first warning the user.  */
+	  internal_warning (__FILE__, __LINE__,
 			    "Missing unwind_dummy_id architecture method");
-	  }
-	break;
-      case NORMAL_FRAME:
-      case SIGTRAMP_FRAME:
-	prev_frame->unwind->id (next_frame, &prev_frame->unwind_cache,
-				&next_frame->id_unwind_cache);
-	/* Check that the unwound ID is valid.  */
-	if (!frame_id_p (next_frame->id_unwind_cache))
-	  {
-	    if (frame_debug)
-	      fprintf_unfiltered (gdb_stdlog,
-				  "Outermost frame - unwound frame ID invalid\n");
-	    return NULL;
-	  }
-	/* Check that the new frame isn't inner to (younger, below,
-	   next) the old frame.  If that happens the frame unwind is
-	   going backwards.  */
-	/* FIXME: cagney/2003-02-25: Ignore the sentinel frame since
-	   that doesn't have a valid frame ID.  Should instead set the
-	   sentinel frame's frame ID to a `sentinel'.  Leave it until
-	   after the switch to storing the frame ID, instead of the
-	   frame base, in the frame object.  */
-	if (next_frame->level >= 0
-	    && frame_id_inner (next_frame->id_unwind_cache,
-			       get_frame_id (next_frame)))
-	  error ("Unwound frame inner-to selected frame (corrupt stack?)");
-	/* Note that, due to frameless functions, the stronger test of
-	   the new frame being outer to the old frame can't be used -
-	   frameless functions differ by only their PC value.  */
-	break;
-      default:
-	internal_error (__FILE__, __LINE__, "bad switch");
-      }
-    /* FIXME: cagney/2002-12-18: Instead of this hack, the frame ID
-       should be directly stored in the `struct frame_info'.
-       Unfortunatly, GDB isn't quite ready for this, need to get HP/UX
-       multi-arch and make 'struct frame_info' opaque.  */
-    next_frame->id_unwind_cache_p = 1;
-    prev_frame->frame = next_frame->id_unwind_cache.base;
-  }
+	  return NULL;
+	}
+      break;
+    case NORMAL_FRAME:
+    case SIGTRAMP_FRAME:
+      prev_frame->unwind->id (next_frame, &prev_frame->unwind_cache,
+			      &prev_frame->id);
+      /* Check that the unwound ID is valid.  */
+      if (!frame_id_p (prev_frame->id))
+	{
+	  if (frame_debug)
+	    fprintf_unfiltered (gdb_stdlog,
+				"Outermost frame - unwound frame ID invalid\n");
+	  return NULL;
+	}
+      /* Check that the new frame isn't inner to (younger, below,
+	 next) the old frame.  If that happens the frame unwind is
+	 going backwards.  */
+      /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since
+	 that doesn't have a valid frame ID.  Should instead set the
+	 sentinel frame's frame ID to a `sentinel'.  Leave it until
+	 after the switch to storing the frame ID, instead of the
+	 frame base, in the frame object.  */
+      if (next_frame->level >= 0
+	  && frame_id_inner (prev_frame->id, get_frame_id (next_frame)))
+	error ("Unwound frame inner-to selected frame (corrupt stack?)");
+      /* Note that, due to frameless functions, the stronger test of
+	 the new frame being outer to the old frame can't be used -
+	 frameless functions differ by only their PC value.  */
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
+    }
+
+  /* FIXME: cagney/2002-12-18: Instead of this hack, should only store
+     the frame ID in PREV_FRAME.  Unfortunatly, some architectures
+     (HP/UX) still reply on EXTRA_FRAME_INFO and, hence, still poke at
+     the "struct frame_info" object directly.  */
+  prev_frame->frame = prev_frame->id.base;
 
   /* Link it in.  */
   next_frame->prev = prev_frame;
@@ -1557,11 +1549,11 @@
 deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc)
 {
   /* See comment in "frame.h".  */
-  gdb_assert (frame->next != NULL);
-  /* Fix up this PC's value.  */
   frame->pc = pc;
-  /* While we're at it, also update the cache, in NEXT, that also
-     contains that value.  */
+  /* While we're at it, update this frame's cached PC value, found in
+     the next frame.  Oh, for the day when "struct frame_info" is
+     opaque and this hack on hack can go.  */
+  gdb_assert (frame->next != NULL);
   frame->next->pc_unwind_cache = pc;
   frame->next->pc_unwind_cache_p = 1;
 }
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.70.2.2
diff -u -r1.70.2.2 frame.h
--- frame.h	4 Mar 2003 23:15:24 -0000	1.70.2.2
+++ frame.h	6 Mar 2003 00:56:23 -0000
@@ -310,10 +310,6 @@
 
 extern CORE_ADDR frame_pc_unwind (struct frame_info *frame);
 
-/* Unwind the frame ID.  Return an ID that uniquely identifies the
-   caller's frame.  */
-extern struct frame_id frame_id_unwind (struct frame_info *frame);
-
 /* Discard the specified frame.  Restoring the registers to the state
    of the caller.  */
 extern void frame_pop (struct frame_info *frame);
@@ -412,9 +408,9 @@
     int pc_unwind_cache_p;
     CORE_ADDR pc_unwind_cache;
 
-    /* Cached copy of the previous frame's ID.  */
-    int id_unwind_cache_p;
-    struct frame_id id_unwind_cache;
+    /* This frame's ID.  Note that the frame's ID, base and PC contain
+       redundant information.  */
+    struct frame_id id;
 
     /* Pointers to the next (down, inner, younger) and previous (up,
        outer, older) frame_info's in the frame cache.  */

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