/* Frame unwinder for frames with DWARF Call Frame Information.
- Copyright (C) 2003-2005, 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
Contributed by Mark Kettenis.
#include "value.h"
#include "gdb_assert.h"
-#include "gdb_string.h"
+#include <string.h>
#include "complaints.h"
#include "dwarf2-frame.h"
struct objfile *objfile;
/* Pointer to the .debug_frame section loaded into memory. */
- gdb_byte *dwarf_frame_buffer;
+ const gdb_byte *dwarf_frame_buffer;
/* Length of the loaded .debug_frame section. */
bfd_size_type dwarf_frame_size;
/* Helper functions for execute_stack_op. */
static CORE_ADDR
-read_reg (void *baton, int reg)
+read_addr_from_reg (void *baton, int reg)
{
struct frame_info *this_frame = (struct frame_info *) baton;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
buf = alloca (register_size (gdbarch, regnum));
get_frame_register (this_frame, regnum, buf);
- /* Convert the register to an integer. This returns a LONGEST
- rather than a CORE_ADDR, but unpack_pointer does the same thing
- under the covers, and this makes more sense for non-pointer
- registers. Maybe read_reg and the associated interfaces should
- deal with "struct value" instead of CORE_ADDR. */
- return unpack_long (register_type (gdbarch, regnum), buf);
+ return unpack_pointer (register_type (gdbarch, regnum), buf);
+}
+
+/* Implement struct dwarf_expr_context_funcs' "get_reg_value" callback. */
+
+static struct value *
+get_reg_value (void *baton, struct type *type, int reg)
+{
+ struct frame_info *this_frame = (struct frame_info *) baton;
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
+
+ return value_from_register (type, regnum, this_frame);
}
static void
static const struct dwarf_expr_context_funcs dwarf2_frame_ctx_funcs =
{
- read_reg,
+ read_addr_from_reg,
+ get_reg_value,
read_mem,
ctx_no_get_frame_base,
ctx_no_get_frame_cfa,
if (ctx->location == DWARF_VALUE_MEMORY)
result = dwarf_expr_fetch_address (ctx, 0);
else if (ctx->location == DWARF_VALUE_REGISTER)
- result = read_reg (this_frame, value_as_long (dwarf_expr_fetch (ctx, 0)));
+ result = read_addr_from_reg (this_frame,
+ value_as_long (dwarf_expr_fetch (ctx, 0)));
else
{
/* This is actually invalid DWARF, but if we ever do run across
CORE_ADDR pc, struct dwarf2_frame_state *fs)
{
int eh_frame_p = fde->eh_frame_p;
- int bytes_read;
+ unsigned int bytes_read;
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
while (insn_ptr < insn_end && fs->pc <= pc)
case DW_CFA_GNU_negative_offset_extended:
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
- insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &offset);
- offset *= fs->data_align;
+ insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
+ offset = utmp * fs->data_align;
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = -offset;
CORE_ADDR pc,
struct dwarf2_per_cu_data *data)
{
- const int num_regs = gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch);
struct dwarf2_fde *fde;
CORE_ADDR text_offset;
struct dwarf2_frame_state fs;
/* The .text offset. */
CORE_ADDR text_offset;
+ /* True if we already checked whether this frame is the bottom frame
+ of a virtual tail call frame chain. */
+ int checked_tailcall_bottom;
+
/* If not NULL then this frame is the bottom frame of a TAILCALL_FRAME
sequence. If NULL then it is a normal case with no TAILCALL_FRAME
involved. Non-bottom frames of a virtual tail call frames chain use
dwarf2_tailcall_frame_unwind unwinder so this field does not apply for
them. */
void *tailcall_cache;
+
+ /* The number of bytes to subtract from TAILCALL_FRAME frames frame
+ base to get the SP, to simulate the return address pushed on the
+ stack. */
+ LONGEST entry_cfa_sp_offset;
+ int entry_cfa_sp_offset_p;
};
/* A cleanup that sets a pointer to NULL. */
struct dwarf2_fde *fde;
volatile struct gdb_exception ex;
CORE_ADDR entry_pc;
- LONGEST entry_cfa_sp_offset;
- int entry_cfa_sp_offset_p = 0;
const gdb_byte *instr;
if (*this_cache)
&& (gdbarch_dwarf2_reg_to_regnum (gdbarch, fs->regs.cfa_reg)
== gdbarch_sp_regnum (gdbarch)))
{
- entry_cfa_sp_offset = fs->regs.cfa_offset;
- entry_cfa_sp_offset_p = 1;
+ cache->entry_cfa_sp_offset = fs->regs.cfa_offset;
+ cache->entry_cfa_sp_offset_p = 1;
}
}
else
switch (fs->regs.cfa_how)
{
case CFA_REG_OFFSET:
- cache->cfa = read_reg (this_frame, fs->regs.cfa_reg);
+ cache->cfa = read_addr_from_reg (this_frame, fs->regs.cfa_reg);
if (fs->armcc_cfa_offsets_reversed)
cache->cfa -= fs->regs.cfa_offset;
else
cache->undefined_retaddr = 1;
do_cleanups (old_chain);
-
- /* Try to find a virtual tail call frames chain with bottom (callee) frame
- starting at THIS_FRAME. */
- dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache,
- (entry_cfa_sp_offset_p
- ? &entry_cfa_sp_offset : NULL));
-
discard_cleanups (reset_cache_cleanup);
return cache;
}
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 addr;
int realnum;
+ /* Check whether THIS_FRAME is the bottom frame of a virtual tail
+ call frame chain. */
+ if (!cache->checked_tailcall_bottom)
+ {
+ cache->checked_tailcall_bottom = 1;
+ dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache,
+ (cache->entry_cfa_sp_offset_p
+ ? &cache->entry_cfa_sp_offset : NULL));
+ }
+
/* Non-bottom frames of a virtual tail call frames chain use
dwarf2_tailcall_frame_unwind unwinder so this code does not apply for
them. If dwarf2_tailcall_prev_register_first does not have specific value
if (self->type != NORMAL_FRAME)
return 0;
- /* Preinitializa the cache so that TAILCALL_FRAME can find the record by
- dwarf2_tailcall_sniffer_first. */
- dwarf2_frame_cache (this_frame, this_cache);
-
return 1;
}
fde_table->entries[fde_table->num_entries - 1] = fde;
}
-#ifdef CC_HAS_LONG_LONG
#define DW64_CIE_ID 0xffffffffffffffffULL
-#else
-#define DW64_CIE_ID ~0
-#endif
/* Defines the type of eh_frames that are expected to be decoded: CIE, FDE
or any of them. */
if (e.reason < 0)
{
warning (_("skipping .eh_frame info of %s: %s"),
- objfile->name, e.message);
+ objfile_name (objfile), e.message);
if (fde_table.num_entries != 0)
{
if (e.reason < 0)
{
warning (_("skipping .debug_frame info of %s: %s"),
- objfile->name, e.message);
+ objfile_name (objfile), e.message);
if (fde_table.num_entries != 0)
{