From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10on2060.outbound.protection.outlook.com [40.107.93.60]) by sourceware.org (Postfix) with ESMTPS id E41F03857C6E for ; Fri, 5 Nov 2021 11:39:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E41F03857C6E ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PTcV7xKh/GRhxG4blgAorrgNTDVht9kfFthGsLe9gxYPK+JN6I5DpSUd0PBDcCMM5uZDD93lyLMqMnCzI7yV+N4wZ/g8GFDLPItXrFNYPzpSGEzvWV95AxspveqI0f8AMYG+V3oTIa1faKb2sT3Mk20E/mSHHsdhA3ARJKJvJvfXz4RPgp5Rn8xRbduhC3qbJE9M83umRKiKdeti7BhGhYMzIdJ8KtSa1ubPyS/HQf0aaJe5tLT9+vBe7vWjMomt7HY0hMes3UMTdtS/Jk6cNEyaVnrO4KnQqgWQKe7fQ4Jf8gtVHcyZzbnE8a83qp+LdeIAu+pvOPeBc7O4Ou3h3w== 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=co5CsB9wqK+hZtF708UOJ+qUrItWUiOmM+ktNF9dzo4=; b=SYJkfsPefCof+SGXQnWzWOgAN5p0oV89bxIlegZepNhbNm9mTe8ZALzW2e5RPcKltXpYE0VCbCIUGgHnt5q80u0dIh9qfp6rZ0OlNYVBN791k9oiFkzJBExehru62BdnQQ1Lf1iTjHxTZCzy8VCdrzQbvdid92b4gRv/Oh2u9nDROuf+LRYMbbTjj4AXm+Sbe6+g1jhsJD9lThl1hRdqNK+ZCJVnc6377Oya+rBhi+XibHn2BcAvvZqgxoNttQECwesFUVT97H14mHQTyAeox3rlkNH5WUKYNlNrc1zYZ3X8eYFnM01rpEtoDA+QHfJZIzLy5Chyhw7CfcGqBoRmBA== 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 MW2PR16CA0004.namprd16.prod.outlook.com (2603:10b6:907::17) by MN2PR12MB4581.namprd12.prod.outlook.com (2603:10b6:208:260::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4669.10; Fri, 5 Nov 2021 11:39:23 +0000 Received: from CO1NAM11FT042.eop-nam11.prod.protection.outlook.com (2603:10b6:907:0:cafe::f3) by MW2PR16CA0004.outlook.office365.com (2603:10b6:907::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4669.11 via Frontend Transport; Fri, 5 Nov 2021 11:39:22 +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 CO1NAM11FT042.mail.protection.outlook.com (10.13.174.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.4669.10 via Frontend Transport; Fri, 5 Nov 2021 11:39:22 +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.15; Fri, 5 Nov 2021 06:39:19 -0500 From: Zoran Zaric To: Subject: [PATCH v4 15/28] Add to_gdb_value method to DWARF entry class Date: Fri, 5 Nov 2021 11:38:36 +0000 Message-ID: <20211105113849.118800-16-zoran.zaric@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211105113849.118800-1-zoran.zaric@amd.com> References: <20211105113849.118800-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: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a1b1ef3e-23ab-4d68-7e00-08d9a050e9a0 X-MS-TrafficTypeDiagnostic: MN2PR12MB4581: 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: jZVeRl/6VwFxDuJrlbS7UUXSCIU00Zmqlv4nDRkRE5D+0jZFP1ThAOJ04hmqHu7OVCitQzFwKDVwjOh8CyZrjkZypjUHouE49Awc+EPpSFIcylu3Voaun2PoPTSiU4uMbrfh9ICFkbzQtQObkJ1/ygoXmihU/GhIJKW9i3L3BOqmFHedbVRZTLT5H4rtVq5WKGk5BQ4aaRLhjFqlD4OI2AFYXdPKPUXC+zW6SWFu3UmQzioW4tkgtx8x2XVGnVTweyadtDQFbVF+64v9FCsTb3+rOD9bJZdbZOO1UER3pZod88jO50ssXctcm6BVnYAu4Z7w03PypKwZ5G1X7lZZsnxx1MWjTxuxktqrILAmhMEBeUB5VkCNtyT1uCGP8BCQZHn6ZMKzpxFFOSz8b46DmvtOBuXZl6CEkiwWW6OnBaTUCPDuD50eumqN1TJiCAP9mWw0zLOGi2PuopCTlBESCEXIXbABq5IFG0OqL02Smp/xeRt4VoOFXIAX11XgkKUcxqRUt9+n6396X2qAyMH5tHlJghAvt2vDMdcw19+pzNH5w39N8fY+VzlZyuAhW8xMQxUsjNg0ynUCz4p+Kp/o5mhYLSfaHTigjAuTjBqVwDT1V/M8yvkWgq4wXh8gd6dpNGKxBGbqRp7NplRVkDfqqzRpkhO3fIxtWxcqLb6jy5ASLJL/3NeEK/WLXHn690hUzjxW8B4jtSABY0F1UQU4/UvfI+0NxEp8b2nOyznYLfw= 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)(36840700001)(46966006)(508600001)(83380400001)(6666004)(356005)(8676002)(70586007)(186003)(26005)(16526019)(1076003)(6916009)(82310400003)(5660300002)(2906002)(81166007)(70206006)(4326008)(30864003)(2616005)(47076005)(36860700001)(36756003)(8936002)(316002)(426003)(44832011)(336012)(86362001)(36900700001); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Nov 2021 11:39:22.4934 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a1b1ef3e-23ab-4d68-7e00-08d9a050e9a0 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: CO1NAM11FT042.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4581 X-Spam-Status: No, score=-12.4 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: Fri, 05 Nov 2021 11:39:27 -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 | 283 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index d76dddab643..ac26b4c5613 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -436,6 +436,10 @@ class dwarf_location : public dwarf_entry public: 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) { @@ -588,6 +592,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; @@ -670,6 +684,15 @@ class dwarf_value final : public dwarf_entry pack_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); + m_contents + = std::move (gdb::byte_vector (contents.begin (), contents.end ())); + m_gdb_value = gdb_value; + } + gdb::array_view contents () const { return m_contents; @@ -694,12 +717,22 @@ class dwarf_value final : 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; @@ -741,6 +774,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).data (), + 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. */ @@ -752,6 +802,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 @@ -774,6 +829,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 @@ -783,6 +851,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; @@ -805,6 +878,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; @@ -996,6 +1073,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 @@ -1005,6 +1103,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; @@ -1018,6 +1121,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; @@ -1129,6 +1237,55 @@ 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 == nullptr) + 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)); + + /* DWARF evaluator only supports targets with byte size of 8 bits, + while struct value offset is expressed in memory unit size. */ + int unit_size = gdbarch_addressable_memory_unit_size (m_arch); + LONGEST retval_offset = value_offset (retval) * unit_size; + + 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) / unit_size); + else + set_value_offset (retval, (retval_offset + m_offset) / unit_size); + + /* 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. */ @@ -1144,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; @@ -1164,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; @@ -1211,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).data (), + (void *) (m_contents.data () + subobj_offset), subtype_len); + + return retval; +} + /* Implicit pointer location description entry. */ class dwarf_implicit_pointer final : public dwarf_location @@ -1226,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; @@ -1265,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; @@ -1328,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 @@ -1337,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); @@ -1373,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. */ @@ -1383,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; }; @@ -1682,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