From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id caSRGO1Y8WmJ+AEAWB0awg (envelope-from ) for ; Tue, 28 Apr 2026 21:03:41 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=polymtl.ca header.i=@polymtl.ca header.a=rsa-sha256 header.s=oct2025 header.b=ZktnckPw; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 5C7181E0BA; Tue, 28 Apr 2026 21:03:41 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id A54E61E093 for ; Tue, 28 Apr 2026 21:03:38 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id DB3C64BBC0EE for ; Wed, 29 Apr 2026 01:03:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DB3C64BBC0EE Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=polymtl.ca header.i=@polymtl.ca header.a=rsa-sha256 header.s=oct2025 header.b=ZktnckPw Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 4818E4BBC0C9 for ; Wed, 29 Apr 2026 01:03:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4818E4BBC0C9 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4818E4BBC0C9 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777424580; cv=none; b=dUTxZoEGTZIU/AGLMRZAEKXa9xge3E11OpS0z7sgiPxQn1iw+woihBzcmS89c2H2s3B490YSOwJGuMSOaUrF4QcTxziD7H4vJmuLUnIxXNqbQnd5ILX7w3ATM9atlIL3rKpZUEV1yjw3D2yvNcYeglQpKyZvxparUDDEj2sUFcc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777424580; c=relaxed/simple; bh=6cwTbXoM9rF2j1Z1RBLuMiNIoXOVRRvc0Abh5NVSbTE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=FRrXr51U0vyyHMoeCmpHDHXVB3J5IoILPRdJzrEcYObEbjkNW7SrPmNkbNmu8FfMqfeZ+w2xT5uHTv8lGvpXz8lau17kL7OlmJx4T+3yeHuu5lAG1fhUIubG7r8rnhZJiv7Tt1kduVs7joO3RYKEyspCLTBds/UKGa+ChXEQW1s= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4818E4BBC0C9 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 63T12rE9113949 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 28 Apr 2026 21:02:58 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 63T12rE9113949 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=oct2025; t=1777424578; bh=oIOHeTVLDr+/xiKHfqhPhAXntN1OWvK9Xu4qy2wxgk4=; h=From:To:Cc:Subject:Date:From; b=ZktnckPwGQ3evw+PVlE0j3cWWMrOW52p41tzxf8BoWn7L7qNjo8/AeLBAxB6vDKL6 X4RIDl7vEFe3y1ZjLk4RYwSyW1CgssQc9tUH2JZrXSlXeQVYb/WTbzw4qLINuLMf/s x9S+XLKR8KMp9iEve98Wmsl36OikmnQGvqY/blREUOVITvMnG1dfcRF/jffrIvtYV1 H+G7p5OmOw/EutuHN1xIjW865k2YLxeaCTvnxtDLwgfMaXLMOFFk8AYPnJ+0Bby53A r1zMaoU9ljztegIeYW0SegSpqadasGqRLTLU0BDaSP5XNatjvMZGOBaxn158nYh8Dh MB0ldq2btD5hA== Received: by simark.ca (Postfix) id 753CB1E093; Tue, 28 Apr 2026 21:02:53 -0400 (EDT) From: simon.marchi@polymtl.ca To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH] gdb/dwarf2: pass around DWARF expressions as gdb::array_view Date: Tue, 28 Apr 2026 20:55:42 -0400 Message-ID: <20260429010252.927650-1-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.54.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 29 Apr 2026 01:02:53 +0000 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org From: Simon Marchi This patch converts a bunch of functions to take or return DWARF expressions as `gdb::array_view`, 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 *info, std::vector *to_do, enum bfd_endian byte_order, unsigned int addr_size, - const gdb_byte *op_ptr, const gdb_byte *op_end) + gdb::array_view 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 expr, int initial_depth, std::vector *info) { std::vector 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 ®isters_used, unsigned int addr_size, - const gdb_byte *op_ptr, const gdb_byte *op_end, + gdb::array_view 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 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 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 ®isters_used, unsigned int addr_size, - const gdb_byte *op_ptr, const gdb_byte *op_end, + gdb::array_view 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 ®isters_used, unsigned int addr_size, - const gdb_byte *op_ptr, const gdb_byte *op_end, + gdb::array_view 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 ®isters_used, unsigned int addr_size, - const gdb_byte *op_ptr, - const gdb_byte *op_end, + gdb::array_view 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 ®isters_used, unsigned int addr_size, - const gdb_byte *op_ptr, - const gdb_byte *op_end, + gdb::array_view 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 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 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 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 +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 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 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 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 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 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 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 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 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 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 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 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 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 block, CORE_ADDR *deref_size_return); -/* If block, CORE_ADDR *fb_offset_return); -/* If 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); - - -/* 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 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 &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 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 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 &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 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 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 +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 +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 +func_get_frame_base_dwarf_block (struct symbol *framefunc, CORE_ADDR pc) { + gdb::array_view 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 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 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 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 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 expr, if (symbol_needs != SYMBOL_NEEDS_FRAME) { gdbarch *arch = baton.per_objfile->objfile->arch (); - gdb::array_view 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 expr, if (symbol_needs != SYMBOL_NEEDS_FRAME) { gdbarch *arch = baton.per_objfile->objfile->arch (); - gdb::array_view 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 expr, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile) { - gdbarch *arch = expr->gdbarch; + gdbarch *arch = ax->gdbarch; std::vector 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 offsets (op_end - op_ptr, -1); + std::vector 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 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 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 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 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 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 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 expr () const + { return gdb::make_array_view (data, size); } + + /* Set the expression in this baton from EXPR. */ + void set_expr (gdb::array_view 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 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 ()); } 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 (*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