From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2080.outbound.protection.outlook.com [40.107.220.80]) by sourceware.org (Postfix) with ESMTPS id 3758D3857C53 for ; Thu, 14 Oct 2021 09:33:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3758D3857C53 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=WfTcHzTis/K8MgBqBlL5M0ACzG6AaJPa2C8UtEzFUL/GAYFkmxWD2m8WHfO5KQ81EIQcapUimWW3uxxKctovJg4fbpyO7aYEnXPWxuEXm8UuG19X+lXPBr1/BpPNnhMNmuQ41yAeuuLB9mcVnOHDc9ZUiFGO7vFEaDCZl0s7pxbzTZN2rcLNcUoCqOhcYvpEzoetn+hUbs5ydzPEXEjfzNmZpXmHp+nRJ1/aVoVdTs3GuOQ/ZGRhjR0C7QdZw5Jz/Xvnjz+VtED5nuSeMafOmoDufGTs/EuGh5KQOYiv8OVf4q0pgefqLZZILbLIXHHy7Vg1tAuxBrMB2tni2cwLdw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=O/PR3Y9PeDSYsY5bsblezJOMeUxSmLKV1gbBWaqu+hY=; b=QnzYDBjjsd7dvKGyqKq/ZdOCzKA8t/O/uZ1pqzt/lClYXilGIymgC9jgUXj+Ys6d2xb6ilRKTmymuvt6OIASs/5dWrP+juqfQQrvd+LEaMiU09Juqba9zytmaPM5SepvVMI2Y6zmSUsC3iqeQ1x8ClyFw6wo9VCwtAbDmJwRzRwsI/9/SN+u0vKjns/yLtmzJHsVMjRA9zA0GIYcizkXPh2zGwIBrE0vjiIxUf7knwMOzJaV42dTXzkScYWu19gSynmr4AOpEC5C+uYOjQ8JRBHjU/mu0K3tNVJkvGppy7CQaBIpio9KPOHaoUjEWocD+YV+3iozgwDueIn20vLCEw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=sourceware.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none Received: from DM5PR13CA0030.namprd13.prod.outlook.com (2603:10b6:3:7b::16) by DM6PR12MB4433.namprd12.prod.outlook.com (2603:10b6:5:2a1::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.15; Thu, 14 Oct 2021 09:33:13 +0000 Received: from DM6NAM11FT047.eop-nam11.prod.protection.outlook.com (2603:10b6:3:7b:cafe::c6) by DM5PR13CA0030.outlook.office365.com (2603:10b6:3:7b::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4628.9 via Frontend Transport; Thu, 14 Oct 2021 09:33:13 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; sourceware.org; dkim=none (message not signed) header.d=none;sourceware.org; dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; Received: from SATLEXMB04.amd.com (165.204.84.17) by DM6NAM11FT047.mail.protection.outlook.com (10.13.172.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.4608.15 via Frontend Transport; Thu, 14 Oct 2021 09:33:12 +0000 Received: from localhost.localdomain (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.8; Thu, 14 Oct 2021 04:33:10 -0500 From: Zoran Zaric To: Subject: [PATCH v3 15/28] Add to_gdb_value method to DWARF entry class Date: Thu, 14 Oct 2021 10:32:22 +0100 Message-ID: <20211014093235.69756-16-zoran.zaric@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211014093235.69756-1-zoran.zaric@amd.com> References: <20211014093235.69756-1-zoran.zaric@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: aa337543-0b10-448c-bebc-08d98ef5a49b X-MS-TrafficTypeDiagnostic: DM6PR12MB4433: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6108; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: r9eUL3ekkEyg0+AMhPXTEuKFljrBv4jay4fzpr6Q8YGBn5ASM8ZXic9SQDVO0jap0E29J+/wS2PdzQtF1zaSJJJpNsHQNaiPSrJm/NGYqlSyR/MJ5D/evhijtzNY8mMUIE3EW+c2DAXX8Ev7BBI9IHC6Erpxc1QnckfMAb4VvJZfBVsbkHfBsZLvUMCNJ3SOeQMViQSe8Dwy2MIqNAQIKEvSwDd9tsxy2kJXXQtR1EFgrmAspQRHGXaEzHW5DU5sja3oSjAy6X0YBxiXq6miN2ouQG6fNvdRzqTQQyeLZj08nivhKDhoebDfcNbQW23MzkG0rGmotQ8FhyX5oqxNTfbV0njYGjM2jlxN2Yn5n4RMvqONPbK5pEqY2dHT5d3d840deitQfhatdPz2cEsj5uawcKvLi6msEYPiI69GjIyAw+xW1SHPL6nXl0c9mc6+6OQ8sljNwcQ14Z+3g2N2oguaN0Wd/rQBBhVBwIOeZbuWVoyT71FPzPCowVRjiLgs4RtRp8ZlI4X3HBWKzbtCuCA2gbpCOqhqPN5lBV/qTQYdF7jfo0Gc5gpFiBZ0GNocmrxABL6EiUYMt8BZt9ze1gCriA2baoXlTEfbqTfizQls9v4V5OHUl4NjRizWPgW47+lg9ngLa2GTGWOzoEaPP/vJMnwj3wJ6Ho/NeNkgw8Md0KuTXkDhITHVzLFoCFZJqhvMvahC7yVpNIsm4MAAcHsGk0qI9uAM3VaqkKKfmDM= X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(36860700001)(336012)(83380400001)(70206006)(8676002)(81166007)(426003)(4326008)(5660300002)(44832011)(30864003)(316002)(82310400003)(36756003)(47076005)(8936002)(2906002)(1076003)(6666004)(26005)(16526019)(86362001)(70586007)(6916009)(2616005)(508600001)(186003)(356005)(36900700001); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Oct 2021 09:33:12.8619 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: aa337543-0b10-448c-bebc-08d98ef5a49b X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT047.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4433 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org 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: , X-List-Received-Date: Thu, 14 Oct 2021 09:33:17 -0000 From: Zoran Zaric The result of the DWARF expression evaluation is expected to be in a format of a struct value object. This means that a new to_gdb_value method is needed for both dwarf_location and dwarf_value classes. In the case of the dwarf_value class, the conversion between that class and struct value can happen often, this is why it is usefull to cache once created struct value object in a dwarf_value m_gdb_value member to reduce the number of conversions needed. However, this also means that the to_gdb_value method cant be declared as a constant method. In the case of classes that derive from dwarf_location class, there is now a need for a cloning method because the encapsulating computed_closure class has a life span separated from the expression evaluator. gdb/ChangeLog: * dwarf2/expr.c (dwarf_entry::to_gdb_value): New method. (dwarf_location::to_gdb_value): New method. (dwarf_location::clone_location): New method. (dwarf_value::m_gdb_value): New member. (dwarf_value::to_gdb_value): New method. (dwarf_undefined::to_gdb_value): New method. (dwarf_undefined::clone_location): New method. (dwarf_memory::to_gdb_value): New method. (dwarf_memory::clone_location): New method. (dwarf_register::to_gdb_value): New method. (dwarf_register::clone_location): New method. (dwarf_implicit::to_gdb_value): New method. (dwarf_implicit::clone_location): New method. (dwarf_implicit_pointer::to_gdb_value): New method. (dwarf_implicit_pointer::clone_location): New method. (dwarf_composite::to_gdb_value): New method. (dwarf_composite::clone_location): New method. --- gdb/dwarf2/expr.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index e33be7e7c1c..a34a5037686 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -441,6 +441,10 @@ class dwarf_location : public dwarf_entry virtual ~dwarf_location () = default; + /* Clone the location and return the result as a + dwarf_location pointer. */ + virtual std::unique_ptr clone_location () const = 0; + /* Add bit offset to the location description. */ void add_bit_offset (LONGEST bit_offset) { @@ -593,6 +597,16 @@ class dwarf_location : public dwarf_entry return false; } + /* Convert DWARF location description to the matching struct value + representation of the given TYPE type in a given FRAME. + SUBOBJ_TYPE information if specified, will be used for more + precise description of the source variable type information. + Where SUBOBJ_OFFSET defines an offset into the DWARF entry + contents. */ + virtual value *to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const = 0; + protected: /* Architecture of the location. */ gdbarch *m_arch; @@ -680,6 +694,16 @@ class dwarf_value : public dwarf_entry pack_unsigned_long (m_contents.data (), type, value); } + dwarf_value (value *gdb_value) + { + m_type = value_type (gdb_value); + gdb::array_view contents (value_contents_raw (gdb_value), + TYPE_LENGTH (m_type)); + m_contents + = std::move (gdb::byte_vector (contents.begin (), contents.end ())); + m_gdb_value = gdb_value; + } + gdb::array_view contents () const { return m_contents; @@ -699,12 +723,22 @@ class dwarf_value : public dwarf_entry ARCH defines an architecture of the location described. */ dwarf_location_up to_location (struct gdbarch *arch) const; + /* Convert DWARF value to the matching struct value representation + of the given TYPE type. Where OFFSET defines an offset into the + DWARF value contents. */ + value *to_gdb_value (struct type *type, LONGEST offset = 0); + private: /* Value contents as a stream of bytes in target byte order. */ gdb::byte_vector m_contents; /* Type of the value held by the entry. */ struct type *m_type; + + /* Struct value representation of the DWARF value. Only used until + a set of arithmethic/logic operations that works with this class + are implemented. */ + value *m_gdb_value = nullptr; }; using dwarf_value_up = std::unique_ptr; @@ -746,6 +780,23 @@ dwarf_location::deref (frame_info *frame, const property_addr_info *addr_info, (gdb::array_view (read_buf), type); } +value * +dwarf_value::to_gdb_value (struct type *type, LONGEST offset) +{ + if (m_gdb_value != nullptr) + return m_gdb_value; + + size_t type_len = TYPE_LENGTH (type); + + if (offset + type_len > TYPE_LENGTH (m_type)) + invalid_synthetic_pointer (); + + m_gdb_value = allocate_value (type); + memcpy (value_contents_raw (m_gdb_value), + m_contents.data () + offset, type_len); + return m_gdb_value; +} + /* Undefined location description entry. This is a special location description type that describes the location description that is not known. */ @@ -757,6 +808,11 @@ class dwarf_undefined final : public dwarf_location : dwarf_location (arch, 0) {} + dwarf_location_up clone_location () const override + { + return make_unique (*this); + } + void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, bool big_endian, int *optimized, int *unavailable) const override @@ -779,6 +835,19 @@ class dwarf_undefined final : public dwarf_location { return true; } + + value *to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const override + { + gdb_assert (type != nullptr); + gdb_assert (subobj_type != nullptr); + + value *retval = allocate_value (subobj_type); + mark_value_bytes_optimized_out (retval, subobj_offset, + TYPE_LENGTH (subobj_type)); + return retval; + } }; class dwarf_memory final : public dwarf_location @@ -788,6 +857,11 @@ class dwarf_memory final : public dwarf_location : dwarf_location (arch, offset), m_stack (stack) {} + dwarf_location_up clone_location () const override + { + return make_unique (*this); + } + void set_stack (bool stack) { m_stack = stack; @@ -810,6 +884,10 @@ class dwarf_memory final : public dwarf_location struct type *type, size_t size = 0) const override; + value *to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const override; + private: /* True if the location belongs to a stack memory region. */ bool m_stack; @@ -999,6 +1077,27 @@ dwarf_memory::deref (frame_info *frame, const property_addr_info *addr_info, (gdb::array_view (read_buf), type); } +value * +dwarf_memory::to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const +{ + gdb_assert (type != nullptr); + gdb_assert (subobj_type != nullptr); + + struct type *ptr_type = builtin_type (m_arch)->builtin_data_ptr; + + if (subobj_type->code () == TYPE_CODE_FUNC + || subobj_type->code () == TYPE_CODE_METHOD) + ptr_type = builtin_type (m_arch)->builtin_func_ptr; + + CORE_ADDR address + = value_as_address (value_from_pointer (ptr_type, m_offset)); + value *retval = value_at_lazy (subobj_type, address + subobj_offset); + set_value_stack (retval, m_stack); + return retval; +} + /* Register location description entry. */ class dwarf_register final : public dwarf_location @@ -1008,6 +1107,11 @@ class dwarf_register final : public dwarf_location : dwarf_location (arch, offset), m_regnum (regnum) {} + dwarf_location_up clone_location () const override + { + return make_unique (*this); + } + void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, bool big_endian, int *optimized, int *unavailable) const override; @@ -1021,6 +1125,11 @@ class dwarf_register final : public dwarf_location LONGEST bits_to_skip, size_t bit_size, size_t location_bit_limit) const override; + value *to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const override; + + private: /* DWARF register number. */ unsigned int m_regnum; @@ -1132,6 +1241,51 @@ dwarf_register::is_optimized_out (frame_info *frame, bool big_endian, return false; } +value * +dwarf_register::to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const +{ + gdb_assert (type != nullptr); + gdb_assert (subobj_type != nullptr); + + gdbarch *frame_arch = get_frame_arch (frame); + int gdb_regnum = dwarf_reg_to_regnum_or_error (frame_arch, m_regnum); + + if (frame == NULL) + internal_error (__FILE__, __LINE__, _("invalid frame information")); + + /* Construct the value. */ + value *retval + = gdbarch_value_from_register (frame_arch, type, + gdb_regnum, get_frame_id (frame)); + LONGEST retval_offset = value_offset (retval); + + if (type_byte_order (type) == BFD_ENDIAN_BIG + && TYPE_LENGTH (type) + m_offset < retval_offset) + /* Big-endian, and we want less than full size. */ + set_value_offset (retval, retval_offset - m_offset); + else + set_value_offset (retval, retval_offset + m_offset); + + /* Get the data. */ + read_frame_register_value (retval, frame); + + if (value_optimized_out (retval)) + { + /* 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 . */ + value *temp = allocate_value (subobj_type); + value_contents_copy (temp, 0, retval, 0, TYPE_LENGTH (subobj_type)); + retval = temp; + } + + return retval; +} + /* Implicit location description entry. Describes a location description not found on the target but instead saved in a gdb-allocated buffer. */ @@ -1147,6 +1301,11 @@ class dwarf_implicit final : public dwarf_location m_byte_order (byte_order) {} + dwarf_location_up clone_location () const override + { + return make_unique (*this); + } + void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, bool big_endian, int *optimized, int *unavailable) const override; @@ -1167,6 +1326,10 @@ class dwarf_implicit final : public dwarf_location return true; } + value *to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const override; + private: /* Implicit location contents as a stream of bytes in target byte-order. */ gdb::byte_vector m_contents; @@ -1214,6 +1377,36 @@ dwarf_implicit::read (frame_info *frame, gdb_byte *buf, total_bits_to_skip, bit_size, big_endian); } +value * +dwarf_implicit::to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const +{ + gdb_assert (type != nullptr); + gdb_assert (subobj_type != nullptr); + + size_t subtype_len = TYPE_LENGTH (subobj_type); + size_t type_len = TYPE_LENGTH (type); + + /* To be compatible with expected error output of the existing + tests, the invalid synthetic pointer is not reported for + DW_OP_implicit_value operation. */ + if (subobj_offset + subtype_len > type_len + && m_byte_order != BFD_ENDIAN_UNKNOWN) + invalid_synthetic_pointer (); + + value *retval = allocate_value (subobj_type); + + /* The given offset is relative to the actual object. */ + if (m_byte_order == BFD_ENDIAN_BIG) + subobj_offset += m_contents.size () - type_len; + + memcpy ((void *) value_contents_raw (retval), + (void *) (m_contents.data () + subobj_offset), subtype_len); + + return retval; +} + /* Implicit pointer location description entry. */ class dwarf_implicit_pointer final : public dwarf_location @@ -1229,6 +1422,11 @@ class dwarf_implicit_pointer final : public dwarf_location m_addr_size (addr_size), m_die_offset (die_offset) {} + dwarf_location_up clone_location () const override + { + return make_unique (*this); + } + void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, bool big_endian, int *optimized, int *unavailable) const override; @@ -1268,6 +1466,10 @@ class dwarf_implicit_pointer final : public dwarf_location LONGEST bit_offset = 0, int bit_length = 0) const override; + value *to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const override; + private: /* Per object file data of the implicit pointer. */ dwarf2_per_objfile *m_per_objfile; @@ -1331,6 +1533,26 @@ dwarf_implicit_pointer::indirect_implicit_ptr (frame_info *frame, m_per_cu, m_per_objfile, frame, type); } +value * +dwarf_implicit_pointer::to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const +{ + gdb_assert (type != nullptr); + gdb_assert (subobj_type != nullptr); + + computed_closure *closure + = new computed_closure (make_unique (*this), + get_frame_id (frame)); + closure->incref (); + + value *retval + = allocate_computed_value (subobj_type, &closure_value_funcs, closure); + set_value_offset (retval, subobj_offset); + + return retval; +} + /* Composite location description entry. */ class dwarf_composite final : public dwarf_location @@ -1340,6 +1562,11 @@ class dwarf_composite final : public dwarf_location : dwarf_location (arch, 0), m_per_cu (per_cu) {} + dwarf_location_up clone_location () const override + { + return make_unique (*this); + } + void add_piece (std::unique_ptr location, ULONGEST bit_size) { gdb_assert (location != nullptr); @@ -1376,6 +1603,10 @@ class dwarf_composite final : public dwarf_location LONGEST bits_to_skip, size_t bit_size, size_t location_bit_limit) const override; + value *to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const override; + private: /* Composite piece that contains a piece location description and it's size. */ @@ -1386,6 +1617,17 @@ class dwarf_composite final : public dwarf_location : location (std::move (location)), size (size) {} + /* We need to make a piece copyiable, because dwarf_composite can be + copied / cloned. */ + piece (const piece &other) + : location (other.location->clone_location ()), size (other.size) + {} + + piece (piece &&) = default; + + void operator=(const piece &) = delete; + void operator=(piece &&) = delete; + std::unique_ptr location; ULONGEST size; }; @@ -1685,6 +1927,44 @@ dwarf_composite::is_optimized_out (frame_info *frame, bool big_endian, return false; } +value * +dwarf_composite::to_gdb_value (frame_info *frame, struct type *type, + struct type *subobj_type, + LONGEST subobj_offset) const +{ + gdb_assert (type != nullptr); + gdb_assert (subobj_type != nullptr); + + ULONGEST bit_size = 0; + + for (const piece &piece : m_pieces) + bit_size += piece.size; + + /* Complain if the expression is larger than the size of the + outer type. */ + if (bit_size > HOST_CHAR_BIT * TYPE_LENGTH (type)) + invalid_synthetic_pointer (); + + computed_closure *closure; + + /* If compilation unit information is not available + we are in a CFI context. */ + if (m_per_cu == nullptr) + closure = new computed_closure (make_unique (*this), + frame); + else + closure = new computed_closure (make_unique (*this), + get_frame_id (frame)); + + closure->incref (); + + value *retval + = allocate_computed_value (subobj_type, &closure_value_funcs, closure); + set_value_offset (retval, subobj_offset); + + return retval; +} + static void * copy_value_closure (const value *v) { -- 2.17.1