/* Cache and manage frames for GDB, the GNU debugger.
- Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001,
- 2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1986-1987, 1989, 1991, 1994-1996, 1998, 2000-2004,
+ 2007-2012 Free Software Foundation, Inc.
This file is part of GDB.
return frame_unwind_register_unsigned (frame->next, regnum);
}
+int
+read_frame_register_unsigned (struct frame_info *frame, int regnum,
+ ULONGEST *val)
+{
+ struct value *regval = get_frame_register_value (frame, regnum);
+
+ if (!value_optimized_out (regval)
+ && value_entirely_available (regval))
+ {
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ int size = register_size (gdbarch, VALUE_REGNUM (regval));
+
+ *val = extract_unsigned_integer (value_contents (regval), size, byte_order);
+ return 1;
+ }
+
+ return 0;
+}
+
void
put_frame_register (struct frame_info *frame, int regnum,
const gdb_byte *buf)
if (!target_has_registers || !target_has_stack || !target_has_memory)
return 0;
- /* No current inferior, no frame. */
- if (ptid_equal (inferior_ptid, null_ptid))
- return 0;
+ /* Traceframes are effectively a substitute for the live inferior. */
+ if (get_traceframe_number () < 0)
+ {
+ /* No current inferior, no frame. */
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return 0;
- /* Don't try to read from a dead thread. */
- if (is_exited (inferior_ptid))
- return 0;
+ /* Don't try to read from a dead thread. */
+ if (is_exited (inferior_ptid))
+ return 0;
- /* ... or from a spinning thread. */
- if (is_executing (inferior_ptid))
- return 0;
+ /* ... or from a spinning thread. */
+ if (is_executing (inferior_ptid))
+ return 0;
+ }
return 1;
}
while (get_frame_type (next_frame) == INLINE_FRAME)
next_frame = next_frame->next;
- if (get_frame_type (next_frame) == NORMAL_FRAME
+ if ((get_frame_type (next_frame) == NORMAL_FRAME
+ || get_frame_type (next_frame) == TAILCALL_FRAME)
&& (get_frame_type (this_frame) == NORMAL_FRAME
+ || get_frame_type (this_frame) == TAILCALL_FRAME
|| get_frame_type (this_frame) == INLINE_FRAME))
return pc - 1;
we can't do much better. */
sal->pc = get_frame_pc (frame);
+ sal->pspace = get_frame_program_space (frame);
+
return;
}
{
switch (reason)
{
- case UNWIND_NULL_ID:
- return _("unwinder did not report frame ID");
-
- case UNWIND_UNAVAILABLE:
- return _("Not enough registers or memory available to unwind further");
-
- case UNWIND_INNER_ID:
- return _("previous frame inner to this frame (corrupt stack?)");
-
- case UNWIND_SAME_ID:
- return _("previous frame identical to this frame (corrupt stack?)");
-
- case UNWIND_NO_SAVED_PC:
- return _("frame did not save the PC");
+#define SET(name, description) \
+ case name: return _(description);
+#include "unwind_stop_reasons.def"
+#undef SET
- case UNWIND_NO_REASON:
- case UNWIND_FIRST_ERROR:
default:
internal_error (__FILE__, __LINE__,
"Invalid frame stop reason");