mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-01 22:42:18 +00:00
* frame.c (frame_register_unwind_location): New function.
(get_prev_frame_1): Check for UNWIND_NO_SAVED_PC. (frame_stop_reason_string): Handle UNWIND_NO_SAVED_PC. * frame.h (enum unwind_stop_reason): Add UNWIND_NO_SAVED_PC.
This commit is contained in:
parent
7a10774786
commit
e48af409a9
@ -1,3 +1,10 @@
|
|||||||
|
2006-11-10 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
|
* frame.c (frame_register_unwind_location): New function.
|
||||||
|
(get_prev_frame_1): Check for UNWIND_NO_SAVED_PC.
|
||||||
|
(frame_stop_reason_string): Handle UNWIND_NO_SAVED_PC.
|
||||||
|
* frame.h (enum unwind_stop_reason): Add UNWIND_NO_SAVED_PC.
|
||||||
|
|
||||||
2006-11-10 Daniel Jacobowitz <dan@codesourcery.com>
|
2006-11-10 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
* arch-utils.c (target_byte_order_user): Renamed from
|
* arch-utils.c (target_byte_order_user): Renamed from
|
||||||
|
69
gdb/frame.c
69
gdb/frame.c
@ -1023,6 +1023,36 @@ reinit_frame_cache (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find where a register is saved (in memory or another register).
|
||||||
|
The result of frame_register_unwind is just where it is saved
|
||||||
|
relative to this particular frame.
|
||||||
|
|
||||||
|
FIXME: alpha, m32c, and h8300 actually do the transitive operation
|
||||||
|
themselves. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
frame_register_unwind_location (struct frame_info *this_frame, int regnum,
|
||||||
|
int *optimizedp, enum lval_type *lvalp,
|
||||||
|
CORE_ADDR *addrp, int *realnump)
|
||||||
|
{
|
||||||
|
gdb_assert (this_frame == NULL || this_frame->level >= 0);
|
||||||
|
|
||||||
|
while (this_frame != NULL)
|
||||||
|
{
|
||||||
|
frame_register_unwind (this_frame, regnum, optimizedp, lvalp,
|
||||||
|
addrp, realnump, NULL);
|
||||||
|
|
||||||
|
if (*optimizedp)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (*lvalp != lval_register)
|
||||||
|
break;
|
||||||
|
|
||||||
|
regnum = *realnump;
|
||||||
|
this_frame = get_next_frame (this_frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Return a "struct frame_info" corresponding to the frame that called
|
/* Return a "struct frame_info" corresponding to the frame that called
|
||||||
THIS_FRAME. Returns NULL if there is no such frame.
|
THIS_FRAME. Returns NULL if there is no such frame.
|
||||||
|
|
||||||
@ -1111,6 +1141,42 @@ get_prev_frame_1 (struct frame_info *this_frame)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that this and the next frame do not unwind the PC register
|
||||||
|
to the same memory location. If they do, then even though they
|
||||||
|
have different frame IDs, the new frame will be bogus; two
|
||||||
|
functions can't share a register save slot for the PC. This can
|
||||||
|
happen when the prologue analyzer finds a stack adjustment, but
|
||||||
|
no PC save. This check does assume that the "PC register" is
|
||||||
|
roughly a traditional PC, even if the gdbarch_unwind_pc method
|
||||||
|
frobs it. */
|
||||||
|
if (this_frame->level > 0
|
||||||
|
&& get_frame_type (this_frame) == NORMAL_FRAME
|
||||||
|
&& get_frame_type (this_frame->next) == NORMAL_FRAME)
|
||||||
|
{
|
||||||
|
int optimized, realnum;
|
||||||
|
enum lval_type lval, nlval;
|
||||||
|
CORE_ADDR addr, naddr;
|
||||||
|
|
||||||
|
frame_register_unwind_location (this_frame, PC_REGNUM, &optimized,
|
||||||
|
&lval, &addr, &realnum);
|
||||||
|
frame_register_unwind_location (get_next_frame (this_frame), PC_REGNUM,
|
||||||
|
&optimized, &nlval, &naddr, &realnum);
|
||||||
|
|
||||||
|
if (lval == lval_memory && lval == nlval && addr == naddr)
|
||||||
|
{
|
||||||
|
if (frame_debug)
|
||||||
|
{
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "-> ");
|
||||||
|
fprint_frame (gdb_stdlog, NULL);
|
||||||
|
fprintf_unfiltered (gdb_stdlog, " // no saved PC }\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
this_frame->stop_reason = UNWIND_NO_SAVED_PC;
|
||||||
|
this_frame->prev = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate the new frame but do not wire it in to the frame chain.
|
/* Allocate the new frame but do not wire it in to the frame chain.
|
||||||
Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along
|
Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along
|
||||||
frame->next to pull some fancy tricks (of course such code is, by
|
frame->next to pull some fancy tricks (of course such code is, by
|
||||||
@ -1611,6 +1677,9 @@ frame_stop_reason_string (enum unwind_stop_reason reason)
|
|||||||
case UNWIND_SAME_ID:
|
case UNWIND_SAME_ID:
|
||||||
return _("previous frame identical to this frame (corrupt stack?)");
|
return _("previous frame identical to this frame (corrupt stack?)");
|
||||||
|
|
||||||
|
case UNWIND_NO_SAVED_PC:
|
||||||
|
return _("frame did not save the PC");
|
||||||
|
|
||||||
case UNWIND_NO_REASON:
|
case UNWIND_NO_REASON:
|
||||||
case UNWIND_FIRST_ERROR:
|
case UNWIND_FIRST_ERROR:
|
||||||
default:
|
default:
|
||||||
|
@ -428,6 +428,10 @@ enum unwind_stop_reason
|
|||||||
this is a sign of unwinder failure. It could also indicate
|
this is a sign of unwinder failure. It could also indicate
|
||||||
stack corruption. */
|
stack corruption. */
|
||||||
UNWIND_SAME_ID,
|
UNWIND_SAME_ID,
|
||||||
|
|
||||||
|
/* The frame unwinder didn't find any saved PC, but we needed
|
||||||
|
one to unwind further. */
|
||||||
|
UNWIND_NO_SAVED_PC,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return the reason why we can't unwind past this frame. */
|
/* Return the reason why we can't unwind past this frame. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user