@@ -846,7 +846,7 @@ dwarf_expr_context::dwarf_call (cu_offset die_cu_off)
/* DW_OP_call_ref is currently not supported. */
gdb_assert (block.per_cu == this->m_per_cu);
- this->eval (block.expr ());
+ this->eval (block.expr);
}
/* See expr.h. */
@@ -376,10 +376,8 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
CORE_ADDR text_offset = baton->per_objfile->objfile->text_section_offset ();
unrelocated_addr unrel_pc = (unrelocated_addr) (pc - text_offset);
unrelocated_addr base_address = baton->base_address;
- const gdb_byte *loc_ptr, *buf_end;
-
- loc_ptr = baton->data;
- buf_end = baton->data + baton->size;
+ const gdb_byte *loc_ptr = baton->loclist.data ();
+ const gdb_byte *buf_end = loc_ptr + baton->loclist.size ();
while (1)
{
@@ -487,7 +485,7 @@ locexpr_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc)
struct dwarf2_locexpr_baton *symbaton
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (framefunc);
- return symbaton->expr ();
+ return symbaton->expr;
}
/* Implement the struct symbol_block_ops::get_frame_base method for
@@ -678,8 +676,7 @@ call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch,
caller_arch = get_frame_arch (caller_frame);
caller_core_addr_type = builtin_type (caller_arch)->builtin_func_ptr;
val = dwarf2_evaluate_loc_desc (caller_core_addr_type, caller_frame,
- dwarf_block->expr (),
- dwarf_block->per_cu,
+ dwarf_block->expr, dwarf_block->per_cu,
dwarf_block->per_objfile);
/* DW_AT_call_target is a DWARF expression, not a DWARF location. */
if (val->lval () == lval_memory)
@@ -1462,10 +1459,9 @@ indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
/* If pointed-to DIE has a DW_AT_location, evaluate it and return the
resulting value. Otherwise, it may have a DW_AT_const_value instead,
or it may've been optimized out. */
- auto expr = baton.expr ();
- if (!expr.empty ())
- return dwarf2_evaluate_loc_desc_full (orig_type, frame, expr, baton.per_cu,
- baton.per_objfile,
+ if (!baton.expr.empty ())
+ return dwarf2_evaluate_loc_desc_full (orig_type, frame, baton.expr,
+ baton.per_cu, baton.per_objfile,
type->target_type (), byte_offset);
else
return fetch_const_value_from_synthetic_pointer (die, byte_offset, per_cu,
@@ -1572,7 +1568,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
gdb::array_view<CORE_ADDR> push_values,
bool *is_reference)
{
- if (dlbaton->size == 0)
+ if (dlbaton->expr.empty ())
return false;
dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
@@ -1588,8 +1584,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
try
{
- result = ctx.evaluate (dlbaton->expr (), true, per_cu, frame,
- addr_stack);
+ result = ctx.evaluate (dlbaton->expr, true, per_cu, frame, addr_stack);
}
catch (const gdb_exception_error &ex)
{
@@ -1645,7 +1640,7 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
{
case PROP_LOCEXPR:
{
- const struct dwarf2_property_baton *baton = prop->baton ();
+ const dwarf2_locexpr_property_baton *baton = prop->locexpr ();
gdb_assert (baton->property_type != NULL);
bool is_reference = baton->locexpr.is_reference;
@@ -1687,7 +1682,7 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
case PROP_LOCLIST:
{
- const dwarf2_property_baton *baton = prop->baton ();
+ const dwarf2_loclist_property_baton *baton = prop->loclist ();
CORE_ADDR pc;
struct value *val;
@@ -1716,7 +1711,7 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
case PROP_FIELD:
{
- const dwarf2_property_baton *baton = prop->baton ();
+ const dwarf2_field_property_baton *baton = prop->field ();
const struct property_addr_info *pinfo;
for (pinfo = addr_stack; pinfo != NULL; pinfo = pinfo->next)
@@ -1791,14 +1786,15 @@ dwarf2_compile_property_to_c (string_file *stream,
struct symbol *sym)
{
#if defined (HAVE_COMPILE)
- const dwarf2_property_baton *baton = prop->baton ();
gdb::array_view<const gdb_byte> expr;
dwarf2_per_cu *per_cu;
dwarf2_per_objfile *per_objfile;
if (prop->kind () == PROP_LOCEXPR)
{
- expr = baton->locexpr.expr ();
+ const dwarf2_locexpr_property_baton *baton = prop->locexpr ();
+
+ expr = baton->locexpr.expr;
per_cu = baton->locexpr.per_cu;
per_objfile = baton->locexpr.per_objfile;
}
@@ -1806,6 +1802,8 @@ dwarf2_compile_property_to_c (string_file *stream,
{
gdb_assert (prop->kind () == PROP_LOCLIST);
+ const dwarf2_loclist_property_baton *baton = prop->loclist ();
+
expr = dwarf2_find_location_expression (&baton->loclist, pc);
per_cu = baton->loclist.per_cu;
per_objfile = baton->loclist.per_objfile;
@@ -2166,7 +2164,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr,
{
gdbarch *arch = baton.per_objfile->objfile->arch ();
symbol_needs
- = dwarf2_get_symbol_read_needs (baton.expr (),
+ = dwarf2_get_symbol_read_needs (baton.expr,
baton.per_cu,
baton.per_objfile,
gdbarch_byte_order (arch),
@@ -2217,7 +2215,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr,
{
gdbarch *arch = baton.per_objfile->objfile->arch ();
symbol_needs
- = dwarf2_get_symbol_read_needs (baton.expr (),
+ = dwarf2_get_symbol_read_needs (baton.expr,
baton.per_cu,
baton.per_objfile,
gdbarch_byte_order (arch),
@@ -3007,7 +3005,6 @@ dwarf2_compile_expr_to_ax (struct agent_expr *ax, struct axs_value *loc,
case DW_OP_call2:
case DW_OP_call4:
{
- struct dwarf2_locexpr_baton block;
int size = (op == DW_OP_call2 ? 2 : 4);
uoffset = extract_unsigned_integer (op_ptr, size, byte_order);
@@ -3018,14 +3015,15 @@ dwarf2_compile_expr_to_ax (struct agent_expr *ax, struct axs_value *loc,
return ax->scope;
};
cu_offset cuoffset = (cu_offset) uoffset;
- block = dwarf2_fetch_die_loc_cu_off (cuoffset, per_cu, per_objfile,
- get_frame_pc_from_expr);
+ dwarf2_locexpr_baton block
+ = dwarf2_fetch_die_loc_cu_off (cuoffset, per_cu, per_objfile,
+ get_frame_pc_from_expr);
/* DW_OP_call_ref is currently not supported. */
gdb_assert (block.per_cu == per_cu);
- dwarf2_compile_expr_to_ax (ax, loc, addr_size, block.expr (),
- per_cu, per_objfile);
+ dwarf2_compile_expr_to_ax (ax, loc, addr_size, block.expr, per_cu,
+ per_objfile);
}
break;
@@ -3058,12 +3056,9 @@ locexpr_read_variable (struct symbol *symbol, const 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 (), frame, dlbaton->expr (),
- dlbaton->per_cu, dlbaton->per_objfile);
-
- return val;
+ return dwarf2_evaluate_loc_desc (symbol->type (), frame, dlbaton->expr,
+ dlbaton->per_cu, dlbaton->per_objfile);
}
/* Return the value of SYMBOL in FRAME at (callee) FRAME's function
@@ -3076,7 +3071,7 @@ locexpr_read_variable_at_entry (struct symbol *symbol, const frame_info_ptr &fra
struct dwarf2_locexpr_baton *dlbaton
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
- return value_of_dwarf_block_entry (symbol->type (), frame, dlbaton->expr ());
+ return value_of_dwarf_block_entry (symbol->type (), frame, dlbaton->expr);
}
/* Implementation of get_symbol_read_needs from
@@ -3090,7 +3085,7 @@ locexpr_get_symbol_read_needs (struct symbol *symbol)
gdbarch *arch = dlbaton->per_objfile->objfile->arch ();
- return dwarf2_get_symbol_read_needs (dlbaton->expr (), dlbaton->per_cu,
+ return dwarf2_get_symbol_read_needs (dlbaton->expr, dlbaton->per_cu,
dlbaton->per_objfile,
gdbarch_byte_order (arch),
dlbaton->per_cu->addr_size (),
@@ -3825,10 +3820,9 @@ locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr,
unsigned int addr_size = dlbaton->per_cu->addr_size ();
int offset_size = dlbaton->per_cu->offset_size ();
- locexpr_describe_location_1 (symbol, addr, stream,
- dlbaton->expr (),
- addr_size, offset_size,
- dlbaton->per_cu, dlbaton->per_objfile);
+ locexpr_describe_location_1 (symbol, addr, stream, dlbaton->expr, addr_size,
+ offset_size, dlbaton->per_cu,
+ dlbaton->per_objfile);
}
/* Describe the location of SYMBOL as an agent value in VALUE, generating
@@ -3842,10 +3836,10 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax,
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
unsigned int addr_size = dlbaton->per_cu->addr_size ();
- if (dlbaton->size == 0)
+ if (dlbaton->expr.empty ())
value->optimized_out = 1;
else
- dwarf2_compile_expr_to_ax (ax, value, addr_size, dlbaton->expr (),
+ dwarf2_compile_expr_to_ax (ax, value, addr_size, dlbaton->expr,
dlbaton->per_cu, dlbaton->per_objfile);
}
@@ -3861,7 +3855,7 @@ locexpr_generate_c_location (struct symbol *sym, string_file *stream,
struct dwarf2_locexpr_baton *dlbaton
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (sym);
unsigned int addr_size = dlbaton->per_cu->addr_size ();
- auto expr = dlbaton->expr ();
+ auto expr = dlbaton->expr;
if (expr.empty ())
error (_("symbol \"%s\" is optimized out"), sym->natural_name ());
@@ -3954,7 +3948,6 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
{
struct dwarf2_loclist_baton *dlbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
- const gdb_byte *loc_ptr, *buf_end;
dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
struct objfile *objfile = per_objfile->objfile;
struct gdbarch *gdbarch = objfile->arch ();
@@ -3964,9 +3957,8 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
unrelocated_addr base_address = dlbaton->base_address;
int done = 0;
-
- loc_ptr = dlbaton->data;
- buf_end = dlbaton->data + dlbaton->size;
+ const gdb_byte *loc_ptr = dlbaton->loclist.data ();
+ const gdb_byte *buf_end = loc_ptr + dlbaton->loclist.size ();
gdb_printf (stream, _("multi-location:\n"));
@@ -124,42 +124,27 @@ void dwarf2_compile_property_to_c (string_file *stream,
expression; "struct dwarf2_loclist_baton" is for a symbol with a
location list. */
-struct dwarf2_locexpr_baton
+struct dwarf2_locexpr_baton : allocate_on_obstack<dwarf2_locexpr_baton>
{
- /* Return the expression in this baton. */
- gdb::array_view<const gdb_byte> expr () const
- { return gdb::make_array_view (data, size); }
-
- /* Set the expression in this baton from EXPR. */
- void set_expr (gdb::array_view<const gdb_byte> expr)
+ dwarf2_locexpr_baton (gdb::array_view<const gdb_byte> expr,
+ dwarf2_per_objfile &per_objfile, dwarf2_per_cu &per_cu)
+ : expr (expr),
+ per_objfile (&per_objfile),
+ per_cu (&per_cu)
{
- data = expr.data ();
- size = expr.size ();
}
- /* Set the expression in this baton from BLOCK. */
- void set_expr (const dwarf_block &block)
- {
- data = block.data;
- size = block.size;
- }
-
- /* Pointer to the start of the location expression. nullptr for optimized
- out expressions. */
- const gdb_byte *data;
-
- /* Length of the location expression. For optimized out expressions it is
- zero. */
- size_t size;
+ /* The location expression. Empty for optimized out expressions. */
+ gdb::array_view<const gdb_byte> expr;
/* When true this location expression is a reference and actually
describes the address at which the value of the attribute can be
found. When false the expression provides the value of the attribute
directly. */
- bool is_reference;
+ bool is_reference = false;
/* True if this object is actually a dwarf2_field_location_baton. */
- bool is_field_location;
+ bool is_field_location = false;
/* The objfile that was used when creating this. */
dwarf2_per_objfile *per_objfile;
@@ -176,31 +161,48 @@ struct dwarf2_locexpr_baton
'is_field_location' member in dwarf2_locexpr_baton. See also
apply_bit_offset_to_field. */
-struct dwarf2_field_location_baton : public dwarf2_locexpr_baton
+struct dwarf2_field_location_baton
+ : dwarf2_locexpr_baton,
+ allocate_on_obstack<dwarf2_field_location_baton>
{
+ using allocate_on_obstack<dwarf2_field_location_baton>::operator new;
+ using allocate_on_obstack<dwarf2_field_location_baton>::operator delete;
+
+ dwarf2_field_location_baton (gdb::array_view<const gdb_byte> expr,
+ dwarf2_per_objfile &per_objfile,
+ dwarf2_per_cu &per_cu, LONGEST bit_offset,
+ LONGEST explicit_byte_size)
+ : dwarf2_locexpr_baton (expr, per_objfile, per_cu),
+ bit_offset (bit_offset),
+ explicit_byte_size (explicit_byte_size)
+ {
+ is_field_location = true;
+ }
+
/* The bit offset, coming from DW_AT_bit_offset. */
- LONGEST bit_offset;
+ LONGEST bit_offset = 0;
/* The DW_AT_byte_size of the field. If no explicit byte size was
specified, this is 0. */
- LONGEST explicit_byte_size;
+ LONGEST explicit_byte_size = 0;
};
-struct dwarf2_loclist_baton
+struct dwarf2_loclist_baton : allocate_on_obstack<dwarf2_loclist_baton>
{
- /* Return the location list in this baton. */
- gdb::array_view<const gdb_byte> expr () const
- { return gdb::make_array_view (data, size); }
+ dwarf2_loclist_baton (gdb::array_view<const gdb_byte> loclist,
+ dwarf2_per_objfile &per_objfile, dwarf2_per_cu &per_cu)
+ : loclist (loclist),
+ per_objfile (&per_objfile),
+ per_cu (&per_cu)
+ {
+ }
/* The initial base address for the location list, based on the compilation
unit. */
- unrelocated_addr base_address;
+ unrelocated_addr base_address {};
- /* Pointer to the start of the location list. */
- const gdb_byte *data;
-
- /* Length of the location list. */
- size_t size;
+ /* The location list. */
+ gdb::array_view<const gdb_byte> loclist;
/* The objfile that was used when creating this. */
dwarf2_per_objfile *per_objfile;
@@ -211,10 +213,10 @@ struct dwarf2_loclist_baton
/* Non-zero if the location list lives in .debug_loc.dwo.
The format of entries in this section are different. */
- unsigned char from_dwo;
+ unsigned char from_dwo = 0;
/* The version of DWARF this loclist comes from. */
- unsigned char dwarf_version;
+ unsigned char dwarf_version = 0;
};
/* A dynamic property is either expressed as a single location expression
@@ -225,23 +227,57 @@ struct dwarf2_loclist_baton
struct dwarf2_property_baton
{
+ dwarf2_property_baton (type &property_type)
+ : property_type (&property_type)
+ {
+ }
+
/* If the property is an indirection, we need to evaluate the location
in the context of the type PROPERTY_TYPE. If the property is supplied
by value then it will be of PROPERTY_TYPE. This field should never be
NULL. */
struct type *property_type;
- union
+};
+
+struct dwarf2_locexpr_property_baton
+ : dwarf2_property_baton,
+ allocate_on_obstack<dwarf2_locexpr_property_baton>
+{
+ dwarf2_locexpr_property_baton (type &property_type,
+ const dwarf2_locexpr_baton &locexpr)
+ : dwarf2_property_baton (property_type),
+ locexpr (locexpr)
{
- /* Location expression either evaluated in the context of
- PROPERTY_TYPE, or a value of type PROPERTY_TYPE. */
- struct dwarf2_locexpr_baton locexpr;
+ }
- /* Location list to be evaluated in the context of PROPERTY_TYPE. */
- struct dwarf2_loclist_baton loclist;
+ /* Location expression either evaluated in the context of
+ PROPERTY_TYPE, or a value of type PROPERTY_TYPE. */
+ dwarf2_locexpr_baton locexpr;
+};
- /* The location is stored in a field of PROPERTY_TYPE. */
- struct field field;
- };
+struct dwarf2_loclist_property_baton
+ : dwarf2_property_baton,
+ allocate_on_obstack<dwarf2_loclist_property_baton>
+{
+ dwarf2_loclist_property_baton (type &property_type,
+ const dwarf2_loclist_baton &loclist)
+ : dwarf2_property_baton (property_type),
+ loclist (loclist)
+ {
+ }
+
+ /* Location list to be evaluated in the context of PROPERTY_TYPE. */
+ dwarf2_loclist_baton loclist;
+};
+
+struct dwarf2_field_property_baton
+ : dwarf2_property_baton,
+ allocate_on_obstack<dwarf2_field_property_baton>
+{
+ using dwarf2_property_baton::dwarf2_property_baton;
+
+ /* The field of PROPERTY_TYPE that contains the property value. */
+ struct field field {};
};
extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
@@ -907,9 +907,8 @@ static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int, int);
-static void fill_in_loclist_baton (struct dwarf2_cu *cu,
- struct dwarf2_loclist_baton *baton,
- const struct attribute *attr);
+static dwarf2_loclist_baton make_loclist_baton (struct dwarf2_cu *cu,
+ const struct attribute *attr);
static void dwarf2_symbol_mark_computed (const struct attribute *attr,
struct symbol *sym,
@@ -5268,8 +5267,7 @@ dwarf2_compute_name (const char *name,
struct value_print_options opts;
if (baton != NULL)
- v = dwarf2_evaluate_loc_desc (type, NULL,
- baton->expr (),
+ v = dwarf2_evaluate_loc_desc (type, NULL, baton->expr,
baton->per_cu,
baton->per_objfile);
else if (bytes != NULL)
@@ -8101,12 +8099,9 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
/* Keep NULL DWARF_BLOCK. */;
else if (attr->form_is_block ())
{
- dwarf2_locexpr_baton *dlbaton
- = OBSTACK_ZALLOC (&objfile->objfile_obstack, dwarf2_locexpr_baton);
-
- dlbaton->set_expr (*attr->as_block ());
- dlbaton->per_objfile = per_objfile;
- dlbaton->per_cu = cu->per_cu;
+ auto dlbaton = new (&objfile->objfile_obstack)
+ dwarf2_locexpr_baton (attr->as_block ()->view (), *per_objfile,
+ *cu->per_cu);
call_site->target.set_loc_dwarf_block (dlbaton);
}
@@ -9370,28 +9365,21 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct objfile *objfile = per_objfile->objfile;
struct dwarf2_locexpr_baton *dlbaton;
- if (has_bit_offset)
- {
- dwarf2_field_location_baton *flbaton
- = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- dwarf2_field_location_baton);
- flbaton->is_field_location = true;
- flbaton->bit_offset = bit_offset;
- flbaton->explicit_byte_size = anonymous_size;
- dlbaton = flbaton;
- }
- else
- dlbaton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_locexpr_baton);
+ gdb::array_view<const gdb_byte> expr
+ = data_member_location_attr->as_block ()->view ();
- dlbaton->set_expr (*data_member_location_attr->as_block ());
+ if (has_bit_offset)
+ dlbaton = new (&objfile->objfile_obstack)
+ dwarf2_field_location_baton (expr, *per_objfile, *cu->per_cu,
+ bit_offset, anonymous_size);
+ else
+ dlbaton = new (&objfile->objfile_obstack)
+ dwarf2_locexpr_baton (expr, *per_objfile, *cu->per_cu);
/* When using this baton, we want to compute the address
of the field, not the value. This is why
is_reference is set to false here. */
dlbaton->is_reference = false;
- dlbaton->per_objfile = per_objfile;
- dlbaton->per_cu = cu->per_cu;
field->set_loc_dwarf_block_addr (dlbaton);
}
@@ -9415,13 +9403,9 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
/* This is a DWARF extension. See
https://dwarfstd.org/issues/250501.1.html. */
dwarf2_per_objfile *per_objfile = cu->per_objfile;
- dwarf2_locexpr_baton *dlbaton
- = OBSTACK_ZALLOC (&per_objfile->objfile->objfile_obstack,
- dwarf2_locexpr_baton);
-
- dlbaton->set_expr (*data_bit_offset_attr->as_block ());
- dlbaton->per_objfile = per_objfile;
- dlbaton->per_cu = cu->per_cu;
+ auto dlbaton = new (&per_objfile->objfile->objfile_obstack)
+ dwarf2_locexpr_baton ((data_bit_offset_attr->as_block ()
+ ->view ()), *per_objfile, *cu->per_cu);
field->set_loc_dwarf_block_bitpos (dlbaton);
}
@@ -10738,21 +10722,6 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
handle_variant (child_die, type, fi, template_args, cu);
}
-/* Create a property baton for a field. DIE is the field's DIE. The
- baton's "field" member is filled in, but the other members of the
- baton are not. The new property baton is returned. */
-
-static dwarf2_property_baton *
-find_field_create_baton (dwarf2_cu *cu, die_info *die)
-{
- dwarf2_property_baton *result
- = XOBNEW (&cu->per_objfile->objfile->objfile_obstack,
- struct dwarf2_property_baton);
- memset (&result->field, 0, sizeof (result->field));
- compute_field_location (cu, die, &result->field);
- return result;
-}
-
/* Finish creating a structure or union type, including filling in its
members and creating a symbol for it. This function also handles Fortran
namelist variables, their items or members and creating a symbol for
@@ -11749,7 +11718,6 @@ mark_common_block_symbol_computed (struct symbol *sym,
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct objfile *objfile = per_objfile->objfile;
- struct dwarf2_locexpr_baton *baton;
unsigned int cu_off;
enum bfd_endian byte_order = gdbarch_byte_order (objfile->arch ());
LONGEST offset = 0;
@@ -11759,12 +11727,6 @@ mark_common_block_symbol_computed (struct symbol *sym,
gdb_assert (member_loc->form_is_block ()
|| member_loc->form_is_constant ());
- baton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_locexpr_baton);
- baton->per_objfile = per_objfile;
- baton->per_cu = cu->per_cu;
- gdb_assert (baton->per_cu);
-
std::size_t size = 5 /* DW_OP_call4 */ + 1 /* DW_OP_plus */;
if (member_loc->form_is_constant ())
@@ -11802,7 +11764,9 @@ mark_common_block_symbol_computed (struct symbol *sym,
*ptr++ = DW_OP_plus;
gdb_assert (ptr - start == size);
- baton->set_expr (gdb::make_array_view (start, size));
+ auto baton = new (&objfile->objfile_obstack)
+ dwarf2_locexpr_baton (gdb::make_array_view (start, size), *per_objfile,
+ *cu->per_cu);
SYMBOL_LOCATION_BATON (sym) = baton;
sym->set_loc_class_index (dwarf2_locexpr_index);
@@ -13403,7 +13367,6 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
struct dwarf2_cu *cu, struct dynamic_prop *prop,
struct type *default_type)
{
- struct dwarf2_property_baton *baton;
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct objfile *objfile = per_objfile->objfile;
struct obstack *obstack = &objfile->objfile_obstack;
@@ -13415,27 +13378,26 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
if (attr->form_is_block ())
{
- baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->property_type = default_type;
- baton->locexpr.per_cu = cu->per_cu;
- baton->locexpr.per_objfile = per_objfile;
+ gdb::array_view<const gdb_byte> expr;
- struct dwarf_block block;
if (attr->form == DW_FORM_data16)
{
- size_t data_size = 16;
- block.size = (data_size
- + 2 /* Extra bytes for DW_OP and arg. */);
- gdb_byte *data = XOBNEWVEC (obstack, gdb_byte, block.size);
- data[0] = DW_OP_implicit_value;
- data[1] = data_size;
- memcpy (&data[2], attr->as_block ()->data, data_size);
- block.data = data;
+ std::size_t data_size = 16;
+ std::size_t expr_size = (data_size
+ + 2 /* Extra bytes for DW_OP and arg. */);
+ gdb_byte *expr_data = XOBNEWVEC (obstack, gdb_byte, expr_size);
+ expr_data[0] = DW_OP_implicit_value;
+ expr_data[1] = data_size;
+ memcpy (&expr_data[2], attr->as_block ()->data, data_size);
+ expr = gdb::make_array_view (expr_data, expr_size);
}
else
- block = *attr->as_block ();
+ expr = attr->as_block ()->view ();
+
+ auto baton = new (obstack)
+ dwarf2_locexpr_property_baton (*default_type,
+ {expr, *per_objfile, *cu->per_cu});
- baton->locexpr.set_expr (block);
switch (attr->name)
{
case DW_AT_string_length:
@@ -13447,7 +13409,6 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
}
prop->set_locexpr (baton);
- gdb_assert (prop->baton () != NULL);
}
else if (attr->form_is_ref ())
{
@@ -13479,22 +13440,21 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
case DW_AT_location:
if (target_attr->form_is_section_offset ())
{
- baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->property_type = die_type (target_die, target_cu);
- fill_in_loclist_baton (cu, &baton->loclist, target_attr);
+ type *property_type = die_type (target_die, target_cu);
+ auto baton = new (obstack) dwarf2_loclist_property_baton
+ (*property_type, make_loclist_baton (cu, target_attr));
prop->set_loclist (baton);
- gdb_assert (prop->baton () != NULL);
}
else if (target_attr->form_is_block ())
{
- baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->property_type = die_type (target_die, target_cu);
- baton->locexpr.per_cu = cu->per_cu;
- baton->locexpr.per_objfile = per_objfile;
- baton->locexpr.set_expr (*target_attr->as_block ());
+ type *property_type = die_type (target_die, target_cu);
+ auto baton = new (obstack)
+ dwarf2_locexpr_property_baton (*property_type,
+ {(target_attr->as_block ()
+ ->view()), *per_objfile,
+ *cu->per_cu});
baton->locexpr.is_reference = true;
prop->set_locexpr (baton);
- gdb_assert (prop->baton () != NULL);
}
else
{
@@ -13506,12 +13466,12 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
case DW_AT_data_member_location:
case DW_AT_data_bit_offset:
{
- baton = find_field_create_baton (cu, target_die);
- if (baton == nullptr)
- return false;
+ type *property_type = read_type_die (target_die->parent,
+ target_cu);
+ auto baton = new (&cu->per_objfile->objfile->objfile_obstack)
+ dwarf2_field_property_baton (*property_type);
- baton->property_type = read_type_die (target_die->parent,
- target_cu);
+ compute_field_location (cu, target_die, &baton->field);
prop->set_field (baton);
break;
}
@@ -13524,12 +13484,13 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
switch (attr->name)
{
case DW_AT_string_length:
- baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->property_type = default_type;
- fill_in_loclist_baton (cu, &baton->loclist, attr);
- prop->set_loclist (baton);
- gdb_assert (prop->baton () != NULL);
- break;
+ {
+ auto baton = new (obstack)
+ dwarf2_loclist_property_baton (*default_type,
+ make_loclist_baton (cu, attr));
+ prop->set_loclist (baton);
+ break;
+ }
default:
goto invalid;
}
@@ -16002,8 +15963,6 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
{
- gdb_byte *data;
-
if (type->length () != cu_header->addr_size)
dwarf2_const_value_length_mismatch_complaint (name,
cu_header->addr_size,
@@ -16011,14 +15970,11 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
/* Symbols of this form are reasonably rare, so we just
piggyback on the existing location code rather than writing
a new implementation of symbol_computed_ops. */
- *baton = OBSTACK_ZALLOC (obstack, struct dwarf2_locexpr_baton);
- (*baton)->per_objfile = per_objfile;
- (*baton)->per_cu = cu->per_cu;
- gdb_assert ((*baton)->per_cu);
-
std::size_t size = 2 + cu_header->addr_size;
- data = (gdb_byte *) obstack_alloc (obstack, size);
- (*baton)->set_expr (gdb::make_array_view (data, size));
+ auto data = (gdb_byte *) obstack_alloc (obstack, size);
+ *baton = new (obstack)
+ dwarf2_locexpr_baton (gdb::make_array_view (data, size),
+ *per_objfile, *cu->per_cu);
data[0] = DW_OP_addr;
store_unsigned_integer (&data[1], cu_header->addr_size,
@@ -17029,7 +16985,6 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
bool resolve_abstract_p)
{
struct attribute *attr;
- struct dwarf2_locexpr_baton retval;
struct objfile *objfile = per_objfile->objfile;
dwarf2_cu *cu = per_objfile->get_cu (per_cu);
@@ -17079,19 +17034,18 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
}
}
+ gdb::array_view<const gdb_byte> expr;
+
if (!attr)
{
/* DWARF: "If there is no such attribute, then there is no effect.". */
- retval.set_expr (gdb::array_view<const gdb_byte> ());
}
else if (attr->form_is_section_offset ())
{
- struct dwarf2_loclist_baton loclist_baton;
+ dwarf2_loclist_baton loclist_baton = make_loclist_baton (cu, attr);
CORE_ADDR pc = get_frame_pc ();
- fill_in_loclist_baton (cu, &loclist_baton, attr);
-
- retval.set_expr (dwarf2_find_location_expression (&loclist_baton, pc));
+ expr = dwarf2_find_location_expression (&loclist_baton, pc);
}
else
{
@@ -17101,10 +17055,10 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
" [in module %s]"),
sect_offset_str (sect_off), objfile_name (objfile));
- retval.set_expr (*attr->as_block ());
+ expr = attr->as_block ()->view ();
}
- retval.per_objfile = per_objfile;
- retval.per_cu = cu->per_cu;
+
+ dwarf2_locexpr_baton retval (expr, *per_objfile, *cu->per_cu);
per_objfile->age_comp_units ();
@@ -17854,29 +17808,30 @@ cu_debug_rnglists_section (struct dwarf2_cu *cu, dwarf_tag tag)
/* A helper function that fills in a dwarf2_loclist_baton. */
-static void
-fill_in_loclist_baton (struct dwarf2_cu *cu,
- struct dwarf2_loclist_baton *baton,
- const struct attribute *attr)
+static dwarf2_loclist_baton
+make_loclist_baton (struct dwarf2_cu *cu, const struct attribute *attr)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct dwarf2_section_info *section = cu_debug_loc_section (cu);
section->read (per_objfile->objfile);
- baton->per_objfile = per_objfile;
- baton->per_cu = cu->per_cu;
- gdb_assert (baton->per_cu);
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
- baton->size = section->size - attr->as_unsigned ();
- baton->data = section->buffer + attr->as_unsigned ();
+ std::size_t loclist_size = section->size - attr->as_unsigned ();
+ const gdb_byte *loclist_data = section->buffer + attr->as_unsigned ();
+
+ dwarf2_loclist_baton baton (gdb::make_array_view (loclist_data,
+ loclist_size),
+ *per_objfile, *cu->per_cu);
+
if (cu->base_address.has_value ())
- baton->base_address = *cu->base_address;
- else
- baton->base_address = {};
- baton->from_dwo = cu->dwo_unit != NULL;
- baton->dwarf_version = cu->header.version;
+ baton.base_address = *cu->base_address;
+
+ baton.from_dwo = cu->dwo_unit != NULL;
+ baton.dwarf_version = cu->header.version;
+
+ return baton;
}
static void
@@ -17893,11 +17848,8 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
other branch. */
&& attr->as_unsigned () < section->size)
{
- struct dwarf2_loclist_baton *baton;
-
- baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_loclist_baton);
-
- fill_in_loclist_baton (cu, baton, attr);
+ auto baton = new (&objfile->objfile_obstack)
+ dwarf2_loclist_baton (make_loclist_baton (cu, attr));
if (!cu->base_address.has_value ())
complaint (_("Location list used without "
@@ -17910,13 +17862,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
}
else
{
- struct dwarf2_locexpr_baton *baton;
-
- baton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_locexpr_baton);
- baton->per_objfile = per_objfile;
- baton->per_cu = cu->per_cu;
- gdb_assert (baton->per_cu);
+ gdb::array_view<const gdb_byte> expr;
if (attr->form_is_block ())
{
@@ -17925,18 +17871,18 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
info_buffer for SYM's objfile; right now we never release
that buffer, but when we do clean up properly this may
need to change. */
- baton->set_expr (*attr->as_block ());
+ expr = attr->as_block ()->view ();
}
else
- {
- dwarf2_invalid_attrib_class_complaint ("location description",
- sym->natural_name ());
- baton->size = 0;
- }
+ dwarf2_invalid_attrib_class_complaint ("location description",
+ sym->natural_name ());
- sym->set_loc_class_index ((is_block
- ? dwarf2_locexpr_block_index
- : dwarf2_locexpr_index));
+ auto baton = new (&objfile->objfile_obstack)
+ dwarf2_locexpr_baton (expr, *per_objfile, *cu->per_cu);
+
+ sym->set_loc_class_index (is_block
+ ? dwarf2_locexpr_block_index
+ : dwarf2_locexpr_index);
SYMBOL_LOCATION_BATON (sym) = baton;
}
}
@@ -797,9 +797,11 @@ operator== (const dynamic_prop &l, const dynamic_prop &r)
case PROP_CONST:
return l.const_val () == r.const_val ();
case PROP_FIELD:
+ return l.field () == r.field ();
case PROP_LOCEXPR:
+ return l.locexpr () == r.locexpr ();
case PROP_LOCLIST:
- return l.baton () == r.baton ();
+ return l.loclist () == r.loclist ();
case PROP_VARIANT_PARTS:
return l.variant_parts () == r.variant_parts ();
case PROP_TYPE:
@@ -2666,12 +2668,9 @@ resolve_dynamic_field (struct field &field,
if (field.loc_is_dwarf_block ())
{
- dwarf2_locexpr_baton *field_loc
- = field.loc_dwarf_block ();
-
- struct dwarf2_property_baton baton;
- baton.property_type = lookup_pointer_type (field.type ());
- baton.locexpr = *field_loc;
+ dwarf2_locexpr_baton *field_loc = field.loc_dwarf_block ();
+ dwarf2_locexpr_property_baton baton
+ (*lookup_pointer_type (field.type ()), *field_loc);
struct dynamic_prop prop;
prop.set_locexpr (&baton);
@@ -4221,8 +4220,7 @@ check_types_equal (struct type *type1, struct type *type2,
block1 = field1->loc_dwarf_block ();
block2 = field2->loc_dwarf_block ();
if (block1->per_cu != block2->per_cu
- || block1->size != block2->size
- || memcmp (block1->data, block2->data, block1->size) != 0)
+ || block1->expr != block2->expr)
return false;
}
break;
@@ -59,6 +59,9 @@ struct language_defn;
struct dwarf2_per_cu;
struct dwarf2_per_objfile;
struct dwarf2_property_baton;
+struct dwarf2_locexpr_property_baton;
+struct dwarf2_loclist_property_baton;
+struct dwarf2_field_property_baton;
/* * Different kinds of data types are distinguished by the `code'
field. */
@@ -344,31 +347,49 @@ struct dynamic_prop
bool is_constant () const
{ return m_kind == PROP_CONST; }
- const dwarf2_property_baton *baton () const
- {
- gdb_assert (m_kind == PROP_LOCEXPR
- || m_kind == PROP_LOCLIST
- || m_kind == PROP_FIELD);
+ /* We need to use reinterpret_cast below instead of static_cast below, because
+ the baton types are not complete, and including dwarf2/loc.h would cause a
+ cyclic dependency. */
- return m_data.baton;
+ const dwarf2_locexpr_property_baton *locexpr () const
+ {
+ gdb_assert (m_kind == PROP_LOCEXPR);
+
+ return (reinterpret_cast<const dwarf2_locexpr_property_baton *>
+ (m_data.baton));
}
- void set_locexpr (const dwarf2_property_baton *baton)
+ const dwarf2_loclist_property_baton *loclist () const
+ {
+ gdb_assert (m_kind == PROP_LOCLIST);
+
+ return (reinterpret_cast<const dwarf2_loclist_property_baton *>
+ (m_data.baton));
+ }
+
+ const dwarf2_field_property_baton *field () const
+ {
+ gdb_assert (m_kind == PROP_FIELD);
+
+ return reinterpret_cast<const dwarf2_field_property_baton *> (m_data.baton);
+ }
+
+ void set_locexpr (const dwarf2_locexpr_property_baton *baton)
{
m_kind = PROP_LOCEXPR;
- m_data.baton = baton;
+ m_data.baton = reinterpret_cast<const dwarf2_property_baton *> (baton);
}
- void set_loclist (const dwarf2_property_baton *baton)
+ void set_loclist (const dwarf2_loclist_property_baton *baton)
{
m_kind = PROP_LOCLIST;
- m_data.baton = baton;
+ m_data.baton = reinterpret_cast<const dwarf2_property_baton *> (baton);
}
- void set_field (const dwarf2_property_baton *baton)
+ void set_field (const dwarf2_field_property_baton *baton)
{
m_kind = PROP_FIELD;
- m_data.baton = baton;
+ m_data.baton = reinterpret_cast<const dwarf2_property_baton *> (baton);
}
const gdb::array_view<variant_part> *variant_parts () const
@@ -478,10 +478,10 @@ gnuv3_baseclass_offset (struct type *type, int index,
/* If we have a DWARF expression for the offset, evaluate it. */
if (type->field (index).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK_ADDR)
{
- struct dwarf2_property_baton baton;
- baton.property_type
+ struct type *property_type
= lookup_pointer_type (type->field (index).type ());
- baton.locexpr = *type->field (index).loc_dwarf_block ();
+ dwarf2_locexpr_baton *locexpr = type->field (index).loc_dwarf_block ();
+ dwarf2_locexpr_property_baton baton (*property_type, *locexpr);
struct dynamic_prop prop;
prop.set_locexpr (&baton);