aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2003-07-11 14:54:14 +0000
committerAndrew Cagney <cagney@redhat.com>2003-07-11 14:54:14 +0000
commitd9b4458e794c2dabace4da12bcfab6b4e6430dc6 (patch)
tree4bbbe3ffc4a5b07d27531a747553eebc20d82567
parent69909394d45f5041458396bf8c36062fab8bb792 (diff)
downloadgdb-d9b4458e794c2dabace4da12bcfab6b4e6430dc6.zip
gdb-d9b4458e794c2dabace4da12bcfab6b4e6430dc6.tar.gz
gdb-d9b4458e794c2dabace4da12bcfab6b4e6430dc6.tar.bz2
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.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/frame.c27
-rw-r--r--gdb/frame.h18
3 files changed, 52 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 18600f7..5b8cc84 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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-09 Andreas Schwab <schwab@suse.de>
* m68k-tdep.h (enum struct_return): Define.
diff --git a/gdb/frame.c b/gdb/frame.c
index 087a9f0..fc01e3c 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -2033,6 +2033,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)
{
diff --git a/gdb/frame.h b/gdb/frame.h
index 87c2057..bb2eb6e 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -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. */
@@ -524,6 +540,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);