From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id mC7kBG/+PGAGJAAAWB0awg (envelope-from ) for ; Mon, 01 Mar 2021 09:47:11 -0500 Received: by simark.ca (Postfix, from userid 112) id 5BA621EF7C; Mon, 1 Mar 2021 09:47:09 -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 AF0D11EF64 for ; Mon, 1 Mar 2021 09:47:08 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3B5BF3938396; Mon, 1 Mar 2021 14:47:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3B5BF3938396 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1614610028; bh=gc3nIoaD9rWJ90bvvLDxr3yWJA+DT46nAwWG4rZ0KAA=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=GdsEekAZMPBKCkN7CUIIzmrY4eoz5+OQZrfLgNsyGQP3fSmbdoBoq7UH9xDSOuTCw hQc6ZSEyQC9SVji0zoIo8kyJDPQm8VY0is2NndyA+IsJEeBlJHCZrokXvXGFbegcRj Vbi1e2ixzu/EQlYjHV65tXIoBWEvMkLn5+cO6mgI= Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2046.outbound.protection.outlook.com [40.107.244.46]) by sourceware.org (Postfix) with ESMTPS id BEBDA393A40A for ; Mon, 1 Mar 2021 14:47:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org BEBDA393A40A ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fzs7qb8ak7gEbRkXuJd9eu2vqtAlPXT8mgZ9CUBh0M6uC7brplOoHiTCnliMeZjZn7QwSUL2JLXf9XtIGVe7QXGdTDX4jNfSuWS/aUNFHYAn/v2ZLr+NjPZzeIFyR7JoeCxPUT+ScSe0sr4bjZtv8ZHLeZdEmuta46QsqeUym5EsU3WBNFK6caIIvtrPAqC25SMmYhY3dQBRmQrJFwNjsgHEpGoIafBkJCpIjtP3Qfs0bTj6Xnwu02dexDSdk6mGO5Pk4XBqYVnEH+6yFrW262I9vIvp6EjM5uM8onmQxRtBVRC98Bgel7N2u0z7mL/dtgZs8Mjcz7Tav64M75oblg== 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=gc3nIoaD9rWJ90bvvLDxr3yWJA+DT46nAwWG4rZ0KAA=; b=E2qGRHEJg8ilqRBX3Qew9x2lRxhifayq+Nu10EC1k0Dj8tD0UkVEAYH2YEnwW+PqY+6FSwkKhhmJlh/33pixrF/j4bXgtZ/zpVjpLCownWQozk/IBQe7Kifq8qjYCJH5uTa+rnURCqQr6j77TGSZ4j1i29kCY8WExgZvyt4/RXquyDqwCWuWNheirjSZHNJpWNq3r6s5ruQsxCs649J5iAPhr/Y2LtwHpkSPfu1WK9xNMyRyQaau1HxV3NOI5mJkvmM+nekEpoXVL/qmJtXoeS0hfKptwTYEV31enfk4AHcPnwDlQ/INJjjUN1ioalwbxOgIBArPqCQKr3fbW8Ecxw== 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 DM6PR12MB3676.namprd12.prod.outlook.com (2603:10b6:5:1c7::29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3890.19; Mon, 1 Mar 2021 14:46:56 +0000 Received: from DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::31d8:f503:f7b2:f44]) by DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::31d8:f503:f7b2:f44%3]) with mapi id 15.20.3868.033; Mon, 1 Mar 2021 14:46:56 +0000 To: gdb-patches@sourceware.org Subject: [PATCH 15/43] Make DWARF evaluator return a single struct value Date: Mon, 1 Mar 2021 14:45:52 +0000 Message-Id: <20210301144620.103016-16-Zoran.Zaric@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210301144620.103016-1-Zoran.Zaric@amd.com> References: <20210301144620.103016-1-Zoran.Zaric@amd.com> Content-Type: text/plain X-Originating-IP: [2a00:23c7:5a85:6801:b4ed:fe7b:8064:d4d] X-ClientProxiedBy: AM0PR04CA0073.eurprd04.prod.outlook.com (2603:10a6:208:be::14) 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:b4ed:fe7b:8064:d4d) by AM0PR04CA0073.eurprd04.prod.outlook.com (2603:10a6:208:be::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3890.19 via Frontend Transport; Mon, 1 Mar 2021 14:46:55 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 36d0182f-48cd-460f-8056-08d8dcc0dc20 X-MS-TrafficTypeDiagnostic: DM6PR12MB3676: 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: oydKvb35msZ87ScvWtn5/wQaaKC+A64q7nOSslBRKzUz6Z1U5+yPUkaJuUD5ouYbjglngYbK4UizdAaZjmtSdhUtoScyoQSvCZLowFfFDvwnwZ0ynAnjWm55zpVqfunueM+5F251n1lwb7uJ2x/FmBFF2aW4CNjXqlY3R1KMA2TRzC/1rKpX/0rzvAUncZk0CidUAmh+QN6G3xuw8ZoS2cZl6GFIplU/qthgXi4foZAGz6eLmgFYzKaVof8qpw0B/CIVytOBKjlsWoJJajGZRTIH0V0xGTMix9ZdlG3UJvYUwdjzmoAV7OUbRnAT+qhdLhUjZMjha18b6+CfNdWs0IukJr2yNpcLWNE2rMoNJKvs/48ZZEJKThKBrhsfSybxYt1a0qPqeFXvPevFbnltoOe3bJuwTKTVL5GYhApa1WvYPDg6E45RBCTKzuH96KeGbFwcdrcBbRjEafTIJdOSN+OAm8Zom/yXcW7xHyKyULt7Sb4z0CAn2lU0ZbQzV21ljnMDHEhNr+CMGPTb9+OiW258AiNOnnO6i8on41qFdHYfZqzt0VJbXkjY4mgA3Na7Wn0ZTDINWTUbhahLEaTqvQ== 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)(366004)(396003)(346002)(136003)(39860400002)(6666004)(16526019)(1076003)(83380400001)(2616005)(69590400012)(2906002)(186003)(36756003)(66946007)(316002)(66476007)(8936002)(52116002)(86362001)(6506007)(478600001)(5660300002)(4326008)(6486002)(8676002)(30864003)(6916009)(6512007)(66556008); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?baAaoFnTgv60wKue2WcXa1TYdFH3IjH6m7322O88ryTVqko40PsAqY/BpVID?= =?us-ascii?Q?sfrobOAtnqlRiEkWUHHQ2rphVnSWTvotq78zidY/A2ehHIsmOr1Zuq7I4F4f?= =?us-ascii?Q?3g6zgOrv5Vd3OHgFvgMQpcy8q9AMx4Hv6z383ge4OrdKQNal8AYT4mk3/UpW?= =?us-ascii?Q?hgmm/sMje69lVDLL6RON8bxPMIDihUVPq8bO/AaJCvLdiTVJrQwcg4sp589D?= =?us-ascii?Q?AJ7PzDwftctzocmfd3d/Zc402utraW+kL+2SXV+atQYKKch1EbMnIRm9oL2Q?= =?us-ascii?Q?areKx7iiRwEkFwES9FJn1CmnGQ+5tK+Q7/yuoghYFhNQiZcysJ/u+eknzgh8?= =?us-ascii?Q?qo+1buO/8geCwptckwWtxSZ1KHDtyhFW+E04zOsHRVWms4WddKXZLoZZWX4Z?= =?us-ascii?Q?mIiESz9z1kZRVstXJ+6i5jls2KJRu4B+BU76J9UfcmuTtL6AKqmFg9BFbOdo?= =?us-ascii?Q?60g91HzaLJ0HFqYXF+1KP6Gk5d4PNeccqEbUtYMldWQXl+JZYPmT1EEdDAWJ?= =?us-ascii?Q?w7PkL6beZLmgKro+bLw1YFnwUFWwChipB++eKZwbDREly1/UE+mNOxCJdXxM?= =?us-ascii?Q?dQrg12MuYO1gQKV4mRoTcVQ5YBWORc6wdIJ8PwqmEM97qrD8cJx0nYgvFspm?= =?us-ascii?Q?Xlbia5kZT2Z2mIQMLwrC0lj5iWkvFl+ETdE18XkRUu01Wx3ZsjxxFCGCZyY/?= =?us-ascii?Q?u1WonuPAUJoanu8NCEylBjhWBMecX0VlAvYW6DDXIcMJfB2yDNx4J1h2jiZX?= =?us-ascii?Q?A9lSS4TLhvHYLK2cmr3BMUdgdyLnG5QFGfRGmo1TsgKz7gLUhmNLG+H1mmWl?= =?us-ascii?Q?+aFkK27bdvnKfi5jRJWzbSZ3iLF3uuz6PwDem2fDDIG+8ojw1eG9HRfChcZx?= =?us-ascii?Q?BCr9seS/jDX6jdaAqC5E8OxsQAyEicwEHPF2P8A/1PS5yZZdV9YfUai+A/nE?= =?us-ascii?Q?FcdemUNIe3ufqVVfdovCZNdBy8VZWjzLoCg40yysgF+BZO8Cf0DyXf5UN1LQ?= =?us-ascii?Q?Gq7SStJnsed+OABs1DDCMKn7T5m1Q+xqxeHpoP8Tp3AWqb+KP//e/v/m6W9I?= =?us-ascii?Q?Z9e9Vx9XLZUg0K2VEyIyR/p4o1uAX+X1WC3aY1W3IFJJpXlrcarTJelfrcmJ?= =?us-ascii?Q?d7qXIPh/ZdPdfileYUpg4rL5EIhILQzCrCRH3d/Yfpbt4Bg8muGemfnJ4uRa?= =?us-ascii?Q?oGqWILYVnhzR6DUp1s6tl+EHCqhCS6xhGqN+YKTbOIgQo9YSIqE+T3JXCTM6?= =?us-ascii?Q?IXAW0ed226J/6Ws5gRiXvtpWLTF0+jtywBPrIXawG0VMNYmw8aj5sRYeBPmM?= =?us-ascii?Q?BWH6Ac0vwisZLf/9bK4OIDvjznpVeHxP/N2tISwPpuQKc88Q6Q6n9D2/8ogl?= =?us-ascii?Q?x0jGJ/ILuaWD+logxCCO8SGH+jfs?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 36d0182f-48cd-460f-8056-08d8dcc0dc20 X-MS-Exchange-CrossTenant-AuthSource: DM6PR12MB2762.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Mar 2021 14:46:56.3061 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Dy16MfG/nBzwZB2MLYSSKBFDi9IVFtu0n0cWqHnFj81GyaOmYul/u8Z/2Aj/twue2hlWP155li9BNVGxpjC65g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3676 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 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. * dwarf2/loc.h (invalid_synthetic_pointer): Expose function. --- gdb/dwarf2/expr.c | 163 ++++++++++++++++++++++++++++++++++++- gdb/dwarf2/expr.h | 25 +++--- gdb/dwarf2/frame.c | 19 ++--- gdb/dwarf2/loc.c | 195 ++++++--------------------------------------- gdb/dwarf2/loc.h | 5 ++ 5 files changed, 207 insertions(+), 200 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 486521b5e04..b2248681899 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -125,9 +125,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, @@ -628,7 +629,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, @@ -886,6 +887,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 3ac19e5ba0b..a0ac21f2ed1 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 8faadeb3469..21daecec61c 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 92ff3111a5a..e2d6b32717b 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -91,7 +91,7 @@ enum debug_loc_kind /* See loc.h. */ -static void +void invalid_synthetic_pointer (void) { error (_("access outside bounds of object " @@ -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; - - 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); + /* 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 (); - 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. */ diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h index 33388ef88ee..02c686e5592 100644 --- a/gdb/dwarf2/loc.h +++ b/gdb/dwarf2/loc.h @@ -278,6 +278,11 @@ extern int dwarf_reg_to_regnum (struct gdbarch *arch, int dwarf_reg); extern int dwarf_reg_to_regnum_or_error (struct gdbarch *arch, ULONGEST dwarf_reg); +/* Helper function which throws an error if a synthetic pointer is + invalid. */ + +extern void invalid_synthetic_pointer (); + /* Fetch the value pointed to by a synthetic pointer. */ extern struct value *indirect_synthetic_pointer -- 2.17.1