/* Frame unwinder for frames with DWARF Call Frame Information.
- Copyright (C) 2003-2013 Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
Contributed by Mark Kettenis.
#include "objfiles.h"
#include "regcache.h"
#include "value.h"
-
-#include "gdb_assert.h"
-#include <string.h>
+#include "record.h"
#include "complaints.h"
#include "dwarf2-frame.h"
#include "ax.h"
#include "dwarf2loc.h"
-#include "exceptions.h"
#include "dwarf2-frame-tailcall.h"
struct comp_unit;
{
struct frame_info *this_frame = (struct frame_info *) baton;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
- int regnum;
- gdb_byte *buf;
-
- regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
-
- buf = alloca (register_size (gdbarch, regnum));
- get_frame_register (this_frame, regnum, buf);
+ int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
- return unpack_pointer (register_type (gdbarch, regnum), buf);
+ return address_from_register (regnum, this_frame);
}
/* Implement struct dwarf_expr_context_funcs' "get_reg_value" callback. */
{
struct dwarf2_frame_state_reg_info *new_rs;
- new_rs = XMALLOC (struct dwarf2_frame_state_reg_info);
+ new_rs = XNEW (struct dwarf2_frame_state_reg_info);
*new_rs = fs->regs;
fs->regs.reg = dwarf2_frame_state_copy_regs (&fs->regs);
fs->regs.prev = new_rs;
reset_cache_cleanup = make_cleanup (clear_pointer_cleanup, this_cache);
/* Allocate and initialize the frame state. */
- fs = XZALLOC (struct dwarf2_frame_state);
+ fs = XCNEW (struct dwarf2_frame_state);
old_chain = make_cleanup (dwarf2_frame_state_free, fs);
/* Unwind the PC.
if (fs->retaddr_column < fs->regs.num_regs
&& fs->regs.reg[fs->retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED)
cache->undefined_retaddr = 1;
- else if (fs->retaddr_column >= fs->regs.num_regs
- || (fs->regs.reg[fs->retaddr_column].how
- == DWARF2_FRAME_REG_UNSPECIFIED))
- cache->undefined_retaddr = 1;
do_cleanups (old_chain);
discard_cleanups (reset_cache_cleanup);
dwarf2_frame_cache (this_frame, this_cache);
if (cache->unavailable_retaddr)
+ (*this_id) = frame_id_build_unavailable_stack (get_frame_func (this_frame));
+ else if (cache->undefined_retaddr)
return;
-
- if (cache->undefined_retaddr)
- return;
-
- (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
+ else
+ (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
}
static struct value *
CORE_ADDR
dwarf2_frame_cfa (struct frame_info *this_frame)
{
+ if (frame_unwinder_is (this_frame, &record_btrace_tailcall_frame_unwind)
+ || frame_unwinder_is (this_frame, &record_btrace_frame_unwind))
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("cfa not available for record btrace target"));
+
while (get_frame_type (this_frame) == INLINE_FRAME)
this_frame = get_prev_frame (this_frame);
+ if (get_frame_unwind_stop_reason (this_frame) == UNWIND_UNAVAILABLE)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("can't compute CFA for this frame: "
+ "required registers or memory are unavailable"));
/* This restriction could be lifted if other unwinders are known to
compute the frame base in a way compatible with the DWARF
unwinder. */
if (!frame_unwinder_is (this_frame, &dwarf2_frame_unwind)
&& !frame_unwinder_is (this_frame, &dwarf2_tailcall_frame_unwind))
error (_("can't compute CFA for this frame"));
- if (get_frame_unwind_stop_reason (this_frame) == UNWIND_UNAVAILABLE)
- throw_error (NOT_AVAILABLE_ERROR,
- _("can't compute CFA for this frame: "
- "required registers or memory are unavailable"));
return get_frame_base (this_frame);
}
\f