2002-11-15 Andrew Cagney <ac131313@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Fri, 15 Nov 2002 22:16:25 +0000 (22:16 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 15 Nov 2002 22:16:25 +0000 (22:16 +0000)
* frame.c (frame_pc_unwind): New function.
(frame_saved_regs_pc_unwind): New function.
(frame_register_unwind): Pass unwind_cache instead of
register_unwind_cache.
(set_unwind_by_pc): Add unwind_pc parameter, set.
(create_new_frame): Pass frame->pc_unwind to set_unwind_by_pc.
(get_prev_frame): Ditto.
* frame.h (frame_pc_unwind_ftype): Declare.
(struct frame_info): Add pc_unwind, pc_unwind_cache_p and
pc_unwind_cache.  Rename register_unwind_cache to unwind_cache.
(frame_pc_unwind): Declare.
* dummy-frame.c (dummy_frame_pc_unwind): New function.
(struct dummy_frame): Add comment mentioning that values are for
previous frame.
* dummy-frame.h (dummy_frame_pc_unwind): Declare.
* blockframe.c (file_frame_chain_valid): Use frame_pc_unwind.
(generic_file_frame_chain_valid): Ditto.
* stack.c (frame_info): Ditto.

gdb/ChangeLog
gdb/blockframe.c
gdb/dummy-frame.c
gdb/dummy-frame.h
gdb/frame.c
gdb/frame.h
gdb/stack.c

index 397849bbfcd894bdd73b1733a061db8402262ba5..2fbb8fdb37abd42ad44a5407fa331349e9fd300e 100644 (file)
@@ -1,3 +1,24 @@
+2002-11-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.c (frame_pc_unwind): New function.
+       (frame_saved_regs_pc_unwind): New function.
+       (frame_register_unwind): Pass unwind_cache instead of
+       register_unwind_cache.
+       (set_unwind_by_pc): Add unwind_pc parameter, set.
+       (create_new_frame): Pass frame->pc_unwind to set_unwind_by_pc.
+       (get_prev_frame): Ditto.
+       * frame.h (frame_pc_unwind_ftype): Declare.
+       (struct frame_info): Add pc_unwind, pc_unwind_cache_p and
+       pc_unwind_cache.  Rename register_unwind_cache to unwind_cache.
+       (frame_pc_unwind): Declare.
+       * dummy-frame.c (dummy_frame_pc_unwind): New function.
+       (struct dummy_frame): Add comment mentioning that values are for
+       previous frame.
+       * dummy-frame.h (dummy_frame_pc_unwind): Declare.
+       * blockframe.c (file_frame_chain_valid): Use frame_pc_unwind.
+       (generic_file_frame_chain_valid): Ditto.
+       * stack.c (frame_info): Ditto.
+
 2002-11-15  David Carlton  <carlton@math.stanford.edu>
 
        * linespec.c (locate_first_half): New function.
index 1a2a5684e6c6af53af12c885194ea5e2e2588e7f..3e70b2a495d85931de241c4934ebc1cb2d8d91a0 100644 (file)
@@ -49,7 +49,7 @@ int
 file_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
 {
   return ((chain) != 0
-         && !inside_entry_file (FRAME_SAVED_PC (thisframe)));
+         && !inside_entry_file (frame_pc_unwind (thisframe)));
 }
 
 /* Use the alternate method of avoiding running up off the end of the
@@ -753,12 +753,12 @@ pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp,
 int
 generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
 {
-  if (PC_IN_CALL_DUMMY (FRAME_SAVED_PC (fi), fp, fp))
+  if (PC_IN_CALL_DUMMY (frame_pc_unwind (fi), fp, fp))
     return 1;                  /* don't prune CALL_DUMMY frames */
   else                         /* fall back to default algorithm (see frame.h) */
     return (fp != 0
            && (INNER_THAN (fi->frame, fp) || fi->frame == fp)
-           && !inside_entry_file (FRAME_SAVED_PC (fi)));
+           && !inside_entry_file (frame_pc_unwind (fi)));
 }
 
 int
index ddc4db8f4b36c88f9c79dec1e162163091fbf67c..06dacbbeed17f9cd57ae343e37f6c642b490e890 100644 (file)
@@ -37,6 +37,8 @@ struct dummy_frame
 {
   struct dummy_frame *next;
 
+  /* These values belong to the caller (the previous frame, the frame
+     that this unwinds back to).  */
   CORE_ADDR pc;
   CORE_ADDR fp;
   CORE_ADDR sp;
@@ -308,3 +310,16 @@ dummy_frame_register_unwind (struct frame_info *frame, void **cache,
     }
 }
 
+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;
+}
+
index bd4e199c758ca2cf63e501e34e47f1f929f1d455..d85fcfbe10a8f7cb281fa23003fbbee8e588c7de 100644 (file)
@@ -54,6 +54,12 @@ extern void dummy_frame_register_unwind (struct frame_info *frame,
                                         int *realnump,
                                         void *valuep);
 
+/* Assuming that FRAME is a dummy, return the resume address for the
+   previous frame.  */
+
+extern CORE_ADDR dummy_frame_pc_unwind (struct frame_info *frame,
+                                       void **unwind_cache);
+
 /* Return the regcache that belongs to the dummy-frame identifed by PC
    and FP, or NULL if no such frame exists.  */
 /* FIXME: cagney/2002-11-08: The function only exists because of
index bfefc77693448cc05c069542573a0c5f30bb0e6f..6cd1777c397fb4791e18cdf4a49f4d6fdea9eb4e 100644 (file)
@@ -84,6 +84,17 @@ frame_find_by_id (struct frame_id id)
   return NULL;
 }
 
+CORE_ADDR
+frame_pc_unwind (struct frame_info *frame)
+{
+  if (!frame->pc_unwind_cache_p)
+    {
+      frame->pc_unwind_cache = frame->pc_unwind (frame, &frame->unwind_cache);
+      frame->pc_unwind_cache_p = 1;
+    }
+  return frame->pc_unwind_cache;
+}
+
 void
 frame_register_unwind (struct frame_info *frame, int regnum,
                       int *optimizedp, enum lval_type *lvalp,
@@ -124,7 +135,7 @@ frame_register_unwind (struct frame_info *frame, int regnum,
     }
 
   /* Ask this frame to unwind its register.  */
-  frame->register_unwind (frame, &frame->register_unwind_cache, regnum,
+  frame->register_unwind (frame, &frame->unwind_cache, regnum,
                          optimizedp, lvalp, addrp, realnump, bufferp);
 }
 
@@ -524,6 +535,12 @@ frame_saved_regs_register_unwind (struct frame_info *frame, void **cache,
     }
 }
 
+static CORE_ADDR
+frame_saved_regs_pc_unwind (struct frame_info *frame, void **cache)
+{
+  return FRAME_SAVED_PC (frame);
+}
+       
 /* Function: get_saved_register
    Find register number REGNUM relative to FRAME and put its (raw,
    target format) contents in *RAW_BUFFER.  
@@ -627,18 +644,28 @@ deprecated_generic_get_saved_register (char *raw_buffer, int *optimized,
 
 static void
 set_unwind_by_pc (CORE_ADDR pc, CORE_ADDR fp,
-                 frame_register_unwind_ftype **unwind)
+                 frame_register_unwind_ftype **unwind_register,
+                 frame_pc_unwind_ftype **unwind_pc)
 {
   if (!USE_GENERIC_DUMMY_FRAMES)
-    /* Still need to set this to something.  The ``info frame'' code
-       calls this function to find out where the saved registers are.
-       Hopefully this is robust enough to stop any core dumps and
-       return vaguely correct values..  */
-    *unwind = frame_saved_regs_register_unwind;
+    {
+      /* Still need to set this to something.  The ``info frame'' code
+        calls this function to find out where the saved registers are.
+        Hopefully this is robust enough to stop any core dumps and
+        return vaguely correct values..  */
+      *unwind_register = frame_saved_regs_register_unwind;
+      *unwind_pc = frame_saved_regs_pc_unwind;
+    }
   else if (PC_IN_CALL_DUMMY (pc, fp, fp))
-    *unwind = dummy_frame_register_unwind;
+    {
+      *unwind_register = dummy_frame_register_unwind;
+      *unwind_pc = dummy_frame_pc_unwind;
+    }
   else
-    *unwind = frame_saved_regs_register_unwind;
+    {
+      *unwind_register = frame_saved_regs_register_unwind;
+      *unwind_pc = frame_saved_regs_pc_unwind;
+    }
 }
 
 /* Create an arbitrary (i.e. address specified by user) or innermost frame.
@@ -666,7 +693,8 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
     INIT_EXTRA_FRAME_INFO (0, fi);
 
   /* Select/initialize an unwind function.  */
-  set_unwind_by_pc (fi->pc, fi->frame, &fi->register_unwind);
+  set_unwind_by_pc (fi->pc, fi->frame, &fi->register_unwind,
+                   &fi->pc_unwind);
 
   return fi;
 }
@@ -913,7 +941,8 @@ get_prev_frame (struct frame_info *next_frame)
      (and probably other architectural information).  The PC lets you
      check things like the debug info at that point (dwarf2cfi?) and
      use that to decide how the frame should be unwound.  */
-  set_unwind_by_pc (prev->pc, prev->frame, &prev->register_unwind);
+  set_unwind_by_pc (prev->pc, prev->frame, &prev->register_unwind,
+                   &prev->pc_unwind);
 
   find_pc_partial_function (prev->pc, &name,
                            (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
index 70d85f13c9c6cdda83958ec99634d2ef994f71a8..a371a58de424923a4598c60d729df9fd7538f0fa 100644 (file)
@@ -139,6 +139,12 @@ extern void frame_read_unsigned_register (struct frame_info *frame,
 extern int frame_map_name_to_regnum (const char *name, int strlen);
 extern const char *frame_map_regnum_to_name (int regnum);
 
+/* Unwind the PC.  Strictly speaking return the resume address of the
+   calling frame.  For GDB, `pc' is the resume address and not a
+   specific register.  */
+
+extern CORE_ADDR frame_pc_unwind (struct frame_info *frame);
+
 \f
 /* Return the location (and possibly value) of REGNUM for the previous
    (older, up) frame.  All parameters except VALUEP can be assumed to
@@ -163,6 +169,12 @@ typedef void (frame_register_unwind_ftype) (struct frame_info *frame,
                                            int *realnump,
                                            void *valuep);
 
+/* Same as for registers above, but return the address at which the
+   calling frame would resume.  */
+
+typedef CORE_ADDR (frame_pc_unwind_ftype) (struct frame_info *frame,
+                                          void **unwind_cache);
+
 /* Describe the saved registers of a frame.  */
 
 #if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS)
@@ -252,10 +264,18 @@ struct frame_info
        related unwind data.  */
     struct context *context;
 
-    /* See description above.  Return the register value for the
-       previous frame.  */
+    /* Unwind cache shared between the unwind functions - they had
+       better all agree as to the contents.  */
+    void *unwind_cache;
+
+    /* See description above.  The previous frame's registers.  */
     frame_register_unwind_ftype *register_unwind;
-    void *register_unwind_cache;
+
+    /* See description above.  The previous frame's resume address.
+       Save the previous PC in a local cache.  */
+    frame_pc_unwind_ftype *pc_unwind;
+    int pc_unwind_cache_p;
+    CORE_ADDR pc_unwind_cache;
 
     /* Pointers to the next (down, inner, younger) and previous (up,
        outer, older) frame_info's in the frame cache.  */
index b9a3033d87dea9d0f116072eeca53432ee903b4b..ba7edd51275c4cc5fcc05ff9cfe48a1ea601b5ba 100644 (file)
@@ -866,7 +866,7 @@ frame_info (char *addr_exp, int from_tty)
   puts_filtered ("; ");
   wrap_here ("    ");
   printf_filtered ("saved %s ", REGISTER_NAME (PC_REGNUM));
-  print_address_numeric (FRAME_SAVED_PC (fi), 1, gdb_stdout);
+  print_address_numeric (frame_pc_unwind (fi), 1, gdb_stdout);
   printf_filtered ("\n");
 
   {