From: Joel Brobecker Date: Tue, 2 Jul 2002 19:08:55 +0000 (+0000) Subject: * frame.h (frame_address_in_block): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=42f99ac23d53ee64774126aa640be47c2cbbd998;p=binutils-gdb.git * frame.h (frame_address_in_block): New function. * blockframe.c (frame_address_in_block): New function extracted from get_frame_block(). (get_frame_block): Use frame_address_in_block(). (block_innermost_frame): Use frame_address_in_block() to match the frame pc address against the block boundaries rather than the frame pc directly. This prevents a failure when a frame pc is actually a return-address pointing immediately after the end of the given block. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a6576bd65ae..591e7fe6e42 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2002-07-02 Joel Brobecker + + * frame.h (frame_address_in_block): New function. + + * blockframe.c (frame_address_in_block): New function extracted + from get_frame_block(). + (get_frame_block): Use frame_address_in_block(). + (block_innermost_frame): Use frame_address_in_block() to match + the frame pc address against the block boundaries rather than + the frame pc directly. This prevents a failure when a frame pc + is actually a return-address pointing immediately after the end + of the given block. + 2002-07-02 Grace Sainsbury * MAINTAINERS: Add self under write after approval. diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 9971e5dff33..8f95a891291 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -528,6 +528,26 @@ get_frame_pc (struct frame_info *frame) return frame->pc; } +/* return the address of the PC for the given FRAME, ie the current PC value + if FRAME is the innermost frame, or the address adjusted to point to the + call instruction if not. */ + +CORE_ADDR +frame_address_in_block (struct frame_info *frame) +{ + CORE_ADDR pc = frame->pc; + + /* If we are not in the innermost frame, and we are not interrupted + by a signal, frame->pc points to the instruction following the + call. As a consequence, we need to get the address of the previous + instruction. Unfortunately, this is not straightforward to do, so + we just use the address minus one, which is a good enough + approximation. */ + if (frame->next != 0 && frame->next->signal_handler_caller == 0) + --pc; + + return pc; +} #ifdef FRAME_FIND_SAVED_REGS /* XXX - deprecated. This is a compatibility function for targets @@ -576,17 +596,7 @@ get_frame_saved_regs (struct frame_info *frame, struct block * get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block) { - CORE_ADDR pc; - - pc = frame->pc; - if (frame->next != 0 && frame->next->signal_handler_caller == 0) - /* We are not in the innermost frame and we were not interrupted - by a signal. We need to subtract one to get the correct block, - in case the call instruction was the last instruction of the block. - If there are any machines on which the saved pc does not point to - after the call insn, we probably want to make frame->pc point after - the call insn anyway. */ - --pc; + const CORE_ADDR pc = frame_address_in_block (frame); if (addr_in_block) *addr_in_block = pc; @@ -970,6 +980,7 @@ block_innermost_frame (struct block *block) struct frame_info *frame; register CORE_ADDR start; register CORE_ADDR end; + CORE_ADDR calling_pc; if (block == NULL) return NULL; @@ -983,7 +994,8 @@ block_innermost_frame (struct block *block) frame = get_prev_frame (frame); if (frame == NULL) return NULL; - if (frame->pc >= start && frame->pc < end) + calling_pc = frame_address_in_block (frame); + if (calling_pc >= start && calling_pc < end) return frame; } } diff --git a/gdb/frame.h b/gdb/frame.h index d3bd2ab4d51..20ffff00daf 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -250,6 +250,8 @@ extern struct symbol *get_frame_function (struct frame_info *); extern CORE_ADDR get_frame_pc (struct frame_info *); +extern CORE_ADDR frame_address_in_block (struct frame_info *); + extern CORE_ADDR get_pc_function_start (CORE_ADDR); extern struct block *block_for_pc (CORE_ADDR);