| Index: gdb/dwarf2loc.c
|
| diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
|
| index 38e4814be8ca8862e6478c53e875c1fc124382da..2b1f32314a8feefb2d0378de980cea9e56cf66d0 100644
|
| --- a/gdb/dwarf2loc.c
|
| +++ b/gdb/dwarf2loc.c
|
| @@ -1,6 +1,6 @@
|
| /* DWARF 2 location expression support for GDB.
|
|
|
| - Copyright (C) 2003, 2005, 2007-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
|
|
| Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
|
|
|
| @@ -39,11 +39,9 @@
|
| #include "dwarf2loc.h"
|
| #include "dwarf2-frame.h"
|
|
|
| -#include "gdb_string.h"
|
| +#include <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,
|
| @@ -54,8 +52,8 @@ static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs;
|
| static struct value *dwarf2_evaluate_loc_desc_full (struct type *type,
|
| struct frame_info *frame,
|
| const gdb_byte *data,
|
| - unsigned short size,
|
| - struct dwarf2_per_cu_data *per_cu,
|
| + size_t size,
|
| + struct dwarf2_per_cu_data *per_cu,
|
| LONGEST byte_offset);
|
|
|
| /* Until these have formal names, we define these here.
|
| @@ -90,6 +88,16 @@ enum debug_loc_kind
|
| DEBUG_LOC_INVALID_ENTRY = -2
|
| };
|
|
|
| +/* Helper function which throws an error if a synthetic pointer is
|
| + invalid. */
|
| +
|
| +static void
|
| +invalid_synthetic_pointer (void)
|
| +{
|
| + error (_("access outside bounds of object "
|
| + "referenced via synthetic pointer"));
|
| +}
|
| +
|
| /* Decode the addresses in a non-dwo .debug_loc entry.
|
| A pointer to the next byte to examine is returned in *NEW_PTR.
|
| The encoded low,high addresses are return in *LOW,*HIGH.
|
| @@ -252,9 +260,14 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
|
| gdb_assert_not_reached ("bad debug_loc_kind");
|
| }
|
|
|
| - /* Otherwise, a location expression entry. */
|
| - low += base_address;
|
| - high += base_address;
|
| + /* Otherwise, a location expression entry.
|
| + If the entry is from a DWO, don't add base address: the entry is
|
| + from .debug_addr which has absolute addresses. */
|
| + if (! baton->from_dwo)
|
| + {
|
| + low += base_address;
|
| + high += base_address;
|
| + }
|
|
|
| length = extract_unsigned_integer (loc_ptr, 2, byte_order);
|
| loc_ptr += 2;
|
| @@ -300,7 +313,7 @@ struct dwarf_expr_baton
|
| /* Using the frame specified in BATON, return the value of register
|
| REGNUM, treated as a pointer. */
|
| static CORE_ADDR
|
| -dwarf_expr_read_reg (void *baton, int dwarf_regnum)
|
| +dwarf_expr_read_addr_from_reg (void *baton, int dwarf_regnum)
|
| {
|
| struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
|
| struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
|
| @@ -313,6 +326,18 @@ dwarf_expr_read_reg (void *baton, int dwarf_regnum)
|
| return result;
|
| }
|
|
|
| +/* Implement struct dwarf_expr_context_funcs' "get_reg_value" callback. */
|
| +
|
| +static struct value *
|
| +dwarf_expr_get_reg_value (void *baton, struct type *type, int dwarf_regnum)
|
| +{
|
| + struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
|
| + struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
|
| + int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
|
| +
|
| + return value_from_register (type, regnum, debaton->frame);
|
| +}
|
| +
|
| /* Read memory at ADDR (length LEN) into BUF. */
|
|
|
| static void
|
| @@ -332,11 +357,15 @@ dwarf_expr_frame_base (void *baton, const gdb_byte **start, size_t * length)
|
| this_base method. */
|
| struct symbol *framefunc;
|
| struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
|
| + struct block *bl = get_frame_block (debaton->frame, NULL);
|
| +
|
| + if (bl == NULL)
|
| + error (_("frame address is not available."));
|
|
|
| /* Use block_linkage_function, which returns a real (not inlined)
|
| function, instead of get_frame_function, which may return an
|
| inlined function. */
|
| - framefunc = block_linkage_function (get_frame_block (debaton->frame, NULL));
|
| + framefunc = block_linkage_function (bl);
|
|
|
| /* If we found a frame-relative symbol then it was certainly within
|
| some function associated with a frame. If we can't find the frame,
|
| @@ -348,32 +377,59 @@ dwarf_expr_frame_base (void *baton, const gdb_byte **start, size_t * length)
|
| start, length);
|
| }
|
|
|
| +/* Implement find_frame_base_location method for LOC_BLOCK functions using
|
| + DWARF expression for its DW_AT_frame_base. */
|
| +
|
| +static void
|
| +locexpr_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
|
| + const gdb_byte **start, size_t *length)
|
| +{
|
| + struct dwarf2_locexpr_baton *symbaton = SYMBOL_LOCATION_BATON (framefunc);
|
| +
|
| + *length = symbaton->size;
|
| + *start = symbaton->data;
|
| +}
|
| +
|
| +/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
|
| + function uses DWARF expression for its DW_AT_frame_base. */
|
| +
|
| +const struct symbol_block_ops dwarf2_block_frame_base_locexpr_funcs =
|
| +{
|
| + locexpr_find_frame_base_location
|
| +};
|
| +
|
| +/* Implement find_frame_base_location method for LOC_BLOCK functions using
|
| + DWARF location list for its DW_AT_frame_base. */
|
| +
|
| +static void
|
| +loclist_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
|
| + const gdb_byte **start, size_t *length)
|
| +{
|
| + struct dwarf2_loclist_baton *symbaton = SYMBOL_LOCATION_BATON (framefunc);
|
| +
|
| + *start = dwarf2_find_location_expression (symbaton, length, pc);
|
| +}
|
| +
|
| +/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
|
| + function uses DWARF location list for its DW_AT_frame_base. */
|
| +
|
| +const struct symbol_block_ops dwarf2_block_frame_base_loclist_funcs =
|
| +{
|
| + loclist_find_frame_base_location
|
| +};
|
| +
|
| static void
|
| dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
|
| const gdb_byte **start, size_t *length)
|
| {
|
| - if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
|
| - *length = 0;
|
| - else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
|
| + if (SYMBOL_BLOCK_OPS (framefunc) != NULL)
|
| {
|
| - struct dwarf2_loclist_baton *symbaton;
|
| + const struct symbol_block_ops *ops_block = SYMBOL_BLOCK_OPS (framefunc);
|
|
|
| - symbaton = SYMBOL_LOCATION_BATON (framefunc);
|
| - *start = dwarf2_find_location_expression (symbaton, length, pc);
|
| + ops_block->find_frame_base_location (framefunc, pc, start, length);
|
| }
|
| else
|
| - {
|
| - struct dwarf2_locexpr_baton *symbaton;
|
| -
|
| - symbaton = SYMBOL_LOCATION_BATON (framefunc);
|
| - if (symbaton != NULL)
|
| - {
|
| - *length = symbaton->size;
|
| - *start = symbaton->data;
|
| - }
|
| - else
|
| - *length = 0;
|
| - }
|
| + *length = 0;
|
|
|
| if (*length == 0)
|
| error (_("Could not find the frame base for \"%s\"."),
|
| @@ -425,8 +481,7 @@ per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset,
|
| {
|
| struct dwarf2_locexpr_baton block;
|
|
|
| - block = dwarf2_fetch_die_location_block (die_offset, per_cu,
|
| - get_frame_pc, baton);
|
| + block = dwarf2_fetch_die_loc_cu_off (die_offset, per_cu, get_frame_pc, baton);
|
|
|
| /* DW_OP_call_ref is currently not supported. */
|
| gdb_assert (block.per_cu == per_cu);
|
| @@ -458,7 +513,7 @@ dwarf_expr_get_base_type (struct dwarf_expr_context *ctx,
|
|
|
| /* See dwarf2loc.h. */
|
|
|
| -int entry_values_debug = 0;
|
| +unsigned int entry_values_debug = 0;
|
|
|
| /* Helper to set entry_values_debug. */
|
|
|
| @@ -492,19 +547,20 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
|
| dwarf_block = FIELD_DWARF_BLOCK (call_site->target);
|
| if (dwarf_block == NULL)
|
| {
|
| - struct minimal_symbol *msym;
|
| + struct bound_minimal_symbol msym;
|
|
|
| msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
|
| throw_error (NO_ENTRY_VALUE_ERROR,
|
| _("DW_AT_GNU_call_site_target is not specified "
|
| "at %s in %s"),
|
| paddress (call_site_gdbarch, call_site->pc),
|
| - msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
| + (msym.minsym == NULL ? "???"
|
| + : SYMBOL_PRINT_NAME (msym.minsym)));
|
|
|
| }
|
| if (caller_frame == NULL)
|
| {
|
| - struct minimal_symbol *msym;
|
| + struct bound_minimal_symbol msym;
|
|
|
| msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
|
| throw_error (NO_ENTRY_VALUE_ERROR,
|
| @@ -512,7 +568,8 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
|
| "requires known frame which is currently not "
|
| "available at %s in %s"),
|
| paddress (call_site_gdbarch, call_site->pc),
|
| - msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
| + (msym.minsym == NULL ? "???"
|
| + : SYMBOL_PRINT_NAME (msym.minsym)));
|
|
|
| }
|
| caller_arch = get_frame_arch (caller_frame);
|
| @@ -534,10 +591,12 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
|
| struct minimal_symbol *msym;
|
|
|
| physname = FIELD_STATIC_PHYSNAME (call_site->target);
|
| - msym = lookup_minimal_symbol_text (physname, NULL);
|
| +
|
| + /* Handle both the mangled and demangled PHYSNAME. */
|
| + msym = lookup_minimal_symbol (physname, NULL, NULL);
|
| if (msym == NULL)
|
| {
|
| - msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
|
| + msym = lookup_minimal_symbol_by_pc (call_site->pc - 1).minsym;
|
| throw_error (NO_ENTRY_VALUE_ERROR,
|
| _("Cannot find function \"%s\" for a call site target "
|
| "at %s in %s"),
|
| @@ -633,14 +692,15 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
|
|
|
| if (target_addr == verify_addr)
|
| {
|
| - struct minimal_symbol *msym;
|
| + struct bound_minimal_symbol msym;
|
|
|
| msym = lookup_minimal_symbol_by_pc (verify_addr);
|
| throw_error (NO_ENTRY_VALUE_ERROR,
|
| _("DW_OP_GNU_entry_value resolving has found "
|
| "function \"%s\" at %s can call itself via tail "
|
| "calls"),
|
| - msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym),
|
| + (msym.minsym == NULL ? "???"
|
| + : SYMBOL_PRINT_NAME (msym.minsym)),
|
| paddress (gdbarch, verify_addr));
|
| }
|
|
|
| @@ -664,10 +724,11 @@ static void
|
| tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site)
|
| {
|
| CORE_ADDR addr = call_site->pc;
|
| - struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (addr - 1);
|
| + struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1);
|
|
|
| fprintf_unfiltered (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
|
| - msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
| + (msym.minsym == NULL ? "???"
|
| + : SYMBOL_PRINT_NAME (msym.minsym)));
|
|
|
| }
|
|
|
| @@ -700,8 +761,9 @@ chain_candidate (struct gdbarch *gdbarch, struct call_site_chain **resultp,
|
| * (length - 1));
|
| result->length = length;
|
| result->callers = result->callees = length;
|
| - memcpy (result->call_site, VEC_address (call_sitep, chain),
|
| - sizeof (*result->call_site) * length);
|
| + if (!VEC_empty (call_sitep, chain))
|
| + memcpy (result->call_site, VEC_address (call_sitep, chain),
|
| + sizeof (*result->call_site) * length);
|
| *resultp = result;
|
|
|
| if (entry_values_debug)
|
| @@ -785,6 +847,7 @@ static struct call_site_chain *
|
| call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
|
| CORE_ADDR callee_pc)
|
| {
|
| + CORE_ADDR save_callee_pc = callee_pc;
|
| struct obstack addr_obstack;
|
| struct cleanup *back_to_retval, *back_to_workdata;
|
| struct call_site_chain *retval = NULL;
|
| @@ -803,7 +866,7 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
|
| callee_pc = get_pc_function_start (callee_pc);
|
| if (callee_pc == 0)
|
| throw_error (NO_ENTRY_VALUE_ERROR, _("Unable to find function for PC %s"),
|
| - paddress (gdbarch, callee_pc));
|
| + paddress (gdbarch, save_callee_pc));
|
|
|
| back_to_retval = make_cleanup (free_current_contents, &retval);
|
|
|
| @@ -896,7 +959,7 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
|
|
|
| if (retval == NULL)
|
| {
|
| - struct minimal_symbol *msym_caller, *msym_callee;
|
| + struct bound_minimal_symbol msym_caller, msym_callee;
|
|
|
| msym_caller = lookup_minimal_symbol_by_pc (caller_pc);
|
| msym_callee = lookup_minimal_symbol_by_pc (callee_pc);
|
| @@ -904,11 +967,11 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
|
| _("There are no unambiguously determinable intermediate "
|
| "callers or callees between caller function \"%s\" at %s "
|
| "and callee function \"%s\" at %s"),
|
| - (msym_caller == NULL
|
| - ? "???" : SYMBOL_PRINT_NAME (msym_caller)),
|
| + (msym_caller.minsym == NULL
|
| + ? "???" : SYMBOL_PRINT_NAME (msym_caller.minsym)),
|
| paddress (gdbarch, caller_pc),
|
| - (msym_callee == NULL
|
| - ? "???" : SYMBOL_PRINT_NAME (msym_callee)),
|
| + (msym_callee.minsym == NULL
|
| + ? "???" : SYMBOL_PRINT_NAME (msym_callee.minsym)),
|
| paddress (gdbarch, callee_pc));
|
| }
|
|
|
| @@ -980,19 +1043,28 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
|
| union call_site_parameter_u kind_u,
|
| struct dwarf2_per_cu_data **per_cu_return)
|
| {
|
| - CORE_ADDR func_addr = get_frame_func (frame);
|
| - CORE_ADDR caller_pc;
|
| - struct gdbarch *gdbarch = get_frame_arch (frame);
|
| - struct frame_info *caller_frame = get_prev_frame (frame);
|
| + CORE_ADDR func_addr, caller_pc;
|
| + struct gdbarch *gdbarch;
|
| + struct frame_info *caller_frame;
|
| struct call_site *call_site;
|
| int iparams;
|
| /* Initialize it just to avoid a GCC false warning. */
|
| struct call_site_parameter *parameter = NULL;
|
| CORE_ADDR target_addr;
|
|
|
| + while (get_frame_type (frame) == INLINE_FRAME)
|
| + {
|
| + frame = get_prev_frame (frame);
|
| + gdb_assert (frame != NULL);
|
| + }
|
| +
|
| + func_addr = get_frame_func (frame);
|
| + gdbarch = get_frame_arch (frame);
|
| + caller_frame = get_prev_frame (frame);
|
| if (gdbarch != frame_unwind_arch (frame))
|
| {
|
| - struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr);
|
| + struct bound_minimal_symbol msym
|
| + = lookup_minimal_symbol_by_pc (func_addr);
|
| struct gdbarch *caller_gdbarch = frame_unwind_arch (frame);
|
|
|
| throw_error (NO_ENTRY_VALUE_ERROR,
|
| @@ -1000,18 +1072,21 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
|
| "(of %s (%s)) does not match caller gdbarch %s"),
|
| gdbarch_bfd_arch_info (gdbarch)->printable_name,
|
| paddress (gdbarch, func_addr),
|
| - msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym),
|
| + (msym.minsym == NULL ? "???"
|
| + : SYMBOL_PRINT_NAME (msym.minsym)),
|
| gdbarch_bfd_arch_info (caller_gdbarch)->printable_name);
|
| }
|
|
|
| if (caller_frame == NULL)
|
| {
|
| - struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr);
|
| + struct bound_minimal_symbol msym
|
| + = lookup_minimal_symbol_by_pc (func_addr);
|
|
|
| throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_GNU_entry_value resolving "
|
| "requires caller of %s (%s)"),
|
| paddress (gdbarch, func_addr),
|
| - msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
| + (msym.minsym == NULL ? "???"
|
| + : SYMBOL_PRINT_NAME (msym.minsym)));
|
| }
|
| caller_pc = get_frame_pc (caller_frame);
|
| call_site = call_site_for_pc (gdbarch, caller_pc);
|
| @@ -1021,8 +1096,8 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
|
| {
|
| struct minimal_symbol *target_msym, *func_msym;
|
|
|
| - target_msym = lookup_minimal_symbol_by_pc (target_addr);
|
| - func_msym = lookup_minimal_symbol_by_pc (func_addr);
|
| + target_msym = lookup_minimal_symbol_by_pc (target_addr).minsym;
|
| + func_msym = lookup_minimal_symbol_by_pc (func_addr).minsym;
|
| throw_error (NO_ENTRY_VALUE_ERROR,
|
| _("DW_OP_GNU_entry_value resolving expects callee %s at %s "
|
| "but the called frame is for %s at %s"),
|
| @@ -1045,7 +1120,8 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
|
| }
|
| if (iparams == call_site->parameter_count)
|
| {
|
| - struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (caller_pc);
|
| + struct minimal_symbol *msym
|
| + = lookup_minimal_symbol_by_pc (caller_pc).minsym;
|
|
|
| /* DW_TAG_GNU_call_site_parameter will be missing just if GCC could not
|
| determine its value. */
|
| @@ -1539,7 +1615,7 @@ read_pieced_value (struct value *v)
|
| struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v));
|
| size_t type_len;
|
| size_t buffer_size = 0;
|
| - char *buffer = NULL;
|
| + gdb_byte *buffer = NULL;
|
| struct cleanup *cleanup;
|
| int bits_big_endian
|
| = gdbarch_bits_big_endian (get_type_arch (value_type (v)));
|
| @@ -1576,8 +1652,6 @@ read_pieced_value (struct value *v)
|
| bits_to_skip -= this_size_bits;
|
| continue;
|
| }
|
| - if (this_size_bits > type_len - offset)
|
| - this_size_bits = type_len - offset;
|
| if (bits_to_skip > 0)
|
| {
|
| dest_offset_bits = 0;
|
| @@ -1590,6 +1664,8 @@ read_pieced_value (struct value *v)
|
| dest_offset_bits = offset;
|
| source_offset_bits = 0;
|
| }
|
| + if (this_size_bits > type_len - offset)
|
| + this_size_bits = type_len - offset;
|
|
|
| this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
|
| source_offset = source_offset_bits / 8;
|
| @@ -1722,7 +1798,7 @@ write_pieced_value (struct value *to, struct value *from)
|
| struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to));
|
| size_t type_len;
|
| size_t buffer_size = 0;
|
| - char *buffer = NULL;
|
| + gdb_byte *buffer = NULL;
|
| struct cleanup *cleanup;
|
| int bits_big_endian
|
| = gdbarch_bits_big_endian (get_type_arch (value_type (to)));
|
| @@ -1817,9 +1893,10 @@ write_pieced_value (struct value *to, struct value *from)
|
| &optim, &unavail))
|
| {
|
| if (optim)
|
| - error (_("Can't do read-modify-write to "
|
| - "update bitfield; containing word has been "
|
| - "optimized out"));
|
| + throw_error (OPTIMIZED_OUT_ERROR,
|
| + _("Can't do read-modify-write to "
|
| + "update bitfield; containing word "
|
| + "has been optimized out"));
|
| if (unavail)
|
| throw_error (NOT_AVAILABLE_ERROR,
|
| _("Can't do read-modify-write to update "
|
| @@ -2022,17 +2099,53 @@ indirect_pieced_value (struct value *value)
|
|
|
| frame = get_selected_frame (_("No frame selected."));
|
|
|
| - /* This is an offset requested by GDB, such as value subcripts. */
|
| + /* This is an offset requested by GDB, such as value subscripts.
|
| + However, due to how synthetic pointers are implemented, this is
|
| + always presented to us as a pointer type. This means we have to
|
| + sign-extend it manually as appropriate. */
|
| byte_offset = value_as_address (value);
|
| + if (TYPE_LENGTH (value_type (value)) < sizeof (LONGEST))
|
| + byte_offset = gdb_sign_extend (byte_offset,
|
| + 8 * TYPE_LENGTH (value_type (value)));
|
| + byte_offset += piece->v.ptr.offset;
|
|
|
| gdb_assert (piece);
|
| - baton = dwarf2_fetch_die_location_block (piece->v.ptr.die, c->per_cu,
|
| - get_frame_address_in_block_wrapper,
|
| - frame);
|
| + baton
|
| + = dwarf2_fetch_die_loc_sect_off (piece->v.ptr.die, c->per_cu,
|
| + get_frame_address_in_block_wrapper,
|
| + frame);
|
| +
|
| + if (baton.data != NULL)
|
| + return dwarf2_evaluate_loc_desc_full (TYPE_TARGET_TYPE (type), frame,
|
| + baton.data, baton.size, baton.per_cu,
|
| + byte_offset);
|
| +
|
| + {
|
| + struct obstack temp_obstack;
|
| + struct cleanup *cleanup;
|
| + const gdb_byte *bytes;
|
| + LONGEST len;
|
| + struct value *result;
|
| +
|
| + obstack_init (&temp_obstack);
|
| + cleanup = make_cleanup_obstack_free (&temp_obstack);
|
| +
|
| + bytes = dwarf2_fetch_constant_bytes (piece->v.ptr.die, c->per_cu,
|
| + &temp_obstack, &len);
|
| + if (bytes == NULL)
|
| + result = allocate_optimized_out_value (TYPE_TARGET_TYPE (type));
|
| + else
|
| + {
|
| + if (byte_offset < 0
|
| + || byte_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > len)
|
| + invalid_synthetic_pointer ();
|
| + bytes += byte_offset;
|
| + result = value_from_contents (TYPE_TARGET_TYPE (type), bytes);
|
| + }
|
|
|
| - return dwarf2_evaluate_loc_desc_full (TYPE_TARGET_TYPE (type), frame,
|
| - baton.data, baton.size, baton.per_cu,
|
| - piece->v.ptr.offset + byte_offset);
|
| + do_cleanups (cleanup);
|
| + return result;
|
| + }
|
| }
|
|
|
| static void *
|
| @@ -2078,21 +2191,12 @@ static const struct lval_funcs pieced_value_funcs = {
|
| free_pieced_value_closure
|
| };
|
|
|
| -/* Helper function which throws an error if a synthetic pointer is
|
| - invalid. */
|
| -
|
| -static void
|
| -invalid_synthetic_pointer (void)
|
| -{
|
| - error (_("access outside bounds of object "
|
| - "referenced via synthetic pointer"));
|
| -}
|
| -
|
| /* Virtual method table for dwarf2_evaluate_loc_desc_full below. */
|
|
|
| static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs =
|
| {
|
| - dwarf_expr_read_reg,
|
| + dwarf_expr_read_addr_from_reg,
|
| + dwarf_expr_get_reg_value,
|
| dwarf_expr_read_mem,
|
| dwarf_expr_frame_base,
|
| dwarf_expr_frame_cfa,
|
| @@ -2111,7 +2215,7 @@ static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs =
|
|
|
| static struct value *
|
| dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
|
| - const gdb_byte *data, unsigned short size,
|
| + const gdb_byte *data, size_t size,
|
| struct dwarf2_per_cu_data *per_cu,
|
| LONGEST byte_offset)
|
| {
|
| @@ -2194,17 +2298,28 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
|
| case DWARF_VALUE_REGISTER:
|
| {
|
| struct gdbarch *arch = get_frame_arch (frame);
|
| - ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
|
| + int dwarf_regnum
|
| + = longest_to_int (value_as_long (dwarf_expr_fetch (ctx, 0)));
|
| int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
|
|
|
| if (byte_offset != 0)
|
| error (_("cannot use offset on synthetic pointer to register"));
|
| do_cleanups (value_chain);
|
| - if (gdb_regnum != -1)
|
| - retval = value_from_register (type, gdb_regnum, frame);
|
| - else
|
| - error (_("Unable to access DWARF register number %s"),
|
| - paddress (arch, dwarf_regnum));
|
| + if (gdb_regnum == -1)
|
| + error (_("Unable to access DWARF register number %d"),
|
| + dwarf_regnum);
|
| + retval = value_from_register (type, gdb_regnum, frame);
|
| + if (value_optimized_out (retval))
|
| + {
|
| + /* This means the register has undefined value / was
|
| + not saved. As we're computing the location of some
|
| + variable etc. in the program, not a value for
|
| + inspecting a register ($pc, $sp, etc.), return a
|
| + generic optimized out value instead, so that we show
|
| + <optimized out> instead of <not saved>. */
|
| + do_cleanups (value_chain);
|
| + retval = allocate_optimized_out_value (type);
|
| + }
|
| }
|
| break;
|
|
|
| @@ -2214,11 +2329,9 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
|
| int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
|
|
|
| do_cleanups (value_chain);
|
| - retval = allocate_value_lazy (type);
|
| - VALUE_LVAL (retval) = lval_memory;
|
| + retval = value_at_lazy (type, address + byte_offset);
|
| if (in_stack_memory)
|
| set_value_stack (retval, 1);
|
| - set_value_address (retval, address + byte_offset);
|
| }
|
| break;
|
|
|
| @@ -2312,7 +2425,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
|
|
|
| struct value *
|
| dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
|
| - const gdb_byte *data, unsigned short size,
|
| + const gdb_byte *data, size_t size,
|
| struct dwarf2_per_cu_data *per_cu)
|
| {
|
| return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
|
| @@ -2329,7 +2442,7 @@ struct needs_frame_baton
|
|
|
| /* Reads from registers do require a frame. */
|
| static CORE_ADDR
|
| -needs_frame_read_reg (void *baton, int regnum)
|
| +needs_frame_read_addr_from_reg (void *baton, int regnum)
|
| {
|
| struct needs_frame_baton *nf_baton = baton;
|
|
|
| @@ -2337,6 +2450,18 @@ needs_frame_read_reg (void *baton, int regnum)
|
| return 1;
|
| }
|
|
|
| +/* struct dwarf_expr_context_funcs' "get_reg_value" callback:
|
| + Reads from registers do require a frame. */
|
| +
|
| +static struct value *
|
| +needs_frame_get_reg_value (void *baton, struct type *type, int regnum)
|
| +{
|
| + struct needs_frame_baton *nf_baton = baton;
|
| +
|
| + nf_baton->needs_frame = 1;
|
| + return value_zero (type, not_lval);
|
| +}
|
| +
|
| /* Reads from memory do not require a frame. */
|
| static void
|
| needs_frame_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len)
|
| @@ -2417,7 +2542,8 @@ needs_get_addr_index (void *baton, unsigned int index)
|
|
|
| static const struct dwarf_expr_context_funcs needs_frame_ctx_funcs =
|
| {
|
| - needs_frame_read_reg,
|
| + needs_frame_read_addr_from_reg,
|
| + needs_frame_get_reg_value,
|
| needs_frame_read_mem,
|
| needs_frame_frame_base,
|
| needs_frame_frame_cfa,
|
| @@ -2433,7 +2559,7 @@ static const struct dwarf_expr_context_funcs needs_frame_ctx_funcs =
|
| requires a frame to evaluate. */
|
|
|
| static int
|
| -dwarf2_loc_desc_needs_frame (const gdb_byte *data, unsigned short size,
|
| +dwarf2_loc_desc_needs_frame (const gdb_byte *data, size_t size,
|
| struct dwarf2_per_cu_data *per_cu)
|
| {
|
| struct needs_frame_baton baton;
|
| @@ -2519,9 +2645,9 @@ access_memory (struct gdbarch *arch, struct agent_expr *expr, ULONGEST nbits)
|
| {
|
| ULONGEST nbytes = (nbits + 7) / 8;
|
|
|
| - gdb_assert (nbits > 0 && nbits <= sizeof (LONGEST));
|
| + gdb_assert (nbytes > 0 && nbytes <= sizeof (LONGEST));
|
|
|
| - if (trace_kludge)
|
| + if (expr->tracing)
|
| ax_trace_quick (expr, nbytes);
|
|
|
| if (nbits <= 8)
|
| @@ -2848,7 +2974,6 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
|
| size_t datalen;
|
| struct block *b;
|
| struct symbol *framefunc;
|
| - LONGEST base_offset = 0;
|
|
|
| b = block_for_pc (expr->scope);
|
|
|
| @@ -2866,6 +2991,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
|
| op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
|
| dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, datastart,
|
| datastart + datalen, per_cu);
|
| + if (loc->kind == axs_lvalue_register)
|
| + require_rvalue (expr, loc);
|
|
|
| if (offset != 0)
|
| {
|
| @@ -2912,26 +3039,10 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
|
| else
|
| size = addr_size;
|
|
|
| - switch (size)
|
| - {
|
| - case 8:
|
| - ax_simple (expr, aop_ref8);
|
| - break;
|
| - case 16:
|
| - ax_simple (expr, aop_ref16);
|
| - break;
|
| - case 32:
|
| - ax_simple (expr, aop_ref32);
|
| - break;
|
| - case 64:
|
| - ax_simple (expr, aop_ref64);
|
| - break;
|
| - default:
|
| - /* Note that get_DW_OP_name will never return
|
| - NULL here. */
|
| - error (_("Unsupported size %d in %s"),
|
| - size, get_DW_OP_name (op));
|
| - }
|
| + if (size != 1 && size != 2 && size != 4 && size != 8)
|
| + error (_("Unsupported size %d in %s"),
|
| + size, get_DW_OP_name (op));
|
| + access_memory (arch, expr, size * TARGET_CHAR_BIT);
|
| }
|
| break;
|
|
|
| @@ -3193,8 +3304,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
|
| op_ptr += size;
|
|
|
| offset.cu_off = uoffset;
|
| - block = dwarf2_fetch_die_location_block (offset, per_cu,
|
| - get_ax_pc, expr);
|
| + block = dwarf2_fetch_die_loc_cu_off (offset, per_cu,
|
| + get_ax_pc, expr);
|
|
|
| /* DW_OP_call_ref is currently not supported. */
|
| gdb_assert (block.per_cu == per_cu);
|
| @@ -3414,7 +3525,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
|
| fprintf_filtered (stream,
|
| _("a thread-local variable at offset 0x%s "
|
| "in the thread-local storage for `%s'"),
|
| - phex_nz (offset, addr_size), objfile->name);
|
| + phex_nz (offset, addr_size), objfile_name (objfile));
|
|
|
| data += 1 + addr_size + 1;
|
| }
|
| @@ -3430,14 +3541,14 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
|
| && data[1 + leb128_size] == DW_OP_GNU_push_tls_address
|
| && piece_end_p (data + 2 + leb128_size, end))
|
| {
|
| - ULONGEST offset;
|
| + uint64_t offset;
|
|
|
| data = safe_read_uleb128 (data + 1, end, &offset);
|
| offset = dwarf2_read_addr_index (per_cu, offset);
|
| fprintf_filtered (stream,
|
| _("a thread-local variable at offset 0x%s "
|
| "in the thread-local storage for `%s'"),
|
| - phex_nz (offset, addr_size), objfile->name);
|
| + phex_nz (offset, addr_size), objfile_name (objfile));
|
| ++data;
|
| }
|
|
|
| @@ -3827,7 +3938,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
|
| static void
|
| locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
|
| struct ui_file *stream,
|
| - const gdb_byte *data, int size,
|
| + const gdb_byte *data, size_t size,
|
| struct objfile *objfile, unsigned int addr_size,
|
| int offset_size, struct dwarf2_per_cu_data *per_cu)
|
| {
|
| @@ -3958,6 +4069,7 @@ const struct symbol_computed_ops dwarf2_locexpr_funcs = {
|
| locexpr_read_variable_at_entry,
|
| locexpr_read_needs_frame,
|
| locexpr_describe_location,
|
| + 0, /* location_has_loclist */
|
| locexpr_tracepoint_var_ref
|
| };
|
|
|
| @@ -4032,7 +4144,6 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
|
| {
|
| struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
|
| const gdb_byte *loc_ptr, *buf_end;
|
| - int first = 1;
|
| struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
|
| struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
| @@ -4137,6 +4248,7 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = {
|
| loclist_read_variable_at_entry,
|
| loclist_read_needs_frame,
|
| loclist_describe_location,
|
| + 1, /* location_has_loclist */
|
| loclist_tracepoint_var_ref
|
| };
|
|
|
| @@ -4146,16 +4258,16 @@ extern initialize_file_ftype _initialize_dwarf2loc;
|
| void
|
| _initialize_dwarf2loc (void)
|
| {
|
| - add_setshow_zinteger_cmd ("entry-values", class_maintenance,
|
| - &entry_values_debug,
|
| - _("Set entry values and tail call frames "
|
| - "debugging."),
|
| - _("Show entry values and tail call frames "
|
| - "debugging."),
|
| - _("When non-zero, the process of determining "
|
| - "parameter values from function entry point "
|
| - "and tail call frames will be printed."),
|
| - NULL,
|
| - show_entry_values_debug,
|
| - &setdebuglist, &showdebuglist);
|
| + add_setshow_zuinteger_cmd ("entry-values", class_maintenance,
|
| + &entry_values_debug,
|
| + _("Set entry values and tail call frames "
|
| + "debugging."),
|
| + _("Show entry values and tail call frames "
|
| + "debugging."),
|
| + _("When non-zero, the process of determining "
|
| + "parameter values from function entry point "
|
| + "and tail call frames will be printed."),
|
| + NULL,
|
| + show_entry_values_debug,
|
| + &setdebuglist, &showdebuglist);
|
| }
|
|
|