2003-07-11 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Fri, 11 Jul 2003 14:52:17 +0000 (14:52 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 11 Jul 2003 14:52:17 +0000 (14:52 +0000)
* frame.h (get_frame_address_in_block): Declare.
(frame_unwind_address_in_block): Declare.
* frame.c (frame_unwind_address_in_block): New function.
(get_frame_address_in_block): New function.

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

index 99e1b3dfd4bf817d9dedcab379bb5146e23a7506..c88156e499fd5ab99eccb542913f28e65b1925be 100644 (file)
@@ -1,3 +1,10 @@
+2003-07-11  Andrew Cagney  <cagney@redhat.com>
+
+       * frame.h (get_frame_address_in_block): Declare.
+       (frame_unwind_address_in_block): Declare.
+       * frame.c (frame_unwind_address_in_block): New function.
+       (get_frame_address_in_block): New function.
+
 2003-07-10  Andrew Cagney  <cagney@redhat.com>
 
        * gdbarch.sh: Simplify predicate methods.  Remove need to provide
index 9f9122674678a5c0ca895826677a486512a6bd4e..dd716c54dcc5873355a249b8f9216608a1b08fc8 100644 (file)
@@ -212,7 +212,7 @@ frame_address_in_block (struct frame_info *frame)
 struct block *
 get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block)
 {
-  const CORE_ADDR pc = frame_address_in_block (frame);
+  const CORE_ADDR pc = get_frame_address_in_block (frame);
 
   if (addr_in_block)
     *addr_in_block = pc;
@@ -512,7 +512,7 @@ block_innermost_frame (struct block *block)
       frame = get_prev_frame (frame);
       if (frame == NULL)
        return NULL;
-      calling_pc = frame_address_in_block (frame);
+      calling_pc = get_frame_address_in_block (frame);
       if (calling_pc >= start && calling_pc < end)
        return frame;
     }
index 23fb5b17f6299b3c28ebb280f8615976edde7d12..1e364bdcb78855916132466ea0f62fd4ad15e2bc 100644 (file)
@@ -2006,6 +2006,33 @@ get_frame_pc (struct frame_info *frame)
   return frame_pc_unwind (frame->next);
 }
 
+/* Return an address of that falls within the frame's code block.  */
+
+CORE_ADDR
+frame_unwind_address_in_block (struct frame_info *next_frame)
+{
+  /* A draft address.  */
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
+
+  /* If THIS frame is not inner most (i.e., NEXT isn't the sentinel),
+     and NEXT is `normal' (i.e., not a sigtramp, dummy, ....) THIS
+     frame's PC ends up pointing at the instruction fallowing the
+     "call".  Adjust that PC value so that it falls on the call
+     instruction (which, hopefully, falls within THIS frame's code
+     block.  So far it's proved to be a very good approximation.  See
+     get_frame_type for why ->type can't be used.  */
+  if (next_frame->level >= 0
+      && get_frame_type (next_frame) == NORMAL_FRAME)
+    --pc;
+  return pc;
+}
+
+CORE_ADDR
+get_frame_address_in_block (struct frame_info *this_frame)
+{
+  return frame_unwind_address_in_block (this_frame->next);
+}
+
 static int
 pc_notcurrent (struct frame_info *frame)
 {
index e821db6912bb2266f39e3e10c7a511989da2b297..56cb72e12502e372afeff32fdf96b637cdb2ff3c 100644 (file)
@@ -214,6 +214,22 @@ extern struct frame_info *frame_find_by_id (struct frame_id id);
    This replaced: frame->pc; */
 extern CORE_ADDR get_frame_pc (struct frame_info *);
 
+/* An address (not necessarily alligned to an instruction boundary)
+   that falls within THIS frame's code block.
+
+   When a function call is the last statement in a block, the return
+   address for the call may land at the start of the next block.
+   Similarly, if a no-return function call is the last statement in
+   the function, the return address may end up pointing beyond the
+   function, and possibly at the start of the next function.
+
+   These methods make an allowance for this.  For call frames, this
+   function returns the frame's PC-1 which "should" be an address in
+   the frame's block.  */
+
+extern CORE_ADDR get_frame_address_in_block (struct frame_info *this_frame);
+extern CORE_ADDR frame_unwind_address_in_block (struct frame_info *next_frame);
+
 /* The frame's inner-most bound.  AKA the stack-pointer.  Confusingly
    known as top-of-stack.  */
 
@@ -526,6 +542,8 @@ extern struct block *get_selected_block (CORE_ADDR *addr_in_block);
 
 extern struct symbol *get_frame_function (struct frame_info *);
 
+/* DEPRECATED: Replaced by tye pair get_frame_address_in_block and
+   frame_unwind_address_in_block.  */
 extern CORE_ADDR frame_address_in_block (struct frame_info *);
 
 extern CORE_ADDR get_pc_function_start (CORE_ADDR);
index ff098a1e38a1e84fd2e9e49cd767a8c3b3672ce8..d3e8ac916af85d0c15571f4386fd8071b5e60998 100644 (file)
@@ -547,7 +547,7 @@ print_frame (struct frame_info *fi,
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
 
-  func = find_pc_function (frame_address_in_block (fi));
+  func = find_pc_function (get_frame_address_in_block (fi));
   if (func)
     {
       /* In certain pathological cases, the symtabs give the wrong
@@ -566,7 +566,7 @@ print_frame (struct frame_info *fi,
          ever changed many parts of GDB will need to be changed (and we'll
          create a find_pc_minimal_function or some such).  */
 
-      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (frame_address_in_block (fi));
+      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_address_in_block (fi));
       if (msymbol != NULL
          && (SYMBOL_VALUE_ADDRESS (msymbol)
              > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
@@ -614,7 +614,7 @@ print_frame (struct frame_info *fi,
     }
   else
     {
-      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (frame_address_in_block (fi));
+      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_address_in_block (fi));
       if (msymbol != NULL)
        {
          funname = DEPRECATED_SYMBOL_NAME (msymbol);
@@ -1206,7 +1206,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
           fi = get_prev_frame (fi))
        {
          QUIT;
-         ps = find_pc_psymtab (frame_address_in_block (fi));
+         ps = find_pc_psymtab (get_frame_address_in_block (fi));
          if (ps)
            PSYMTAB_TO_SYMTAB (ps);     /* Force syms to come in */
        }