From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2044.outbound.protection.outlook.com [40.107.92.44]) by sourceware.org (Postfix) with ESMTPS id 9ACF83858433 for ; Thu, 14 Oct 2021 09:32:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9ACF83858433 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UXQD+9ZtTlo5uM90iLMidCgOQoXRi+LneW2VhBlkKhlpzmPXP2+hBCfEeOoplNkEHWp+RlRVYpsJ2mng/JhJwJxI0CnLAMWIoSX/MxPXqmLKFLGckVqPVB2dTsdWRU6eCjv/00LhRT6Pspue0KsUrcL43veriJEjy43jMn/UDaR75+xmhLwh7IpYLcQeE01yZc5YdFM3hwNqYxqDOINZAHGIS10vFU03pUf41NGXlukUvaZfqsFb/p1ZATk6ze8HaDJarl9AqcogLQEzKKryT5YjxviJzJUyjaLAIznn/v0c3iGdu5Rzo+9KO5oNyWuLbEYetTbCKBGZ6S5WTfnTPQ== 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=3DwW8F0aoFCrpDh+PugWQMaH5xMdAxpcKSJPKMBtPIA=; b=bhx/TaWBa13gcLarCAEyB61tLizpJO3YlJQ5G5PVjyOzlvxUzNErWTr+fUUGxXJWXh9S54K7ldAbPJD9CWGwT9g6dWZvvOu0FHdUgM2nxz02knuzjDDhgBI1y3NOj+ZDDuFAtTjrfYO+Bc073X5pVI3HuYH9Y64bPGq0B9QYQe8ejZF3So9/K6zQeC+enF2L4ZS6I6/nOVwGwnDgH0EXV6oMu13mc7ZlBuXN5s2W9HP8anQefeNJTt4wQM2hzh3OsECbFn6hj2VxbA5JgOMO9V0JUGvnNKi8jQ9qTnA94N8XQHF3UDbtzuLnmnk8gHQcfzqljxqZ7zjhxRkNCX8FuQ== 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 DM5PR1401CA0024.namprd14.prod.outlook.com (2603:10b6:4:4a::34) by DM5PR12MB1241.namprd12.prod.outlook.com (2603:10b6:3:72::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.22; Thu, 14 Oct 2021 09:32:57 +0000 Received: from DM6NAM11FT012.eop-nam11.prod.protection.outlook.com (2603:10b6:4:4a:cafe::5b) by DM5PR1401CA0024.outlook.office365.com (2603:10b6:4:4a::34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.14 via Frontend Transport; Thu, 14 Oct 2021 09:32:57 +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 DM6NAM11FT012.mail.protection.outlook.com (10.13.173.109) 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:32:57 +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:32:56 -0500 From: Zoran Zaric To: Subject: [PATCH v3 03/28] Add new classes that model DWARF stack element Date: Thu, 14 Oct 2021 10:32:10 +0100 Message-ID: <20211014093235.69756-4-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-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit 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: 91242fd5-7299-4775-c94c-08d98ef59b78 X-MS-TrafficTypeDiagnostic: DM5PR12MB1241: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:9508; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: tC2iQUnZE97pi5X1GX2DEK66QRvprKF1xKB1RgbXUGxmB+vmcsFK95l7bOb6zaQxegzdhWgNpHQ7+BxFYPAyy3/v+oUAHVygkIvDeWMXJ8uy7k6aIPRKh2nMnBbAzST53p+AmDGIxGGvUcUI2Du4o6M9E0iTMUuOvTvEuPG+i7GLe+BoKLcdFEn4SKULUlKSPkompMigCWyta3GYUlOeOu17hscxrEtURLx15lvqBnobvJADGloPSk49RdOJNmqT4dv96xFRPcjzX4Md1aQFSUnqiSC9Miy7ftM8t1/JaZFlLPB2YU54jQhNL1rphc0lF5cSUovApx6F9iQemY/qTzfYCk5BxCWSiWOuKorLchhxWvCvhjeZ5XGVBBFWV5DqFPwSmDzh35BOC33NywfmgOO+2SjOMBnpHdpuUyNuKbhalL+qJX7/b38UvvMTJTE0j6U70/d7x12raow3ww2ce0lT6pzLk/qwwou3LsnIrvjsYvJHAyQjGBk2CkswRYB5cXA7bC3KtrqY+O80C6EZgJ8OdhrdsJ3QG0k/mJmCJLJcPLsbG5NHVJNt4gzr3o3V908caRQBwc1vwNO5BcxtBvBPss7syqAnFN9+s+9nnr8Rxmp7iu8hU4628D/4EsTqV2HUSiFnvBCN9imWUE9FzaayMvp3wyNQjijPb7bCotGELhTNfPq6onsLpTcTIfBq7xBCCZ+TQoKphK+EMN0H3U5fMoEog0g+4mwEmBXyWiwb7p2FyIM+RcezQkJ5Imt0D3U7tK0t8iGT8j0FVJrEtLGIZpDiIF/Q7XIZag8smb6XPp5ptl1qd+rG9buCE6kG 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)(6666004)(83380400001)(2616005)(8676002)(426003)(36756003)(44832011)(47076005)(4326008)(16526019)(70206006)(81166007)(966005)(36860700001)(508600001)(82310400003)(1076003)(26005)(186003)(8936002)(6916009)(2906002)(316002)(30864003)(336012)(86362001)(5660300002)(70586007)(356005)(36900700001); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Oct 2021 09:32:57.5322 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 91242fd5-7299-4775-c94c-08d98ef59b78 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: DM6NAM11FT012.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1241 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, 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:04 -0000 From: Zoran Zaric The rest of the patch series addresses the issues described in a "Motivation" section of the AMD’s DWARF standard extensions that can be found at: https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html The document describes a couple of main issues found when using the current DWARF 5 version to describe optimized code for SIMD and SIMT architectures. Without going much into details described in the document, the main point is that DWARF version 5 does not allow a proper support for address spaces and it does not allow a location description to be used anywhere in the DWARF expression, instead a location description can using a result left on the DWARF stack (after the evaluation of that expression) to describe the location. Both issues can be solved in a clean way by introducing a new set of classes that describe all entry types which can be placed on a DWARF stack, while keeping most of backward compatibility with the previous standard version. These entry types can now be either a typed value or any location description. Known edge case where placing a location description on the DWARF stack is not fully backward compatible with DWARF version 5 is in the case of DW_OP_call operations, where the current standard only defines that an expression stack is shared between the caller and the callee, but there it is unknown what happens with the resuling location description after the evaluation of the callee's location description expression. Considering that this edge case is not defined in the standard, it would be very unusual and dangerous for any compiler to use it in their own way and in the existing testsuite, there is no indication of that. Currently, the result of an expression evaluation is kept in a separate data structure, while with the new approach, it will be always found as a top element of the DWARF stack. Question here is, why do we need a new set of classes and why not just use the struct value instead? As it stands, there are couple of issues with using the struct value to describe a DWARF stack element: - It is not designed to represent a DWARF location description specifically, instead it behaves more like unified debug information format that represents an actual target resource. One example of this is accessing data of a struct value register location description, where if the amount of data accessed is larger then the register, results in accessing more then one register. In DWARF this is not a valid behavior and locations that span more then one register should be described as a composite location description. - There is a tight coupling between struct value and it’s type information, regardless if the data represented is describing a value (not_lval) or a location description. While the type information dictates how the data is accessed for a struct value case, in DWARF, location description doesn’t have a type so data access is not bound by it. - DWARF values only support much simpler base types, while struct value can be linked to any type. Admittedly, new classes are still using the same struct value infrastructure for a value based operations at the moment, but that is planned to change in the near future. - struct value register location description requires a frame id information which makes them unsuitable for CFA expression evaluation. So, there seems to be a lack of separation of concerns in the design of a struct value infrastructure, while the new classes are handling one specific purpose and are completely encapsulated in the expr.c. Additional benefit of this design is that it makes a step in a right direction for being able to evaluate DWARF expressions on a gdbserver side in the near future, which sounds like a desirable thing. It is also worth mentioning that this new location description representation is based on a bit granularity (the bit_suboffset class member) even though the DWARF standard has a very limited support for it (mostly used for DW_OP_bit_piece operation). By allowing any location description to define a bit sub-offset of the location, we are able to give more options for supporting of new concepts (like the existing packed arrays in Ada language). In this patch, a new set of classes that describe a DWARF stack element are added. The new classes are: - Value - describes a numerical value with a DWARF base type. - Location description - describes a DWARF location description. - Undefined location - describes a location that is not defined. - Memory location - describes a location in memory. - Register location - describes a register location in a frame context. - Implicit location - describes a location that implicitly holds a value that it describes. - Implicit pointer - describes a concept of an implicit pointer to a source variable. - Composite location - describes a location that is composed from pieces of other location descriptions. For now, these classes are just defined, and they are planned to be used by the following patches. gdb/ChangeLog: * dwarf2/expr.c (class dwarf_entry): New class. (class dwarf_value): New class. (class dwarf_location): New class. (class dwarf_undefined): New class. (class dwarf_memory): New class. (class dwarf_register): New class. (class dwarf_implicit): New class. (class dwarf_implicit_pointer): New class. (class dwarf_composite): New class. * value.c (pack_unsigned_long): Expose function. * value.h (pack_unsigned_long): Expose function. --- gdb/dwarf2/expr.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/value.c | 2 +- gdb/value.h | 2 + 3 files changed, 237 insertions(+), 1 deletion(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index c0ca78ce236..f44dfd1b260 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -271,6 +271,240 @@ write_to_memory (CORE_ADDR address, const gdb_byte *buffer, length, buffer); } +/* Base class that describes entries found on a DWARF expression + evaluation stack. */ + +class dwarf_entry +{ +public: + /* Not expected to be called on it's own. */ + dwarf_entry () = default; + + virtual ~dwarf_entry () = default; +}; + +/* Location description entry found on a DWARF expression evaluation + stack. + + Types of locations descirbed can be: register location, memory + location, implicit location, implicit pointer location, undefined + location and composite location (composed out of any of the location + types including another composite location). */ + +class dwarf_location : public dwarf_entry +{ +public: + /* Not expected to be called on it's own. */ + dwarf_location (gdbarch *arch, LONGEST offset) + : m_arch (arch), m_offset (offset) + {} + + virtual ~dwarf_location () = default; + + /* Add bit offset to the location description. */ + void add_bit_offset (LONGEST bit_offset) + { + LONGEST bit_total_offset = m_bit_suboffset + bit_offset; + + m_offset += bit_total_offset / HOST_CHAR_BIT; + m_bit_suboffset = bit_total_offset % HOST_CHAR_BIT; + }; + + void set_initialised (bool initialised) + { + m_initialised = initialised; + }; + +protected: + /* Architecture of the location. */ + gdbarch *m_arch; + + /* Byte offset into the location. */ + LONGEST m_offset; + + /* Bit suboffset of the last byte. */ + LONGEST m_bit_suboffset = 0; + + /* Whether the location is initialized. Used for non-standard + DW_OP_GNU_uninit operation. */ + bool m_initialised = true; +}; + +/* Value entry found on a DWARF expression evaluation stack. */ + +class dwarf_value : public dwarf_entry +{ +public: + dwarf_value (gdb::array_view contents, struct type *type) + : m_contents (contents.begin (), contents.end ()), m_type (type) + {} + + dwarf_value (ULONGEST value, struct type *type) + : m_contents (TYPE_LENGTH (type)), m_type (type) + { + pack_unsigned_long (m_contents.data (), type, value); + } + + dwarf_value (LONGEST value, struct type *type) + : m_contents (TYPE_LENGTH (type)), m_type (type) + { + pack_unsigned_long (m_contents.data (), type, value); + } + + gdb::array_view contents () const + { + return m_contents; + } + + struct type* type () const + { + return m_type; + } + + LONGEST to_long () const + { + return unpack_long (m_type, m_contents.data ()); + } + +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; +}; + +/* Undefined location description entry. This is a special location + description type that describes the location description that is + not known. */ + +class dwarf_undefined final : public dwarf_location +{ +public: + dwarf_undefined (gdbarch *arch) + : dwarf_location (arch, 0) + {} +}; + +class dwarf_memory final : public dwarf_location +{ +public: + dwarf_memory (gdbarch *arch, LONGEST offset, bool stack = false) + : dwarf_location (arch, offset), m_stack (stack) + {} + + void set_stack (bool stack) + { + m_stack = stack; + }; + +private: + /* True if the location belongs to a stack memory region. */ + bool m_stack; +}; + +/* Register location description entry. */ + +class dwarf_register final : public dwarf_location +{ +public: + dwarf_register (gdbarch *arch, unsigned int regnum, LONGEST offset = 0) + : dwarf_location (arch, offset), m_regnum (regnum) + {} + +private: + /* DWARF register number. */ + unsigned int m_regnum; +}; + +/* Implicit location description entry. Describes a location + description not found on the target but instead saved in a + gdb-allocated buffer. */ + +class dwarf_implicit final : public dwarf_location +{ +public: + + dwarf_implicit (gdbarch *arch, gdb::array_view contents, + enum bfd_endian byte_order) + : dwarf_location (arch, 0), + m_contents (contents.begin (), contents.end ()), + m_byte_order (byte_order) + {} + +private: + /* Implicit location contents as a stream of bytes in target byte-order. */ + gdb::byte_vector m_contents; + + /* Contents original byte order. */ + bfd_endian m_byte_order; +}; + +/* Implicit pointer location description entry. */ + +class dwarf_implicit_pointer final : public dwarf_location +{ +public: + dwarf_implicit_pointer (gdbarch *arch, + dwarf2_per_objfile *per_objfile, + dwarf2_per_cu_data *per_cu, + int addr_size, sect_offset die_offset, + LONGEST offset) + : dwarf_location (arch, offset), + m_per_objfile (per_objfile), m_per_cu (per_cu), + m_addr_size (addr_size), m_die_offset (die_offset) + {} + +private: + /* Per object file data of the implicit pointer. */ + dwarf2_per_objfile *m_per_objfile; + + /* Compilation unit context of the implicit pointer. */ + dwarf2_per_cu_data *m_per_cu; + + /* Address size for the evaluation. */ + int m_addr_size; + + /* DWARF die offset pointed by the implicit pointer. */ + sect_offset m_die_offset; +}; + +/* Composite location description entry. */ + +class dwarf_composite final : public dwarf_location +{ +public: + dwarf_composite (gdbarch *arch, dwarf2_per_cu_data *per_cu) + : dwarf_location (arch, 0), m_per_cu (per_cu) + {} + + void add_piece (std::unique_ptr location, ULONGEST bit_size) + { + gdb_assert (location != nullptr); + m_pieces.emplace_back (std::move (location), bit_size); + } + +private: + /* Composite piece that contains a piece location + description and it's size. */ + struct piece + { + public: + piece (std::unique_ptr location, ULONGEST size) + : location (std::move (location)), size (size) + {} + + std::unique_ptr location; + ULONGEST size; + }; + + /* Compilation unit context of the pointer. */ + dwarf2_per_cu_data *m_per_cu; + + /* Vector of composite pieces. */ + std::vector m_pieces; +}; + struct piece_closure { /* Reference count. */ diff --git a/gdb/value.c b/gdb/value.c index bb2adae0a51..0623d29a595 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3465,7 +3465,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num) /* Pack NUM into BUF using a target format of TYPE. */ -static void +void pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) { LONGEST len; diff --git a/gdb/value.h b/gdb/value.h index 45012372dbf..a01dc8de9f7 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -678,6 +678,8 @@ extern struct value *value_field_bitfield (struct type *type, int fieldno, const struct value *val); extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num); +extern void pack_unsigned_long (gdb_byte *buf, struct type *type, + ULONGEST num); extern struct value *value_from_longest (struct type *type, LONGEST num); extern struct value *value_from_ulongest (struct type *type, ULONGEST num); -- 2.17.1