/* DWARF 2 location expression support for GDB.
- Copyright (C) 2003-2021 Free Software Foundation, Inc.
+ Copyright (C) 2003-2023 Free Software Foundation, Inc.
Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
#include "gdbsupport/byte-vector.h"
static struct value *dwarf2_evaluate_loc_desc_full
- (struct type *type, struct frame_info *frame, const gdb_byte *data,
+ (struct type *type, frame_info_ptr frame, const gdb_byte *data,
size_t size, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
struct type *subobj_type, LONGEST subobj_byte_offset, bool as_lval = true);
struct gdbarch *gdbarch = objfile->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int addr_size = baton->per_cu->addr_size ();
- int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
- /* Adjust base_address for relocatable objects. */
- CORE_ADDR base_offset = baton->per_objfile->objfile->text_section_offset ();
- CORE_ADDR base_address = baton->base_address + base_offset;
+ int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
+ /* Adjustment for relocatable objects. */
+ CORE_ADDR text_offset = baton->per_objfile->objfile->text_section_offset ();
+ CORE_ADDR base_address = baton->base_address;
const gdb_byte *loc_ptr, *buf_end;
loc_ptr = baton->data;
return NULL;
case DEBUG_LOC_BASE_ADDRESS:
- base_address = high + base_offset;
+ base_address = high;
continue;
case DEBUG_LOC_START_END:
/* Otherwise, a location expression entry.
If the entry is from a DWO, don't add base address: the entry is from
.debug_addr which already has the DWARF "base address". We still add
- base_offset in case we're debugging a PIE executable. However, if the
+ text offset in case we're debugging a PIE executable. However, if the
entry is DW_LLE_offset_pair from a DWO, add the base address as the
operands are offsets relative to the applicable base address.
If the entry is DW_LLE_start_end or DW_LLE_start_length, then
it already is an address, and we don't need to add the base. */
- if (baton->from_dwo && kind != DEBUG_LOC_OFFSET_PAIR)
- {
- low += base_offset;
- high += base_offset;
- }
- else if (kind == DEBUG_LOC_OFFSET_PAIR)
+ low += text_offset;
+ high += text_offset;
+ if (!baton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
{
low += base_address;
high += base_address;
if (pc_block)
pc_func = block_linkage_function (pc_block);
- if (pc_func && pc == BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (pc_func)))
+ if (pc_func && pc == pc_func->value_block ()->entry_pc ())
{
*locexpr_length = length;
return loc_ptr;
LOC_BLOCK functions using a DWARF expression as its DW_AT_frame_base. */
static CORE_ADDR
-locexpr_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
+locexpr_get_frame_base (struct symbol *framefunc, frame_info_ptr frame)
{
struct gdbarch *gdbarch;
struct type *type;
dwarf2_evaluate_loc_desc returns a value representing a variable at
that address. The frame base address is thus this variable's
address. */
- return value_address (result);
+ return result->address ();
}
/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
LOC_BLOCK functions using a DWARF location list as its DW_AT_frame_base. */
static CORE_ADDR
-loclist_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
+loclist_get_frame_base (struct symbol *framefunc, frame_info_ptr frame)
{
struct gdbarch *gdbarch;
struct type *type;
dwarf2_evaluate_loc_desc returns a value representing a variable at
that address. The frame base address is thus this variable's
address. */
- return value_address (result);
+ return result->address ();
}
/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
loclist_get_frame_base
};
-/* See dwarf2loc.h. */
+/* See dwarf2/loc.h. */
void
func_get_frame_base_dwarf_block (struct symbol *framefunc, CORE_ADDR pc,
return nullptr;
}
-/* See dwarf2loc.h. */
+/* See dwarf2/loc.h. */
unsigned int entry_values_debug = 0;
show_entry_values_debug (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file,
- _("Entry values and tail call frames debugging is %s.\n"),
- value);
+ gdb_printf (file,
+ _("Entry values and tail call frames debugging is %s.\n"),
+ value);
}
-/* Find DW_TAG_call_site's DW_AT_call_target address.
- CALLER_FRAME (for registers) can be NULL if it is not known. This function
- always returns valid address or it throws NO_ENTRY_VALUE_ERROR. */
+/* See gdbtypes.h. */
-static CORE_ADDR
-call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
- struct call_site *call_site,
- struct frame_info *caller_frame)
+void
+call_site_target::iterate_over_addresses
+ (struct gdbarch *call_site_gdbarch,
+ const struct call_site *call_site,
+ frame_info_ptr caller_frame,
+ iterate_ftype callback) const
{
- switch (call_site->target.loc_kind ())
+ switch (m_loc_kind)
{
- case FIELD_LOC_KIND_DWARF_BLOCK:
+ case call_site_target::DWARF_BLOCK:
{
struct dwarf2_locexpr_baton *dwarf_block;
struct value *val;
struct type *caller_core_addr_type;
struct gdbarch *caller_arch;
- dwarf_block = call_site->target.loc_dwarf_block ();
+ dwarf_block = m_loc.dwarf_block;
if (dwarf_block == NULL)
{
struct bound_minimal_symbol msym;
dwarf_block->per_objfile);
/* DW_AT_call_target is a DWARF expression, not a DWARF location. */
if (VALUE_LVAL (val) == lval_memory)
- return value_address (val);
+ callback (val->address ());
else
- return value_as_address (val);
+ callback (value_as_address (val));
}
+ break;
- case FIELD_LOC_KIND_PHYSNAME:
+ case call_site_target::PHYSNAME:
{
const char *physname;
struct bound_minimal_symbol msym;
- physname = call_site->target.loc_physname ();
+ physname = m_loc.physname;
/* Handle both the mangled and demangled PHYSNAME. */
msym = lookup_minimal_symbol (physname, NULL, NULL);
: msym.minsym->print_name ()));
}
- return BMSYMBOL_VALUE_ADDRESS (msym);
+ callback (msym.value_address ());
+ }
+ break;
+
+ case call_site_target::PHYSADDR:
+ {
+ dwarf2_per_objfile *per_objfile = call_site->per_objfile;
+ CORE_ADDR delta = per_objfile->objfile->text_section_offset ();
+
+ callback (m_loc.physaddr + delta);
}
+ break;
- case FIELD_LOC_KIND_PHYSADDR:
+ case call_site_target::ADDRESSES:
{
dwarf2_per_objfile *per_objfile = call_site->per_objfile;
- compunit_symtab *cust = per_objfile->get_symtab (call_site->per_cu);
- int sect_idx = COMPUNIT_BLOCK_LINE_SECTION (cust);
- CORE_ADDR delta = per_objfile->objfile->section_offsets[sect_idx];
+ CORE_ADDR delta = per_objfile->objfile->text_section_offset ();
- return call_site->target.loc_physaddr () + delta;
+ for (unsigned i = 0; i < m_loc.addresses.length; ++i)
+ callback (m_loc.addresses.values[i] + delta);
}
+ break;
default:
- internal_error (__FILE__, __LINE__, _("invalid call site target kind"));
+ internal_error (_("invalid call site target kind"));
}
}
struct symbol *sym = find_pc_function (addr);
struct type *type;
- if (sym == NULL || BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)) != addr)
+ if (sym == NULL || sym->value_block ()->entry_pc () != addr)
throw_error (NO_ENTRY_VALUE_ERROR,
_("DW_TAG_call_site resolving failed to find function "
"name for address %s"),
paddress (gdbarch, addr));
- type = SYMBOL_TYPE (sym);
+ type = sym->type ();
gdb_assert (type->code () == TYPE_CODE_FUNC);
gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
func_sym = func_addr_to_tail_call_list (gdbarch, addr);
- for (call_site = TYPE_TAIL_CALL_LIST (SYMBOL_TYPE (func_sym));
+ for (call_site = TYPE_TAIL_CALL_LIST (func_sym->type ());
call_site; call_site = call_site->tail_call_next)
{
- CORE_ADDR target_addr;
-
/* CALLER_FRAME with registers is not available for tail-call jumped
frames. */
- target_addr = call_site_to_target_addr (gdbarch, call_site, NULL);
-
- if (target_addr == verify_addr)
+ call_site->iterate_over_addresses (gdbarch, nullptr,
+ [&] (CORE_ADDR target_addr)
{
- struct bound_minimal_symbol msym;
-
- msym = lookup_minimal_symbol_by_pc (verify_addr);
- throw_error (NO_ENTRY_VALUE_ERROR,
- _("DW_OP_entry_value resolving has found "
- "function \"%s\" at %s can call itself via tail "
- "calls"),
- (msym.minsym == NULL ? "???"
- : msym.minsym->print_name ()),
- paddress (gdbarch, verify_addr));
- }
+ if (target_addr == verify_addr)
+ {
+ struct bound_minimal_symbol msym;
+
+ msym = lookup_minimal_symbol_by_pc (verify_addr);
+ throw_error (NO_ENTRY_VALUE_ERROR,
+ _("DW_OP_entry_value resolving has found "
+ "function \"%s\" at %s can call itself via tail "
+ "calls"),
+ (msym.minsym == NULL ? "???"
+ : msym.minsym->print_name ()),
+ paddress (gdbarch, verify_addr));
+ }
- if (addr_hash.insert (target_addr).second)
- todo.push_back (target_addr);
+ if (addr_hash.insert (target_addr).second)
+ todo.push_back (target_addr);
+ });
}
}
}
CORE_ADDR addr = call_site->pc ();
struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1);
- fprintf_unfiltered (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
- (msym.minsym == NULL ? "???"
- : msym.minsym->print_name ()));
+ gdb_printf (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
+ (msym.minsym == NULL ? "???"
+ : msym.minsym->print_name ()));
}
static void
chain_candidate (struct gdbarch *gdbarch,
gdb::unique_xmalloc_ptr<struct call_site_chain> *resultp,
- std::vector<struct call_site *> *chain)
+ const std::vector<struct call_site *> &chain)
{
- long length = chain->size ();
+ long length = chain.size ();
int callers, callees, idx;
if (*resultp == NULL)
+ sizeof (*result->call_site) * (length - 1)));
result->length = length;
result->callers = result->callees = length;
- if (!chain->empty ())
- memcpy (result->call_site, chain->data (),
+ if (!chain.empty ())
+ memcpy (result->call_site, chain.data (),
sizeof (*result->call_site) * length);
resultp->reset (result);
if (entry_values_debug)
{
- fprintf_unfiltered (gdb_stdlog, "tailcall: initial:");
+ gdb_printf (gdb_stdlog, "tailcall: initial:");
for (idx = 0; idx < length; idx++)
tailcall_dump (gdbarch, result->call_site[idx]);
- fputc_unfiltered ('\n', gdb_stdlog);
+ gdb_putc ('\n', gdb_stdlog);
}
return;
if (entry_values_debug)
{
- fprintf_unfiltered (gdb_stdlog, "tailcall: compare:");
+ gdb_printf (gdb_stdlog, "tailcall: compare:");
for (idx = 0; idx < length; idx++)
- tailcall_dump (gdbarch, chain->at (idx));
- fputc_unfiltered ('\n', gdb_stdlog);
+ tailcall_dump (gdbarch, chain[idx]);
+ gdb_putc ('\n', gdb_stdlog);
}
/* Intersect callers. */
callers = std::min ((long) (*resultp)->callers, length);
for (idx = 0; idx < callers; idx++)
- if ((*resultp)->call_site[idx] != chain->at (idx))
+ if ((*resultp)->call_site[idx] != chain[idx])
{
(*resultp)->callers = idx;
break;
callees = std::min ((long) (*resultp)->callees, length);
for (idx = 0; idx < callees; idx++)
if ((*resultp)->call_site[(*resultp)->length - 1 - idx]
- != chain->at (length - 1 - idx))
+ != chain[length - 1 - idx])
{
(*resultp)->callees = idx;
break;
if (entry_values_debug)
{
- fprintf_unfiltered (gdb_stdlog, "tailcall: reduced:");
+ gdb_printf (gdb_stdlog, "tailcall: reduced:");
for (idx = 0; idx < (*resultp)->callers; idx++)
tailcall_dump (gdbarch, (*resultp)->call_site[idx]);
- fputs_unfiltered (" |", gdb_stdlog);
+ gdb_puts (" |", gdb_stdlog);
for (idx = 0; idx < (*resultp)->callees; idx++)
tailcall_dump (gdbarch,
(*resultp)->call_site[(*resultp)->length
- (*resultp)->callees + idx]);
- fputc_unfiltered ('\n', gdb_stdlog);
+ gdb_putc ('\n', gdb_stdlog);
}
if ((*resultp)->callers == 0 && (*resultp)->callees == 0)
gdb_assert ((*resultp)->callers + (*resultp)->callees <= (*resultp)->length);
}
-/* Create and return call_site_chain for CALLER_PC and CALLEE_PC. All the
- assumed frames between them use GDBARCH. Use depth first search so we can
- keep single CHAIN of call_site's back to CALLER_PC. Function recursion
- would have needless GDB stack overhead. Any unreliability results
- in thrown NO_ENTRY_VALUE_ERROR. */
+/* Recursively try to construct the call chain. GDBARCH, RESULTP, and
+ CHAIN are passed to chain_candidate. ADDR_HASH tracks which
+ addresses have already been seen along the current chain.
+ CALL_SITE is the call site to visit, and CALLEE_PC is the PC we're
+ trying to "reach". Returns false if an error has already been
+ detected and so an early return can be done. If it makes sense to
+ keep trying (even if no answer has yet been found), returns
+ true. */
+
+static bool
+call_site_find_chain_2
+ (struct gdbarch *gdbarch,
+ gdb::unique_xmalloc_ptr<struct call_site_chain> *resultp,
+ std::vector<struct call_site *> &chain,
+ std::unordered_set<CORE_ADDR> &addr_hash,
+ struct call_site *call_site,
+ CORE_ADDR callee_pc)
+{
+ std::vector<CORE_ADDR> addresses;
+ bool found_exact = false;
+ call_site->iterate_over_addresses (gdbarch, nullptr,
+ [&] (CORE_ADDR addr)
+ {
+ if (addr == callee_pc)
+ found_exact = true;
+ else
+ addresses.push_back (addr);
+ });
+
+ if (found_exact)
+ {
+ chain_candidate (gdbarch, resultp, chain);
+ /* If RESULTP was reset, then chain_candidate failed, and so we
+ can tell our callers to early-return. */
+ return *resultp != nullptr;
+ }
+
+ for (CORE_ADDR target_func_addr : addresses)
+ {
+ struct symbol *target_func
+ = func_addr_to_tail_call_list (gdbarch, target_func_addr);
+ for (struct call_site *target_call_site
+ = TYPE_TAIL_CALL_LIST (target_func->type ());
+ target_call_site != nullptr;
+ target_call_site = target_call_site->tail_call_next)
+ {
+ if (addr_hash.insert (target_call_site->pc ()).second)
+ {
+ /* Successfully entered TARGET_CALL_SITE. */
+ chain.push_back (target_call_site);
+
+ if (!call_site_find_chain_2 (gdbarch, resultp, chain,
+ addr_hash, target_call_site,
+ callee_pc))
+ return false;
+
+ size_t removed = addr_hash.erase (target_call_site->pc ());
+ gdb_assert (removed == 1);
+ chain.pop_back ();
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Create and return call_site_chain for CALLER_PC and CALLEE_PC. All
+ the assumed frames between them use GDBARCH. Any unreliability
+ results in thrown NO_ENTRY_VALUE_ERROR. */
static gdb::unique_xmalloc_ptr<call_site_chain>
call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
TAIL_CALL_NEXT. This is inappropriate for CALLER_PC's call_site. */
std::vector<struct call_site *> chain;
+ /* A given call site may have multiple associated addresses. This
+ can happen if, e.g., the caller is split by hot/cold
+ partitioning. This vector tracks the ones we haven't visited
+ yet. */
+ std::vector<std::vector<CORE_ADDR>> unvisited_addresses;
+
/* We are not interested in the specific PC inside the callee function. */
callee_pc = get_pc_function_start (callee_pc);
if (callee_pc == 0)
target's function will get iterated as already pushed into CHAIN via their
TAIL_CALL_NEXT. */
call_site = call_site_for_pc (gdbarch, caller_pc);
-
- while (call_site)
- {
- CORE_ADDR target_func_addr;
- struct call_site *target_call_site;
-
- /* CALLER_FRAME with registers is not available for tail-call jumped
- frames. */
- target_func_addr = call_site_to_target_addr (gdbarch, call_site, NULL);
-
- if (target_func_addr == callee_pc)
- {
- chain_candidate (gdbarch, &retval, &chain);
- if (retval == NULL)
- break;
-
- /* There is no way to reach CALLEE_PC again as we would prevent
- entering it twice as being already marked in ADDR_HASH. */
- target_call_site = NULL;
- }
- else
- {
- struct symbol *target_func;
-
- target_func = func_addr_to_tail_call_list (gdbarch, target_func_addr);
- target_call_site = TYPE_TAIL_CALL_LIST (SYMBOL_TYPE (target_func));
- }
-
- do
- {
- /* Attempt to visit TARGET_CALL_SITE. */
-
- if (target_call_site)
- {
- if (addr_hash.insert (target_call_site->pc ()).second)
- {
- /* Successfully entered TARGET_CALL_SITE. */
-
- chain.push_back (target_call_site);
- break;
- }
- }
-
- /* Backtrack (without revisiting the originating call_site). Try the
- callers's sibling; if there isn't any try the callers's callers's
- sibling etc. */
-
- target_call_site = NULL;
- while (!chain.empty ())
- {
- call_site = chain.back ();
- chain.pop_back ();
-
- size_t removed = addr_hash.erase (call_site->pc ());
- gdb_assert (removed == 1);
-
- target_call_site = call_site->tail_call_next;
- if (target_call_site)
- break;
- }
- }
- while (target_call_site);
-
- if (chain.empty ())
- call_site = NULL;
- else
- call_site = chain.back ();
- }
+ /* No need to check the return value here, because we no longer care
+ about possible early returns. */
+ call_site_find_chain_2 (gdbarch, &retval, chain, addr_hash, call_site,
+ callee_pc);
if (retval == NULL)
{
/* See loc.h. */
struct call_site_parameter *
-dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
+dwarf_expr_reg_to_entry_parameter (frame_info_ptr frame,
enum call_site_parameter_kind kind,
union call_site_parameter_u kind_u,
dwarf2_per_cu_data **per_cu_return,
{
CORE_ADDR func_addr, caller_pc;
struct gdbarch *gdbarch;
- struct frame_info *caller_frame;
+ frame_info_ptr caller_frame;
struct call_site *call_site;
int iparams;
/* Initialize it just to avoid a GCC false warning. */
caller_pc = get_frame_pc (caller_frame);
call_site = call_site_for_pc (gdbarch, caller_pc);
- target_addr = call_site_to_target_addr (gdbarch, call_site, caller_frame);
- if (target_addr != func_addr)
+ bool found = false;
+ unsigned count = 0;
+ call_site->iterate_over_addresses (gdbarch, caller_frame,
+ [&] (CORE_ADDR addr)
+ {
+ /* Preserve any address. */
+ target_addr = addr;
+ ++count;
+ if (addr == func_addr)
+ found = true;
+ });
+ if (!found)
{
struct minimal_symbol *target_msym, *func_msym;
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_entry_value resolving expects callee %s at %s "
+ _("DW_OP_entry_value resolving expects callee %s at %s %s"
"but the called frame is for %s at %s"),
(target_msym == NULL ? "???"
: target_msym->print_name ()),
paddress (gdbarch, target_addr),
+ (count > 0
+ ? _("(but note there are multiple addresses not listed)")
+ : ""),
func_msym == NULL ? "???" : func_msym->print_name (),
paddress (gdbarch, func_addr));
}
static struct value *
dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
CORE_ADDR deref_size, struct type *type,
- struct frame_info *caller_frame,
+ frame_info_ptr caller_frame,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile)
{
static struct value *
entry_data_value_coerce_ref (const struct value *value)
{
- struct type *checked_type = check_typedef (value_type (value));
+ struct type *checked_type = check_typedef (value->type ());
struct value *target_val;
if (!TYPE_IS_REFERENCE (checked_type))
return NULL;
- target_val = (struct value *) value_computed_closure (value);
- value_incref (target_val);
+ target_val = (struct value *) value->computed_closure ();
+ target_val->incref ();
return target_val;
}
static void *
entry_data_value_copy_closure (const struct value *v)
{
- struct value *target_val = (struct value *) value_computed_closure (v);
+ struct value *target_val = (struct value *) v->computed_closure ();
- value_incref (target_val);
+ target_val->incref ();
return target_val;
}
static void
entry_data_value_free_closure (struct value *v)
{
- struct value *target_val = (struct value *) value_computed_closure (v);
+ struct value *target_val = (struct value *) v->computed_closure ();
- value_decref (target_val);
+ target_val->decref ();
}
/* Vector for methods for an entry value reference where the referenced value
entry_data_value_free_closure
};
-/* Read parameter of TYPE at (callee) FRAME's function entry. KIND and KIND_U
- are used to match DW_AT_location at the caller's
- DW_TAG_call_site_parameter.
-
- Function always returns non-NULL value. It throws NO_ENTRY_VALUE_ERROR if it
- cannot resolve the parameter for any reason. */
-
-static struct value *
-value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
+/* See dwarf2/loc.h. */
+struct value *
+value_of_dwarf_reg_entry (struct type *type, frame_info_ptr frame,
enum call_site_parameter_kind kind,
union call_site_parameter_u kind_u)
{
struct type *checked_type = check_typedef (type);
- struct type *target_type = TYPE_TARGET_TYPE (checked_type);
- struct frame_info *caller_frame = get_prev_frame (frame);
+ struct type *target_type = checked_type->target_type ();
+ frame_info_ptr caller_frame = get_prev_frame (frame);
struct value *outer_val, *target_val, *val;
struct call_site_parameter *parameter;
dwarf2_per_cu_data *caller_per_cu;
entry value. */
if (!TYPE_IS_REFERENCE (checked_type)
- || TYPE_TARGET_TYPE (checked_type) == NULL)
+ || checked_type->target_type () == NULL)
return outer_val;
target_val = dwarf_entry_parameter_to_value (parameter,
- TYPE_LENGTH (target_type),
+ target_type->length (),
target_type, caller_frame,
caller_per_cu,
caller_per_objfile);
- val = allocate_computed_value (type, &entry_data_value_funcs,
+ val = value::allocate_computed (type, &entry_data_value_funcs,
release_value (target_val).release ());
/* Copy the referencing pointer to the new computed value. */
- memcpy (value_contents_raw (val).data (),
- value_contents_raw (outer_val).data (),
- TYPE_LENGTH (checked_type));
- set_value_lazy (val, 0);
+ memcpy (val->contents_raw ().data (),
+ outer_val->contents_raw ().data (),
+ checked_type->length ());
+ val->set_lazy (0);
return val;
}
cannot resolve the parameter for any reason. */
static struct value *
-value_of_dwarf_block_entry (struct type *type, struct frame_info *frame,
+value_of_dwarf_block_entry (struct type *type, frame_info_ptr frame,
const gdb_byte *block, size_t block_len)
{
union call_site_parameter_u kind_u;
if (bytes != NULL)
{
if (byte_offset >= 0
- && byte_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)) <= len)
+ && byte_offset + type->target_type ()->length () <= len)
{
bytes += byte_offset;
- result = value_from_contents (TYPE_TARGET_TYPE (type), bytes);
+ result = value_from_contents (type->target_type (), bytes);
}
else
invalid_synthetic_pointer ();
}
else
- result = allocate_optimized_out_value (TYPE_TARGET_TYPE (type));
+ result = value::allocate_optimized_out (type->target_type ());
return result;
}
indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
- struct frame_info *frame, struct type *type,
+ frame_info_ptr frame, struct type *type,
bool resolve_abstract_p)
{
/* Fetch the location expression of the DIE we're pointing to. */
return dwarf2_evaluate_loc_desc_full (orig_type, frame, baton.data,
baton.size, baton.per_cu,
baton.per_objfile,
- TYPE_TARGET_TYPE (type),
+ type->target_type (),
byte_offset);
else
return fetch_const_value_from_synthetic_pointer (die, byte_offset, per_cu,
SUBOBJ_BYTE_OFFSET within the variable of type TYPE. */
static struct value *
-dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
+dwarf2_evaluate_loc_desc_full (struct type *type, frame_info_ptr frame,
const gdb_byte *data, size_t size,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
invalid_synthetic_pointer ();
if (size == 0)
- return allocate_optimized_out_value (subobj_type);
+ return value::allocate_optimized_out (subobj_type);
dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
if (ex.error == NOT_AVAILABLE_ERROR)
{
free_values.free_to_mark ();
- retval = allocate_value (subobj_type);
- mark_value_bytes_unavailable (retval, 0,
- TYPE_LENGTH (subobj_type));
+ retval = value::allocate (subobj_type);
+ retval->mark_bytes_unavailable (0,
+ subobj_type->length ());
return retval;
}
else if (ex.error == NO_ENTRY_VALUE_ERROR)
if (entry_values_debug)
exception_print (gdb_stdout, ex);
free_values.free_to_mark ();
- return allocate_optimized_out_value (subobj_type);
+ return value::allocate_optimized_out (subobj_type);
}
else
throw;
value_ref_ptr value_holder = value_ref_ptr::new_reference (retval);
free_values.free_to_mark ();
- return value_copy (retval);
+ return retval->copy ();
}
/* The exported interface to dwarf2_evaluate_loc_desc_full; it always
passes 0 as the byte_offset. */
struct value *
-dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
+dwarf2_evaluate_loc_desc (struct type *type, frame_info_ptr frame,
const gdb_byte *data, size_t size,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile, bool as_lval)
CORE_ADDR. FRAME is the frame in which the expression is
evaluated. ADDR_STACK is a context (location of a variable) and
might be needed to evaluate the location expression.
- PUSH_INITIAL_VALUE is true if the address (either from ADDR_STACK,
- or the default of 0) should be pushed on the DWARF expression
- evaluation stack before evaluating the expression; this is required
- by certain forms of DWARF expression. Returns 1 on success, 0
- otherwise. */
+
+ PUSH_VALUES is an array of values to be pushed to the expression stack
+ before evaluation starts. PUSH_VALUES[0] is pushed first, then
+ PUSH_VALUES[1], and so on.
+
+ Returns 1 on success, 0 otherwise. */
static int
dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
- struct frame_info *frame,
+ frame_info_ptr frame,
const struct property_addr_info *addr_stack,
CORE_ADDR *valp,
- bool push_initial_value,
+ gdb::array_view<CORE_ADDR> push_values,
bool *is_reference)
{
if (dlbaton == NULL || dlbaton->size == 0)
value *result;
scoped_value_mark free_values;
- if (push_initial_value)
- {
- if (addr_stack != nullptr)
- ctx.push_address (addr_stack->addr, false);
- else
- ctx.push_address (0, false);
- }
+ /* Place any initial values onto the expression stack. */
+ for (const auto &val : push_values)
+ ctx.push_address (val, false);
try
{
throw;
}
- if (value_optimized_out (result))
+ if (result->optimized_out ())
return 0;
if (VALUE_LVAL (result) == lval_memory)
- *valp = value_address (result);
+ *valp = result->address ();
else
{
if (VALUE_LVAL (result) == not_lval)
return 1;
}
-/* See dwarf2loc.h. */
+/* See dwarf2/loc.h. */
bool
dwarf2_evaluate_property (const struct dynamic_prop *prop,
- struct frame_info *frame,
+ frame_info_ptr frame,
const struct property_addr_info *addr_stack,
CORE_ADDR *value,
- bool push_initial_value)
+ gdb::array_view<CORE_ADDR> push_values)
{
if (prop == NULL)
return false;
+ /* Evaluating a property should not change the current language.
+ Without this here this could happen if the code below selects a
+ frame. */
+ scoped_restore_current_language save_language;
+
if (frame == NULL && has_stack_frames ())
frame = get_selected_frame (NULL);
bool is_reference = baton->locexpr.is_reference;
if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame, addr_stack,
- value, push_initial_value, &is_reference))
+ value, push_values, &is_reference))
{
if (is_reference)
{
gdb_assert (baton->property_type != NULL);
struct type *type = check_typedef (baton->property_type);
- if (TYPE_LENGTH (type) < sizeof (CORE_ADDR)
+ if (type->length () < sizeof (CORE_ADDR)
&& !type->is_unsigned ())
{
/* If we have a valid return candidate and it's value
val = dwarf2_evaluate_loc_desc (baton->property_type, frame, data,
size, baton->loclist.per_cu,
baton->loclist.per_objfile);
- if (!value_optimized_out (val))
+ if (!val->optimized_out ())
{
*value = value_as_address (val);
return true;
return false;
}
-/* See dwarf2loc.h. */
+/* See dwarf2/loc.h. */
void
dwarf2_compile_property_to_c (string_file *stream,
op);
}
-/* See dwarf2loc.h.
+/* See dwarf2/loc.h.
This is basically a wrapper on gdbarch_dwarf2_reg_to_regnum so that we
can issue a complaint, which is better than having every target's
pulongest (dwarf_reg));
}
-/* See dwarf2loc.h. */
+/* See dwarf2/loc.h. */
int
dwarf_reg_to_regnum_or_error (struct gdbarch *arch, ULONGEST dwarf_reg)
{
int targ = offsets[dw_labels[i]];
if (targ == -1)
- internal_error (__FILE__, __LINE__, _("invalid label"));
+ internal_error (_("invalid label"));
ax_label (expr, patches[i], targ);
}
}
/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
evaluator to calculate the location. */
static struct value *
-locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
+locexpr_read_variable (struct symbol *symbol, frame_info_ptr frame)
{
struct dwarf2_locexpr_baton *dlbaton
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
struct value *val;
- val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, dlbaton->data,
+ val = dwarf2_evaluate_loc_desc (symbol->type (), frame, dlbaton->data,
dlbaton->size, dlbaton->per_cu,
dlbaton->per_objfile);
will be thrown. */
static struct value *
-locexpr_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
+locexpr_read_variable_at_entry (struct symbol *symbol, frame_info_ptr frame)
{
struct dwarf2_locexpr_baton *dlbaton
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
- return value_of_dwarf_block_entry (SYMBOL_TYPE (symbol), frame, dlbaton->data,
+ return value_of_dwarf_block_entry (symbol->type (), frame, dlbaton->data,
dlbaton->size);
}
if (data[0] >= DW_OP_reg0 && data[0] <= DW_OP_reg31)
{
- fprintf_filtered (stream, _("a variable in $%s"),
- locexpr_regname (gdbarch, data[0] - DW_OP_reg0));
+ gdb_printf (stream, _("a variable in $%s"),
+ locexpr_regname (gdbarch, data[0] - DW_OP_reg0));
data += 1;
}
else if (data[0] == DW_OP_regx)
uint64_t reg;
data = safe_read_uleb128 (data + 1, end, ®);
- fprintf_filtered (stream, _("a variable in $%s"),
- locexpr_regname (gdbarch, reg));
+ gdb_printf (stream, _("a variable in $%s"),
+ locexpr_regname (gdbarch, reg));
}
else if (data[0] == DW_OP_fbreg)
{
return save_data;
}
- fprintf_filtered (stream,
- _("a variable at frame base reg $%s offset %s+%s"),
- locexpr_regname (gdbarch, frame_reg),
- plongest (base_offset), plongest (frame_offset));
+ gdb_printf (stream,
+ _("a variable at frame base reg $%s offset %s+%s"),
+ locexpr_regname (gdbarch, frame_reg),
+ plongest (base_offset), plongest (frame_offset));
}
else if (data[0] >= DW_OP_breg0 && data[0] <= DW_OP_breg31
&& piece_end_p (data, end))
data = safe_read_sleb128 (data + 1, end, &offset);
- fprintf_filtered (stream,
- _("a variable at offset %s from base reg $%s"),
- plongest (offset),
- locexpr_regname (gdbarch, data[0] - DW_OP_breg0));
+ gdb_printf (stream,
+ _("a variable at offset %s from base reg $%s"),
+ plongest (offset),
+ locexpr_regname (gdbarch, data[0] - DW_OP_breg0));
}
/* The location expression for a TLS variable looks like this (on a
offset = extract_unsigned_integer (data + 1, addr_size,
gdbarch_byte_order (gdbarch));
- 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 (objfile));
+ gdb_printf (stream,
+ _("a thread-local variable at offset 0x%s "
+ "in the thread-local storage for `%s'"),
+ phex_nz (offset, addr_size), objfile_name (objfile));
data += 1 + addr_size + 1;
}
data = safe_read_uleb128 (data + 1, end, &offset);
offset = dwarf2_read_addr_index (per_cu, per_objfile, 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 (objfile));
+ gdb_printf (stream,
+ _("a thread-local variable at offset 0x%s "
+ "in the thread-local storage for `%s'"),
+ phex_nz (offset, addr_size), objfile_name (objfile));
++data;
}
&& data + 1 < end
&& data[1] == DW_OP_stack_value)
{
- fprintf_filtered (stream, _("the constant %d"), data[0] - DW_OP_lit0);
+ gdb_printf (stream, _("the constant %d"), data[0] - DW_OP_lit0);
data += 2;
}
if (!name)
error (_("Unrecognized DWARF opcode 0x%02x at %ld"),
op, (long) (data - 1 - start));
- fprintf_filtered (stream, " %*ld: %s", indent + 4,
- (long) (data - 1 - start), name);
+ gdb_printf (stream, " %*ld: %s", indent + 4,
+ (long) (data - 1 - start), name);
switch (op)
{
ul = extract_unsigned_integer (data, addr_size,
gdbarch_byte_order (arch));
data += addr_size;
- fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size));
+ gdb_printf (stream, " 0x%s", phex_nz (ul, addr_size));
break;
case DW_OP_const1u:
ul = extract_unsigned_integer (data, 1, gdbarch_byte_order (arch));
data += 1;
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_const1s:
l = extract_signed_integer (data, 1, gdbarch_byte_order (arch));
data += 1;
- fprintf_filtered (stream, " %s", plongest (l));
+ gdb_printf (stream, " %s", plongest (l));
break;
case DW_OP_const2u:
ul = extract_unsigned_integer (data, 2, gdbarch_byte_order (arch));
data += 2;
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_const2s:
l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
data += 2;
- fprintf_filtered (stream, " %s", plongest (l));
+ gdb_printf (stream, " %s", plongest (l));
break;
case DW_OP_const4u:
ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
data += 4;
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_const4s:
l = extract_signed_integer (data, 4, gdbarch_byte_order (arch));
data += 4;
- fprintf_filtered (stream, " %s", plongest (l));
+ gdb_printf (stream, " %s", plongest (l));
break;
case DW_OP_const8u:
ul = extract_unsigned_integer (data, 8, gdbarch_byte_order (arch));
data += 8;
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_const8s:
l = extract_signed_integer (data, 8, gdbarch_byte_order (arch));
data += 8;
- fprintf_filtered (stream, " %s", plongest (l));
+ gdb_printf (stream, " %s", plongest (l));
break;
case DW_OP_constu:
data = safe_read_uleb128 (data, end, &ul);
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_consts:
data = safe_read_sleb128 (data, end, &l);
- fprintf_filtered (stream, " %s", plongest (l));
+ gdb_printf (stream, " %s", plongest (l));
break;
case DW_OP_reg0:
case DW_OP_reg29:
case DW_OP_reg30:
case DW_OP_reg31:
- fprintf_filtered (stream, " [$%s]",
- locexpr_regname (arch, op - DW_OP_reg0));
+ gdb_printf (stream, " [$%s]",
+ locexpr_regname (arch, op - DW_OP_reg0));
break;
case DW_OP_regx:
data = safe_read_uleb128 (data, end, &ul);
- fprintf_filtered (stream, " %s [$%s]", pulongest (ul),
- locexpr_regname (arch, (int) ul));
+ gdb_printf (stream, " %s [$%s]", pulongest (ul),
+ locexpr_regname (arch, (int) ul));
break;
case DW_OP_implicit_value:
data = safe_read_uleb128 (data, end, &ul);
data += ul;
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_breg0:
case DW_OP_breg30:
case DW_OP_breg31:
data = safe_read_sleb128 (data, end, &l);
- fprintf_filtered (stream, " %s [$%s]", plongest (l),
- locexpr_regname (arch, op - DW_OP_breg0));
+ gdb_printf (stream, " %s [$%s]", plongest (l),
+ locexpr_regname (arch, op - DW_OP_breg0));
break;
case DW_OP_bregx:
data = safe_read_uleb128 (data, end, &ul);
data = safe_read_sleb128 (data, end, &l);
- fprintf_filtered (stream, " register %s [$%s] offset %s",
- pulongest (ul),
- locexpr_regname (arch, (int) ul),
- plongest (l));
+ gdb_printf (stream, " register %s [$%s] offset %s",
+ pulongest (ul),
+ locexpr_regname (arch, (int) ul),
+ plongest (l));
break;
case DW_OP_fbreg:
data = safe_read_sleb128 (data, end, &l);
- fprintf_filtered (stream, " %s", plongest (l));
+ gdb_printf (stream, " %s", plongest (l));
break;
case DW_OP_xderef_size:
case DW_OP_deref_size:
case DW_OP_pick:
- fprintf_filtered (stream, " %d", *data);
+ gdb_printf (stream, " %d", *data);
++data;
break;
case DW_OP_plus_uconst:
data = safe_read_uleb128 (data, end, &ul);
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_skip:
l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
data += 2;
- fprintf_filtered (stream, " to %ld",
- (long) (data + l - start));
+ gdb_printf (stream, " to %ld",
+ (long) (data + l - start));
break;
case DW_OP_bra:
l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
data += 2;
- fprintf_filtered (stream, " %ld",
- (long) (data + l - start));
+ gdb_printf (stream, " %ld",
+ (long) (data + l - start));
break;
case DW_OP_call2:
ul = extract_unsigned_integer (data, 2, gdbarch_byte_order (arch));
data += 2;
- fprintf_filtered (stream, " offset %s", phex_nz (ul, 2));
+ gdb_printf (stream, " offset %s", phex_nz (ul, 2));
break;
case DW_OP_call4:
ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
data += 4;
- fprintf_filtered (stream, " offset %s", phex_nz (ul, 4));
+ gdb_printf (stream, " offset %s", phex_nz (ul, 4));
break;
case DW_OP_call_ref:
ul = extract_unsigned_integer (data, offset_size,
gdbarch_byte_order (arch));
data += offset_size;
- fprintf_filtered (stream, " offset %s", phex_nz (ul, offset_size));
+ gdb_printf (stream, " offset %s", phex_nz (ul, offset_size));
break;
case DW_OP_piece:
data = safe_read_uleb128 (data, end, &ul);
- fprintf_filtered (stream, " %s (bytes)", pulongest (ul));
+ gdb_printf (stream, " %s (bytes)", pulongest (ul));
break;
case DW_OP_bit_piece:
data = safe_read_uleb128 (data, end, &ul);
data = safe_read_uleb128 (data, end, &offset);
- fprintf_filtered (stream, " size %s offset %s (bits)",
- pulongest (ul), pulongest (offset));
+ gdb_printf (stream, " size %s offset %s (bits)",
+ pulongest (ul), pulongest (offset));
}
break;
data = safe_read_sleb128 (data, end, &l);
- fprintf_filtered (stream, " DIE %s offset %s",
- phex_nz (ul, offset_size),
- plongest (l));
+ gdb_printf (stream, " DIE %s offset %s",
+ phex_nz (ul, offset_size),
+ plongest (l));
}
break;
data = safe_read_uleb128 (data, end, &ul);
cu_offset offset = (cu_offset) ul;
type = dwarf2_get_die_type (offset, per_cu, per_objfile);
- fprintf_filtered (stream, "<");
+ gdb_printf (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]> %d",
- phex_nz (to_underlying (offset), 0),
- deref_addr_size);
+ gdb_printf (stream, " [0x%s]> %d",
+ phex_nz (to_underlying (offset), 0),
+ deref_addr_size);
}
break;
data = safe_read_uleb128 (data, end, &ul);
cu_offset type_die = (cu_offset) ul;
type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
- fprintf_filtered (stream, "<");
+ gdb_printf (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]>",
- phex_nz (to_underlying (type_die), 0));
+ gdb_printf (stream, " [0x%s]>",
+ phex_nz (to_underlying (type_die), 0));
int n = *data++;
- fprintf_filtered (stream, " %d byte block:", n);
+ gdb_printf (stream, " %d byte block:", n);
for (int i = 0; i < n; ++i)
- fprintf_filtered (stream, " %02x", data[i]);
+ gdb_printf (stream, " %02x", data[i]);
data += n;
}
break;
cu_offset type_die = (cu_offset) ul;
type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
- fprintf_filtered (stream, "<");
+ gdb_printf (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]> [$%s]",
- phex_nz (to_underlying (type_die), 0),
- locexpr_regname (arch, reg));
+ gdb_printf (stream, " [0x%s]> [$%s]",
+ phex_nz (to_underlying (type_die), 0),
+ locexpr_regname (arch, reg));
}
break;
cu_offset type_die = (cu_offset) ul;
if (to_underlying (type_die) == 0)
- fprintf_filtered (stream, "<0>");
+ gdb_printf (stream, "<0>");
else
{
struct type *type;
type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
- fprintf_filtered (stream, "<");
+ gdb_printf (stream, "<");
type_print (type, "", stream, -1);
- fprintf_filtered (stream, " [0x%s]>",
- phex_nz (to_underlying (type_die), 0));
+ gdb_printf (stream, " [0x%s]>",
+ phex_nz (to_underlying (type_die), 0));
}
}
break;
case DW_OP_entry_value:
case DW_OP_GNU_entry_value:
data = safe_read_uleb128 (data, end, &ul);
- fputc_filtered ('\n', stream);
+ gdb_putc ('\n', stream);
disassemble_dwarf_expression (stream, arch, addr_size, offset_size,
start, data, data + ul, indent + 2,
all, per_cu, per_objfile);
case DW_OP_GNU_parameter_ref:
ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
data += 4;
- fprintf_filtered (stream, " offset %s", phex_nz (ul, 4));
+ gdb_printf (stream, " offset %s", phex_nz (ul, 4));
break;
case DW_OP_addrx:
case DW_OP_GNU_addr_index:
data = safe_read_uleb128 (data, end, &ul);
ul = dwarf2_read_addr_index (per_cu, per_objfile, ul);
- fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size));
+ gdb_printf (stream, " 0x%s", phex_nz (ul, addr_size));
break;
case DW_OP_GNU_const_index:
data = safe_read_uleb128 (data, end, &ul);
ul = dwarf2_read_addr_index (per_cu, per_objfile, ul);
- fprintf_filtered (stream, " %s", pulongest (ul));
+ gdb_printf (stream, " %s", pulongest (ul));
break;
case DW_OP_GNU_variable_value:
ul = extract_unsigned_integer (data, offset_size,
gdbarch_byte_order (arch));
data += offset_size;
- fprintf_filtered (stream, " offset %s", phex_nz (ul, offset_size));
+ gdb_printf (stream, " offset %s", phex_nz (ul, offset_size));
break;
}
- fprintf_filtered (stream, "\n");
+ gdb_printf (stream, "\n");
}
return data;
show_dwarf_always_disassemble (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file,
- _("Whether to always disassemble "
- "DWARF expressions is %s.\n"),
- value);
+ gdb_printf (file,
+ _("Whether to always disassemble "
+ "DWARF expressions is %s.\n"),
+ value);
}
/* Describe a single location, which may in turn consist of multiple
if (first_piece)
first_piece = 0;
else
- fprintf_filtered (stream, _(", and "));
+ gdb_printf (stream, _(", and "));
if (!dwarf_always_disassemble)
{
}
if (disassemble)
{
- fprintf_filtered (stream, _("a complex DWARF expression:\n"));
+ gdb_printf (stream, _("a complex DWARF expression:\n"));
data = disassemble_dwarf_expression (stream,
objfile->arch (),
addr_size, offset_size, data,
int empty = data == here;
if (disassemble)
- fprintf_filtered (stream, " ");
+ gdb_printf (stream, " ");
if (data[0] == DW_OP_piece)
{
uint64_t bytes;
data = safe_read_uleb128 (data + 1, end, &bytes);
if (empty)
- fprintf_filtered (stream, _("an empty %s-byte piece"),
- pulongest (bytes));
+ gdb_printf (stream, _("an empty %s-byte piece"),
+ pulongest (bytes));
else
- fprintf_filtered (stream, _(" [%s-byte piece]"),
- pulongest (bytes));
+ gdb_printf (stream, _(" [%s-byte piece]"),
+ pulongest (bytes));
}
else if (data[0] == DW_OP_bit_piece)
{
data = safe_read_uleb128 (data, end, &offset);
if (empty)
- fprintf_filtered (stream,
- _("an empty %s-bit piece"),
- pulongest (bits));
+ gdb_printf (stream,
+ _("an empty %s-bit piece"),
+ pulongest (bits));
else
- fprintf_filtered (stream,
- _(" [%s-bit piece, offset %s bits]"),
- pulongest (bits), pulongest (offset));
+ gdb_printf (stream,
+ _(" [%s-bit piece, offset %s bits]"),
+ pulongest (bits), pulongest (offset));
}
else
{
/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
evaluator to calculate the location. */
static struct value *
-loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
+loclist_read_variable (struct symbol *symbol, frame_info_ptr frame)
{
struct dwarf2_loclist_baton *dlbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
CORE_ADDR pc = frame ? get_frame_address_in_block (frame) : 0;
data = dwarf2_find_location_expression (dlbaton, &size, pc);
- val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, data, size,
+ val = dwarf2_evaluate_loc_desc (symbol->type (), frame, data, size,
dlbaton->per_cu, dlbaton->per_objfile);
return val;
if it cannot resolve the parameter for any reason. */
static struct value *
-loclist_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
+loclist_read_variable_at_entry (struct symbol *symbol, frame_info_ptr frame)
{
struct dwarf2_loclist_baton *dlbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
CORE_ADDR pc;
if (frame == NULL || !get_frame_func_if_available (frame, &pc))
- return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
+ return value::allocate_optimized_out (symbol->type ());
data = dwarf2_find_location_expression (dlbaton, &size, pc);
if (data == NULL)
- return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
+ return value::allocate_optimized_out (symbol->type ());
- return value_of_dwarf_block_entry (SYMBOL_TYPE (symbol), frame, data, size);
+ return value_of_dwarf_block_entry (symbol->type (), frame, data, size);
}
/* Implementation of get_symbol_read_needs from
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int addr_size = dlbaton->per_cu->addr_size ();
int offset_size = dlbaton->per_cu->offset_size ();
- int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
- /* Adjust base_address for relocatable objects. */
- CORE_ADDR base_offset = objfile->text_section_offset ();
- CORE_ADDR base_address = dlbaton->base_address + base_offset;
+ int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
+ /* Adjustment for relocatable objects. */
+ CORE_ADDR text_offset = objfile->text_section_offset ();
+ CORE_ADDR base_address = dlbaton->base_address;
int done = 0;
loc_ptr = dlbaton->data;
buf_end = dlbaton->data + dlbaton->size;
- fprintf_filtered (stream, _("multi-location:\n"));
+ gdb_printf (stream, _("multi-location:\n"));
/* Iterate through locations until we run out. */
while (!done)
continue;
case DEBUG_LOC_BASE_ADDRESS:
- base_address = high + base_offset;
- fprintf_filtered (stream, _(" Base address %s"),
- paddress (gdbarch, base_address));
+ base_address = high;
+ gdb_printf (stream, _(" Base address %s"),
+ paddress (gdbarch, base_address));
continue;
case DEBUG_LOC_START_END:
}
/* Otherwise, a location expression entry. */
- if (kind == DEBUG_LOC_OFFSET_PAIR)
+ low += text_offset;
+ high += text_offset;
+ if (!dlbaton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
{
low += base_address;
high += base_address;
/* (It would improve readability to print only the minimum
necessary digits of the second number of the range.) */
- fprintf_filtered (stream, _(" Range %s-%s: "),
- paddress (gdbarch, low), paddress (gdbarch, high));
+ gdb_printf (stream, _(" Range %s-%s: "),
+ paddress (gdbarch, low), paddress (gdbarch, high));
/* Now describe this particular location. */
locexpr_describe_location_1 (symbol, low, stream, loc_ptr, length,
addr_size, offset_size,
dlbaton->per_cu, dlbaton->per_objfile);
- fprintf_filtered (stream, "\n");
+ gdb_printf (stream, "\n");
loc_ptr += length;
}