diff options
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/blockframe.c | 4 | ||||
-rw-r--r-- | gdb/frame.c | 27 | ||||
-rw-r--r-- | gdb/frame.h | 18 | ||||
-rw-r--r-- | gdb/stack.c | 8 |
5 files changed, 58 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 99e1b3d..c88156e 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-10 Andrew Cagney <cagney@redhat.com> * gdbarch.sh: Simplify predicate methods. Remove need to provide diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 9f91226..dd716c5 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -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; } diff --git a/gdb/frame.c b/gdb/frame.c index 23fb5b1..1e364bd 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -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) { diff --git a/gdb/frame.h b/gdb/frame.h index e821db6..56cb72e 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. */ @@ -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); diff --git a/gdb/stack.c b/gdb/stack.c index ff098a1..d3e8ac9 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -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 */ } |