From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id CDLlNQV8zl+QTQAAWB0awg (envelope-from ) for ; Mon, 07 Dec 2020 14:01:25 -0500 Received: by simark.ca (Postfix, from userid 112) id C7C8F1F096; Mon, 7 Dec 2020 14:01:25 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,RDNS_NONE, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id A2B5D1EF4B for ; Mon, 7 Dec 2020 14:01:23 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E6ABD39450D0; Mon, 7 Dec 2020 19:01:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E6ABD39450D0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1607367682; bh=emuhBN6cADyfhSV/KXcyxA4O9cDRy2MFGJm+PtFY2A4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=a9oI19gAjXF0Ih/uLIf7JsURjRugaSeX+pyzZF4wOFT9G2mJlmDAr0Wxk0oDziLJ0 jXdNbvL8dSoV/xU53cSak8HJfA+Pqm98QIoptm4Vdx4m4j3KjIgLLa2U3SaUIh5sWe 41nGJFvDi+aqwGKh9LmMiiIG9YrnN8oQ9Zuu6SXM= Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2049.outbound.protection.outlook.com [40.107.244.49]) by sourceware.org (Postfix) with ESMTPS id AA63039518A8 for ; Mon, 7 Dec 2020 19:01:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org AA63039518A8 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PyZOokEe9gBR2OwWWMNaU5krLUJrYjtrKqU1azunD7wR8hLeXhLmMG6IwkPZZMQWTxfof3C011sBkzrW3zDRZJtMV+5Em5P7EE6za/K5IxH7b6Q7Qz489B7xRXzONzpCLcHBJkDO5A4moMnYEq7NBP9KpE+0ZBbhyZi2ItUTHZww9jO7BxMZ4YUF7lqJ5v4ChyOFaNMfu7FScRz373rUFECd5C564McS1CNEwS4uMdRA6BEyOJD0AiwRn6IGWT2sOfDvmHZiD5XHaBIw1hZu2yfKSYjluKY+TqY0cWpIwtPP8oItQsIBbkCjWpfFRhth8Mt5UZA0lGtBdxrK3EHUWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=emuhBN6cADyfhSV/KXcyxA4O9cDRy2MFGJm+PtFY2A4=; b=fsRL6bc40RnhU+SYfoWuVPEwY+vvESjjvuylLcTN7Fg3S3cUVCmEOVNUuwmJ8lmPUA80KmTbdOj7fV/rqf/Nc+jcNsbNXYu1gEHdgiJnX648gpCE0kdaLwid2j9yAjp7rJRVR/rWe247lLz5ogBxnorHMvhr1csWDiEFBeCpW0oUCB1dkiFG18Tjd7kwpQdqA9RhyiP6YkoW/IKujwylEdPs11dWlF3vzIdutQRtC4m6smelE4/mbipYpiM7y3R3/DiL0WidRU3fh32h7SITglieSwM4nDzw9wjLmT0ku0ZyCoVbH9INPphWDln508rgmog28AmrYS3U+0jcv57+Wg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none Received: from DM6PR12MB2762.namprd12.prod.outlook.com (2603:10b6:5:45::15) by DM6PR12MB4561.namprd12.prod.outlook.com (2603:10b6:5:2ac::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3632.18; Mon, 7 Dec 2020 19:01:09 +0000 Received: from DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::6841:61df:984b:b3c]) by DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::6841:61df:984b:b3c%3]) with mapi id 15.20.3632.021; Mon, 7 Dec 2020 19:01:09 +0000 To: gdb-patches@sourceware.org Subject: [PATCH 13/30] Make DWARF evaluator return a single struct value Date: Mon, 7 Dec 2020 19:00:14 +0000 Message-Id: <20201207190031.13341-14-Zoran.Zaric@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201207190031.13341-1-Zoran.Zaric@amd.com> References: <20201207190031.13341-1-Zoran.Zaric@amd.com> Content-Type: text/plain X-Originating-IP: [2a00:23c7:5a85:6801:5c7:2db6:d2c2:ae4e] X-ClientProxiedBy: AM4PR0101CA0053.eurprd01.prod.exchangelabs.com (2603:10a6:200:41::21) To DM6PR12MB2762.namprd12.prod.outlook.com (2603:10b6:5:45::15) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2a00:23c7:5a85:6801:5c7:2db6:d2c2:ae4e) by AM4PR0101CA0053.eurprd01.prod.exchangelabs.com (2603:10a6:200:41::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3632.17 via Frontend Transport; Mon, 7 Dec 2020 19:01:07 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 806321d1-ad17-4a58-0285-08d89ae27520 X-MS-TrafficTypeDiagnostic: DM6PR12MB4561: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:9508; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: WXq5sD1ZpQRbZa7sU7nZeZKyx3bbelhHAJp798pranAqRzoiIKhCwozqasKQWLCu6cher872ygfwFNX8YMorq7ptrlvr45BAvNVVY2kvjqG/mVx8uMNGYSByzty/pGmmU8xdF1BbCrZBfvOcnE7UH2GRrcpgBa3mqCxH6837HU+ZpVDlGnt7DiahyWkQBWYDcvuOnQBFImsWzlk90qcWwqespxDHIGucyzEfLCtDTE2WJnx431wAC0JeUvtFTuTcQ2QrUHWMfQ+sUolmS3KDT4ThQx6nq0MHK3K/UmgNUAajXl4fT4poXZO5vcUjdp89TPob3UlBg/D4ySNR5IrJ+theB/M0US8eYKvtElm1hZAuyYs6wh0Ep8SLqLJkCmjJ X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM6PR12MB2762.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(376002)(346002)(39860400002)(366004)(136003)(396003)(1076003)(30864003)(83380400001)(86362001)(6506007)(4326008)(69590400008)(52116002)(36756003)(2906002)(6512007)(8676002)(6486002)(16526019)(2616005)(66946007)(66476007)(66556008)(6916009)(5660300002)(186003)(8936002)(478600001)(6666004)(316002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?yrBO7/sfwuchYBN5I719ogXU75bCNakuxQ2p9RgtIKWmlUm4P2ALnqVEue2v?= =?us-ascii?Q?YZCxZsiKHmF//txO2MRQlD1PdSb8Jni6jHyz4Qy1RJXX1PF95OIUGlnF+srf?= =?us-ascii?Q?Ti1HR7Di0UhXTJazUAaOyd5v/kzs3Edy9bGVVi/pju3ZScPhQVZmRt7M1q5C?= =?us-ascii?Q?80fZIEQfEvFa63Fvx5cpB5HNuWfqZeni755Gut8D2fQvUNI6HZ8F2vajy6fw?= =?us-ascii?Q?+2dQCNBG9uTKx8OsSaiQwSMQKV8aeywSHt0t8wvG4V1iPxP0eU21r54wTKBX?= =?us-ascii?Q?cZOT0zqW+EP3O2cBRPMAR5L3qTYWRG+22BEeFWKlVTkr4C2b2PZ3Md/K6xfx?= =?us-ascii?Q?BpxJN2cz5RiuHuDKsu93lf9UNI6hxGJ7jAdMmsmt3VtYj3QIEofiNJFG/vzF?= =?us-ascii?Q?KAMUS4OCAl9KoUXxK2yCke/MaspHfabv0le/2yK/XLsVSXHqv86z0IEKCVSB?= =?us-ascii?Q?tRLUdiaN3gKf1SjdMWR5X4eRnf06toume+FTdFMVqbRJ2x+0NB9w3F+Yw3UI?= =?us-ascii?Q?UD1MMbTr8cOErq2oNa84TTAs3arJtfj7hQlIbHHKDuqNOdQw2btzxwu1tu79?= =?us-ascii?Q?feVIRYXIymjXdfZk9BOKMyN2bfhyhaI4rXrp23RCStoKFj8PRt+PcOxxji+t?= =?us-ascii?Q?aEiRvsNTq4NOrvUKIygTXGXMhg66T0xTPO6u5jVjOlEzXPOTDistUYGIuzrI?= =?us-ascii?Q?9QvfmpQK4sKGM+LCanPa5KX+d1HVhczPKS2bf0uR9v89tBYwlDujIvsxtNvE?= =?us-ascii?Q?KcxKLPTQH6+KXmYRmyIOutu4kiTSazLVmYXR55JEzdGAw4FqwvYGJPaRcXch?= =?us-ascii?Q?NFnNhuzXbxA14QR/nqHGplQg/jMutF0+1Dau5H4V0a7ebc/dkR4Lb3R4lmXE?= =?us-ascii?Q?Dhey9R0XUAe26tg+rc7HRDr9W1GOQ1ABerv9/I3KXvk5suDAA+eX5Uzjczj4?= =?us-ascii?Q?4RP3wun5otmJZhAe7jpd0pq5zVVsoJG9i9KCxsbrMO13Xdf/igtbPCmDps5M?= =?us-ascii?Q?B7NgHHB8JmTVpA2OY0YjAC5xCwt/3ul5rpyBsAKuZgyCCdulkuivy26IWV8m?= =?us-ascii?Q?sF6HXUiZ?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthSource: DM6PR12MB2762.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Dec 2020 19:01:08.6366 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: 806321d1-ad17-4a58-0285-08d89ae27520 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: o30a0g1Y78VFucO9v+qJe8D7XagmGPfd1n8rm8i+tRoU648Gi8+pZaqcyIV6BfQ0Gk4HebjrN8jPD/UJTKwa6A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4561 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Zoran Zaric via Gdb-patches Reply-To: Zoran Zaric Cc: Zoran Zaric Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" From: Zoran Zaric The patch is addressing the issue of class users writing and reading the internal data of the dwarf_expr_context class. At this point, all conditions are met for the DWARF evaluator to return an evaluation result in a form of a single struct value object. gdb/ChangeLog: * dwarf2/expr.c (pieced_value_funcs): Chenge to static function. (allocate_piece_closure): Change to static function. (dwarf_expr_context::fetch_result): New function. * dwarf2/expr.h (struct piece_closure): Remove declaration. (struct dwarf_expr_context): fetch_result new declaration. fetch, fetch_address and fetch_in_stack_memory members move to private. (allocate_piece_closure): Remove. * dwarf2/frame.c (execute_stack_op): Change to use fetch_result. * dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Change to use fetch_result. (dwarf2_locexpr_baton_eval): Change to use fetch_result. --- gdb/dwarf2/expr.c | 163 +++++++++++++++++++++++++++++++++++++- gdb/dwarf2/expr.h | 25 +++--- gdb/dwarf2/frame.c | 19 ++--- gdb/dwarf2/loc.c | 193 ++++++--------------------------------------- 4 files changed, 201 insertions(+), 199 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 675f044e6f..7f8e8134a4 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -117,9 +117,10 @@ struct piece_closure struct frame_id frame_id; }; -/* See expr.h. */ +/* Allocate a closure for a value formed from separately-described + PIECES. */ -struct piece_closure * +static struct piece_closure * allocate_piece_closure (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile, std::vector &&pieces, @@ -622,7 +623,7 @@ free_pieced_value_closure (struct value *v) } /* Functions for accessing a variable described by DW_OP_piece. */ -const struct lval_funcs pieced_value_funcs = { +static const struct lval_funcs pieced_value_funcs = { read_pieced_value, write_pieced_value, indirect_pieced_value, @@ -892,6 +893,162 @@ dwarf_expr_context::push_dwarf_reg_entry_value this->eval (data_src, size); } +/* See expr.h. */ + +struct value * +dwarf_expr_context::fetch_result (struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) +{ + struct value *retval = nullptr; + + if (type == nullptr) + type = address_type (); + + if (subobj_type == nullptr) + subobj_type = type; + + if (this->pieces.size () > 0) + { + struct piece_closure *c; + ULONGEST bit_size = 0; + + for (dwarf_expr_piece &piece : this->pieces) + bit_size += piece.size; + /* Complain if the expression is larger than the size of the + outer type. */ + if (bit_size > 8 * TYPE_LENGTH (type)) + invalid_synthetic_pointer (); + + c = allocate_piece_closure (this->per_cu, this->per_objfile, + std::move (this->pieces), this->frame); + retval = allocate_computed_value (subobj_type, + &pieced_value_funcs, c); + set_value_offset (retval, subobj_offset); + } + else + { + switch (this->location) + { + case DWARF_VALUE_REGISTER: + { + int dwarf_regnum + = longest_to_int (value_as_long (this->fetch (0))); + int gdb_regnum = dwarf_reg_to_regnum_or_error (this->gdbarch, + dwarf_regnum); + + if (subobj_offset != 0) + error (_("cannot use offset on synthetic pointer to register")); + + gdb_assert (this->frame != NULL); + + retval = value_from_register (subobj_type, gdb_regnum, + this->frame); + if (value_optimized_out (retval)) + { + struct value *tmp; + + /* This means the register has undefined value / was + not saved. As we're computing the location of some + variable etc. in the program, not a value for + inspecting a register ($pc, $sp, etc.), return a + generic optimized out value instead, so that we show + instead of . */ + tmp = allocate_value (subobj_type); + value_contents_copy (tmp, 0, retval, 0, + TYPE_LENGTH (subobj_type)); + retval = tmp; + } + } + break; + + case DWARF_VALUE_MEMORY: + { + struct type *ptr_type; + CORE_ADDR address = this->fetch_address (0); + bool in_stack_memory = this->fetch_in_stack_memory (0); + + /* DW_OP_deref_size (and possibly other operations too) may + create a pointer instead of an address. Ideally, the + pointer to address conversion would be performed as part + of those operations, but the type of the object to + which the address refers is not known at the time of + the operation. Therefore, we do the conversion here + since the type is readily available. */ + + switch (subobj_type->code ()) + { + case TYPE_CODE_FUNC: + case TYPE_CODE_METHOD: + ptr_type = builtin_type (this->gdbarch)->builtin_func_ptr; + break; + default: + ptr_type = builtin_type (this->gdbarch)->builtin_data_ptr; + break; + } + address = value_as_address (value_from_pointer (ptr_type, address)); + + retval = value_at_lazy (subobj_type, + address + subobj_offset); + if (in_stack_memory) + set_value_stack (retval, 1); + } + break; + + case DWARF_VALUE_STACK: + { + struct value *value = this->fetch (0); + size_t n = TYPE_LENGTH (value_type (value)); + size_t len = TYPE_LENGTH (subobj_type); + size_t max = TYPE_LENGTH (type); + + if (subobj_offset + len > max) + invalid_synthetic_pointer (); + + retval = allocate_value (subobj_type); + + /* The given offset is relative to the actual object. */ + if (gdbarch_byte_order (this->gdbarch) == BFD_ENDIAN_BIG) + subobj_offset += n - max; + + memcpy (value_contents_raw (retval), + value_contents_all (value) + subobj_offset, len); + } + break; + + case DWARF_VALUE_LITERAL: + { + bfd_byte *contents; + size_t n = TYPE_LENGTH (subobj_type); + + if (subobj_offset + n > this->len) + invalid_synthetic_pointer (); + + retval = allocate_value (subobj_type); + contents = value_contents_raw (retval); + memcpy (contents, this->data + subobj_offset, n); + } + break; + + case DWARF_VALUE_OPTIMIZED_OUT: + retval = allocate_optimized_out_value (subobj_type); + break; + + /* DWARF_VALUE_IMPLICIT_POINTER was converted to a pieced + operation by execute_stack_op. */ + case DWARF_VALUE_IMPLICIT_POINTER: + /* DWARF_VALUE_OPTIMIZED_OUT can't occur in this context -- + it can only be encountered when making a piece. */ + default: + internal_error (__FILE__, __LINE__, _("invalid location type")); + } + } + + set_value_initialized (retval, this->initialized); + + return retval; +} + /* Require that TYPE be an integral type; throw an exception if not. */ static void diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index 1dee2249a0..b7605ffd28 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -26,7 +26,6 @@ #include "gdbtypes.h" struct dwarf2_per_objfile; -struct piece_closure; /* The location of a value. */ enum dwarf_value_location @@ -125,9 +124,13 @@ struct dwarf_expr_context void push_address (CORE_ADDR value, bool in_stack_memory); void eval (const gdb_byte *addr, size_t len); - struct value *fetch (int n); - CORE_ADDR fetch_address (int n); - bool fetch_in_stack_memory (int n); + + /* Fetch the result of the expression evaluation in a form of + a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET + describe the source level representation of that result. */ + struct value *fetch_result (struct type *type = nullptr, + struct type *subobj_type = nullptr, + LONGEST subobj_offset = 0); /* The stack of values. */ std::vector stack; @@ -207,6 +210,9 @@ struct dwarf_expr_context void add_piece (ULONGEST size, ULONGEST offset); void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end); void pop (); + struct value *fetch (int n); + CORE_ADDR fetch_address (int n); + bool fetch_in_stack_memory (int n); /* Return the location expression for the frame base attribute, in START and LENGTH. The result must be live until the current @@ -301,15 +307,4 @@ extern const gdb_byte *safe_read_sleb128 (const gdb_byte *buf, extern const gdb_byte *safe_skip_leb128 (const gdb_byte *buf, const gdb_byte *buf_end); -extern const struct lval_funcs pieced_value_funcs; - -/* Allocate a closure for a value formed from separately-described - PIECES. */ - -struct piece_closure *allocate_piece_closure - (dwarf2_per_cu_data *per_cu, - dwarf2_per_objfile *per_objfile, - std::vector &&pieces, - struct frame_info *frame); - #endif /* dwarf2expr.h */ diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index 9081ec0c92..039990dea3 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -228,8 +228,6 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, struct frame_info *this_frame, CORE_ADDR initial, int initial_in_stack_memory, dwarf2_per_objfile *per_objfile) { - CORE_ADDR result; - dwarf_expr_context ctx (per_objfile); scoped_value_mark free_values; @@ -241,18 +239,13 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, ctx.push_address (initial, initial_in_stack_memory); ctx.eval (exp, len); - if (ctx.location == DWARF_VALUE_MEMORY) - result = ctx.fetch_address (0); - else if (ctx.location == DWARF_VALUE_REGISTER) - result = read_addr_from_reg (this_frame, value_as_long (ctx.fetch (0))); + CORE_ADDR result; + struct value *result_val = ctx.fetch_result (); + + if (VALUE_LVAL (result_val) == lval_memory) + result = value_address (result_val); else - { - /* This is actually invalid DWARF, but if we ever do run across - it somehow, we might as well support it. So, instead, report - it as unimplemented. */ - error (_("\ -Not implemented: computing unwound register using explicit value operator")); - } + result = value_as_address (result_val); return result; } diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index 2f75b380a2..90ab2077c6 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1457,6 +1457,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, try { ctx.eval (data, size); + retval = ctx.fetch_result (type, subobj_type, + subobj_byte_offset); } catch (const gdb_exception_error &ex) { @@ -1479,155 +1481,15 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, throw; } - if (ctx.pieces.size () > 0) - { - struct piece_closure *c; - ULONGEST bit_size = 0; - - for (dwarf_expr_piece &piece : ctx.pieces) - bit_size += piece.size; - /* Complain if the expression is larger than the size of the - outer type. */ - if (bit_size > 8 * TYPE_LENGTH (type)) - invalid_synthetic_pointer (); - - c = allocate_piece_closure (per_cu, per_objfile, std::move (ctx.pieces), - frame); - /* We must clean up the value chain after creating the piece - closure but before allocating the result. */ - free_values.free_to_mark (); - retval = allocate_computed_value (subobj_type, - &pieced_value_funcs, c); - set_value_offset (retval, subobj_byte_offset); - } - else - { - switch (ctx.location) - { - case DWARF_VALUE_REGISTER: - { - struct gdbarch *arch = get_frame_arch (frame); - int dwarf_regnum - = longest_to_int (value_as_long (ctx.fetch (0))); - int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, dwarf_regnum); - - if (subobj_byte_offset != 0) - error (_("cannot use offset on synthetic pointer to register")); - free_values.free_to_mark (); - retval = value_from_register (subobj_type, gdb_regnum, frame); - if (value_optimized_out (retval)) - { - struct value *tmp; - - /* This means the register has undefined value / was - not saved. As we're computing the location of some - variable etc. in the program, not a value for - inspecting a register ($pc, $sp, etc.), return a - generic optimized out value instead, so that we show - instead of . */ - tmp = allocate_value (subobj_type); - value_contents_copy (tmp, 0, retval, 0, - TYPE_LENGTH (subobj_type)); - retval = tmp; - } - } - break; - - case DWARF_VALUE_MEMORY: - { - struct type *ptr_type; - CORE_ADDR address = ctx.fetch_address (0); - bool in_stack_memory = ctx.fetch_in_stack_memory (0); - - /* DW_OP_deref_size (and possibly other operations too) may - create a pointer instead of an address. Ideally, the - pointer to address conversion would be performed as part - of those operations, but the type of the object to - which the address refers is not known at the time of - the operation. Therefore, we do the conversion here - since the type is readily available. */ - - switch (subobj_type->code ()) - { - case TYPE_CODE_FUNC: - case TYPE_CODE_METHOD: - ptr_type = builtin_type (ctx.gdbarch)->builtin_func_ptr; - break; - default: - ptr_type = builtin_type (ctx.gdbarch)->builtin_data_ptr; - break; - } - address = value_as_address (value_from_pointer (ptr_type, address)); - - free_values.free_to_mark (); - retval = value_at_lazy (subobj_type, - address + subobj_byte_offset); - if (in_stack_memory) - set_value_stack (retval, 1); - } - break; - - case DWARF_VALUE_STACK: - { - struct value *value = ctx.fetch (0); - size_t n = TYPE_LENGTH (value_type (value)); - size_t len = TYPE_LENGTH (subobj_type); - size_t max = TYPE_LENGTH (type); - gdbarch *objfile_gdbarch = per_objfile->objfile->arch (); - - if (subobj_byte_offset + len > max) - invalid_synthetic_pointer (); - - /* Preserve VALUE because we are going to free values back - to the mark, but we still need the value contents - below. */ - value_ref_ptr value_holder = value_ref_ptr::new_reference (value); - free_values.free_to_mark (); - - retval = allocate_value (subobj_type); - - /* The given offset is relative to the actual object. */ - if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG) - subobj_byte_offset += n - max; + /* We need to clean up all the values that are not needed any more. + The problem with a value_ref_ptr class is that it disconnects the + RETVAL from the value garbage collection, so we need to make + a copy of that value on the stack to keep everything consistent. + The value_ref_ptr will clean up after itself at the end of this block. */ + value_ref_ptr value_holder = value_ref_ptr::new_reference (retval); + free_values.free_to_mark (); - memcpy (value_contents_raw (retval), - value_contents_all (value) + subobj_byte_offset, len); - } - break; - - case DWARF_VALUE_LITERAL: - { - bfd_byte *contents; - size_t n = TYPE_LENGTH (subobj_type); - - if (subobj_byte_offset + n > ctx.len) - invalid_synthetic_pointer (); - - free_values.free_to_mark (); - retval = allocate_value (subobj_type); - contents = value_contents_raw (retval); - memcpy (contents, ctx.data + subobj_byte_offset, n); - } - break; - - case DWARF_VALUE_OPTIMIZED_OUT: - free_values.free_to_mark (); - retval = allocate_optimized_out_value (subobj_type); - break; - - /* DWARF_VALUE_IMPLICIT_POINTER was converted to a pieced - operation by execute_stack_op. */ - case DWARF_VALUE_IMPLICIT_POINTER: - /* DWARF_VALUE_OPTIMIZED_OUT can't occur in this context -- - it can only be encountered when making a piece. */ - default: - internal_error (__FILE__, __LINE__, _("invalid location type")); - } - } - - set_value_initialized (retval, ctx.initialized); - - return retval; + return value_copy(retval); } /* The exported interface to dwarf2_evaluate_loc_desc_full; it always @@ -1668,6 +1530,9 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, dwarf2_per_objfile *per_objfile = dlbaton->per_objfile; dwarf_expr_context ctx (per_objfile); + struct value *result; + scoped_value_mark free_values; + ctx.frame = frame; ctx.per_cu = dlbaton->per_cu; if (addr_stack != nullptr) @@ -1686,6 +1551,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, try { ctx.eval (dlbaton->data, dlbaton->size); + result = ctx.fetch_result (); } catch (const gdb_exception_error &ex) { @@ -1703,29 +1569,20 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, throw; } - switch (ctx.location) + if (value_optimized_out (result)) + return 0; + + if (VALUE_LVAL (result) == lval_memory) + *valp = value_address (result); + else { - case DWARF_VALUE_STACK: - *is_reference = false; - /* FALLTHROUGH */ - - case DWARF_VALUE_REGISTER: - case DWARF_VALUE_MEMORY: - *valp = ctx.fetch_address (0); - if (ctx.location == DWARF_VALUE_REGISTER) - *valp = read_addr_from_reg (frame, *valp); - return 1; - case DWARF_VALUE_LITERAL: - *valp = extract_signed_integer (ctx.data, ctx.len, - gdbarch_byte_order (ctx.gdbarch)); - return 1; - /* Unsupported dwarf values. */ - case DWARF_VALUE_OPTIMIZED_OUT: - case DWARF_VALUE_IMPLICIT_POINTER: - break; + if (VALUE_LVAL (result) == not_lval) + *is_reference = false; + + *valp = value_as_address (result); } - return 0; + return 1; } /* See dwarf2loc.h. */ -- 2.17.1