/* DWARF 2 location expression support for GDB.
- Copyright (C) 2003, 2005, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005, 2007-2012 Free Software Foundation, Inc.
Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
#include "gdb_string.h"
#include "gdb_assert.h"
+DEF_VEC_I(int);
+
extern int dwarf2_always_disassemble;
static void dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
call and return. */
static void
-per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset,
+per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset,
struct dwarf2_per_cu_data *per_cu,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton)
/* Helper interface of per_cu_dwarf_call for dwarf2_evaluate_loc_desc. */
static void
-dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
{
struct dwarf_expr_baton *debaton = ctx->baton;
/* Callback function for dwarf2_evaluate_loc_desc. */
static struct type *
-dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx,
+ cu_offset die_offset)
{
struct dwarf_expr_baton *debaton = ctx->baton;
return sym;
}
-/* Define VEC (CORE_ADDR) functions. */
-DEF_VEC_I (CORE_ADDR);
-
/* Verify function with entry point exact address ADDR can never call itself
via its tail calls (incl. transitively). Throw NO_ENTRY_VALUE_ERROR if it
can call itself via tail calls.
ctx->baton = saved_ctx.baton;
}
+/* Callback function for dwarf2_evaluate_loc_desc.
+ Fetch the address indexed by DW_OP_GNU_addr_index. */
+
+static CORE_ADDR
+dwarf_expr_get_addr_index (void *baton, unsigned int index)
+{
+ struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
+
+ return dwarf2_read_addr_index (debaton->per_cu, index);
+}
+
/* VALUE must be of type lval_computed with entry_data_value_funcs. Perform
the indirect method on it, that is use its stored target value, the sole
purpose of entry_data_value_funcs.. */
dwarf_expr_tls_address,
dwarf_expr_dwarf_call,
dwarf_expr_get_base_type,
- dwarf_expr_push_dwarf_reg_entry_value
+ dwarf_expr_push_dwarf_reg_entry_value,
+ dwarf_expr_get_addr_index
};
/* Evaluate a location description, starting at DATA and with length
/* Helper interface of per_cu_dwarf_call for dwarf2_loc_desc_needs_frame. */
static void
-needs_frame_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+needs_frame_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
{
struct needs_frame_baton *nf_baton = ctx->baton;
nf_baton->needs_frame = 1;
}
+/* DW_OP_GNU_addr_index doesn't require a frame. */
+
+static CORE_ADDR
+needs_get_addr_index (void *baton, unsigned int index)
+{
+ /* Nothing to do. */
+ return 1;
+}
+
/* Virtual method table for dwarf2_loc_desc_needs_frame below. */
static const struct dwarf_expr_context_funcs needs_frame_ctx_funcs =
needs_frame_tls_address,
needs_frame_dwarf_call,
NULL, /* get_base_type */
- needs_dwarf_reg_entry_value
+ needs_dwarf_reg_entry_value,
+ needs_get_addr_index
};
/* Return non-zero iff the location expression at DATA (length SIZE)
static void
unimplemented (unsigned int op)
{
- const char *name = dwarf_stack_op_name (op);
+ const char *name = get_DW_OP_name (op);
if (name)
error (_("DWARF operator %s cannot be translated to an agent expression"),
ax_simple (expr, aop_ref64);
break;
default:
- /* Note that dwarf_stack_op_name will never return
+ /* Note that get_DW_OP_name will never return
NULL here. */
error (_("Unsupported size %d in %s"),
- size, dwarf_stack_op_name (op));
+ size, get_DW_OP_name (op));
}
}
break;
{
struct dwarf2_locexpr_baton block;
int size = (op == DW_OP_call2 ? 2 : 4);
+ cu_offset offset;
uoffset = extract_unsigned_integer (op_ptr, size, byte_order);
op_ptr += size;
- block = dwarf2_fetch_die_location_block (uoffset, per_cu,
+ offset.cu_off = uoffset;
+ block = dwarf2_fetch_die_location_block (offset, per_cu,
get_ax_pc, expr);
/* DW_OP_call_ref is currently not supported. */
LONGEST l;
const char *name;
- name = dwarf_stack_op_name (op);
+ name = get_DW_OP_name (op);
if (!name)
error (_("Unrecognized DWARF opcode 0x%02x at %ld"),
case DW_OP_GNU_deref_type:
{
int addr_size = *data++;
- ULONGEST offset;
+ cu_offset offset;
struct type *type;
- data = read_uleb128 (data, end, &offset);
+ data = read_uleb128 (data, end, &ul);
+ offset.cu_off = ul;
type = dwarf2_get_die_type (offset, per_cu);
fprintf_filtered (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset, 0),
+ fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset.cu_off, 0),
addr_size);
}
break;
case DW_OP_GNU_const_type:
{
- ULONGEST type_die;
+ cu_offset type_die;
struct type *type;
- data = read_uleb128 (data, end, &type_die);
+ data = read_uleb128 (data, end, &ul);
+ type_die.cu_off = ul;
type = dwarf2_get_die_type (type_die, per_cu);
fprintf_filtered (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+ fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.cu_off, 0));
}
break;
case DW_OP_GNU_regval_type:
{
- ULONGEST type_die, reg;
+ ULONGEST reg;
+ cu_offset type_die;
struct type *type;
data = read_uleb128 (data, end, ®);
- data = read_uleb128 (data, end, &type_die);
+ data = read_uleb128 (data, end, &ul);
+ type_die.cu_off = ul;
type = dwarf2_get_die_type (type_die, per_cu);
fprintf_filtered (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]> [$%s]", phex_nz (type_die, 0),
+ fprintf_filtered (stream, " [0x%s]> [$%s]",
+ phex_nz (type_die.cu_off, 0),
locexpr_regname (arch, reg));
}
break;
case DW_OP_GNU_convert:
case DW_OP_GNU_reinterpret:
{
- ULONGEST type_die;
+ cu_offset type_die;
- data = read_uleb128 (data, end, &type_die);
+ data = read_uleb128 (data, end, &ul);
+ type_die.cu_off = ul;
- if (type_die == 0)
+ if (type_die.cu_off == 0)
fprintf_filtered (stream, "<0>");
else
{
type = dwarf2_get_die_type (type_die, per_cu);
fprintf_filtered (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+ fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.cu_off, 0));
}
}
break;
loclist_tracepoint_var_ref
};
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_dwarf2loc;
+
void
_initialize_dwarf2loc (void)
{