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-branch] Add unwind_pc arch method, merge with mainline


FYI,

I've commited the attached to my offbyone branch. It adds the unwind_pc() method to that source base. And re-syncs other changes from the mainline.

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

	* gdbarch.sh (gdbarch_unwind_pc): New method.
	* gdbarch.h, gdbarch.c: Regenerate.
	* frame.c (frame_pc_unwind): Rewrite.  Prefer gdbarch_unwind_pc,
	but use read_pc and FRAME_SAVED_PC as fall backs.
	(frame_saved_regs_pc_unwind): Delete function.
	(trad_frame_unwinder): Update.
	* frame-unwind.h (frame_unwind_pc_ftype): Delete declaration.
	(struct frame_unwind): Update.
	* dummy-frame.c (dummy_frame_pc_unwind): Delete function.
	(dummy_frame_unwind): Update.
	* sentinel-frame.c (sentinel_frame_pc_unwind): Delete function.
	(sentinel_frame_unwinder): Update.
	* d10v-tdep.c (d10v_frame_pc_unwind): Delete function.
	(d10v_frame_unwind): Update.
	(d10v_unwind_pc): New function.
	(d10v_gdbarch_init): Set unwind_pc.

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 19:20:07 -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;
 }
@@ -1432,22 +1433,12 @@
     }
 }
 
-
 static CORE_ADDR
-d10v_frame_pc_unwind (struct frame_info *next_frame,
-		      void **this_cache)
+d10v_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  /* FIXME: This shouldn't be needed.  Instead single per-architecture
-     method should be called for all frames.  */
-  CORE_ADDR lr;
-  struct d10v_unwind_cache *info
-    = d10v_frame_unwind_cache (next_frame, this_cache);
-  void *buffer = alloca (max_register_size (current_gdbarch));
-  saved_regs_unwind (next_frame, info->saved_regs, LR_REGNUM, buffer);
-  lr = extract_unsigned_integer (buffer, register_size (current_gdbarch,
-							LR_REGNUM));
-  return d10v_make_iaddr (lr);
-			
+  ULONGEST pc;
+  frame_unwind_unsigned_register (next_frame, PC_REGNUM, &pc);
+  return d10v_make_iaddr (pc);
 }
 
 /* Given the next frame, determine the address of this function's
@@ -1587,18 +1578,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)
@@ -1635,7 +1614,6 @@
 
 static struct frame_unwind d10v_frame_unwind = {
   d10v_frame_pop,
-  d10v_frame_pc_unwind,
   d10v_frame_id_unwind,
   d10v_frame_register_unwind
 };
@@ -1646,6 +1624,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,8 +1776,13 @@
   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);
+
+  /* Return the unwound PC value.  */
+  set_gdbarch_unwind_pc (gdbarch, d10v_unwind_pc);
 
   return gdbarch;
 }
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 19:20:07 -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);
 }
 
@@ -371,23 +376,6 @@
     }
 }
 
-/* Assuming that FRAME is a dummy, return the resume address for the
-   previous frame.  */
-
-static CORE_ADDR
-dummy_frame_pc_unwind (struct frame_info *next_frame,
-		       void **this_cache)
-{
-  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
-     return a has-no-caller indication?  */
-  if (dummy == NULL)
-    return 0;
-  return dummy->pc;
-}
-
-
 /* Assuming that FRAME is a dummy, return the ID of the calling frame
    (the frame that the dummy has the saved state of).  */
 
@@ -396,6 +384,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,12 +393,19 @@
     (*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 =
 {
   dummy_frame_pop,
-  dummy_frame_pc_unwind,
   dummy_frame_id_unwind,
   dummy_frame_register_unwind
 };
Index: frame-unwind.h
===================================================================
RCS file: /cvs/src/src/gdb/frame-unwind.h,v
retrieving revision 1.3.6.1
diff -u -r1.3.6.1 frame-unwind.h
--- frame-unwind.h	4 Mar 2003 23:15:23 -0000	1.3.6.1
+++ frame-unwind.h	6 Mar 2003 19:20:07 -0000
@@ -104,26 +104,6 @@
 
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    use the NEXT frame, and its register unwind method, to unwind THIS
-   frame's PC, returning the value of PC (the return address) in PREV
-   frame.
-
-   Traditionally, THIS frame's PC was unwound by examining THIS
-   frame's function prolog and identifying where (in a register or on
-   the stack) that return address was saved.
-
-   Please note that this per-frame method may be superseeded by an
-   architecture specific method that determines the unwound PC (aka
-   return address) using just the register unwind methods.
-
-   THIS_CACHE can be used to share any prologue analysis data with the
-   other unwind methods.  Memory for that cache should be allocated
-   using frame_obstack_zalloc().  */
-
-typedef CORE_ADDR (frame_unwind_pc_ftype) (struct frame_info *next_frame,
-					   void **this_cache);
-
-/* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
-   use the NEXT frame, and its register unwind method, to unwind THIS
    frame's entire stack, writing PREV's frames register values into
    REGCACHE.
 
@@ -151,7 +131,6 @@
   /* Should an attribute indicating the frame's address-in-block go
      here?  */
   frame_unwind_pop_ftype *pop;
-  frame_unwind_pc_ftype *pc;
   frame_unwind_id_ftype *id;
   frame_unwind_reg_ftype *reg;
 };
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 19:20:07 -0000
@@ -135,27 +135,54 @@
 }
 
 CORE_ADDR
-frame_pc_unwind (struct frame_info *this_frame)
+frame_pc_unwind (struct frame_info *next_frame)
 {
-  if (!this_frame->pc_unwind_cache_p)
+  if (!next_frame->pc_unwind_cache_p)
     {
-      this_frame->pc_unwind_cache
-	= this_frame->unwind->pc (this_frame->next, &this_frame->unwind_cache);
-      this_frame->pc_unwind_cache_p = 1;
-    }
-  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;
+      CORE_ADDR pc;
+      if (gdbarch_unwind_pc_p (current_gdbarch))
+	{
+	  /* The right way.  The `pure' way.  The one true way.  This
+	     method depends solely on the register-unwind code to
+	     determine the value of registers in THIS frame, and hence
+	     the value of this frame's PC (resume address).  A typical
+	     implementation is no more than:
+	   
+	     frame_unwind_register (next_frame, ISA_PC_REGNUM, buf);
+	     return extract_address (buf, size of ISA_PC_REGNUM);
+
+	     Note: this method is very heavily dependent on a correct
+	     register-unwind implementation, it pays to fix that
+	     method first; this method is frame type agnostic, since
+	     it only deals with register values, it works with any
+	     frame.  This is all in stark contrast to the old
+	     FRAME_SAVED_PC which would try to directly handle all the
+	     different ways that a PC could be unwound.  */
+	  pc = gdbarch_unwind_pc (current_gdbarch, next_frame);
+	}
+      else if (next_frame->level < 0)
+	{
+	  /* FIXME: cagney/2003-03-06: Old code and and a sentinel
+             frame.  Do like was always done.  Fetch the PC's value
+             direct from the global registers array (via read_pc).
+             This assumes that this frame belongs to the current
+             global register cache.  The assumption is dangerous.  */
+	  pc = read_pc ();
+	}
+      else if (FRAME_SAVED_PC_P ())
+	{
+	  /* FIXME: cagney/2003-03-06: Old code, but not a sentinel
+             frame.  Do like was always done.  Note that this method,
+             unlike unwind_pc(), tries to handle all the different
+             frame cases directly.  It fails.  */
+	  pc = FRAME_SAVED_PC (next_frame);
+	}
+      else
+	internal_error (__FILE__, __LINE__, "No gdbarch_unwind_pc method");
+      next_frame->pc_unwind_cache = pc;
+      next_frame->pc_unwind_cache_p = 1;
     }
-  return this_frame->id_unwind_cache;
+  return next_frame->pc_unwind_cache;
 }
 
 void
@@ -682,13 +709,6 @@
 		  bufferp);
 }
 
-static CORE_ADDR
-frame_saved_regs_pc_unwind (struct frame_info *frame, void **cache)
-{
-  gdb_assert (FRAME_SAVED_PC_P ());
-  return FRAME_SAVED_PC (frame);
-}
-	
 static void
 frame_saved_regs_id_unwind (struct frame_info *next_frame, void **cache,
 			    struct frame_id *id)
@@ -760,7 +780,6 @@
 
 const struct frame_unwind trad_frame_unwinder = {
   frame_saved_regs_pop,
-  frame_saved_regs_pc_unwind,
   frame_saved_regs_id_unwind,
   frame_saved_regs_register_unwind
 };
@@ -1346,83 +1365,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 +1580,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 19:20:07 -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: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.186.2.1
diff -u -r1.186.2.1 gdbarch.c
--- gdbarch.c	5 Mar 2003 05:00:03 -0000	1.186.2.1
+++ gdbarch.c	6 Mar 2003 19:20:08 -0000
@@ -242,6 +242,7 @@
   gdbarch_frame_chain_ftype *frame_chain;
   gdbarch_frame_chain_valid_ftype *frame_chain_valid;
   gdbarch_frame_saved_pc_ftype *frame_saved_pc;
+  gdbarch_unwind_pc_ftype *unwind_pc;
   gdbarch_frame_args_address_ftype *frame_args_address;
   gdbarch_frame_locals_address_ftype *frame_locals_address;
   gdbarch_saved_pc_after_call_ftype *saved_pc_after_call;
@@ -433,6 +434,7 @@
   0,
   0,
   0,
+  0,
   generic_in_function_epilogue_p,
   construct_inferior_arguments,
   0,
@@ -759,6 +761,7 @@
   /* Skip verify of frame_chain, has predicate */
   /* Skip verify of frame_chain_valid, has predicate */
   /* Skip verify of frame_saved_pc, has predicate */
+  /* Skip verify of unwind_pc, has predicate */
   /* Skip verify of frame_args_address, invalid_p == 0 */
   /* Skip verify of frame_locals_address, invalid_p == 0 */
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
@@ -2578,6 +2581,14 @@
     fprintf_unfiltered (file,
                         "gdbarch_dump: unwind_dummy_id = 0x%08lx\n",
                         (long) current_gdbarch->unwind_dummy_id);
+  if (GDB_MULTI_ARCH)
+    fprintf_unfiltered (file,
+                        "gdbarch_dump: gdbarch_unwind_pc_p() = %d\n",
+                        gdbarch_unwind_pc_p (current_gdbarch));
+  if (GDB_MULTI_ARCH)
+    fprintf_unfiltered (file,
+                        "gdbarch_dump: unwind_pc = 0x%08lx\n",
+                        (long) current_gdbarch->unwind_pc);
 #ifdef USE_STRUCT_CONVENTION
   fprintf_unfiltered (file,
                       "gdbarch_dump: %s # %s\n",
@@ -4843,6 +4854,32 @@
                             gdbarch_frame_saved_pc_ftype frame_saved_pc)
 {
   gdbarch->frame_saved_pc = frame_saved_pc;
+}
+
+int
+gdbarch_unwind_pc_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->unwind_pc != 0;
+}
+
+CORE_ADDR
+gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  gdb_assert (gdbarch != NULL);
+  if (gdbarch->unwind_pc == 0)
+    internal_error (__FILE__, __LINE__,
+                    "gdbarch: gdbarch_unwind_pc invalid");
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_pc called\n");
+  return gdbarch->unwind_pc (gdbarch, next_frame);
+}
+
+void
+set_gdbarch_unwind_pc (struct gdbarch *gdbarch,
+                       gdbarch_unwind_pc_ftype unwind_pc)
+{
+  gdbarch->unwind_pc = unwind_pc;
 }
 
 CORE_ADDR
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.147.2.1
diff -u -r1.147.2.1 gdbarch.h
--- gdbarch.h	5 Mar 2003 05:00:03 -0000	1.147.2.1
+++ gdbarch.h	6 Mar 2003 19:20:08 -0000
@@ -2230,6 +2230,8 @@
 #endif
 #endif
 
+/* NOTE: FRAME_SAVED_PC is replaced by UNWIND_PC */
+
 #if defined (FRAME_SAVED_PC)
 /* Legacy for systems yet to multi-arch FRAME_SAVED_PC */
 #if !defined (FRAME_SAVED_PC_P)
@@ -2266,6 +2268,12 @@
 #define FRAME_SAVED_PC(fi) (gdbarch_frame_saved_pc (current_gdbarch, fi))
 #endif
 #endif
+
+extern int gdbarch_unwind_pc_p (struct gdbarch *gdbarch);
+
+typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame);
+extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame);
+extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc);
 
 /* Default (function) for non- multi-arch platforms. */
 #if (!GDB_MULTI_ARCH) && !defined (FRAME_ARGS_ADDRESS)
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.199.2.1
diff -u -r1.199.2.1 gdbarch.sh
--- gdbarch.sh	5 Mar 2003 05:00:03 -0000	1.199.2.1
+++ gdbarch.sh	6 Mar 2003 19:20:09 -0000
@@ -591,7 +591,9 @@
 f:2:FRAMELESS_FUNCTION_INVOCATION:int:frameless_function_invocation:struct frame_info *fi:fi:::generic_frameless_function_invocation_not::0
 F:2:FRAME_CHAIN:CORE_ADDR:frame_chain:struct frame_info *frame:frame::0:0
 F:2:FRAME_CHAIN_VALID:int:frame_chain_valid:CORE_ADDR chain, struct frame_info *thisframe:chain, thisframe::0:0
+# NOTE: FRAME_SAVED_PC is replaced by UNWIND_PC
 F:2:FRAME_SAVED_PC:CORE_ADDR:frame_saved_pc:struct frame_info *fi:fi::0:0
+M::UNWIND_PC:CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame:
 f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:get_frame_base::0
 f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:get_frame_base::0
 f:2:SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame::0:0
Index: sentinel-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/sentinel-frame.c,v
retrieving revision 1.2.6.1
diff -u -r1.2.6.1 sentinel-frame.c
--- sentinel-frame.c	4 Mar 2003 23:15:24 -0000	1.2.6.1
+++ sentinel-frame.c	6 Mar 2003 19:20:09 -0000
@@ -76,17 +76,6 @@
     }
 }
 
-CORE_ADDR
-sentinel_frame_pc_unwind (struct frame_info *next_frame,
-			  void **this_cache)
-{
-  /* FIXME: cagney/2003-01-08: This should be using a per-architecture
-     method that doesn't suffer from DECR_PC_AFTER_BREAK problems.
-     Such a method would take unwind_cache, regcache and stop reason
-     parameters.  */
-  return read_pc ();
-}
-
 void
 sentinel_frame_id_unwind (struct frame_info *next_frame,
 			  void **this_cache,
@@ -106,7 +95,6 @@
 const struct frame_unwind sentinel_frame_unwinder =
 {
   sentinel_frame_pop,
-  sentinel_frame_pc_unwind,
   sentinel_frame_id_unwind,
   sentinel_frame_register_unwind
 };

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