From patchwork Sat Nov 2 22:36:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 100120 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D87F53857434 for ; Sat, 2 Nov 2024 22:39:14 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.burntcomma.com (mail2.burntcomma.com [217.169.27.34]) by sourceware.org (Postfix) with ESMTPS id C29763858C39 for ; Sat, 2 Nov 2024 22:36:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C29763858C39 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=harmstone.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=harmstone.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C29763858C39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.169.27.34 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730587096; cv=none; b=Fj9vFQyIvDykKTwTF18Vq5YywijTwwBGShY7VIZnNjXmzbZ7uBQCl26ZZWVzMgxrh42grXoptrvsJRvOOjMeh0udews0N4B9471W9Tx6SXYxbHLru4SuPuiHGubKxFH5muq6dtSNGXo0uVuIOeLDbPcyXq539piHw37QTLD3iIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730587096; c=relaxed/simple; bh=wgTyAtw7fG8ICzrBxFqNcQnAyKV2SQ+Xg3eDdb6ZKYU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:Mime-Version; b=LMydjRXQaYPf+4DSl18+f+dMHyQVh3psftZulVHBkjyVBKB6wAKk/9RQLBen/FIhTIO1pF6oLbsEBFAkXa5L3gnrM1MvmmnncWD6ixNYLkEaY/g2kVio3dFnlEXQ7FV5JQlCCLi7gsybWXJZjvUHVotf+8uqgtGn6EurL+2THdI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from localhost.localdomain (beren.burntcomma.com [IPv6:2a02:8012:8cf0:0:ce28:aaff:fe0d:6db2]) (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) (Client did not present a certificate) by mail.burntcomma.com (Postfix) with ESMTPSA id D3E5C1F02CB; Sat, 2 Nov 2024 22:36:30 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmstone.com; s=mail; t=1730586990; bh=8sq8VKgbrrigQm4sn2yB1ZbQyckR0poxq8XvC3KcGcw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Y+3Aw1NKZ1rpmdVe9GsS1i0tEx1CzsnUl76I4H8heLAZzDkyKRBRp/O6asS+XzBp+ CUhkC91epr2pQX7J8NtPZoCcbOqjvh+bkjJGlPscH5xkOVh985ZEP1iPUUfqcDrsF9 neFSt3tsv6dLFJehtKHP+ISBePhLYHllZYwXDPjM= From: Mark Harmstone To: gcc-patches@gcc.gnu.org Cc: Mark Harmstone Subject: [PATCH 2/3] Write LF_POINTER CodeView types for pointers to member functions or data Date: Sat, 2 Nov 2024 22:36:24 +0000 Message-ID: <20241102223625.22493-2-mark@harmstone.com> In-Reply-To: <20241102223625.22493-1-mark@harmstone.com> References: <20241102223625.22493-1-mark@harmstone.com> Mime-Version: 1.0 X-Spam-Status: No, score=-14.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org Translate DW_TAG_ptr_to_member_type DIEs into special extended LF_POINTER CodeView types. gcc/ * dwarf2codeview.cc (struct codeview_custom_type): Add new fields to lf_pointer struct in union. (write_lf_pointer): Write containing_class and ptr_to_mem_type if applicable. (get_type_num_subroutine_type): Write correct containing_class_type if this is a pointer to a member function. (get_type_num_ptr_to_member_type): New function. (get_type_num): Call get_type_num_ptr_to_member_type. * dwarf2codeview.h (CV_PTR_MODE_MASK, CV_PTR_MODE_PMEM): Define. (CV_PTR_MODE_PMFUNC, CV_PMTYPE_D_Single, CV_PMTYPE_F_Single): Likewise. --- gcc/dwarf2codeview.cc | 103 ++++++++++++++++++++++++++++++++++++++++++ gcc/dwarf2codeview.h | 9 ++++ 2 files changed, 112 insertions(+) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index 722a54b9c4e..876057b5a8c 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -1270,6 +1270,8 @@ struct codeview_custom_type { uint32_t base_type; uint32_t attributes; + uint32_t containing_class; + uint16_t ptr_to_mem_type; } lf_pointer; struct { @@ -3393,6 +3395,10 @@ write_lf_pointer (codeview_custom_type *t) uint16_t kind; uint32_t base_type; uint32_t attributes; + (following only if CV_PTR_MODE_PMEM or CV_PTR_MODE_PMFUNC in attributes) + uint32_t containing_class; + uint16_t ptr_to_mem_type; + uint16_t padding; } ATTRIBUTE_PACKED; */ @@ -3414,6 +3420,20 @@ write_lf_pointer (codeview_custom_type *t) fprint_whex (asm_out_file, t->lf_pointer.attributes); putc ('\n', asm_out_file); + if ((t->lf_pointer.attributes & CV_PTR_MODE_MASK) == CV_PTR_MODE_PMEM + || (t->lf_pointer.attributes & CV_PTR_MODE_MASK) == CV_PTR_MODE_PMFUNC) + { + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, t->lf_pointer.containing_class); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, t->lf_pointer.ptr_to_mem_type); + putc ('\n', asm_out_file); + + write_cv_padding (2); + } + asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num); } @@ -5886,6 +5906,30 @@ get_type_num_subroutine_type (dw_die_ref type, bool in_struct, return_type = T_VOID; } + /* Handle pointer to member function. */ + if (containing_class_type == 0) + { + dw_die_ref obj_ptr = get_AT_ref (type, DW_AT_object_pointer); + + if (obj_ptr) + { + dw_die_ref obj_ptr_type = get_AT_ref (obj_ptr, DW_AT_type); + + if (obj_ptr_type + && dw_get_die_tag (obj_ptr_type) == DW_TAG_pointer_type) + { + dw_die_ref cont_class = get_AT_ref (obj_ptr_type, DW_AT_type); + + if (dw_get_die_tag (cont_class) == DW_TAG_const_type) + cont_class = get_AT_ref (cont_class, DW_AT_type); + + containing_class_type = get_type_num (cont_class, in_struct, + false); + this_type = get_type_num (obj_ptr_type, in_struct, false); + } + } + } + /* Count the arguments. */ first_child = dw_get_die_child (type); @@ -6121,6 +6165,61 @@ get_type_num_array_type (dw_die_ref type, bool in_struct) return element_type; } +/* Translate a DW_TAG_ptr_to_member_type DIE, that is a pointer to member + function or field, into an LF_POINTER record. */ + +static uint32_t +get_type_num_ptr_to_member_type (dw_die_ref type, bool in_struct) +{ + uint32_t base_type_num; + uint32_t containing_class; + dw_die_ref base_type; + codeview_custom_type *ct; + + base_type = get_AT_ref (type, DW_AT_type); + + base_type_num = get_type_num (base_type, in_struct, false); + if (base_type_num == 0) + return 0; + + containing_class = get_type_num (get_AT_ref (type, DW_AT_containing_type), + in_struct, false); + + ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type)); + + ct->next = NULL; + ct->kind = LF_POINTER; + ct->lf_pointer.base_type = base_type_num; + + if (TARGET_64BIT) + { + ct->lf_pointer.attributes = CV_PTR_64; + ct->lf_pointer.attributes |= 8 << 13; + } + else + { + ct->lf_pointer.attributes = CV_PTR_NEAR32; + ct->lf_pointer.attributes |= 4 << 13; + } + + ct->lf_pointer.containing_class = containing_class; + + if (base_type && dw_get_die_tag (base_type) == DW_TAG_subroutine_type) + { + ct->lf_pointer.attributes |= CV_PTR_MODE_PMFUNC; + ct->lf_pointer.ptr_to_mem_type = CV_PMTYPE_F_Single; + } + else + { + ct->lf_pointer.attributes |= CV_PTR_MODE_PMEM; + ct->lf_pointer.ptr_to_mem_type = CV_PMTYPE_D_Single; + } + + add_custom_type (ct); + + return ct->num; +} + /* Process a DIE representing a type definition, add a CodeView type if necessary, and return its number. If it's something we can't handle, return 0. We keep a hash table so that we're not adding the same type multiple @@ -6198,6 +6297,10 @@ get_type_num (dw_die_ref type, bool in_struct, bool no_fwd_ref) num = get_type_num_subroutine_type (type, in_struct, 0, 0, 0); break; + case DW_TAG_ptr_to_member_type: + num = get_type_num_ptr_to_member_type (type, in_struct); + break; + default: num = 0; break; diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h index c631349640f..c895ef3e04c 100644 --- a/gcc/dwarf2codeview.h +++ b/gcc/dwarf2codeview.h @@ -55,9 +55,18 @@ along with GCC; see the file COPYING3. If not see /* LF_POINTER attributes. */ #define CV_PTR_NEAR32 0x0a #define CV_PTR_64 0x0c + +/* enum CV_ptrmode_e in cvinfo.h, shifted by 5 for the lfPointerAttr bitfield */ +#define CV_PTR_MODE_MASK 0xe0 #define CV_PTR_MODE_LVREF 0x20 +#define CV_PTR_MODE_PMEM 0x40 +#define CV_PTR_MODE_PMFUNC 0x60 #define CV_PTR_MODE_RVREF 0x80 +/* enum CV_pmtype_e in in cvinfo.h */ +#define CV_PMTYPE_D_Single 0x01 +#define CV_PMTYPE_F_Single 0x05 + /* LF_MODIFIER values. */ #define MOD_const 0x1 #define MOD_volatile 0x2