2003-03-10 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Mon, 10 Mar 2003 15:28:41 +0000 (15:28 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 10 Mar 2003 15:28:41 +0000 (15:28 +0000)
* 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.

Index: doc/ChangeLog
2003-03-10  Andrew Cagney  <cagney@redhat.com>

* gdbint.texinfo (Target Architecture Definition): Cross reference
FRAME_SAVED_PC to unwind_pc.  Document unwind_pc.

gdb/ChangeLog
gdb/d10v-tdep.c
gdb/doc/ChangeLog
gdb/doc/gdbint.texinfo
gdb/dummy-frame.c
gdb/frame-unwind.h
gdb/frame.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/sentinel-frame.c

index a50510366b9108d0be97f05b8af30df4944c8eec..4a4a5f43e55c82f545151581795e5794f0f1f018 100644 (file)
@@ -1,3 +1,22 @@
+2003-03-10  Andrew Cagney  <cagney@redhat.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-10  Andrew Cagney  <cagney@redhat.com>
 
        * gdbarch.h: Re-generate.
index b50cfa75a8fdeabab77687324dfa1ead0fd9b219..516cde468ad625270aeabe7c5b2bf8c47a63b3d5 100644 (file)
@@ -1445,13 +1445,12 @@ display_trace (int low, int high)
     }
 }
 
-
 static CORE_ADDR
-d10v_frame_pc_unwind (struct frame_info *frame,
-                     void **cache)
+d10v_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  struct d10v_unwind_cache *info = d10v_frame_unwind_cache (frame, cache);
-  return info->return_pc;
+  ULONGEST pc;
+  frame_unwind_unsigned_register (next_frame, PC_REGNUM, &pc);
+  return d10v_make_iaddr (pc);
 }
 
 /* Given a GDB frame, determine the address of the calling function's
@@ -1612,7 +1611,6 @@ d10v_frame_pop (struct frame_info *fi, void **unwind_cache,
 
 static struct frame_unwind d10v_frame_unwind = {
   d10v_frame_pop,
-  d10v_frame_pc_unwind,
   d10v_frame_id_unwind,
   d10v_frame_register_unwind
 };
@@ -1780,6 +1778,9 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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 4971d3268fac6c72eb75177e8e1864e8c0395316..603675878e5014079d6d1ae1f3fa408ea436b4dc 100644 (file)
@@ -1,3 +1,8 @@
+2003-03-10  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbint.texinfo (Target Architecture Definition): Cross reference
+       FRAME_SAVED_PC to unwind_pc.  Document unwind_pc.
+
 2003-03-07  Andrew Cagney  <cagney@redhat.com>
 
        * gdb.texinfo (Debugging Output): Mention the "set/show debug
index 7deabfc6d3723e957e63a926fdeab7eaa4d4f843..625f6213e1edd80f58e510e1fc34a157602a4530 100644 (file)
@@ -3270,8 +3270,28 @@ are being passed.  If the number of arguments is not known, return
 
 @item FRAME_SAVED_PC(@var{frame})
 @findex FRAME_SAVED_PC
-Given @var{frame}, return the pc saved there.  This is the return
-address.
+@anchor{FRAME_SAVED_PC} Given @var{frame}, return the pc saved there.
+This is the return address.
+
+This method is deprecated. @xref{unwind_pc}.
+
+@item CORE_ADDR unwind_pc (struct frame_info *@var{this_frame})
+@findex unwind_pc
+@anchor{unwind_pc} Return the instruction address, in @var{this_frame}'s
+caller, at which execution will resume after @var{this_frame} returns.
+This is commonly refered to as the return address.
+
+The implementation, which must be frame agnostic (work with any frame),
+is typically no more than:
+
+@smallexample
+ULONGEST pc;
+frame_unwind_unsigned_register (this_frame, D10V_PC_REGNUM, &pc);
+return d10v_make_iaddr (pc);
+@end smallexample
+
+@noindent
+@xref{FRAME_SAVED_PC}, which this method replaces.
 
 @item FUNCTION_EPILOGUE_SIZE
 @findex FUNCTION_EPILOGUE_SIZE
index 5b638306fd3956ed7733e96f0308e92d7e3fecc8..95c859889a8e9e0a1c8a4bb03738ae10c16e89fd 100644 (file)
@@ -370,23 +370,6 @@ dummy_frame_register_unwind (struct frame_info *frame, void **cache,
     }
 }
 
-/* Assuming that FRAME is a dummy, return the resume address for the
-   previous frame.  */
-
-static CORE_ADDR
-dummy_frame_pc_unwind (struct frame_info *frame,
-                      void **cache)
-{
-  struct dummy_frame *dummy = cached_find_dummy_frame (frame, 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).  */
 
@@ -408,7 +391,6 @@ dummy_frame_id_unwind (struct frame_info *frame,
 static struct frame_unwind dummy_frame_unwind =
 {
   dummy_frame_pop,
-  dummy_frame_pc_unwind,
   dummy_frame_id_unwind,
   dummy_frame_register_unwind
 };
index 2c67c969fb1a8177de6aadebb56026bf605a3a38..7f4a866b1ebb00a8ae6c9639ab7311b058a5064c 100644 (file)
@@ -69,12 +69,6 @@ typedef void (frame_unwind_reg_ftype) (struct frame_info * frame,
                                       CORE_ADDR *addrp,
                                       int *realnump, void *valuep);
 
-/* Same as for registers above, but return the address at which the
-   calling frame would resume.  */
-
-typedef CORE_ADDR (frame_unwind_pc_ftype) (struct frame_info * frame,
-                                          void **unwind_cache);
-
 /* Same as for registers above, but return the ID of the frame that
    called this one.  */
 
@@ -103,7 +97,6 @@ struct frame_unwind
   /* 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 bf860fe2ccd03414341a8fbf8b0aaf34653097ac..bbe870af0f7e5f80140abf7235ac1ee39c75c158 100644 (file)
@@ -135,14 +135,54 @@ frame_find_by_id (struct frame_id id)
 }
 
 CORE_ADDR
-frame_pc_unwind (struct frame_info *frame)
+frame_pc_unwind (struct frame_info *this_frame)
 {
-  if (!frame->pc_unwind_cache_p)
+  if (!this_frame->pc_unwind_cache_p)
     {
-      frame->pc_unwind_cache = frame->unwind->pc (frame, &frame->unwind_cache);
-      frame->pc_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 (this_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, this_frame);
+       }
+      else if (this_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 (this_frame);
+       }
+      else
+       internal_error (__FILE__, __LINE__, "No gdbarch_unwind_pc method");
+      this_frame->pc_unwind_cache = pc;
+      this_frame->pc_unwind_cache_p = 1;
     }
-  return frame->pc_unwind_cache;
+  return this_frame->pc_unwind_cache;
 }
 
 void
@@ -667,13 +707,6 @@ frame_saved_regs_register_unwind (struct frame_info *frame, void **cache,
                  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)
@@ -745,7 +778,6 @@ frame_saved_regs_pop (struct frame_info *fi, void **cache,
 
 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
 };
index 636349c7be2aa3cc0c57e148b58950750f14e18a..8b5a475375ccd9956144c34fb31a4421ce6c01c4 100644 (file)
@@ -242,6 +242,7 @@ struct gdbarch
   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 @@ struct gdbarch startup_gdbarch =
   0,
   0,
   0,
+  0,
   generic_in_function_epilogue_p,
   construct_inferior_arguments,
   0,
@@ -759,6 +761,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* 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 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
     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",
@@ -4845,6 +4856,32 @@ set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch,
   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
 gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi)
 {
index 75d96edd130317c4fccbe52cf0eb05c669213c52..abb454a3a080fbdd4554d8b28874e772070b3e83 100644 (file)
@@ -2228,6 +2228,8 @@ extern void set_gdbarch_frame_chain_valid (struct gdbarch *gdbarch, gdbarch_fram
 #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)
@@ -2265,6 +2267,12 @@ extern void set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch, gdbarch_frame_s
 #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)
 #define FRAME_ARGS_ADDRESS(fi) (get_frame_base (fi))
index 5d41b5c691c4f1776a899ab26183223f76736cde..77d2a69569482b3ad5b36439f66f8a554fa2bfde 100755 (executable)
@@ -591,7 +591,9 @@ v:2:FRAME_ARGS_SKIP:CORE_ADDR:frame_args_skip::::0:-1
 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 fe11d8a6f43ac10c5f48001616b889ba9b507e79..2b1616a1f8cacb4fc6758e16cc10aa7751d14c5b 100644 (file)
@@ -70,17 +70,6 @@ sentinel_frame_register_unwind (struct frame_info *frame,
     }
 }
 
-CORE_ADDR
-sentinel_frame_pc_unwind (struct frame_info *frame,
-                         void **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 *frame,
                          void **cache,
@@ -105,7 +94,6 @@ sentinel_frame_pop (struct frame_info *frame,
 const struct frame_unwind sentinel_frame_unwinder =
 {
   sentinel_frame_pop,
-  sentinel_frame_pc_unwind,
   sentinel_frame_id_unwind,
   sentinel_frame_register_unwind
 };