mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-05-28 14:08:09 +08:00
Convert frame unwinders to use the current frame and
"struct value". * frame.c (frame_debug): Make global. (get_frame_id): Pass this frame to unwinder routines. (frame_pc_unwind): Remove unused unwind->prev_pc support. (do_frame_register_read): Do not discard the return value of frame_register_read. (frame_register_unwind): Remove debug messages. Use frame_unwind_register_value. (frame_unwind_register_value, get_frame_register_value): New functions. (create_new_frame, get_frame_base_address, get_frame_locals_address) (get_frame_args_address, get_frame_type): Pass this frame to unwinder routines. (frame_cleanup_after_sniffer, frame_prepare_for_sniffer): New functions. * frame.h: Update comments. (frame_debug, frame_unwind_register_value, get_frame_register_value) (frame_prepare_for_sniffer): Declare. * frame-unwind.h: Update comments and parameter names. (default_frame_sniffer): Declare. (frame_prev_register_ftype): Return a struct value *. (struct frame_unwind): Remove prev_pc member. (frame_unwind_sniffer_ftype, frame_unwind_append_sniffer): Delete. (frame_unwind_append_unwinder, frame_unwind_got_optimized) (frame_unwind_got_register, frame_unwind_got_memory) (frame_unwind_got_constant, frame_unwind_got_address): Declare. * frame-base.h: Update comments and parameter names. * valops.c (value_fetch_lazy): Use get_frame_register_value. Iterate if necessary. Add debugging output. * sentinel-frame.c (sentinel_frame_prev_register) (sentinel_frame_this_id): Update for new signature. (sentinel_frame_prev_pc): Delete. (sentinel_frame_unwinder): Remove prev_pc. * ia64-tdep.c (ia64_libunwind_frame_unwind): Do not initialize prev_pc. * libunwind-frame.c (libunwind_frame_unwind): Likewise. * frame-unwind.c (struct frame_unwind_table_entry): Remove sniffer. (frame_unwind_append_sniffer): Delete. (frame_unwind_append_unwinder): New function. (frame_unwind_find_by_frame): Take this frame. Only use sniffers from unwinders. Use frame_prepare_for_sniffer. (default_frame_sniffer, frame_unwind_got_optimized) (frame_unwind_got_register, frame_unwind_got_memory) (frame_unwind_got_constant, frame_unwind_got_address): New functions. * dummy-frame.c (dummy_frame_sniffer): Use gdbarch_dummy_id. (dummy_frame_prev_register, dummy_frame_this_id): Update for new signature. * gdbarch.sh: Replace unwind_dummy_id with dummy_id. * gdbarch.c, gdbarch.c: Regenerated. * frame-base.c (default_frame_base_address) (default_frame_locals_address, default_frame_args_address): Update for new signature. (frame_base_find_by_frame): Pass this frame to unwinder routines. * infcall.c (call_function_by_hand): Update comments. * Makefile.in (frame-unwind.o): Update dependencies. * gdbint.texinfo (Stack Frames): New chapter. (Algorithms): Move Frames text to the new chapter. (Target Conditionals): Delete SAVE_DUMMY_FRAME_TOS. Document gdbarch_dummy_id instead of gdbarch_unwind_dummy_id.
This commit is contained in:
89
gdb/valops.c
89
gdb/valops.c
@ -622,24 +622,87 @@ value_fetch_lazy (struct value *val)
|
||||
}
|
||||
else if (VALUE_LVAL (val) == lval_register)
|
||||
{
|
||||
struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (val));
|
||||
int regnum = VALUE_REGNUM (val);
|
||||
struct frame_info *frame;
|
||||
int regnum;
|
||||
struct type *type = check_typedef (value_type (val));
|
||||
struct value *new_val = val, *mark = value_mark ();
|
||||
|
||||
gdb_assert (frame != NULL);
|
||||
/* Offsets are not supported here; lazy register values must
|
||||
refer to the entire register. */
|
||||
gdb_assert (value_offset (val) == 0);
|
||||
|
||||
/* Convertible register routines are used for multi-register
|
||||
values and for interpretation in different types (e.g. float
|
||||
or int from a double register). Lazy register values should
|
||||
have the register's natural type, so they do not apply. */
|
||||
gdb_assert (!gdbarch_convert_register_p (get_frame_arch (frame), regnum,
|
||||
type));
|
||||
while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val))
|
||||
{
|
||||
frame = frame_find_by_id (VALUE_FRAME_ID (new_val));
|
||||
regnum = VALUE_REGNUM (new_val);
|
||||
|
||||
/* Get the data. */
|
||||
if (!get_frame_register_bytes (frame, regnum, value_offset (val),
|
||||
TYPE_LENGTH (value_type (val)),
|
||||
value_contents_raw (val)))
|
||||
gdb_assert (frame != NULL);
|
||||
|
||||
/* Convertible register routines are used for multi-register
|
||||
values and for interpretation in different types
|
||||
(e.g. float or int from a double register). Lazy
|
||||
register values should have the register's natural type,
|
||||
so they do not apply. */
|
||||
gdb_assert (!gdbarch_convert_register_p (get_frame_arch (frame),
|
||||
regnum, type));
|
||||
|
||||
new_val = get_frame_register_value (frame, regnum);
|
||||
}
|
||||
|
||||
/* If it's still lazy (for instance, a saved register on the
|
||||
stack), fetch it. */
|
||||
if (value_lazy (new_val))
|
||||
value_fetch_lazy (new_val);
|
||||
|
||||
/* If the register was not saved, mark it unavailable. */
|
||||
if (value_optimized_out (new_val))
|
||||
set_value_optimized_out (val, 1);
|
||||
else
|
||||
memcpy (value_contents_raw (val), value_contents (new_val),
|
||||
TYPE_LENGTH (type));
|
||||
|
||||
if (frame_debug)
|
||||
{
|
||||
frame = frame_find_by_id (VALUE_FRAME_ID (val));
|
||||
regnum = VALUE_REGNUM (val);
|
||||
|
||||
fprintf_unfiltered (gdb_stdlog, "\
|
||||
{ value_fetch_lazy (frame=%d,regnum=%d(%s),...) ",
|
||||
frame_relative_level (frame), regnum,
|
||||
frame_map_regnum_to_name (frame, regnum));
|
||||
|
||||
fprintf_unfiltered (gdb_stdlog, "->");
|
||||
if (value_optimized_out (new_val))
|
||||
fprintf_unfiltered (gdb_stdlog, " optimized out");
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const gdb_byte *buf = value_contents (new_val);
|
||||
|
||||
if (VALUE_LVAL (new_val) == lval_register)
|
||||
fprintf_unfiltered (gdb_stdlog, " register=%d",
|
||||
VALUE_REGNUM (new_val));
|
||||
else if (VALUE_LVAL (new_val) == lval_memory)
|
||||
fprintf_unfiltered (gdb_stdlog, " address=0x%s",
|
||||
paddr_nz (VALUE_ADDRESS (new_val)));
|
||||
else
|
||||
fprintf_unfiltered (gdb_stdlog, " computed");
|
||||
|
||||
fprintf_unfiltered (gdb_stdlog, " bytes=");
|
||||
fprintf_unfiltered (gdb_stdlog, "[");
|
||||
for (i = 0;
|
||||
i < register_size (get_frame_arch (frame), regnum);
|
||||
i++)
|
||||
fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
|
||||
fprintf_unfiltered (gdb_stdlog, "]");
|
||||
}
|
||||
|
||||
fprintf_unfiltered (gdb_stdlog, " }\n");
|
||||
}
|
||||
|
||||
/* Dispose of the intermediate values. This prevents
|
||||
watchpoints from trying to watch the saved frame pointer. */
|
||||
value_free_to_mark (mark);
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__, "Unexpected lazy value type.");
|
||||
|
Reference in New Issue
Block a user