From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2056.outbound.protection.outlook.com [40.107.244.56]) by sourceware.org (Postfix) with ESMTPS id CAFAB393D02B for ; Mon, 7 Dec 2020 19:01:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org CAFAB393D02B ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FR9ccCUWhaCQ74BOFEb7cPqlnHmQ/UgXgJSEozw8MmXe04/rdgk1DqWsMdXu3k67TvIneGVMdNaEl61unhODoSoDHQzZbOuGRse7sJaeqlUoXEMwWl4TnHUtQaVozmSnAp2Hfbh/oybqgxUA2AWvZUt9upNXAr8QAQ7zBbGkV72DfECOwpVkoUXTPge4Jeu+cwnxT2YN+/SLxkjI5IL0ExBO/BB0hKDso0jgt6rK0BM+5wsf5dEcsHB1wH9npjcopeELxDmzML4vwvQ91flS2fTe12Gr3sTUXKU/ngzvclJ6/v7So7mY5G3WG856Lv+FeneMSIO51V+g+0HJPLn9Gg== 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=CBj4OGxEh3ZHqR/7MljVacPkrNXoCgfyigGyJGsZ6iI=; b=nk6/5ClzOTbvxl9gXVKpCnLr18DvRnJ4ofjHRaxL5H5Qsys9yig0HpeOEphtoQUOlhfBwPOIb8ms03QIb5GwR62gQU+vvBpLaNsB9SHIG5ZGMyo4x0zI7IpvWCrX426SNIy396Lx99EbklKH47pItL6EpVzHvgNXSDJqilbQyKT2q0IW1NEUA7zGTgxkh0ToVHqhHd2AmQBCAU4xjOeOSYY9kTahuxtYrvSe5MGIsRzLejuoRtue7ehRCNP1JCciRsCpGfp4L4pZjFhnDaHYLoqfqXahRDWHD0R/fUcGufsdPJzq3kLv45PEOdHNUnzHZbzhapXNLyiTE3dB+SyK8w== 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:24 +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:24 +0000 From: Zoran Zaric To: gdb-patches@sourceware.org Cc: Zoran Zaric Subject: [PATCH 20/30] Add dwarf_entry factory class to expr.c Date: Mon, 7 Dec 2020 19:00:21 +0000 Message-Id: <20201207190031.13341-21-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:22 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 9ede1e72-789c-475b-eec8-08d89ae27e37 X-MS-TrafficTypeDiagnostic: DM6PR12MB4561: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:1775; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +CJN9dntHVWaukF6qHYpu+IJsN0+XrsTjWABa8zDwKDHZUUVd6Iqv6Fi5SV01fwWMleqGbnzStWX72uk5+hSrS5wNxs5wQHt2oqPE7qfk538Lsp3rc0pspsf1mMxBe+HaD1xcyf88vQoXkGZG4iXfcpYOa/kxapJ1LlRhEtvPjkL2WeUPxEZOUNPK/XTdNIyrK1HgbuQRVhA061pFGIYJb3nqPdIOPB4nTQW4l5YGEDeN+aaly24TNct7pGvEw3lP9p5zpZwrRmCrgdKPSgUPT8b8KzVR6jm3X51T6lYbgApiHkBagm9YTeuUor8JeAnl8muYPpODSwTNR6a/U4VNoUWP7DHPp58z1oB7URvqzq6FcLsHKgI0bg1qQ6hXrwq 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)(316002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?XiMP20ZE00Zn1Idy+e7WxeWeXYMAjtlstoFfbqfLaBwSM22KHhv3rznoITRk?= =?us-ascii?Q?hMhKsvaENSwgCca7QiwrYQC5UYOSo0rx6BxEIVCwSKwO9fnpWr/JuJeRTxs0?= =?us-ascii?Q?GXPmmX+hhjaxOZU/1zQNYruLdRWnHLe88RujDPyuqRZVe/n8+119ZLwfgjsQ?= =?us-ascii?Q?GSepl4+aIC3dTH2ckogt13bjuNkhX/tJPeTFPPL/s2shrRlh+SSCiYCKK1kP?= =?us-ascii?Q?GLrF8LbH4E2WkOg9kSWRH1YkyOZTvVS0+OI1FnFXE4Zw9kwHHU4xKFIwPjjc?= =?us-ascii?Q?6mo1ZdhJRbPQu/sbbrjLcLI3gkstz4AiRhM8FKeXKqdp7jhqrDlAUP2MxrQH?= =?us-ascii?Q?nGZR+twodFlJ/gLSujLt4JyYEoqfdeD8s+aCdgz6hunqycf1z4e/VllJA3hk?= =?us-ascii?Q?9aQzK2EfIl7cw1m8JUxmPXlic3WNxtI4o+wYW7DgKqJdp3hG5LDw23yey3+O?= =?us-ascii?Q?i3HvS6P8WT6FLJupmKgF8quy882OqBFE+HNWefrRuzccG2BwreUv+MoBa+HU?= =?us-ascii?Q?lZo6zLz+MwZukEtdA/4i0GI/Qfk8GZtG7DnknNIAC8wHxhM5oROovRg2e9WJ?= =?us-ascii?Q?i3C9DOJMhNW39SjqM6Hp0jGeRmFfU8j/gmNFVwYr6IZH9Uj49UrIEAkadppq?= =?us-ascii?Q?gxpzNDRuY0EtXjciVxDfTW1+cbWoanMkgaJi6SE/POuAFIbGrZvDw8PcS+Ra?= =?us-ascii?Q?bTEff+T7HYEQJ5tvpyVPHPr43Yqr5sMIesaN46C4kbQmSfam1lQ4/I3lRuMf?= =?us-ascii?Q?ILzxj1O5MOvqCWult2E00OdhUfdK/5PLDo+OzH5tP2oBnK7FUNBFYIMq532P?= =?us-ascii?Q?g2ICnFXG0Bcr4ZrJDFPSMwk+WUkiK22ivF8e0ARhwAU8j7VXbves0RxWkVmY?= =?us-ascii?Q?HKOCpTBkHo6yIhL944TBBPU44QuE8N702j8IEgouo8byvHMZySI7hqNZ8WOr?= =?us-ascii?Q?IjSMu5ajaN/cv/iz1YMXahI9xDIcaJVF0qJDGWr4ouOd+LeaZfwL/7YTxKBg?= =?us-ascii?Q?QWQPgCRr6j2ADjRq1u+SHfl9qh5EDw2XEgMOp8oWp6o7kkJ2VStaA4mPBkHc?= =?us-ascii?Q?IhX/sl87?= 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:24.2737 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: 9ede1e72-789c-475b-eec8-08d89ae27e37 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: bAhPTvHPD27DOK4xsop1DMYVCVJn4dDbeBCS/ZFn+MoyEHyhjpE4C5Xk/Q3+XbV/VccbD1tIBi0/3pBYgSzTcA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4561 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, MSGID_FROM_MTA_HEADER, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Mon, 07 Dec 2020 19:01:35 -0000 This patch introduces a new class in charge of creating, tracking and destroying dwarf_entry class based objects. gdb/ChangeLog: * dwarf2/expr.c (ill_formed_expression): New function. (value_to_gdb_value): New function. (class dwarf_entry_factory): New class. (dwarf_entry_factory::~dwarf_entry_factory): New method. (dwarf_entry_factory::record_entry): New method. (dwarf_entry_factory::create_value): New method. (dwarf_entry_factory::create_undefined): New method. (dwarf_entry_factory::create_memory): New method. (dwarf_entry_factory::create_register): New method. (dwarf_entry_factory::create_implicit): New method. (dwarf_entry_factory::create_implicit_pointer): New method. (dwarf_entry_factory::create_composite): New method. (dwarf_entry_factory::entry_to_location): New method. (dwarf_entry_factory::entry_to_value): New method. (dwarf_entry_factory::value_binary_op): New method. (dwarf_entry_factory::value_negation_op): New method. (dwarf_entry_factory::value_complement_op): New method. (dwarf_entry_factory::value_cast_op): New method. --- gdb/dwarf2/expr.c | 316 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index fea82f8a87..f188240d8b 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -89,6 +89,14 @@ bits_to_bytes (ULONGEST start, ULONGEST n_bits) return (start % HOST_CHAR_BIT + n_bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; } +/* Throw an exception about the invalid DWARF expression. */ + +static void +ill_formed_expression () +{ + error (_("Ill-formed DWARF expression")); +} + /* See expr.h. */ CORE_ADDR @@ -1011,6 +1019,314 @@ write_to_location (const dwarf_location *location, struct frame_info *frame, internal_error (__FILE__, __LINE__, _("invalid location type")); } +/* Convert a value entry to the matching struct value representation + of a given TYPE. OFFSET defines the offset into the value + contents. + + We only need to support dwarf_value to gdb struct value conversion + here so that we can utilize the existing unary and binary operations + on struct value's. + + We could implement them for the dwarf_value's but that would lead + to code duplication with no real gain at the moment. */ + +static struct value * +value_to_gdb_value (const dwarf_value *value, struct type *type, + LONGEST offset = 0) +{ + size_t type_len = TYPE_LENGTH (type); + + if (offset + type_len > TYPE_LENGTH (value->get_type ())) + invalid_synthetic_pointer (); + + struct value *retval = allocate_value (type); + memcpy (value_contents_raw (retval), + value->get_contents () + offset, type_len); + + return retval; +} + +/* Factory class for creation and lifetime management of all DWARF + entries found on a DWARF evaluation stack. */ + +class dwarf_entry_factory +{ +public: + dwarf_entry_factory () = default; + ~dwarf_entry_factory (); + + /* Create a value entry of a given TYPE and copy a type size number of + bytes from the CONTENTS byte stream to the entry. */ + dwarf_value *create_value (const gdb_byte* contents, struct type *type); + + /* Creates a value entry of a TYPE type and copies the NUM + value to it's contents byte stream. */ + dwarf_value *create_value (ULONGEST num, struct type *type); + + /* Create a value entry of TYPE type and copy the NUM value to its + contents byte stream. */ + dwarf_value *create_value (LONGEST num, struct type *type); + + /* Create an undefined location description entry. */ + dwarf_undefined *create_undefined (); + + /* Create a memory location description entry. */ + dwarf_memory *create_memory (LONGEST offset, LONGEST bit_suboffset = 0, + bool stack = false); + + /* Create a register location description entry. */ + dwarf_register *create_register (unsigned int regnum, LONGEST offset = 0, + LONGEST bit_suboffset = 0); + + /* Create an implicit location description entry and copy SIZE + number of bytes from the CONTENTS byte stream to the location. + BYTE_ORDER holds the byte order of the location described. */ + dwarf_implicit *create_implicit (const gdb_byte *content, size_t size, + enum bfd_endian byte_order); + + /* Create an implicit pointer location description entry. */ + dwarf_implicit_pointer *create_implicit_pointer + (dwarf2_per_objfile *per_objfile, struct dwarf2_per_cu_data *per_cu, + int addr_size, sect_offset die_offset, LONGEST offset, + LONGEST bit_suboffset = 0); + + /* Create a composite location description entry. */ + dwarf_composite *create_composite (LONGEST offset = 0, + LONGEST bit_suboffset = 0); + + /* Convert an entry to a location description entry. If the entry + is a location description entry a dynamic cast is applied. + + In a case of a value entry, the value is implicitly + converted to a memory location description entry. */ + dwarf_location *entry_to_location (dwarf_entry *entry); + + /* Convert an entry to a value entry. If the entry is a value entry + a dynamic cast is applied. + + A location description entry is implicitly converted to a value + entry of DEFAULT_TYPE type. + Note that only 'memory location description entry' to 'value + entry' conversion is currently supported. */ + dwarf_value *entry_to_value (dwarf_entry *entry, struct type *default_type); + + /* Execute OP operation between ARG1 and ARG2 and return a new value + entry containing the result of that operation. */ + dwarf_value *value_binary_op (const dwarf_value *arg1, + const dwarf_value *arg2, enum exp_opcode op); + + /* Execute a negation operation on ARG and return a new value entry + containing the result of that operation. */ + dwarf_value *value_negation_op (const dwarf_value *arg); + + /* Execute a complement operation on ARG and return a new value + entry containing the result of that operation. */ + dwarf_value *value_complement_op (const dwarf_value *arg); + + /* Execute a cast operation on ARG and return a new value entry + containing the result of that operation. */ + dwarf_value *value_cast_op (const dwarf_value *arg, struct type *type); + +private: + /* Record entry for garbage collection. */ + void record_entry (dwarf_entry *entry); + + /* List of all entries created by the factory. */ + std::vector m_dwarf_entries; +}; + +dwarf_entry_factory::~dwarf_entry_factory () +{ + for (unsigned int i = 0; i < m_dwarf_entries.size (); i++) + { + dwarf_entry* entry = m_dwarf_entries[i]; + + entry->decref (); + + if (entry->refcount () == 0) + delete entry; + } +} + +void +dwarf_entry_factory::record_entry (dwarf_entry *entry) +{ + entry->incref (); + m_dwarf_entries.push_back (entry); +} + +dwarf_value * +dwarf_entry_factory::create_value (const gdb_byte* content, struct type *type) +{ + dwarf_value *value = new dwarf_value (content, type); + record_entry (value); + return value; +} + +dwarf_value * +dwarf_entry_factory::create_value (ULONGEST num, struct type *type) +{ + dwarf_value *value = new dwarf_value (num, type); + record_entry (value); + return value; +} + +dwarf_value * +dwarf_entry_factory::create_value (LONGEST num, struct type *type) +{ + dwarf_value *value = new dwarf_value (num, type); + record_entry (value); + return value; +} + +dwarf_undefined * +dwarf_entry_factory::create_undefined () +{ + dwarf_undefined *undefined_entry = new dwarf_undefined (); + record_entry (undefined_entry); + return undefined_entry; +} + +dwarf_memory * +dwarf_entry_factory::create_memory (LONGEST offset, LONGEST bit_suboffset, + bool stack) +{ + dwarf_memory *memory_entry + = new dwarf_memory (offset, bit_suboffset, stack); + record_entry (memory_entry); + return memory_entry; +} + +dwarf_register * +dwarf_entry_factory::create_register (unsigned int regnum, LONGEST offset, + LONGEST bit_suboffset) +{ + dwarf_register *register_entry + = new dwarf_register (regnum, offset, bit_suboffset); + record_entry (register_entry); + return register_entry; +} + +dwarf_implicit * +dwarf_entry_factory::create_implicit (const gdb_byte* content, size_t size, + enum bfd_endian byte_order) +{ + dwarf_implicit *implicit_entry + = new dwarf_implicit (content, size, byte_order); + record_entry (implicit_entry); + return implicit_entry; +} + +dwarf_implicit_pointer * +dwarf_entry_factory::create_implicit_pointer + (dwarf2_per_objfile *per_objfile, struct dwarf2_per_cu_data *per_cu, + int addr_size, sect_offset die_offset, LONGEST offset, + LONGEST bit_suboffset) +{ + dwarf_implicit_pointer *implicit_pointer_entry + = new dwarf_implicit_pointer (per_objfile, per_cu, addr_size, + die_offset, offset, bit_suboffset); + record_entry (implicit_pointer_entry); + return implicit_pointer_entry; +} + +dwarf_composite * +dwarf_entry_factory::create_composite (LONGEST offset, LONGEST bit_suboffset) +{ + dwarf_composite *composite_entry + = new dwarf_composite (offset, bit_suboffset); + record_entry (composite_entry); + return composite_entry; +} + +dwarf_location * +dwarf_entry_factory::entry_to_location (dwarf_entry *entry) +{ + /* If the given entry is already a location, + just send it back to the caller. */ + if (auto location = dynamic_cast (entry)) + return location; + + auto value = dynamic_cast (entry); + gdb_assert (value != nullptr); + + struct type *type = value->get_type (); + struct gdbarch *gdbarch = get_type_arch (type); + LONGEST offset; + + if (gdbarch_integer_to_address_p (gdbarch)) + offset = gdbarch_integer_to_address (gdbarch, type, + value->get_contents ()); + + offset = extract_unsigned_integer (value->get_contents (), + TYPE_LENGTH (type), + type_byte_order (type)); + + return create_memory (offset); +} + +dwarf_value * +dwarf_entry_factory::entry_to_value (dwarf_entry *entry, + struct type *default_type) +{ + /* If the given entry is already a value, + just send it back to the caller. */ + if (auto value = dynamic_cast (entry)) + return value; + + auto location = dynamic_cast (entry); + gdb_assert (location != nullptr); + + /* We only support memory location to value conversion at this point. + It is hard to define how would that conversion work for other + location description types. */ + if (dynamic_cast (location) == nullptr) + ill_formed_expression (); + + return create_value (location->get_offset (), default_type); +} + +/* We use the existing struct value operations to avoid code + duplication. Vector types are planned to be promoted to base types + in the future anyway which means that the subset we actually need + from these operations is just going to grow anyway. */ + +dwarf_value * +dwarf_entry_factory::value_binary_op (const dwarf_value *arg1, + const dwarf_value *arg2, + enum exp_opcode op) +{ + struct value *arg1_value = value_to_gdb_value (arg1, arg1->get_type ()); + struct value *arg2_value = value_to_gdb_value (arg2, arg2->get_type ()); + struct value *result = value_binop (arg1_value, arg2_value, op); + + return create_value (value_contents_raw (result), value_type (result)); +} + +dwarf_value * +dwarf_entry_factory::value_negation_op (const dwarf_value *arg) +{ + struct value *result + = value_neg (value_to_gdb_value (arg, arg->get_type ())); + return create_value (value_contents_raw (result), value_type (result)); +} + +dwarf_value * +dwarf_entry_factory::value_complement_op (const dwarf_value *arg) +{ + struct value *result + = value_complement (value_to_gdb_value (arg, arg->get_type ())); + return create_value (value_contents_raw (result), value_type (result)); +} + +dwarf_value * +dwarf_entry_factory::value_cast_op (const dwarf_value *arg, struct type *type) +{ + struct value *result + = value_cast (type, value_to_gdb_value (arg, arg->get_type ())); + return create_value (value_contents_raw (result), type); +} + struct piece_closure { /* Reference count. */ -- 2.17.1