* dwarf2-frame.c (dwarf2_frame_cache): Update comment.
* frame.c (frame_unwind_address_in_block): Delete. (get_frame_address_in_block): Do not use it. Check the type of the next frame first. (frame_cleanup_after_sniffer): Update comment. * frame.h (frame_unwind_address_in_block): Delete prototype. * hppa-tdep.c (hppa_find_unwind_entry_in_block): Update comment.
This commit is contained in:
parent
ef02daa9e6
commit
ad1193e7ad
@ -1,3 +1,13 @@
|
||||
2008-07-15 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* dwarf2-frame.c (dwarf2_frame_cache): Update comment.
|
||||
* frame.c (frame_unwind_address_in_block): Delete.
|
||||
(get_frame_address_in_block): Do not use it. Check the type
|
||||
of the next frame first.
|
||||
(frame_cleanup_after_sniffer): Update comment.
|
||||
* frame.h (frame_unwind_address_in_block): Delete prototype.
|
||||
* hppa-tdep.c (hppa_find_unwind_entry_in_block): Update comment.
|
||||
|
||||
2008-07-15 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* frame.c (frame_func_unwind): Delete.
|
||||
|
@ -900,7 +900,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
|
||||
instruction in the associated delay slot). This should only be
|
||||
done for "normal" frames and not for resume-type frames (signal
|
||||
handlers, sentinel frames, dummy frames). The function
|
||||
frame_unwind_address_in_block does just this. It's not clear how
|
||||
get_frame_address_in_block does just this. It's not clear how
|
||||
reliable the method is though; there is the potential for the
|
||||
register state pre-call being different to that on return. */
|
||||
fs->pc = get_frame_address_in_block (this_frame);
|
||||
|
79
gdb/frame.c
79
gdb/frame.c
@ -1536,43 +1536,54 @@ get_frame_pc (struct frame_info *frame)
|
||||
return frame_pc_unwind (frame->next);
|
||||
}
|
||||
|
||||
/* Return an address that falls within NEXT_FRAME's caller's code
|
||||
block, assuming that the caller is a THIS_TYPE frame. */
|
||||
|
||||
CORE_ADDR
|
||||
frame_unwind_address_in_block (struct frame_info *next_frame,
|
||||
enum frame_type this_type)
|
||||
{
|
||||
/* A draft address. */
|
||||
CORE_ADDR pc = frame_pc_unwind (next_frame);
|
||||
|
||||
/* If NEXT_FRAME was called by a signal frame or dummy frame, then
|
||||
we shold not adjust the unwound PC. These frames may not call
|
||||
their next frame in the normal way; the operating system or GDB
|
||||
may have pushed their resume address manually onto the stack, so
|
||||
it may be the very first instruction. Even if the resume address
|
||||
was not manually pushed, they expect to be returned to. */
|
||||
if (this_type != NORMAL_FRAME)
|
||||
return pc;
|
||||
|
||||
/* 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 following 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;
|
||||
}
|
||||
/* Return an address that falls within THIS_FRAME's code block. */
|
||||
|
||||
CORE_ADDR
|
||||
get_frame_address_in_block (struct frame_info *this_frame)
|
||||
{
|
||||
return frame_unwind_address_in_block (this_frame->next,
|
||||
get_frame_type (this_frame));
|
||||
/* A draft address. */
|
||||
CORE_ADDR pc = get_frame_pc (this_frame);
|
||||
|
||||
struct frame_info *next_frame = this_frame->next;
|
||||
|
||||
/* Calling get_frame_pc returns the resume address for THIS_FRAME.
|
||||
Normally the resume address is inside the body of the function
|
||||
associated with THIS_FRAME, but there is a special case: when
|
||||
calling a function which the compiler knows will never return
|
||||
(for instance abort), the call may be the very last instruction
|
||||
in the calling function. The resume address will point after the
|
||||
call and may be at the beginning of a different function
|
||||
entirely.
|
||||
|
||||
If THIS_FRAME is a signal frame or dummy frame, then we should
|
||||
not adjust the unwound PC. For a dummy frame, GDB pushed the
|
||||
resume address manually onto the stack. For a signal frame, the
|
||||
OS may have pushed the resume address manually and invoked the
|
||||
handler (e.g. GNU/Linux), or invoked the trampoline which called
|
||||
the signal handler - but in either case the signal handler is
|
||||
expected to return to the trampoline. So in both of these
|
||||
cases we know that the resume address is executable and
|
||||
related. So we only need to adjust the PC if THIS_FRAME
|
||||
is a normal function.
|
||||
|
||||
If the program has been interrupted while THIS_FRAME is current,
|
||||
then clearly the resume address is inside the associated
|
||||
function. There are three kinds of interruption: debugger stop
|
||||
(next frame will be SENTINEL_FRAME), operating system
|
||||
signal or exception (next frame will be SIGTRAMP_FRAME),
|
||||
or debugger-induced function call (next frame will be
|
||||
DUMMY_FRAME). So we only need to adjust the PC if
|
||||
NEXT_FRAME is a normal function.
|
||||
|
||||
We check the type of NEXT_FRAME first, since it is already
|
||||
known; frame type is determined by the unwinder, and since
|
||||
we have THIS_FRAME we've already selected an unwinder for
|
||||
NEXT_FRAME. */
|
||||
if (get_frame_type (next_frame) == NORMAL_FRAME
|
||||
&& get_frame_type (this_frame) == NORMAL_FRAME)
|
||||
return pc - 1;
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1835,7 +1846,7 @@ frame_cleanup_after_sniffer (void *arg)
|
||||
/* Clear cached fields dependent on the unwinder.
|
||||
|
||||
The previous PC is independent of the unwinder, but the previous
|
||||
function is not (see frame_unwind_address_in_block). */
|
||||
function is not (see get_frame_address_in_block). */
|
||||
frame->prev_func.p = 0;
|
||||
frame->prev_func.addr = 0;
|
||||
|
||||
|
@ -281,13 +281,6 @@ extern CORE_ADDR get_frame_pc (struct frame_info *);
|
||||
|
||||
extern CORE_ADDR get_frame_address_in_block (struct frame_info *this_frame);
|
||||
|
||||
/* Similar to get_frame_address_in_block, find an address in the
|
||||
block which logically called NEXT_FRAME, assuming it is a THIS_TYPE
|
||||
frame. */
|
||||
|
||||
extern CORE_ADDR frame_unwind_address_in_block (struct frame_info *next_frame,
|
||||
enum frame_type this_type);
|
||||
|
||||
/* The frame's inner-most bound. AKA the stack-pointer. Confusingly
|
||||
known as top-of-stack. */
|
||||
|
||||
|
@ -1792,7 +1792,7 @@ hppa_find_unwind_entry_in_block (struct frame_info *this_frame)
|
||||
CORE_ADDR pc = get_frame_address_in_block (this_frame);
|
||||
|
||||
/* FIXME drow/20070101: Calling gdbarch_addr_bits_remove on the
|
||||
result of frame_unwind_address_in_block implies a problem.
|
||||
result of get_frame_address_in_block implies a problem.
|
||||
The bits should have been removed earlier, before the return
|
||||
value of frame_pc_unwind. That might be happening already;
|
||||
if it isn't, it should be fixed. Then this call can be
|
||||
|
Loading…
x
Reference in New Issue
Block a user