* [PATCH] gdb/dwarf2: pass around DWARF expressions as gdb::array_view
@ 2026-04-29 0:55 simon.marchi
2026-05-01 16:35 ` Tom Tromey
0 siblings, 1 reply; 3+ messages in thread
From: simon.marchi @ 2026-04-29 0:55 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
From: Simon Marchi <simon.marchi@efficios.com>
This patch converts a bunch of functions to take or return DWARF
expressions as `gdb::array_view<const gdb_byte>`, instead of raw pointer
and size. It doesn't do any non-trivial change to function
implementations, but the idea is that we could change them (for example
dwarf_expr_context::execute_stack_op) to operate on the array view
directly, giving us bounds checking when building in debug mode. But
that is not as trivial.
This patch also doesn't change structure fields to array_views (for
instance, dwarf2_loclist_baton), because that would make them
non-trivially constructible, and we'd (technically) need to change how
they are allocated.
Change-Id: I45a40e4d00edfb54b7fdff1447806da5bbe06183
---
gdb/compile/compile-loc2c.c | 83 +++---
gdb/compile/compile.h | 10 +-
gdb/dwarf2/attribute.h | 4 +
gdb/dwarf2/call-site.h | 9 +
gdb/dwarf2/expr.c | 84 +++---
gdb/dwarf2/expr.h | 36 ++-
gdb/dwarf2/frame.c | 40 +--
gdb/dwarf2/frame.h | 20 +-
gdb/dwarf2/loc.c | 543 +++++++++++++++++-------------------
gdb/dwarf2/loc.h | 64 +++--
gdb/dwarf2/read.c | 89 +++---
gdb/symtab.h | 11 +-
12 files changed, 473 insertions(+), 520 deletions(-)
diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c
index dae3e2ebd6b0..9f189ef1cc79 100644
--- a/gdb/compile/compile-loc2c.c
+++ b/gdb/compile/compile-loc2c.c
@@ -70,16 +70,18 @@ struct insn_info
TO_DO is a list of bytecodes which must be examined; it may be
added to by this function.
BYTE_ORDER and ADDR_SIZE describe this bytecode in the obvious way.
- OP_PTR and OP_END are the bounds of the DWARF expression. */
+ EXPR is the DWARF expression. */
static void
compute_stack_depth_worker (int start, int *need_tempvar,
std::vector<struct insn_info> *info,
std::vector<int> *to_do,
enum bfd_endian byte_order, unsigned int addr_size,
- const gdb_byte *op_ptr, const gdb_byte *op_end)
+ gdb::array_view<const gdb_byte> expr)
{
- const gdb_byte * const base = op_ptr;
+ const gdb_byte *const base = expr.data ();
+ const gdb_byte *op_ptr = expr.data ();
+ const gdb_byte *const op_end = expr.data () + expr.size ();
int stack_depth;
op_ptr += start;
@@ -378,7 +380,7 @@ compute_stack_depth_worker (int start, int *need_tempvar,
generator).
IS_TLS is an out parameter which is set if this expression refers
to a TLS variable.
- OP_PTR and OP_END are the bounds of the DWARF expression.
+ EXPR is the DWARF expression.
INITIAL_DEPTH is the initial depth of the DWARF expression stack.
INFO is an array of insn_info objects, indexed by offset from the
start of the DWARF expression.
@@ -388,14 +390,14 @@ compute_stack_depth_worker (int start, int *need_tempvar,
static int
compute_stack_depth (enum bfd_endian byte_order, unsigned int addr_size,
int *need_tempvar, int *is_tls,
- const gdb_byte *op_ptr, const gdb_byte *op_end,
+ gdb::array_view<const gdb_byte> expr,
int initial_depth,
std::vector<struct insn_info> *info)
{
std::vector<int> to_do;
- int stack_depth, i;
+ int stack_depth;
- info->resize (op_end - op_ptr);
+ info->resize (expr.size ());
to_do.push_back (0);
(*info)[0].depth = initial_depth;
@@ -406,14 +408,13 @@ compute_stack_depth (enum bfd_endian byte_order, unsigned int addr_size,
int ndx = to_do.back ();
to_do.pop_back ();
- compute_stack_depth_worker (ndx, need_tempvar, info, &to_do,
- byte_order, addr_size,
- op_ptr, op_end);
+ compute_stack_depth_worker (ndx, need_tempvar, info, &to_do, byte_order,
+ addr_size, expr);
}
stack_depth = 0;
*is_tls = 0;
- for (i = 0; i < op_end - op_ptr; ++i)
+ for (int i = 0; i < expr.size (); ++i)
{
if ((*info)[i].depth > stack_depth)
stack_depth = (*info)[i].depth;
@@ -579,7 +580,7 @@ pushf_register (int indent, string_file *stream,
ADDR_SIZE is the DWARF address size to use.
- OPT_PTR and OP_END are the bounds of the DWARF expression.
+ EXPR is the DWARF expression.
If non-NULL, INITIAL points to an initial value to write to the
stack. If NULL, no initial value is written.
@@ -595,7 +596,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
struct gdbarch *arch,
std::vector<bool> ®isters_used,
unsigned int addr_size,
- const gdb_byte *op_ptr, const gdb_byte *op_end,
+ gdb::array_view<const gdb_byte> expr,
CORE_ADDR *initial,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
@@ -605,7 +606,6 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
static unsigned int scope;
enum bfd_endian byte_order = gdbarch_byte_order (arch);
- const gdb_byte * const base = op_ptr;
int need_tempvar = 0;
int is_tls = 0;
std::vector<struct insn_info> info;
@@ -620,7 +620,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
stack_depth = compute_stack_depth (byte_order, addr_size,
&need_tempvar, &is_tls,
- op_ptr, op_end, initial != NULL,
+ expr, initial != NULL,
&info);
/* This is a hack until we can add a feature to glibc to let us
@@ -668,6 +668,10 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
if (initial != NULL)
pushf (indent, stream, "%s", core_addr_to_string (*initial));
+ const gdb_byte *const base = expr.data ();
+ const gdb_byte *op_ptr = base;
+ const gdb_byte *const op_end = expr.data () + expr.size ();
+
while (op_ptr < op_end)
{
enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr;
@@ -880,8 +884,6 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
break;
case DW_OP_fbreg:
{
- const gdb_byte *datastart;
- size_t datalen;
const struct block *b;
struct symbol *framefunc;
char fb_name[50];
@@ -896,8 +898,8 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
if (!framefunc)
error (_("No function found for block"));
- func_get_frame_base_dwarf_block (framefunc, pc,
- &datastart, &datalen);
+ auto frame_base_expr
+ = func_get_frame_base_dwarf_block (framefunc, pc);
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
@@ -906,12 +908,10 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
xsnprintf (fb_name, sizeof (fb_name), "__frame_base_%ld",
(long) (op_ptr - base));
- do_compile_dwarf_expr_to_c (indent, stream,
- GCC_UINTPTR, fb_name,
- sym, pc,
- arch, registers_used, addr_size,
- datastart, datastart + datalen,
- NULL, per_cu, per_objfile);
+ do_compile_dwarf_expr_to_c (indent, stream, GCC_UINTPTR, fb_name,
+ sym, pc, arch, registers_used,
+ addr_size, frame_base_expr, nullptr,
+ per_cu, per_objfile);
pushf (indent, stream, "%s + %s", fb_name, hex_string (offset));
}
@@ -1074,11 +1074,10 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
int regnum;
CORE_ADDR text_offset;
LONGEST off;
- const gdb_byte *cfa_start, *cfa_end;
+ gdb::array_view<const gdb_byte> cfa_expr;
- if (dwarf2_fetch_cfa_info (arch, pc, per_cu,
- ®num, &off,
- &text_offset, &cfa_start, &cfa_end))
+ if (dwarf2_fetch_cfa_info (arch, pc, per_cu, ®num, &off,
+ &text_offset, cfa_expr))
{
/* Register. */
pushf_register (indent, stream, registers_used, arch, regnum,
@@ -1094,12 +1093,11 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
xsnprintf (cfa_name, sizeof (cfa_name),
"__cfa_%ld", (long) (op_ptr - base));
- do_compile_dwarf_expr_to_c (indent, stream,
- GCC_UINTPTR, cfa_name,
- sym, pc, arch, registers_used,
- addr_size,
- cfa_start, cfa_end,
- &text_offset, per_cu, per_objfile);
+ do_compile_dwarf_expr_to_c (indent, stream, GCC_UINTPTR,
+ cfa_name, sym, pc, arch,
+ registers_used, addr_size,
+ cfa_expr, &text_offset, per_cu,
+ per_objfile);
pushf (indent, stream, "%s", cfa_name);
}
}
@@ -1146,13 +1144,13 @@ compile_dwarf_expr_to_c (string_file *stream, const char *result_name,
struct gdbarch *arch,
std::vector<bool> ®isters_used,
unsigned int addr_size,
- const gdb_byte *op_ptr, const gdb_byte *op_end,
+ gdb::array_view<const gdb_byte> expr,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
{
do_compile_dwarf_expr_to_c (2, stream, GCC_UINTPTR, result_name, sym, pc,
- arch, registers_used, addr_size, op_ptr, op_end,
- NULL, per_cu, per_objfile);
+ arch, registers_used, addr_size, expr, nullptr,
+ per_cu, per_objfile);
}
/* See compile.h. */
@@ -1165,12 +1163,11 @@ compile_dwarf_bounds_to_c (string_file *stream,
struct gdbarch *arch,
std::vector<bool> ®isters_used,
unsigned int addr_size,
- const gdb_byte *op_ptr, const gdb_byte *op_end,
+ gdb::array_view<const gdb_byte> expr,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
{
- do_compile_dwarf_expr_to_c (2, stream, "unsigned long ", result_name,
- sym, pc, arch, registers_used,
- addr_size, op_ptr, op_end, NULL, per_cu,
- per_objfile);
+ do_compile_dwarf_expr_to_c (2, stream, "unsigned long ", result_name, sym,
+ pc, arch, registers_used, addr_size, expr,
+ nullptr, per_cu, per_objfile);
}
diff --git a/gdb/compile/compile.h b/gdb/compile/compile.h
index ca222d2e961a..15fc22cb62cc 100644
--- a/gdb/compile/compile.h
+++ b/gdb/compile/compile.h
@@ -198,7 +198,7 @@ extern void eval_compile_command (struct command_line *cmd,
ADDR_SIZE is the DWARF address size to use.
- OPT_PTR and OP_END are the bounds of the DWARF expression.
+ EXPR is the DWARF expression.
PER_CU is the per-CU object used for looking up various other
things.
@@ -213,8 +213,7 @@ extern void compile_dwarf_expr_to_c (string_file *stream,
struct gdbarch *arch,
std::vector<bool> ®isters_used,
unsigned int addr_size,
- const gdb_byte *op_ptr,
- const gdb_byte *op_end,
+ gdb::array_view<const gdb_byte> expr,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile);
@@ -237,7 +236,7 @@ extern void compile_dwarf_expr_to_c (string_file *stream,
ADDR_SIZE is the DWARF address size to use.
- OPT_PTR and OP_END are the bounds of the DWARF expression.
+ EXPR is the DWARF expression.
PER_CU is the per-CU object used for looking up various other
things.
@@ -252,8 +251,7 @@ extern void compile_dwarf_bounds_to_c (string_file *stream,
struct gdbarch *arch,
std::vector<bool> ®isters_used,
unsigned int addr_size,
- const gdb_byte *op_ptr,
- const gdb_byte *op_end,
+ gdb::array_view<const gdb_byte> expr,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile);
diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index 653638ee1cc8..776ce43825d4 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -33,6 +33,10 @@
/* Blocks are a bunch of untyped bytes. */
struct dwarf_block
{
+ /* Return the contents of this block. */
+ gdb::array_view<const gdb_byte> view () const
+ { return gdb::make_array_view (data, size); }
+
size_t size;
/* Valid only if SIZE is not zero. */
diff --git a/gdb/dwarf2/call-site.h b/gdb/dwarf2/call-site.h
index 872f48cb662a..e55197213907 100644
--- a/gdb/dwarf2/call-site.h
+++ b/gdb/dwarf2/call-site.h
@@ -143,6 +143,15 @@ union call_site_parameter_u
struct call_site_parameter
{
+ /* Return the DW_AT_call_value DWARF expression. */
+ gdb::array_view<const gdb_byte> value_expr () const
+ { return gdb::make_array_view (value, value_size); }
+
+ /* Return the DW_AT_call_data_value DWARF expression. Returns an empty
+ view if not provided by DWARF. */
+ gdb::array_view<const gdb_byte> data_value_expr () const
+ { return gdb::make_array_view (data_value, data_value_size); }
+
ENUM_BITFIELD (call_site_parameter_kind) kind : 2;
union call_site_parameter_u u;
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 222f563e2a95..38b77f317413 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -783,9 +783,8 @@ dwarf_expr_context::fetch (int n)
/* See expr.h. */
-void
-dwarf_expr_context::get_frame_base (const gdb_byte **start,
- size_t * length)
+gdb::array_view<const gdb_byte>
+dwarf_expr_context::get_frame_base ()
{
ensure_have_frame (this->m_frame, "DW_OP_fbreg");
@@ -804,9 +803,8 @@ dwarf_expr_context::get_frame_base (const gdb_byte **start,
something has gone wrong. */
gdb_assert (framefunc != NULL);
- func_get_frame_base_dwarf_block (framefunc,
- get_frame_address_in_block (this->m_frame),
- start, length);
+ return func_get_frame_base_dwarf_block
+ (framefunc, get_frame_address_in_block (this->m_frame));
}
/* See expr.h. */
@@ -848,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.data, block.size);
+ this->eval (block.expr ());
}
/* See expr.h. */
@@ -921,13 +919,12 @@ dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind,
= dwarf_expr_reg_to_entry_parameter (this->m_frame, kind, kind_u,
&caller_per_cu,
&caller_per_objfile);
- const gdb_byte *data_src
- = deref_size == -1 ? parameter->value : parameter->data_value;
- size_t size
- = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
+ auto expr = (deref_size == -1
+ ? parameter->value_expr ()
+ : parameter->data_value_expr ());
/* DEREF_SIZE size is not verified here. */
- if (data_src == nullptr)
+ if (expr.empty ())
throw_error (NO_ENTRY_VALUE_ERROR,
_("Cannot resolve DW_AT_call_data_value"));
@@ -949,7 +946,7 @@ dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind,
scoped_restore save_addr_size = make_scoped_restore (&this->m_addr_size);
this->m_addr_size = this->m_per_cu->addr_size ();
- this->eval (data_src, size);
+ this->eval (expr);
}
/* See expr.h. */
@@ -1119,8 +1116,8 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
/* See expr.h. */
value *
-dwarf_expr_context::evaluate (const gdb_byte *addr, size_t len, bool as_lval,
- dwarf2_per_cu *per_cu,
+dwarf_expr_context::evaluate (gdb::array_view<const gdb_byte> expr,
+ bool as_lval, dwarf2_per_cu *per_cu,
const frame_info_ptr &frame,
const struct property_addr_info *addr_info,
struct type *type, struct type *subobj_type,
@@ -1130,7 +1127,7 @@ dwarf_expr_context::evaluate (const gdb_byte *addr, size_t len, bool as_lval,
this->m_frame = frame;
this->m_addr_info = addr_info;
- eval (addr, len);
+ eval (expr);
return fetch_result (type, subobj_type, subobj_offset, as_lval);
}
@@ -1285,14 +1282,14 @@ dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset,
}
}
-/* Evaluate the expression at ADDR (LEN bytes long). */
+/* Evaluate the expression EXPR. */
void
-dwarf_expr_context::eval (const gdb_byte *addr, size_t len)
+dwarf_expr_context::eval (gdb::array_view<const gdb_byte> expr)
{
int old_recursion_depth = this->m_recursion_depth;
- execute_stack_op (addr, addr + len);
+ execute_stack_op (expr);
/* RECURSION_DEPTH becomes invalid if an exception was thrown here. */
@@ -1365,13 +1362,15 @@ base_types_equal_p (struct type *t1, struct type *t2)
return t1->length () == t2->length ();
}
-/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_reg* return the
+/* If BLOCK contains DW_FORM_block* with single DW_OP_reg* return the
DWARF register number. Otherwise return -1. */
int
-dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end)
+dwarf_block_to_dwarf_reg (gdb::array_view<const gdb_byte> block)
{
uint64_t dwarf_reg;
+ const gdb_byte *buf = block.data ();
+ const gdb_byte *const buf_end = block.data () + block.size ();
if (buf_end <= buf)
return -1;
@@ -1406,17 +1405,19 @@ dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end)
return dwarf_reg;
}
-/* If <BUF..BUF_END] contains DW_FORM_block* with just DW_OP_breg*(0) and
- DW_OP_deref* return the DWARF register number. Otherwise return -1.
- DEREF_SIZE_RETURN contains -1 for DW_OP_deref; otherwise it contains the
- size from DW_OP_deref_size. */
+/* If BLOCK contains DW_FORM_block* with just DW_OP_breg*(0) and DW_OP_deref*
+ return the DWARF register number. Otherwise return -1. DEREF_SIZE_RETURN
+ contains -1 for DW_OP_deref; otherwise it contains the size from
+ DW_OP_deref_size. */
int
-dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf, const gdb_byte *buf_end,
+dwarf_block_to_dwarf_reg_deref (gdb::array_view<const gdb_byte> block,
CORE_ADDR *deref_size_return)
{
uint64_t dwarf_reg;
int64_t offset;
+ const gdb_byte *buf = block.data ();
+ const gdb_byte *const buf_end = block.data () + block.size ();
if (buf_end <= buf)
return -1;
@@ -1470,10 +1471,12 @@ dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf, const gdb_byte *buf_end,
/* See expr.h. */
bool
-dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
+dwarf_block_to_fb_offset (gdb::array_view<const gdb_byte> block,
CORE_ADDR *fb_offset_return)
{
int64_t fb_offset;
+ const gdb_byte *buf = block.data ();
+ const gdb_byte *const buf_end = block.data () + block.size ();
if (buf_end <= buf)
return false;
@@ -1495,11 +1498,14 @@ dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
/* See expr.h. */
bool
-dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
- const gdb_byte *buf_end, CORE_ADDR *sp_offset_return)
+dwarf_block_to_sp_offset (struct gdbarch *gdbarch,
+ gdb::array_view<const gdb_byte> block,
+ CORE_ADDR *sp_offset_return)
{
uint64_t dwarf_reg;
int64_t sp_offset;
+ const gdb_byte *buf = block.data ();
+ const gdb_byte *const buf_end = block.data () + block.size ();
if (buf_end <= buf)
return false;
@@ -1555,11 +1561,10 @@ trivial_entry_value (frame_info_ptr frame)
}
/* The engine for the expression evaluator. Using the context in this
- object, evaluate the expression between OP_PTR and OP_END. */
+ object, evaluate the expression EXPR. */
void
-dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
- const gdb_byte *op_end)
+dwarf_expr_context::execute_stack_op (gdb::array_view<const gdb_byte> expr)
{
gdbarch *arch = this->m_per_objfile->objfile->arch ();
bfd_endian byte_order = gdbarch_byte_order (arch);
@@ -1580,6 +1585,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
this->m_recursion_depth);
this->m_recursion_depth++;
+ const gdb_byte *op_ptr = expr.data ();
+ const gdb_byte *op_end = expr.data () + expr.size ();
+
while (op_ptr < op_end)
{
dwarf_location_atom op = (dwarf_location_atom) *op_ptr++;
@@ -1880,9 +1888,6 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
break;
case DW_OP_fbreg:
{
- const gdb_byte *datastart;
- size_t datalen;
-
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
/* Rather than create a whole new context, we simply
@@ -1895,8 +1900,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* FIXME: cagney/2003-03-26: This code should be using
get_frame_base_address(), and then implement a dwarf2
specific this_base method. */
- this->get_frame_base (&datastart, &datalen);
- eval (datastart, datalen);
+ eval (this->get_frame_base ());
if (this->m_location == DWARF_VALUE_MEMORY)
result = fetch_address (0);
else if (this->m_location == DWARF_VALUE_REGISTER)
@@ -2310,7 +2314,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
if (op_ptr + len > op_end)
error (_("DW_OP_entry_value: too few bytes available."));
- kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (op_ptr, op_ptr + len);
+ auto entry_value_expr = gdb::make_array_view (op_ptr, len);
+ kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (entry_value_expr);
if (kind_u.dwarf_reg != -1)
{
op_ptr += len;
@@ -2331,8 +2336,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
goto no_push;
}
- kind_u.dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr,
- op_ptr + len,
+ kind_u.dwarf_reg = dwarf_block_to_dwarf_reg_deref (entry_value_expr,
&deref_size);
if (kind_u.dwarf_reg != -1)
{
diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h
index eaa166935342..02b0e41f6fde 100644
--- a/gdb/dwarf2/expr.h
+++ b/gdb/dwarf2/expr.h
@@ -129,8 +129,7 @@ struct dwarf_expr_context
void push_address (CORE_ADDR value, bool in_stack_memory);
- /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU
- and FRAME context.
+ /* Evaluate expression EXPR in a given PER_CU and FRAME context.
AS_LVAL defines if the returned struct value is expected to be a
value (false) or a location description (true).
@@ -140,7 +139,7 @@ struct dwarf_expr_context
The ADDR_INFO property can be specified to override the range of
memory addresses with the passed in buffer. */
- value *evaluate (const gdb_byte *addr, size_t len, bool as_lval,
+ value *evaluate (gdb::array_view<const gdb_byte> expr, bool as_lval,
dwarf2_per_cu *per_cu, const frame_info_ptr &frame,
const struct property_addr_info *addr_info = nullptr,
struct type *type = nullptr,
@@ -208,12 +207,12 @@ struct dwarf_expr_context
/* Property address info used for the evaluation. */
const struct property_addr_info *m_addr_info = nullptr;
- void eval (const gdb_byte *addr, size_t len);
+ void eval (gdb::array_view<const gdb_byte> expr);
struct type *address_type () const;
void push (struct value *value, bool in_stack_memory);
bool stack_empty_p () const;
void add_piece (ULONGEST size, ULONGEST offset, enum dwarf_location_atom op);
- void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end);
+ void execute_stack_op (gdb::array_view<const gdb_byte> expr);
void pop ();
struct value *fetch (int n);
CORE_ADDR fetch_address (int n);
@@ -227,10 +226,10 @@ struct dwarf_expr_context
value *fetch_result (struct type *type, struct type *subobj_type,
LONGEST subobj_offset, bool as_lval);
- /* Return the location expression for the frame base attribute, in
- START and LENGTH. The result must be live until the current
- expression evaluation is complete. */
- void get_frame_base (const gdb_byte **start, size_t *length);
+ /* Return the location expression for the frame base attribute. The
+ result must be live until the current expression evaluation is
+ complete. */
+ gdb::array_view<const gdb_byte> get_frame_base ();
/* Return the base type given by the indicated DIE at DIE_CU_OFF.
This can throw an exception if the DIE is invalid or does not
@@ -269,25 +268,24 @@ CORE_ADDR read_addr_from_reg (const frame_info_ptr &frame, int reg);
void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *,
const char *);
-int dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end);
+int dwarf_block_to_dwarf_reg (gdb::array_view<const gdb_byte> block);
-int dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf,
- const gdb_byte *buf_end,
+int dwarf_block_to_dwarf_reg_deref (gdb::array_view<const gdb_byte> block,
CORE_ADDR *deref_size_return);
-/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_fbreg(X) fill
- in FB_OFFSET_RETURN with the X offset and return true. Otherwise return
+/* If BLOCK contains DW_FORM_block* with single DW_OP_fbreg(X) fill in
+ FB_OFFSET_RETURN with the X offset and return true. Otherwise return
false. */
-bool dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
+bool dwarf_block_to_fb_offset (gdb::array_view<const gdb_byte> block,
CORE_ADDR *fb_offset_return);
-/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_bregSP(X) fill
- in SP_OFFSET_RETURN with the X offset and return true. Otherwise return
+/* If BLOCK contains DW_FORM_block* with single DW_OP_bregSP(X) fill in
+ SP_OFFSET_RETURN with the X offset and return true. Otherwise return
false. The matched SP register number depends on GDBARCH. */
-bool dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
- const gdb_byte *buf_end,
+bool dwarf_block_to_sp_offset (struct gdbarch *gdbarch,
+ gdb::array_view<const gdb_byte> block,
CORE_ADDR *sp_offset_return);
/* Wrappers around the leb128 reader routines to simplify them for our
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index 70895e90696d..5b9f41cd53a4 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -183,11 +183,6 @@ static ULONGEST read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
int ptr_len, const gdb_byte *buf,
unsigned int *bytes_read_ptr,
unrelocated_addr func_base);
-\f
-
-/* Store the length the expression for the CFA in the `cfa_reg' field,
- which is unused in that case. */
-#define cfa_exp_len cfa_reg
dwarf2_frame_state::dwarf2_frame_state (CORE_ADDR pc_, struct dwarf2_cie *cie)
: pc (pc_), data_align (cie->data_alignment_factor),
@@ -228,7 +223,7 @@ register %s (#%d) at %s"),
}
static CORE_ADDR
-execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
+execute_stack_op (gdb::array_view<const gdb_byte> expr, int addr_size,
const frame_info_ptr &this_frame, CORE_ADDR initial,
int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
{
@@ -236,7 +231,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
scoped_value_mark free_values;
ctx.push_address (initial, initial_in_stack_memory);
- value *result_val = ctx.evaluate (exp, len, true, nullptr, this_frame);
+ value *result_val = ctx.evaluate (expr, true, nullptr, this_frame);
if (result_val->lval () == lval_memory)
return result_val->address ();
@@ -408,10 +403,9 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
case DW_CFA_def_cfa_expression:
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
- fs->regs.cfa_exp_len = utmp;
- fs->regs.cfa_exp = insn_ptr;
+ fs->regs.cfa_exp = gdb::make_array_view (insn_ptr, utmp);
fs->regs.cfa_how = CFA_EXP;
- insn_ptr += fs->regs.cfa_exp_len;
+ insn_ptr += utmp;
break;
case DW_CFA_expression:
@@ -571,7 +565,7 @@ execute_cfa_program_test (struct gdbarch *gdbarch)
SELF_CHECK (fs.regs.cfa_reg == 1);
SELF_CHECK (fs.regs.cfa_offset == 4);
SELF_CHECK (fs.regs.cfa_how == CFA_REG_OFFSET);
- SELF_CHECK (fs.regs.cfa_exp == NULL);
+ SELF_CHECK (fs.regs.cfa_exp.empty ());
SELF_CHECK (fs.regs.prev == NULL);
}
@@ -759,8 +753,7 @@ bool
dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
dwarf2_per_cu *data, int *regnum_out,
LONGEST *offset_out, CORE_ADDR *text_offset_out,
- const gdb_byte **cfa_start_out,
- const gdb_byte **cfa_end_out)
+ gdb::array_view<const gdb_byte> &cfa_expr_out)
{
struct dwarf2_fde *fde;
dwarf2_per_objfile *per_objfile;
@@ -811,8 +804,7 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
case CFA_EXP:
*text_offset_out = per_objfile->objfile->text_section_offset ();
- *cfa_start_out = fs.regs.cfa_exp;
- *cfa_end_out = fs.regs.cfa_exp + fs.regs.cfa_exp_len;
+ cfa_expr_out = fs.regs.cfa_exp;
return false;
default:
@@ -978,10 +970,8 @@ dwarf2_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
break;
case CFA_EXP:
- cache->cfa =
- execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len,
- cache->addr_size, this_frame, 0, 0,
- cache->per_objfile);
+ cache->cfa = execute_stack_op (fs.regs.cfa_exp, cache->addr_size,
+ this_frame, 0, 0, cache->per_objfile);
break;
default:
@@ -1166,10 +1156,8 @@ dwarf2_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, realnum);
case DWARF2_FRAME_REG_SAVED_EXP:
- addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
- cache->reg[regnum].loc.exp.len,
- cache->addr_size,
- this_frame, cache->cfa, 1,
+ addr = execute_stack_op (cache->reg[regnum].loc.exp.view (),
+ cache->addr_size, this_frame, cache->cfa, 1,
cache->per_objfile);
return frame_unwind_got_memory (this_frame, regnum, addr);
@@ -1178,10 +1166,8 @@ dwarf2_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
return frame_unwind_got_constant (this_frame, regnum, addr);
case DWARF2_FRAME_REG_SAVED_VAL_EXP:
- addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
- cache->reg[regnum].loc.exp.len,
- cache->addr_size,
- this_frame, cache->cfa, 1,
+ addr = execute_stack_op (cache->reg[regnum].loc.exp.view (),
+ cache->addr_size, this_frame, cache->cfa, 1,
cache->per_objfile);
return frame_unwind_got_constant (this_frame, regnum, addr);
diff --git a/gdb/dwarf2/frame.h b/gdb/dwarf2/frame.h
index 6ecd5d0d6563..d3c71c3d16e4 100644
--- a/gdb/dwarf2/frame.h
+++ b/gdb/dwarf2/frame.h
@@ -78,6 +78,10 @@ struct dwarf2_frame_state_reg
ULONGEST reg;
struct
{
+ /* Return this expression. */
+ gdb::array_view<const gdb_byte> view () const
+ { return gdb::make_array_view (start, len); }
+
const gdb_byte *start;
ULONGEST len;
} exp;
@@ -143,7 +147,7 @@ struct dwarf2_frame_state_reg_info
LONGEST cfa_offset = 0;
ULONGEST cfa_reg = 0;
enum cfa_how_kind cfa_how = CFA_UNSET;
- const gdb_byte *cfa_exp = NULL;
+ gdb::array_view<const gdb_byte> cfa_exp;
/* Used to implement DW_CFA_remember_state. */
struct dwarf2_frame_state_reg_info *prev = NULL;
@@ -255,15 +259,13 @@ CORE_ADDR dwarf2_frame_cfa (const frame_info_ptr &this_frame);
OFFSET_OUT is the offset to use from this register.
These are only filled in when true is returned.
- TEXT_OFFSET_OUT, CFA_START_OUT, and CFA_END_OUT describe the CFA
- in other cases. These are only used when false is returned. */
+ TEXT_OFFSET_OUT and CFA_EXPR describe the CFA in other cases. These are
+ only filled in when false is returned. */
-extern bool dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
- dwarf2_per_cu *data, int *regnum_out,
- LONGEST *offset_out,
- CORE_ADDR *text_offset_out,
- const gdb_byte **cfa_start_out,
- const gdb_byte **cfa_end_out);
+extern bool dwarf2_fetch_cfa_info
+ (struct gdbarch *gdbarch, CORE_ADDR pc, dwarf2_per_cu *data, int *regnum_out,
+ LONGEST *offset_out, CORE_ADDR *text_offset_out,
+ gdb::array_view<const gdb_byte> &cfa_expr_out);
/* Allocate a new instance of the function unique data.
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index a493a46dcfc9..5bf863e13d53 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -49,9 +49,10 @@
#include "extract-store-integer.h"
static struct value *dwarf2_evaluate_loc_desc_full
- (struct type *type, const frame_info_ptr &frame, const gdb_byte *data,
- size_t size, dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
- struct type *subobj_type, LONGEST subobj_byte_offset, bool as_lval = true);
+ (struct type *type, const frame_info_ptr &frame,
+ gdb::array_view<const gdb_byte> loc_desc, dwarf2_per_cu *per_cu,
+ dwarf2_per_objfile *per_objfile, struct type *subobj_type,
+ LONGEST subobj_byte_offset, bool as_lval = true);
/* Until these have formal names, we define these here.
ref: http://gcc.gnu.org/wiki/DebugFission
@@ -354,18 +355,16 @@ decode_debug_loc_dwo_addresses (dwarf2_per_cu *per_cu,
}
}
-/* A function for dealing with location lists. Given a
- symbol baton (BATON) and a pc value (PC), find the appropriate
- location expression, set *LOCEXPR_LENGTH, and return a pointer
- to the beginning of the expression. Returns NULL on failure.
+/* A function for dealing with location lists. Given a symbol baton
+ (BATON) and a pc value (PC), find and return the appropriate location
+ expression. Returns an empty view on failure.
For now, only return the first matching location expression; there
can be more than one in the list. */
-const gdb_byte *
+gdb::array_view<const gdb_byte>
dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
- size_t *locexpr_length, const CORE_ADDR pc,
- bool at_entry)
+ const CORE_ADDR pc, bool at_entry)
{
dwarf2_per_objfile *per_objfile = baton->per_objfile;
struct objfile *objfile = per_objfile->objfile;
@@ -410,8 +409,7 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
switch (kind)
{
case DEBUG_LOC_END_OF_LIST:
- *locexpr_length = 0;
- return NULL;
+ return {};
case DEBUG_LOC_BASE_ADDRESS:
base_address = high;
@@ -470,17 +468,11 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
pc_func = pc_block->linkage_function ();
if (pc_func && pc == pc_func->value_block ()->entry_pc ())
- {
- *locexpr_length = length;
- return loc_ptr;
- }
+ return gdb::make_array_view (loc_ptr, length);
}
if (unrel_pc >= low && unrel_pc < high)
- {
- *locexpr_length = length;
- return loc_ptr;
- }
+ return gdb::make_array_view (loc_ptr, length);
loc_ptr += length;
}
@@ -489,15 +481,13 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
/* 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)
+static gdb::array_view<const gdb_byte>
+locexpr_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc)
{
struct dwarf2_locexpr_baton *symbaton
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (framefunc);
- *length = symbaton->size;
- *start = symbaton->data;
+ return symbaton->expr ();
}
/* Implement the struct symbol_block_ops::get_frame_base method for
@@ -509,8 +499,6 @@ locexpr_get_frame_base (struct symbol *framefunc, const frame_info_ptr &frame)
struct gdbarch *gdbarch;
struct type *type;
struct dwarf2_locexpr_baton *dlbaton;
- const gdb_byte *start;
- size_t length;
struct value *result;
/* If this method is called, then FRAMEFUNC is supposed to be a DWARF block.
@@ -522,11 +510,11 @@ locexpr_get_frame_base (struct symbol *framefunc, const frame_info_ptr &frame)
type = builtin_type (gdbarch)->builtin_data_ptr;
dlbaton = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (framefunc);
- framefunc->block_ops ()->find_frame_base_location (framefunc,
- get_frame_pc (frame),
- &start, &length);
- result = dwarf2_evaluate_loc_desc (type, frame, start, length,
- dlbaton->per_cu, dlbaton->per_objfile);
+ auto expr
+ = framefunc->block_ops ()->find_frame_base_location (framefunc,
+ get_frame_pc (frame));
+ result = dwarf2_evaluate_loc_desc (type, frame, expr, dlbaton->per_cu,
+ dlbaton->per_objfile);
/* The DW_AT_frame_base attribute contains a location description which
computes the base address itself. However, the call to
@@ -548,14 +536,13 @@ const struct symbol_block_ops dwarf2_block_frame_base_locexpr_funcs =
/* 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)
+static gdb::array_view<const gdb_byte>
+loclist_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc)
{
struct dwarf2_loclist_baton *symbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (framefunc);
- *start = dwarf2_find_location_expression (symbaton, length, pc);
+ return dwarf2_find_location_expression (symbaton, pc);
}
/* Implement the struct symbol_block_ops::get_frame_base method for
@@ -567,8 +554,6 @@ loclist_get_frame_base (struct symbol *framefunc, const frame_info_ptr &frame)
struct gdbarch *gdbarch;
struct type *type;
struct dwarf2_loclist_baton *dlbaton;
- const gdb_byte *start;
- size_t length;
struct value *result;
/* If this method is called, then FRAMEFUNC is supposed to be a DWARF block.
@@ -580,11 +565,11 @@ loclist_get_frame_base (struct symbol *framefunc, const frame_info_ptr &frame)
type = builtin_type (gdbarch)->builtin_data_ptr;
dlbaton = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (framefunc);
- framefunc->block_ops ()->find_frame_base_location (framefunc,
- get_frame_pc (frame),
- &start, &length);
- result = dwarf2_evaluate_loc_desc (type, frame, start, length,
- dlbaton->per_cu, dlbaton->per_objfile);
+ auto expr
+ = framefunc->block_ops ()->find_frame_base_location (framefunc,
+ get_frame_pc (frame));
+ result = dwarf2_evaluate_loc_desc (type, frame, expr, dlbaton->per_cu,
+ dlbaton->per_objfile);
/* The DW_AT_frame_base attribute contains a location description which
computes the base address itself. However, the call to
@@ -605,19 +590,20 @@ const struct symbol_block_ops dwarf2_block_frame_base_loclist_funcs =
/* See dwarf2/loc.h. */
-void
-func_get_frame_base_dwarf_block (struct symbol *framefunc, CORE_ADDR pc,
- const gdb_byte **start, size_t *length)
+gdb::array_view<const gdb_byte>
+func_get_frame_base_dwarf_block (struct symbol *framefunc, CORE_ADDR pc)
{
+ gdb::array_view<const gdb_byte> block;
+
if (const symbol_block_ops *block_ops = framefunc->block_ops ();
block_ops != nullptr)
- block_ops->find_frame_base_location (framefunc, pc, start, length);
- else
- *length = 0;
+ block = block_ops->find_frame_base_location (framefunc, pc);
- if (*length == 0)
+ if (block.empty ())
error (_("Could not find the frame base for \"%s\"."),
framefunc->natural_name ());
+
+ return block;
}
/* See loc.h. */
@@ -692,7 +678,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->data, dwarf_block->size,
+ dwarf_block->expr (),
dwarf_block->per_cu,
dwarf_block->per_objfile);
/* DW_AT_call_target is a DWARF expression, not a DWARF location. */
@@ -1275,8 +1261,9 @@ dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
throw_error (NO_ENTRY_VALUE_ERROR,
_("Cannot resolve DW_AT_call_data_value"));
- return dwarf2_evaluate_loc_desc (type, caller_frame, data_src, size, per_cu,
- per_objfile, false);
+ return dwarf2_evaluate_loc_desc (type, caller_frame,
+ gdb::make_array_view (data_src, size),
+ per_cu, per_objfile, false);
}
/* VALUE must be of type lval_computed with entry_data_value_funcs. Perform
@@ -1384,8 +1371,8 @@ value_of_dwarf_reg_entry (struct type *type, const frame_info_ptr &frame,
return val;
}
-/* Read parameter of TYPE at (callee) FRAME's function entry. DATA and
- SIZE are DWARF block used to match DW_AT_location at the caller's
+/* Read parameter of TYPE at (callee) FRAME's function entry. BLOCK is the
+ DWARF block 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
@@ -1393,16 +1380,16 @@ value_of_dwarf_reg_entry (struct type *type, const frame_info_ptr &frame,
static struct value *
value_of_dwarf_block_entry (struct type *type, const frame_info_ptr &frame,
- const gdb_byte *block, size_t block_len)
+ gdb::array_view<const gdb_byte> block)
{
union call_site_parameter_u kind_u;
- kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (block, block + block_len);
+ kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (block);
if (kind_u.dwarf_reg != -1)
return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_DWARF_REG,
kind_u);
- if (dwarf_block_to_fb_offset (block, block + block_len, &kind_u.fb_offset))
+ if (dwarf_block_to_fb_offset (block, &kind_u.fb_offset))
return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_FB_OFFSET,
kind_u);
@@ -1475,26 +1462,24 @@ 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. */
- if (baton.data != NULL)
- return dwarf2_evaluate_loc_desc_full (orig_type, frame, baton.data,
- baton.size, baton.per_cu,
+ auto expr = baton.expr ();
+ if (!expr.empty ())
+ return dwarf2_evaluate_loc_desc_full (orig_type, frame, expr, baton.per_cu,
baton.per_objfile,
- type->target_type (),
- byte_offset);
+ type->target_type (), byte_offset);
else
return fetch_const_value_from_synthetic_pointer (die, byte_offset, per_cu,
per_objfile, type);
}
-/* Evaluate a location description, starting at DATA and with length
- SIZE, to find the current location of variable of TYPE in the
- context of FRAME. If SUBOBJ_TYPE is non-NULL, return instead the
- location of the subobject of type SUBOBJ_TYPE at byte offset
- SUBOBJ_BYTE_OFFSET within the variable of type TYPE. */
+/* Evaluate the location description LOC_DESC to find the current location
+ of variable of TYPE in the context of FRAME. If SUBOBJ_TYPE is non-NULL,
+ return instead the location of the subobject of type SUBOBJ_TYPE at byte
+ offset SUBOBJ_BYTE_OFFSET within the variable of type TYPE. */
static struct value *
dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame,
- const gdb_byte *data, size_t size,
+ gdb::array_view<const gdb_byte> loc_desc,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
struct type *subobj_type,
@@ -1509,7 +1494,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame,
else if (subobj_byte_offset < 0)
invalid_synthetic_pointer ();
- if (size == 0)
+ if (loc_desc.empty ())
return value::allocate_optimized_out (subobj_type);
dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
@@ -1519,7 +1504,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame,
try
{
- retval = ctx.evaluate (data, size, as_lval, per_cu, frame, nullptr,
+ retval = ctx.evaluate (loc_desc, as_lval, per_cu, frame, nullptr,
type, subobj_type, subobj_byte_offset);
}
catch (const gdb_exception_error &ex)
@@ -1559,11 +1544,11 @@ dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame,
struct value *
dwarf2_evaluate_loc_desc (struct type *type, const frame_info_ptr &frame,
- const gdb_byte *data, size_t size,
+ gdb::array_view<const gdb_byte> loc_desc,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile, bool as_lval)
{
- return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu,
+ return dwarf2_evaluate_loc_desc_full (type, frame, loc_desc, per_cu,
per_objfile, NULL, 0, as_lval);
}
@@ -1603,8 +1588,8 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
try
{
- result = ctx.evaluate (dlbaton->data, dlbaton->size,
- true, per_cu, frame, addr_stack);
+ result = ctx.evaluate (dlbaton->expr (), true, per_cu, frame,
+ addr_stack);
}
catch (const gdb_exception_error &ex)
{
@@ -1704,19 +1689,17 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
{
const dwarf2_property_baton *baton = prop->baton ();
CORE_ADDR pc;
- const gdb_byte *data;
struct value *val;
- size_t size;
if (frame == NULL
|| !get_frame_address_in_block_if_available (frame, &pc))
return false;
- data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
- if (data != NULL)
+ auto data = dwarf2_find_location_expression (&baton->loclist, pc);
+ if (!data.empty ())
{
val = dwarf2_evaluate_loc_desc (baton->property_type, frame, data,
- size, baton->loclist.per_cu,
+ baton->loclist.per_cu,
baton->loclist.per_objfile);
if (!val->optimized_out ())
{
@@ -1809,15 +1792,13 @@ dwarf2_compile_property_to_c (string_file *stream,
{
#if defined (HAVE_COMPILE)
const dwarf2_property_baton *baton = prop->baton ();
- const gdb_byte *data;
- size_t size;
+ gdb::array_view<const gdb_byte> expr;
dwarf2_per_cu *per_cu;
dwarf2_per_objfile *per_objfile;
if (prop->kind () == PROP_LOCEXPR)
{
- data = baton->locexpr.data;
- size = baton->locexpr.size;
+ expr = baton->locexpr.expr ();
per_cu = baton->locexpr.per_cu;
per_objfile = baton->locexpr.per_objfile;
}
@@ -1825,15 +1806,14 @@ dwarf2_compile_property_to_c (string_file *stream,
{
gdb_assert (prop->kind () == PROP_LOCLIST);
- data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
+ expr = dwarf2_find_location_expression (&baton->loclist, pc);
per_cu = baton->loclist.per_cu;
per_objfile = baton->loclist.per_objfile;
}
- compile_dwarf_bounds_to_c (stream, result_name, prop, sym, pc,
- gdbarch, registers_used,
- per_cu->addr_size (),
- data, data + size, per_cu, per_objfile);
+ compile_dwarf_bounds_to_c (stream, result_name, prop, sym, pc, gdbarch,
+ registers_used, per_cu->addr_size (), expr,
+ per_cu, per_objfile);
#else
gdb_assert_not_reached ("Compile support was disabled");
#endif
@@ -2185,10 +2165,8 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr,
if (symbol_needs != SYMBOL_NEEDS_FRAME)
{
gdbarch *arch = baton.per_objfile->objfile->arch ();
- gdb::array_view<const gdb_byte> sub_expr (baton.data,
- baton.size);
symbol_needs
- = dwarf2_get_symbol_read_needs (sub_expr,
+ = dwarf2_get_symbol_read_needs (baton.expr (),
baton.per_cu,
baton.per_objfile,
gdbarch_byte_order (arch),
@@ -2238,10 +2216,8 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr,
if (symbol_needs != SYMBOL_NEEDS_FRAME)
{
gdbarch *arch = baton.per_objfile->objfile->arch ();
- gdb::array_view<const gdb_byte> sub_expr (baton.data,
- baton.size);
symbol_needs
- = dwarf2_get_symbol_read_needs (sub_expr,
+ = dwarf2_get_symbol_read_needs (baton.expr (),
baton.per_cu,
baton.per_objfile,
gdbarch_byte_order (arch),
@@ -2391,37 +2367,39 @@ access_memory (struct gdbarch *arch, struct agent_expr *expr, ULONGEST nbits)
/* Compile a DWARF location expression to an agent expression.
- EXPR is the agent expression we are building.
+ AX is the agent expression we are building.
LOC is the agent value we modify.
- ARCH is the architecture.
ADDR_SIZE is the size of addresses, in bytes.
- OP_PTR is the start of the location expression.
- OP_END is one past the last byte of the location expression.
+ EXPR is the location expression.
This will throw an exception for various kinds of errors -- for
example, if the expression cannot be compiled, or if the expression
is invalid. */
static void
-dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
- unsigned int addr_size, const gdb_byte *op_ptr,
- const gdb_byte *op_end, dwarf2_per_cu *per_cu,
+dwarf2_compile_expr_to_ax (struct agent_expr *ax, struct axs_value *loc,
+ unsigned int addr_size,
+ gdb::array_view<const gdb_byte> expr,
+ dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
{
- gdbarch *arch = expr->gdbarch;
+ gdbarch *arch = ax->gdbarch;
std::vector<int> dw_labels, patches;
- const gdb_byte * const base = op_ptr;
- const gdb_byte *previous_piece = op_ptr;
+ const gdb_byte *previous_piece = expr.data ();
enum bfd_endian byte_order = gdbarch_byte_order (arch);
ULONGEST bits_collected = 0;
unsigned int addr_size_bits = 8 * addr_size;
bool bits_big_endian = byte_order == BFD_ENDIAN_BIG;
- std::vector<int> offsets (op_end - op_ptr, -1);
+ std::vector<int> offsets (expr.size (), -1);
/* By default we are making an address. */
loc->kind = axs_lvalue_memory;
+ const gdb_byte *const base = expr.data ();
+ const gdb_byte *op_ptr = expr.data ();
+ const gdb_byte *const op_end = expr.data () + expr.size ();
+
while (op_ptr < op_end)
{
enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr;
@@ -2429,7 +2407,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
int64_t offset;
int i;
- offsets[op_ptr - base] = expr->buf.size ();
+ offsets[op_ptr - base] = ax->buf.size ();
++op_ptr;
/* Our basic approach to code generation is to map DWARF
@@ -2482,7 +2460,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
case DW_OP_lit29:
case DW_OP_lit30:
case DW_OP_lit31:
- ax_const_l (expr, op - DW_OP_lit0);
+ ax_const_l (ax, op - DW_OP_lit0);
break;
case DW_OP_addr:
@@ -2494,57 +2472,57 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
branching between the address and the TLS op. */
if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
uoffset += per_objfile->objfile->text_section_offset ();
- ax_const_l (expr, uoffset);
+ ax_const_l (ax, uoffset);
break;
case DW_OP_const1u:
- ax_const_l (expr, extract_unsigned_integer (op_ptr, 1, byte_order));
+ ax_const_l (ax, extract_unsigned_integer (op_ptr, 1, byte_order));
op_ptr += 1;
break;
case DW_OP_const1s:
- ax_const_l (expr, extract_signed_integer (op_ptr, 1, byte_order));
+ ax_const_l (ax, extract_signed_integer (op_ptr, 1, byte_order));
op_ptr += 1;
break;
case DW_OP_const2u:
- ax_const_l (expr, extract_unsigned_integer (op_ptr, 2, byte_order));
+ ax_const_l (ax, extract_unsigned_integer (op_ptr, 2, byte_order));
op_ptr += 2;
break;
case DW_OP_const2s:
- ax_const_l (expr, extract_signed_integer (op_ptr, 2, byte_order));
+ ax_const_l (ax, extract_signed_integer (op_ptr, 2, byte_order));
op_ptr += 2;
break;
case DW_OP_const4u:
- ax_const_l (expr, extract_unsigned_integer (op_ptr, 4, byte_order));
+ ax_const_l (ax, extract_unsigned_integer (op_ptr, 4, byte_order));
op_ptr += 4;
break;
case DW_OP_const4s:
- ax_const_l (expr, extract_signed_integer (op_ptr, 4, byte_order));
+ ax_const_l (ax, extract_signed_integer (op_ptr, 4, byte_order));
op_ptr += 4;
break;
case DW_OP_const8u:
- ax_const_l (expr, extract_unsigned_integer (op_ptr, 8, byte_order));
+ ax_const_l (ax, extract_unsigned_integer (op_ptr, 8, byte_order));
op_ptr += 8;
break;
case DW_OP_const8s:
- ax_const_l (expr, extract_signed_integer (op_ptr, 8, byte_order));
+ ax_const_l (ax, extract_signed_integer (op_ptr, 8, byte_order));
op_ptr += 8;
break;
case DW_OP_constu:
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
- ax_const_l (expr, uoffset);
+ ax_const_l (ax, uoffset);
break;
case DW_OP_consts:
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
- ax_const_l (expr, offset);
+ ax_const_l (ax, offset);
break;
case DW_OP_reg0:
@@ -2602,7 +2580,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
error (_("Cannot translate DW_OP_implicit_value of %d bytes"),
(int) len);
- ax_const_l (expr, extract_unsigned_integer (op_ptr, len,
+ ax_const_l (ax, extract_unsigned_integer (op_ptr, len,
byte_order));
op_ptr += len;
dwarf_expr_require_composition (op_ptr, op_end,
@@ -2651,11 +2629,11 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
case DW_OP_breg31:
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
i = dwarf_reg_to_regnum_or_error (arch, op - DW_OP_breg0);
- ax_reg (expr, i);
+ ax_reg (ax, i);
if (offset != 0)
{
- ax_const_l (expr, offset);
- ax_simple (expr, aop_add);
+ ax_const_l (ax, offset);
+ ax_simple (ax, aop_add);
}
break;
@@ -2664,23 +2642,21 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
op_ptr = safe_read_uleb128 (op_ptr, op_end, ®);
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
i = dwarf_reg_to_regnum_or_error (arch, reg);
- ax_reg (expr, i);
+ ax_reg (ax, i);
if (offset != 0)
{
- ax_const_l (expr, offset);
- ax_simple (expr, aop_add);
+ ax_const_l (ax, offset);
+ ax_simple (ax, aop_add);
}
}
break;
case DW_OP_fbreg:
{
- const gdb_byte *datastart;
- size_t datalen;
const struct block *b;
struct symbol *framefunc;
- b = block_for_pc (expr->scope);
+ b = block_for_pc (ax->scope);
if (!b)
error (_("No block found for address"));
@@ -2690,20 +2666,19 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
if (!framefunc)
error (_("No function found for block"));
- func_get_frame_base_dwarf_block (framefunc, expr->scope,
- &datastart, &datalen);
+ auto frame_base_expr = func_get_frame_base_dwarf_block (framefunc,
+ ax->scope);
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
- dwarf2_compile_expr_to_ax (expr, loc, addr_size, datastart,
- datastart + datalen, per_cu,
- per_objfile);
+ dwarf2_compile_expr_to_ax (ax, loc, addr_size, frame_base_expr,
+ per_cu, per_objfile);
if (loc->kind == axs_lvalue_register)
- require_rvalue (expr, loc);
+ require_rvalue (ax, loc);
if (offset != 0)
{
- ax_const_l (expr, offset);
- ax_simple (expr, aop_add);
+ ax_const_l (ax, offset);
+ ax_simple (ax, aop_add);
}
loc->kind = axs_lvalue_memory;
@@ -2711,28 +2686,28 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
break;
case DW_OP_dup:
- ax_simple (expr, aop_dup);
+ ax_simple (ax, aop_dup);
break;
case DW_OP_drop:
- ax_simple (expr, aop_pop);
+ ax_simple (ax, aop_pop);
break;
case DW_OP_pick:
offset = *op_ptr++;
- ax_pick (expr, offset);
+ ax_pick (ax, offset);
break;
case DW_OP_swap:
- ax_simple (expr, aop_swap);
+ ax_simple (ax, aop_swap);
break;
case DW_OP_over:
- ax_pick (expr, 1);
+ ax_pick (ax, 1);
break;
case DW_OP_rot:
- ax_simple (expr, aop_rot);
+ ax_simple (ax, aop_rot);
break;
case DW_OP_deref:
@@ -2748,36 +2723,36 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
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);
+ access_memory (arch, ax, size * TARGET_CHAR_BIT);
}
break;
case DW_OP_abs:
/* Sign extend the operand. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_dup);
- ax_const_l (expr, 0);
- ax_simple (expr, aop_less_signed);
- ax_simple (expr, aop_log_not);
- i = ax_goto (expr, aop_if_goto);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_dup);
+ ax_const_l (ax, 0);
+ ax_simple (ax, aop_less_signed);
+ ax_simple (ax, aop_log_not);
+ i = ax_goto (ax, aop_if_goto);
/* We have to emit 0 - X. */
- ax_const_l (expr, 0);
- ax_simple (expr, aop_swap);
- ax_simple (expr, aop_sub);
- ax_label (expr, i, expr->buf.size ());
+ ax_const_l (ax, 0);
+ ax_simple (ax, aop_swap);
+ ax_simple (ax, aop_sub);
+ ax_label (ax, i, ax->buf.size ());
break;
case DW_OP_neg:
/* No need to sign extend here. */
- ax_const_l (expr, 0);
- ax_simple (expr, aop_swap);
- ax_simple (expr, aop_sub);
+ ax_const_l (ax, 0);
+ ax_simple (ax, aop_swap);
+ ax_simple (ax, aop_sub);
break;
case DW_OP_not:
/* Sign extend the operand. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_bit_not);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_bit_not);
break;
case DW_OP_plus_uconst:
@@ -2786,116 +2761,116 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
but we micro-optimize anyhow. */
if (reg != 0)
{
- ax_const_l (expr, reg);
- ax_simple (expr, aop_add);
+ ax_const_l (ax, reg);
+ ax_simple (ax, aop_add);
}
break;
case DW_OP_and:
- ax_simple (expr, aop_bit_and);
+ ax_simple (ax, aop_bit_and);
break;
case DW_OP_div:
/* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_simple (expr, aop_div_signed);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_simple (ax, aop_div_signed);
break;
case DW_OP_minus:
- ax_simple (expr, aop_sub);
+ ax_simple (ax, aop_sub);
break;
case DW_OP_mod:
- ax_simple (expr, aop_rem_unsigned);
+ ax_simple (ax, aop_rem_unsigned);
break;
case DW_OP_mul:
- ax_simple (expr, aop_mul);
+ ax_simple (ax, aop_mul);
break;
case DW_OP_or:
- ax_simple (expr, aop_bit_or);
+ ax_simple (ax, aop_bit_or);
break;
case DW_OP_plus:
- ax_simple (expr, aop_add);
+ ax_simple (ax, aop_add);
break;
case DW_OP_shl:
- ax_simple (expr, aop_lsh);
+ ax_simple (ax, aop_lsh);
break;
case DW_OP_shr:
- ax_simple (expr, aop_rsh_unsigned);
+ ax_simple (ax, aop_rsh_unsigned);
break;
case DW_OP_shra:
- ax_simple (expr, aop_rsh_signed);
+ ax_simple (ax, aop_rsh_signed);
break;
case DW_OP_xor:
- ax_simple (expr, aop_bit_xor);
+ ax_simple (ax, aop_bit_xor);
break;
case DW_OP_le:
/* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_ext (ax, addr_size_bits);
/* Note no swap here: A <= B is !(B < A). */
- ax_simple (expr, aop_less_signed);
- ax_simple (expr, aop_log_not);
+ ax_simple (ax, aop_less_signed);
+ ax_simple (ax, aop_log_not);
break;
case DW_OP_ge:
/* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
/* A >= B is !(A < B). */
- ax_simple (expr, aop_less_signed);
- ax_simple (expr, aop_log_not);
+ ax_simple (ax, aop_less_signed);
+ ax_simple (ax, aop_log_not);
break;
case DW_OP_eq:
/* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_ext (ax, addr_size_bits);
/* No need for a second swap here. */
- ax_simple (expr, aop_equal);
+ ax_simple (ax, aop_equal);
break;
case DW_OP_lt:
/* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_simple (expr, aop_less_signed);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_simple (ax, aop_less_signed);
break;
case DW_OP_gt:
/* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_ext (ax, addr_size_bits);
/* Note no swap here: A > B is B < A. */
- ax_simple (expr, aop_less_signed);
+ ax_simple (ax, aop_less_signed);
break;
case DW_OP_ne:
/* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
+ ax_ext (ax, addr_size_bits);
+ ax_simple (ax, aop_swap);
+ ax_ext (ax, addr_size_bits);
/* No need for a swap here. */
- ax_simple (expr, aop_equal);
- ax_simple (expr, aop_log_not);
+ ax_simple (ax, aop_equal);
+ ax_simple (ax, aop_log_not);
break;
case DW_OP_call_frame_cfa:
@@ -2903,26 +2878,25 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
int regnum;
CORE_ADDR text_offset;
LONGEST off;
- const gdb_byte *cfa_start, *cfa_end;
+ gdb::array_view<const gdb_byte> cfa_expr;
- if (dwarf2_fetch_cfa_info (arch, expr->scope, per_cu,
- ®num, &off,
- &text_offset, &cfa_start, &cfa_end))
+ if (dwarf2_fetch_cfa_info (arch, ax->scope, per_cu, ®num,
+ &off, &text_offset, cfa_expr))
{
/* Register. */
- ax_reg (expr, regnum);
+ ax_reg (ax, regnum);
if (off != 0)
{
- ax_const_l (expr, off);
- ax_simple (expr, aop_add);
+ ax_const_l (ax, off);
+ ax_simple (ax, aop_add);
}
}
else
{
/* Another expression. */
- ax_const_l (expr, text_offset);
- dwarf2_compile_expr_to_ax (expr, loc, addr_size, cfa_start,
- cfa_end, per_cu, per_objfile);
+ ax_const_l (ax, text_offset);
+ dwarf2_compile_expr_to_ax (ax, loc, addr_size, cfa_expr,
+ per_cu, per_objfile);
}
loc->kind = axs_lvalue_memory;
@@ -2941,7 +2915,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
case DW_OP_skip:
offset = extract_signed_integer (op_ptr, 2, byte_order);
op_ptr += 2;
- i = ax_goto (expr, aop_goto);
+ i = ax_goto (ax, aop_goto);
dw_labels.push_back (op_ptr + offset - base);
patches.push_back (i);
break;
@@ -2950,8 +2924,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
offset = extract_signed_integer (op_ptr, 2, byte_order);
op_ptr += 2;
/* Zero extend the operand. */
- ax_zero_ext (expr, addr_size_bits);
- i = ax_goto (expr, aop_if_goto);
+ ax_zero_ext (ax, addr_size_bits);
+ i = ax_goto (ax, aop_if_goto);
dw_labels.push_back (op_ptr + offset - base);
patches.push_back (i);
break;
@@ -2984,18 +2958,18 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
switch (loc->kind)
{
case axs_lvalue_register:
- ax_reg (expr, loc->u.reg);
+ ax_reg (ax, loc->u.reg);
break;
case axs_lvalue_memory:
/* Offset the pointer, if needed. */
if (uoffset > 8)
{
- ax_const_l (expr, uoffset / 8);
- ax_simple (expr, aop_add);
+ ax_const_l (ax, uoffset / 8);
+ ax_simple (ax, aop_add);
uoffset %= 8;
}
- access_memory (arch, expr, size);
+ access_memory (arch, ax, size);
break;
}
@@ -3008,18 +2982,18 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
{
if (bits_big_endian)
{
- ax_simple (expr, aop_swap);
- ax_const_l (expr, size);
- ax_simple (expr, aop_lsh);
+ ax_simple (ax, aop_swap);
+ ax_const_l (ax, size);
+ ax_simple (ax, aop_lsh);
/* We don't need a second swap here, because
aop_bit_or is symmetric. */
}
else
{
- ax_const_l (expr, size);
- ax_simple (expr, aop_lsh);
+ ax_const_l (ax, size);
+ ax_simple (ax, aop_lsh);
}
- ax_simple (expr, aop_bit_or);
+ ax_simple (ax, aop_bit_or);
}
bits_collected += size;
@@ -3039,9 +3013,9 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
uoffset = extract_unsigned_integer (op_ptr, size, byte_order);
op_ptr += size;
- auto get_frame_pc_from_expr = [expr] ()
+ auto get_frame_pc_from_expr = [ax] ()
{
- return expr->scope;
+ return ax->scope;
};
cu_offset cuoffset = (cu_offset) uoffset;
block = dwarf2_fetch_die_loc_cu_off (cuoffset, per_cu, per_objfile,
@@ -3050,9 +3024,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
/* DW_OP_call_ref is currently not supported. */
gdb_assert (block.per_cu == per_cu);
- dwarf2_compile_expr_to_ax (expr, loc, addr_size, block.data,
- block.data + block.size, per_cu,
- per_objfile);
+ dwarf2_compile_expr_to_ax (ax, loc, addr_size, block.expr (),
+ per_cu, per_objfile);
}
break;
@@ -3073,7 +3046,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
int targ = offsets[dw_labels[i]];
if (targ == -1)
internal_error (_("invalid label"));
- ax_label (expr, patches[i], targ);
+ ax_label (ax, patches[i], targ);
}
}
@@ -3087,9 +3060,8 @@ locexpr_read_variable (struct symbol *symbol, const frame_info_ptr &frame)
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
struct value *val;
- val = dwarf2_evaluate_loc_desc (symbol->type (), frame, dlbaton->data,
- dlbaton->size, dlbaton->per_cu,
- dlbaton->per_objfile);
+ val = dwarf2_evaluate_loc_desc (symbol->type (), frame, dlbaton->expr (),
+ dlbaton->per_cu, dlbaton->per_objfile);
return val;
}
@@ -3104,8 +3076,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->data,
- dlbaton->size);
+ return value_of_dwarf_block_entry (symbol->type (), frame, dlbaton->expr ());
}
/* Implementation of get_symbol_read_needs from
@@ -3118,10 +3089,8 @@ locexpr_get_symbol_read_needs (struct symbol *symbol)
= (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
gdbarch *arch = dlbaton->per_objfile->objfile->arch ();
- gdb::array_view<const gdb_byte> expr (dlbaton->data, dlbaton->size);
- return dwarf2_get_symbol_read_needs (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 (),
@@ -3196,8 +3165,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
struct symbol *framefunc;
int frame_reg = 0;
int64_t frame_offset;
- const gdb_byte *base_data, *new_data, *save_data = data;
- size_t base_size;
+ const gdb_byte *new_data, *save_data = data;
int64_t base_offset = 0;
new_data = safe_read_sleb128 (data + 1, end, &frame_offset);
@@ -3217,24 +3185,27 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
error (_("No function found for block for symbol \"%s\"."),
symbol->print_name ());
- func_get_frame_base_dwarf_block (framefunc, addr, &base_data, &base_size);
+ auto frame_base_expr = func_get_frame_base_dwarf_block (framefunc, addr);
+ gdb_byte op0 = frame_base_expr[0];
- if (base_data[0] >= DW_OP_breg0 && base_data[0] <= DW_OP_breg31)
+ if (op0 >= DW_OP_breg0 && op0 <= DW_OP_breg31)
{
const gdb_byte *buf_end;
- frame_reg = base_data[0] - DW_OP_breg0;
- buf_end = safe_read_sleb128 (base_data + 1, base_data + base_size,
+ frame_reg = op0 - DW_OP_breg0;
+ buf_end = safe_read_sleb128 (frame_base_expr.data () + 1,
+ (frame_base_expr.data ()
+ + frame_base_expr.size ()),
&base_offset);
- if (buf_end != base_data + base_size)
+ if (buf_end != frame_base_expr.data () + frame_base_expr.size ())
error (_("Unexpected opcode after "
"DW_OP_breg%u for symbol \"%s\"."),
frame_reg, symbol->print_name ());
}
- else if (base_data[0] >= DW_OP_reg0 && base_data[0] <= DW_OP_reg31)
+ else if (op0 >= DW_OP_reg0 && op0 <= DW_OP_reg31)
{
/* The frame base is just the register, with no offset. */
- frame_reg = base_data[0] - DW_OP_reg0;
+ frame_reg = op0 - DW_OP_reg0;
base_offset = 0;
}
else
@@ -3751,12 +3722,13 @@ show_dwarf_always_disassemble (struct ui_file *file, int from_tty,
static void
locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
struct ui_file *stream,
- const gdb_byte *data, size_t size,
+ gdb::array_view<const gdb_byte> expr,
unsigned int addr_size,
int offset_size, dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
{
- const gdb_byte *end = data + size;
+ const gdb_byte *data = expr.data ();
+ const gdb_byte *const end = expr.data () + expr.size ();
int first_piece = 1, bad = 0;
objfile *objfile = per_objfile->objfile;
@@ -3854,7 +3826,7 @@ locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr,
int offset_size = dlbaton->per_cu->offset_size ();
locexpr_describe_location_1 (symbol, addr, stream,
- dlbaton->data, dlbaton->size,
+ dlbaton->expr (),
addr_size, offset_size,
dlbaton->per_cu, dlbaton->per_objfile);
}
@@ -3873,9 +3845,8 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax,
if (dlbaton->size == 0)
value->optimized_out = 1;
else
- dwarf2_compile_expr_to_ax (ax, value, addr_size, dlbaton->data,
- dlbaton->data + dlbaton->size, dlbaton->per_cu,
- dlbaton->per_objfile);
+ dwarf2_compile_expr_to_ax (ax, value, addr_size, dlbaton->expr (),
+ dlbaton->per_cu, dlbaton->per_objfile);
}
/* symbol_computed_ops 'generate_c_location' method. */
@@ -3890,14 +3861,14 @@ 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 ();
- if (dlbaton->size == 0)
+ if (expr.empty ())
error (_("symbol \"%s\" is optimized out"), sym->natural_name ());
- compile_dwarf_expr_to_c (stream, result_name,
- sym, pc, gdbarch, registers_used, addr_size,
- dlbaton->data, dlbaton->data + dlbaton->size,
- dlbaton->per_cu, dlbaton->per_objfile);
+ compile_dwarf_expr_to_c (stream, result_name, sym, pc, gdbarch,
+ registers_used, addr_size, expr, dlbaton->per_cu,
+ dlbaton->per_objfile);
#else
gdb_assert_not_reached ("Compile support was disabled");
#endif
@@ -3926,16 +3897,11 @@ loclist_read_variable (struct symbol *symbol, const frame_info_ptr &frame)
{
struct dwarf2_loclist_baton *dlbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
- struct value *val;
- const gdb_byte *data;
- size_t size;
CORE_ADDR pc = frame ? get_frame_address_in_block (frame) : 0;
+ auto expr = dwarf2_find_location_expression (dlbaton, pc);
- data = dwarf2_find_location_expression (dlbaton, &size, pc);
- val = dwarf2_evaluate_loc_desc (symbol->type (), frame, data, size,
- dlbaton->per_cu, dlbaton->per_objfile);
-
- return val;
+ return dwarf2_evaluate_loc_desc (symbol->type (), frame, expr,
+ dlbaton->per_cu, dlbaton->per_objfile);
}
/* Read variable SYMBOL like loclist_read_variable at (callee) FRAME's function
@@ -3951,18 +3917,16 @@ loclist_read_variable_at_entry (struct symbol *symbol, const frame_info_ptr &fra
{
struct dwarf2_loclist_baton *dlbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
- const gdb_byte *data;
- size_t size;
CORE_ADDR pc;
if (frame == NULL || !get_frame_func_if_available (frame, &pc))
return value::allocate_optimized_out (symbol->type ());
- data = dwarf2_find_location_expression (dlbaton, &size, pc, true);
- if (data == NULL)
+ auto expr = dwarf2_find_location_expression (dlbaton, pc, true);
+ if (expr.empty ())
return value::allocate_optimized_out (symbol->type ());
- return value_of_dwarf_block_entry (symbol->type (), frame, data, size);
+ return value_of_dwarf_block_entry (symbol->type (), frame, expr);
}
/* Implementation of get_symbol_read_needs from
@@ -4088,9 +4052,10 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
paddress (gdbarch, high_reloc));
/* Now describe this particular location. */
- locexpr_describe_location_1 (symbol, low_reloc, stream, loc_ptr, length,
- addr_size, offset_size,
- dlbaton->per_cu, per_objfile);
+ locexpr_describe_location_1 (symbol, low_reloc, stream,
+ gdb::make_array_view (loc_ptr, length),
+ addr_size, offset_size, dlbaton->per_cu,
+ per_objfile);
gdb_printf (stream, "\n");
@@ -4106,16 +4071,14 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax,
{
struct dwarf2_loclist_baton *dlbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
- const gdb_byte *data;
- size_t size;
unsigned int addr_size = dlbaton->per_cu->addr_size ();
- data = dwarf2_find_location_expression (dlbaton, &size, ax->scope);
- if (size == 0)
+ auto expr = dwarf2_find_location_expression (dlbaton, ax->scope);
+ if (expr.empty ())
value->optimized_out = 1;
else
- dwarf2_compile_expr_to_ax (ax, value, addr_size, data, data + size,
- dlbaton->per_cu, dlbaton->per_objfile);
+ dwarf2_compile_expr_to_ax (ax, value, addr_size, expr, dlbaton->per_cu,
+ dlbaton->per_objfile);
}
/* symbol_computed_ops 'generate_c_location' method. */
@@ -4130,17 +4093,13 @@ loclist_generate_c_location (struct symbol *sym, string_file *stream,
struct dwarf2_loclist_baton *dlbaton
= (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (sym);
unsigned int addr_size = dlbaton->per_cu->addr_size ();
- const gdb_byte *data;
- size_t size;
+ auto expr = dwarf2_find_location_expression (dlbaton, pc);
- data = dwarf2_find_location_expression (dlbaton, &size, pc);
- if (size == 0)
+ if (expr.empty ())
error (_("symbol \"%s\" is optimized out"), sym->natural_name ());
- compile_dwarf_expr_to_c (stream, result_name,
- sym, pc, gdbarch, registers_used, addr_size,
- data, data + size,
- dlbaton->per_cu,
+ compile_dwarf_expr_to_c (stream, result_name, sym, pc, gdbarch,
+ registers_used, addr_size, expr, dlbaton->per_cu,
dlbaton->per_objfile);
#else
gdb_assert_not_reached ("Compile support was disabled");
diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h
index d175ba679412..192e53318d67 100644
--- a/gdb/dwarf2/loc.h
+++ b/gdb/dwarf2/loc.h
@@ -21,6 +21,7 @@
#define GDB_DWARF2_LOC_H
#include "gdbtypes.h"
+#include "dwarf2/attribute.h"
#include "dwarf2/expr.h"
struct symbol_computed_ops;
@@ -37,23 +38,16 @@ struct axs_value;
extern unsigned int entry_values_debug;
/* Find a particular location expression from a location list. */
-const gdb_byte *dwarf2_find_location_expression
- (const dwarf2_loclist_baton *baton,
- size_t *locexpr_length,
- CORE_ADDR pc,
- bool at_entry = false);
-
-/* Find the frame base information for FRAMEFUNC at PC. START is an
- out parameter which is set to point to the DWARF expression to
- compute. LENGTH is an out parameter which is set to the length of
- the DWARF expression. This throws an exception on error or if an
- expression is not found; the returned length will never be
- zero. */
-
-extern void func_get_frame_base_dwarf_block (struct symbol *framefunc,
- CORE_ADDR pc,
- const gdb_byte **start,
- size_t *length);
+gdb::array_view<const gdb_byte> dwarf2_find_location_expression
+ (const dwarf2_loclist_baton *baton, CORE_ADDR pc, bool at_entry = false);
+
+/* Find the frame base information for FRAMEFUNC at PC and return the
+ DWARF expression to compute.
+
+ Throw an exception if no expression is found. */
+
+gdb::array_view<const gdb_byte> func_get_frame_base_dwarf_block
+ (struct symbol *framefunc, CORE_ADDR pc);
/* A helper function to find the definition of NAME and compute its
value. Returns nullptr if the name is not found. */
@@ -72,13 +66,13 @@ call_site_parameter *dwarf_expr_reg_to_entry_parameter
dwarf2_per_objfile **per_objfile_return);
-/* Evaluate a location description, starting at DATA and with length
- SIZE, to find the current location of variable of TYPE in the context
- of FRAME. AS_LVAL defines if the resulting struct value is expected to
- be a value or a location description. */
+/* Evaluate the location description LOC_DESC to find the current location
+ of variable of TYPE in the context of FRAME. AS_LVAL defines if the
+ resulting struct value is expected to be a value or a location
+ description. */
value *dwarf2_evaluate_loc_desc (type *type, const frame_info_ptr &frame,
- const gdb_byte *data, size_t size,
+ gdb::array_view<const gdb_byte> loc_desc,
dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
bool as_lval = true);
@@ -132,8 +126,26 @@ void dwarf2_compile_property_to_c (string_file *stream,
struct dwarf2_locexpr_baton
{
- /* Pointer to the start of the location expression. Valid only if SIZE is
- not zero. */
+ /* 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)
+ {
+ 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
@@ -176,6 +188,10 @@ struct dwarf2_field_location_baton : public dwarf2_locexpr_baton
struct 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); }
+
/* The initial base address for the location list, based on the compilation
unit. */
unrelocated_addr base_address;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 1288c076aba1..cb20dcab6f41 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -5269,8 +5269,7 @@ dwarf2_compute_name (const char *name,
if (baton != NULL)
v = dwarf2_evaluate_loc_desc (type, NULL,
- baton->data,
- baton->size,
+ baton->expr (),
baton->per_cu,
baton->per_objfile);
else if (bytes != NULL)
@@ -8102,13 +8101,10 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
/* Keep NULL DWARF_BLOCK. */;
else if (attr->form_is_block ())
{
- struct dwarf2_locexpr_baton *dlbaton;
- struct dwarf_block *block = attr->as_block ();
+ dwarf2_locexpr_baton *dlbaton
+ = OBSTACK_ZALLOC (&objfile->objfile_obstack, dwarf2_locexpr_baton);
- dlbaton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_locexpr_baton);
- dlbaton->data = block->data;
- dlbaton->size = block->size;
+ dlbaton->set_expr (*attr->as_block ());
dlbaton->per_objfile = per_objfile;
dlbaton->per_cu = cu->per_cu;
@@ -8228,14 +8224,12 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
}
else
{
- struct dwarf_block *block = loc->as_block ();
+ auto block = loc->as_block ()->view ();
- parameter->u.dwarf_reg = dwarf_block_to_dwarf_reg
- (block->data, &block->data[block->size]);
+ parameter->u.dwarf_reg = dwarf_block_to_dwarf_reg (block);
if (parameter->u.dwarf_reg != -1)
parameter->kind = CALL_SITE_PARAMETER_DWARF_REG;
- else if (dwarf_block_to_sp_offset (gdbarch, block->data,
- &block->data[block->size],
+ else if (dwarf_block_to_sp_offset (gdbarch, block,
¶meter->u.fb_offset))
parameter->kind = CALL_SITE_PARAMETER_FB_OFFSET;
else
@@ -9389,8 +9383,9 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
else
dlbaton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_locexpr_baton);
- dlbaton->data = data_member_location_attr->as_block ()->data;
- dlbaton->size = data_member_location_attr->as_block ()->size;
+
+ dlbaton->set_expr (*data_member_location_attr->as_block ());
+
/* 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. */
@@ -9423,8 +9418,8 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
dwarf2_locexpr_baton *dlbaton
= OBSTACK_ZALLOC (&per_objfile->objfile->objfile_obstack,
dwarf2_locexpr_baton);
- dlbaton->data = data_bit_offset_attr->as_block ()->data;
- dlbaton->size = data_bit_offset_attr->as_block ()->size;
+
+ dlbaton->set_expr (*data_bit_offset_attr->as_block ());
dlbaton->per_objfile = per_objfile;
dlbaton->per_cu = cu->per_cu;
@@ -11755,7 +11750,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;
- gdb_byte *ptr;
unsigned int cu_off;
enum bfd_endian byte_order = gdbarch_byte_order (objfile->arch ());
LONGEST offset = 0;
@@ -11771,18 +11765,19 @@ mark_common_block_symbol_computed (struct symbol *sym,
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
- baton->size = 5 /* DW_OP_call4 */ + 1 /* DW_OP_plus */;
+ std::size_t size = 5 /* DW_OP_call4 */ + 1 /* DW_OP_plus */;
if (member_loc->form_is_constant ())
{
offset = member_loc->unsigned_constant ().value_or (0);
- baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size;
+ size += 1 /* DW_OP_addr */ + cu->header.addr_size;
}
else
- baton->size += member_loc->as_block ()->size;
+ size += member_loc->as_block ()->size;
- ptr = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, baton->size);
- baton->data = ptr;
+ gdb_byte *const start
+ = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, size);
+ gdb_byte *ptr = start;
*ptr++ = DW_OP_call4;
cu_off = common_die->sect_off - cu->per_cu->sect_off ();
@@ -11805,7 +11800,9 @@ mark_common_block_symbol_computed (struct symbol *sym,
}
*ptr++ = DW_OP_plus;
- gdb_assert (ptr - baton->data == baton->size);
+ gdb_assert (ptr - start == size);
+
+ baton->set_expr (gdb::make_array_view (start, size));
SYMBOL_LOCATION_BATON (sym) = baton;
sym->set_loc_class_index (dwarf2_locexpr_index);
@@ -12787,13 +12784,10 @@ get_mpz_for_rational (dwarf2_cu *cu, gdb_mpz *value, attribute *attr)
*value = gdb_mpz (1);
}
else if (attr->form_is_block ())
- {
- dwarf_block *blk = attr->as_block ();
- value->read (gdb::make_array_view (blk->data, blk->size),
- bfd_big_endian (cu->per_objfile->objfile->obfd.get ())
- ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE,
- true);
- }
+ value->read (attr->as_block ()->view (),
+ (bfd_big_endian (cu->per_objfile->objfile->obfd.get ())
+ ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE),
+ true);
else
{
/* Rational constants for Ada are always unsigned. */
@@ -13444,8 +13438,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
else
block = *attr->as_block ();
- baton->locexpr.size = block.size;
- baton->locexpr.data = block.data;
+ baton->locexpr.set_expr (block);
switch (attr->name)
{
case DW_AT_string_length:
@@ -13501,9 +13494,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
baton->property_type = die_type (target_die, target_cu);
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.per_objfile = per_objfile;
- struct dwarf_block *block = target_attr->as_block ();
- baton->locexpr.size = block->size;
- baton->locexpr.data = block->data;
+ baton->locexpr.set_expr (*target_attr->as_block ());
baton->locexpr.is_reference = true;
prop->set_locexpr (baton);
gdb_assert (prop->baton () != NULL);
@@ -16018,9 +16009,9 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
(*baton)->per_cu = cu->per_cu;
gdb_assert ((*baton)->per_cu);
- (*baton)->size = 2 + cu_header->addr_size;
- data = (gdb_byte *) obstack_alloc (obstack, (*baton)->size);
- (*baton)->data = data;
+ 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));
data[0] = DW_OP_addr;
store_unsigned_integer (&data[1], cu_header->addr_size,
@@ -17078,23 +17069,17 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
if (!attr)
{
- /* DWARF: "If there is no such attribute, then there is no effect.".
- DATA is ignored if SIZE is 0. */
-
- retval.data = NULL;
- retval.size = 0;
+ /* 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;
CORE_ADDR pc = get_frame_pc ();
- size_t size;
fill_in_loclist_baton (cu, &loclist_baton, attr);
- retval.data = dwarf2_find_location_expression (&loclist_baton,
- &size, pc);
- retval.size = size;
+ retval.set_expr (dwarf2_find_location_expression (&loclist_baton, pc));
}
else
{
@@ -17104,9 +17089,7 @@ 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));
- struct dwarf_block *block = attr->as_block ();
- retval.data = block->data;
- retval.size = block->size;
+ retval.set_expr (*attr->as_block ());
}
retval.per_objfile = per_objfile;
retval.per_cu = cu->per_cu;
@@ -17930,9 +17913,7 @@ 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. */
- struct dwarf_block *block = attr->as_block ();
- baton->size = block->size;
- baton->data = block->data;
+ baton->set_expr (*attr->as_block ());
}
else
{
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 7b1a82386131..5a3db47d84fd 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1154,12 +1154,11 @@ struct symbol_computed_ops
struct symbol_block_ops
{
- /* Fill in *START and *LENGTH with DWARF block data of function
- FRAMEFUNC valid for inferior context address PC. Set *LENGTH to
- zero if such location is not valid for PC; *START is left
- uninitialized in such case. */
- void (*find_frame_base_location) (struct symbol *framefunc, CORE_ADDR pc,
- const gdb_byte **start, size_t *length);
+ /* Return the DWARF block data of function FRAMEFUNC valid for inferior
+ context address PC. Return an empty view if no such location is
+ valid for PC. */
+ gdb::array_view<const gdb_byte> (*find_frame_base_location)
+ (struct symbol *framefunc, CORE_ADDR pc);
/* Return the frame base address. FRAME is the frame for which we want to
compute the base address while FRAMEFUNC is the symbol for the
base-commit: 237eed6d652aa1b341c913d37142d060eb9481c4
--
2.54.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] gdb/dwarf2: pass around DWARF expressions as gdb::array_view
2026-04-29 0:55 [PATCH] gdb/dwarf2: pass around DWARF expressions as gdb::array_view simon.marchi
@ 2026-05-01 16:35 ` Tom Tromey
2026-05-02 4:14 ` Simon Marchi
0 siblings, 1 reply; 3+ messages in thread
From: Tom Tromey @ 2026-05-01 16:35 UTC (permalink / raw)
To: simon.marchi; +Cc: gdb-patches, Simon Marchi
>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:
Simon> This patch converts a bunch of functions to take or return DWARF
Simon> expressions as `gdb::array_view<const gdb_byte>`, instead of raw pointer
Simon> and size. It doesn't do any non-trivial change to function
Simon> implementations, but the idea is that we could change them (for example
Simon> dwarf_expr_context::execute_stack_op) to operate on the array view
Simon> directly, giving us bounds checking when building in debug mode. But
Simon> that is not as trivial.
I skimmed this and it seems fine to me.
Approved-By: Tom Tromey <tom@tromey.com>
Simon> This patch also doesn't change structure fields to array_views (for
Simon> instance, dwarf2_loclist_baton), because that would make them
Simon> non-trivially constructible, and we'd (technically) need to change how
Simon> they are allocated.
I thought this sounded backward but I suppose it refers to the fact that
these are stored in a union inside dwarf2_property_baton.
A fix for that might be to use a class hierarchy rather than a union.
thanks,
Tom
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] gdb/dwarf2: pass around DWARF expressions as gdb::array_view
2026-05-01 16:35 ` Tom Tromey
@ 2026-05-02 4:14 ` Simon Marchi
0 siblings, 0 replies; 3+ messages in thread
From: Simon Marchi @ 2026-05-02 4:14 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches, Simon Marchi
On 2026-05-01 12:35, Tom Tromey wrote:
>>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:
>
> Simon> This patch converts a bunch of functions to take or return DWARF
> Simon> expressions as `gdb::array_view<const gdb_byte>`, instead of raw pointer
> Simon> and size. It doesn't do any non-trivial change to function
> Simon> implementations, but the idea is that we could change them (for example
> Simon> dwarf_expr_context::execute_stack_op) to operate on the array view
> Simon> directly, giving us bounds checking when building in debug mode. But
> Simon> that is not as trivial.
>
> I skimmed this and it seems fine to me.
> Approved-By: Tom Tromey <tom@tromey.com>
Thanks, pushed.
> Simon> This patch also doesn't change structure fields to array_views (for
> Simon> instance, dwarf2_loclist_baton), because that would make them
> Simon> non-trivially constructible, and we'd (technically) need to change how
> Simon> they are allocated.
>
> I thought this sounded backward but I suppose it refers to the fact that
> these are stored in a union inside dwarf2_property_baton.
>
> A fix for that might be to use a class hierarchy rather than a union.
Yes, I meant that we would start to have to call "new" on them. They
are currently allocated with XOBNEW, which is disallows on
non-trivially-constructible types. I guess that's what
allocate_on_obstack is for? Anyway, I had to stop somewhere with this
patch otherwise the scope creeps too far.
Simon
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-02 4:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-29 0:55 [PATCH] gdb/dwarf2: pass around DWARF expressions as gdb::array_view simon.marchi
2026-05-01 16:35 ` Tom Tromey
2026-05-02 4:14 ` Simon Marchi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox