From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by sourceware.org (Postfix) with ESMTPS id 2E73C385734D for ; Fri, 3 Jun 2022 02:04:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2E73C385734D Received: from pps.filterd (m0044010.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 2530qfot004361; Thu, 2 Jun 2022 19:04:19 -0700 Received: from nam04-dm6-obe.outbound.protection.outlook.com (mail-dm6nam04lp2040.outbound.protection.outlook.com [104.47.73.40]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3geu05dahm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 02 Jun 2022 19:04:18 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mTXAOp6NWiqD6gYNO9+YC6a8bwzx6dBw91LtmyNa4WzO/O5PsLHamOt8jEO/Ixs+t23Dgqm+Xa7fZjrH+bgkLXJ3hCghDbnVcEoxsjiOpWKxLBVWusVSr2WR8QNy3OsuMAYELLzXKI5SWyL0/gdOZvjVwl3Vn/kl7AnYwx1YofmkpbMUtV/hz9yrLQU0kJkOqIiA7JLRp9/KMH+/BBwEKBFFMfCiQSq2TQgAN3NcVgKVVSN5201S/qBEurdJHVGZkhC+uvqjLrDAD/ai7zs+tSrqt/apaIr6GK3xfTlkdMqDT23V8P4iqKoI50pQgvBCTGCCzCbwXNWoWNNNDnCUdg== 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=L/2vIUxR2iPdYpeGbbVd0i80HceZkO8sUndAaOhjHtY=; b=IchbIguiyrvzgvYfbuHJvfCTkqOeDY2AKk9hkcyzoZ6uEz1AM6+QQSkNTutwb1guX/UQ5RLc3/DpctZQXVswy1VJgxRgp+vY8ls1nCaVCc4jCMOcxGCZ6bQq8XJYT42Rqb0TK6r3JKQb+/pjEocq/NX7Irv8SARGULZv4KAxgr7v8s0zUIOS8c1aygfpcXLk8BzZx6HrUcQEHfmAY9s/BFSv8KG+gj0hryLxfM4C+pOloAaBH2GzHOojtAOyDy0O8nr6CbMgknThQPyiNet/hzMQFYnSYIgevUCiVHxMLewLqOUjOrwmC1qbrRSJboJENlQlzMaca4Sor6tESofsdg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SN6PR1501MB2064.namprd15.prod.outlook.com (2603:10b6:805:d::27) by CH2PR15MB3638.namprd15.prod.outlook.com (2603:10b6:610:8::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5314.15; Fri, 3 Jun 2022 02:04:16 +0000 Received: from SN6PR1501MB2064.namprd15.prod.outlook.com ([fe80::fde9:4:70a9:48c2]) by SN6PR1501MB2064.namprd15.prod.outlook.com ([fe80::fde9:4:70a9:48c2%7]) with mapi id 15.20.5314.013; Fri, 3 Jun 2022 02:04:16 +0000 Message-ID: <3be9e5df-e74a-bca4-2fa8-f865c4da525b@fb.com> Date: Thu, 2 Jun 2022 19:04:13 -0700 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.9.1 Subject: Re: [ping2][PATCH 0/8][RFC] Support BTF decl_tag and type_tag annotations Content-Language: en-US To: David Faust Cc: "Jose E. Marchesi" , Joseph Myers , Yonghong Song via Gcc-patches References: <20220401194216.16469-1-david.faust@oracle.com> <7419ae42-55c8-87d6-2a19-74cebff51fb4@oracle.com> <7125844e-f538-faca-1cdf-5322492c00d9@fb.com> <54eb0e21-cbca-dbf5-88f1-d8febd091be8@fb.com> <9ec418b0-b002-085f-fc89-5a05fc3cd3c4@fb.com> <87h75fxk80.fsf@oracle.com> <0f4fcf9d-c0ab-6221-063f-67c1e6808fe1@oracle.com> <0cb066a7-ba9c-123b-d55a-58667073543f@oracle.com> From: Yonghong Song In-Reply-To: <0cb066a7-ba9c-123b-d55a-58667073543f@oracle.com> Content-Type: text/plain; charset=UTF-8; format=flowed X-ClientProxiedBy: BYAPR02CA0038.namprd02.prod.outlook.com (2603:10b6:a03:54::15) To SN6PR1501MB2064.namprd15.prod.outlook.com (2603:10b6:805:d::27) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: fedc290c-d7b9-4b99-8a48-08da45055ce2 X-MS-TrafficTypeDiagnostic: CH2PR15MB3638:EE_ X-Microsoft-Antispam-PRVS: X-FB-Source: Internal X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 00NuDn8XlZectnry+1wHqWlGwwEZobLFfZQca6vwsHaSIM99VMet5JM6ekn6pPqr49igF36Mu6lC0BNX+JTJeoT6U6vaL/CizSLPEggKBduDPS2bTPDBTNVkTvnkk+Fr2fFHW7pjFVj+M50ZKXisLSU8LMDC56O5bQwxGIHWnWsEDltgk8oGWs5sombo2eEdwG1Wt+tFI01k+TU4d3MdSO6f5686aYSlC6h0XQjq2weszRf5G3y93QGtK2nh9KWZ+AKbJEzPd5qS9TFeXVZODcoFU3R3aTrKY9g15prLccC33omySIWETNjYELkYuETCWu8HTrFOHVJo+fe3Dijpen6IMYpp9VuYePMTIJgOqJBNFVbq+K1FVKhmu/TO1V3hPXecQw4apWJt1Ep4WkiGBor2e7JUpYR7TVCfyJfsxuESLTJ7S/YEs6nACVjcjjPjAf0hXSiKMkNPAGs3ZAYm8ygP31c9CSl0UzupmBNzLd+PHnpki85Kf8FbvOsjyAriS9VD3osaY47Q5DY3bcgqYLrUyrgWsKV/76/goq9dX9CiwVD1r2fqSofMDnb2mGNZX6j5CWc+1m3F+NSwaBQeKJX7n42YNgau8/zwmo4wdcRu5WUOJxRuKLHR5kRF+/YlXBi7ZkTLY53JJNxSmQAu54b7JLGp35/A8T59VgI3FDajg46f/KFg8iZbEZOkTB0TJ+IvHzbJVdDm7I4+TnUCHN+5AHCl+sHlrsInWav2ZY8rZdidEIUYfPPdAN/0LVn/XJsiZR+/DeFi937W36UjhW1yu4lppwKvaCO+6K7bNaL5RAm9d7htmCoyVDejLyiT X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SN6PR1501MB2064.namprd15.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230001)(4636009)(366004)(2906002)(2616005)(53546011)(186003)(6506007)(36756003)(5660300002)(52116002)(31686004)(8936002)(6666004)(31696002)(316002)(86362001)(38100700002)(6486002)(508600001)(966005)(66946007)(66476007)(83380400001)(66556008)(6512007)(30864003)(8676002)(6916009)(54906003)(4326008)(45980500001)(43740500002); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?VnBmWVFma1Viakt1aDBWSXpFVVZSbEJGdGRRaitsSDdabms4WnB4dVVjN0or?= =?utf-8?B?alJXOThFTTRCR1NaQkNzWW5XU2ZsSnhzcGc4TVNNU1I0YlFlNmdWR1o3NlZk?= =?utf-8?B?cnhjaVBLNUZKYmFTdFpGWWpBRVAvVWlmL3FaWGhJQzJUR011UWJwWU9HY3BP?= =?utf-8?B?azNaME9ab3d2WVdyc1FuN1dLU1R1elpXOWNwOUtsYzN5VEJSOTg3RHpaWUpG?= =?utf-8?B?VUpQNjFKSlF3V3pQZ04yVlVtQ0FyVkVhM2toRnc4dGRjZG5pazN3RGJ1OTRw?= =?utf-8?B?cFpMSkRPbnhhU0NkNWtuNG8rTjJmOXdyK0l2QU9zRlJVWVFkVXRSaldjZXJq?= =?utf-8?B?N1pGRkdoeDVPQVpoRDFVd1BlbWQ3R1A4Ylg2TzBRSmdoVWw0T0VDWVBvVEZB?= =?utf-8?B?SEk4a043UHN1MU5SZWxqcUZzM0o3TE1OTDFJb2ErMkNKam1vMWhzYlV2NHUr?= =?utf-8?B?NWovSEFEbk11VTE0T2lxY1lnWkVtaEtEd2tFbWkwamlSU2pIS2huUndTcFRu?= =?utf-8?B?REFoelRJR2VFL1UwUFp2elpiWEJzNTU0dnRrQVNGUGZjWFd6bGMxRFA5c2VX?= =?utf-8?B?d0NXbFA0RFY4REZvV0lUbnNZZWtwbHNTbWZPNFE1WEVZNXV1eExDMnpWNHgx?= =?utf-8?B?N0dKVzBFcWN2a0xlM0dOUnpHZnIzMytYN0wwQ1hTV0N3cm4zVk1td3g3VFhQ?= =?utf-8?B?WTNQbkNuc2ozdzJpdjlTa0V2KytnMWhZdytEOG0rZi9OajZVU204ZVFzYVpE?= =?utf-8?B?d21hRGovOFZkYUpUTEtsWkZuaytJbzFmSnBRc3BubHlRK2ZCRk05UXJtdTFU?= =?utf-8?B?NjNQZ3ZIUFVzUW91REtuYWVnREkzK3RLYlpnOUo4a3JQTEVIbzQxTDluUHUy?= =?utf-8?B?cHU3ekxGVHhiN2hSZGlobmdRSXppQnVsZzd0SHVJVEZiUjVkTitUSXhjQnBo?= =?utf-8?B?OU9EQVd6VEdIb3ZoSmpQN25jRlRaMldqVXVCcWJqQ2E3K1JQZE9aMFBzV3pH?= =?utf-8?B?UUVrNzNKOUFBYm14VCtDTDBJbGE4dURFdVdCeFFXcUQrWG5QUWM2VXRMVnlS?= =?utf-8?B?ZHRpaEE4NTd0L28wNFBJS3pTSFJkTVhUTnBwTTd1UHp3QitEMmhPOWpZMDVo?= =?utf-8?B?SVYxRnFDenk2UU84aXYxUzNBdmVGZVdocDg5MWdta0xySHRXbXFxVjlhTUw1?= =?utf-8?B?dktxTlZCcXF1MGQrQW40c2pvT0oyUGR6RlUzZmthR0NZVXA2U01LNkZzN25t?= =?utf-8?B?RFJ6cXpFUE1BTHQ3QTZkck0rQ1o0ZU9BVEVMamZzMUVNRzhyRkpodnUwbnZS?= =?utf-8?B?ZUZIUThneWc2a1BJT0R6d0J4UTNBQk0wd3VudUJqdzhIMjI4VlJOUnppVUg5?= =?utf-8?B?V0Rya05ZOUlyRytSQm1QbWZKOVl6UFRhdWsySkphNnp3dDQyZWlKUXNRcmRP?= =?utf-8?B?SVNXTW0wZ0FZcFlUbERVM1Y2R1pBeW5mWmtCSDhValNXeTI5QkxENG1nYnNO?= =?utf-8?B?TEI0djg4dDhQMHZmSld0TmdjYnEveXI5cFU3Y29UbDJ1SDRSVGhrdXA1Tnpy?= =?utf-8?B?elBpaWlZRlFTclk2QnpEYTFnS0wzSllZUmpxUEkxMVNJb2ZlU3FXaVl6RzZ3?= =?utf-8?B?Mzh1cWxBZGpESkhCbmY1NlduOTYybUZVeVlodzlvMHU2c0hZdmNNSHd4Rnhp?= =?utf-8?B?akNZVmR2ZUJFa3JUL3hUMkQvT1N0UnRwdStRYng4ZFZyaWpVekFYYUE5VGtu?= =?utf-8?B?dzR4SURacXdIbmlmeEluWmlocDFQYTRvRnBWQTFCVzBLSlBCbW9acUJvVWZX?= =?utf-8?B?YlhQN0Y5TFBWbGI0Z20wM3BYOHBQSEtIRVppRnVJUGdhRVJma05kMlNNOGJ1?= =?utf-8?B?MVBRQVB5M3VrU2ovamZpc1dMTG83WFBkMkF2MHpqbmtiQXhYa3hGYXRXMjhz?= =?utf-8?B?cW42a0NWWTE0RitCaGVudGhWbFExZkJtaVZkdVI1cnE2eTIzUjJPQWRhUGtH?= =?utf-8?B?clhpckl4U3Y5OFdBdU00enVzRnpMT2Rwb1dCS1BEdEF3ZTlvTVVVVngvQitE?= =?utf-8?B?dmtLcVg1dWVlbEt1elFDR00wanE4UXA5S3FTb003MG9qb0JadG9KK3h3RUtS?= =?utf-8?B?ajNaZFRCQnUya2MxRGJTaTgvTW8zbEp5OWg3a0lvQ0NONUpuVHA2NHlEVUdR?= =?utf-8?B?eUVPVnlUblhCTXY3QmFGVzVJWW85QjZCd0JKZHZPNFQ2TXVHaVNqVTBleVZK?= =?utf-8?B?dXhNaTR6aFBzclR3dWdibmEra2VuMVJYWjhkN0hEbmR3bzc1SzhRTkdHYm1v?= =?utf-8?B?VlgrNjljNmxxSFp3Y0M3OTV2R1ZaUHV6cWh2dC9CcTBxeldReXQ4R3VaUDky?= =?utf-8?Q?Kg6wYx4PoP38Ed5I=3D?= X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-Network-Message-Id: fedc290c-d7b9-4b99-8a48-08da45055ce2 X-MS-Exchange-CrossTenant-AuthSource: SN6PR1501MB2064.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Jun 2022 02:04:16.4037 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Nl/ZxwMafJH7V8UyZ5ACAWfDKEEYL9fkRDtencFtIlUd6lhcD9y0QUOrZJ3AjpIN X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR15MB3638 X-Proofpoint-GUID: TWdxiYnCZ4xxZm4YH-CmHxhBPSC9c3pz X-Proofpoint-ORIG-GUID: TWdxiYnCZ4xxZm4YH-CmHxhBPSC9c3pz Content-Transfer-Encoding: 8bit X-Proofpoint-UnRewURL: 1 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.874,Hydra:6.0.517,FMLib:17.11.64.514 definitions=2022-06-03_01,2022-06-02_01,2022-02-23_01 X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00, BODY_8BITS, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, NICE_REPLY_A, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Jun 2022 02:04:26 -0000 On 5/27/22 12:56 PM, David Faust wrote: > > > On 5/26/22 00:29, Yonghong Song wrote: >> >> >> On 5/24/22 10:04 AM, David Faust wrote: >>> >>> >>> On 5/24/22 09:03, Yonghong Song wrote: >>>> >>>> >>>> On 5/24/22 8:53 AM, David Faust wrote: >>>>> >>>>> >>>>> On 5/24/22 04:07, Jose E. Marchesi wrote: >>>>>> >>>>>>> On 5/11/22 11:44 AM, David Faust wrote: >>>>>>>> >>>>>>>> On 5/10/22 22:05, Yonghong Song wrote: >>>>>>>>> >>>>>>>>> >>>>>>>>> On 5/10/22 8:43 PM, Yonghong Song wrote: >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On 5/6/22 2:18 PM, David Faust wrote: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On 5/5/22 16:00, Yonghong Song wrote: >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On 5/4/22 10:03 AM, David Faust wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On 5/3/22 15:32, Joseph Myers wrote: >>>>>>>>>>>>>> On Mon, 2 May 2022, David Faust via Gcc-patches wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Consider the following example: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>       #define __typetag1 __attribute__((btf_type_tag("tag1"))) >>>>>>>>>>>>>>>       #define __typetag2 __attribute__((btf_type_tag("tag2"))) >>>>>>>>>>>>>>>       #define __typetag3 __attribute__((btf_type_tag("tag3"))) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>       int __typetag1 * __typetag2 __typetag3 * g; >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The expected behavior is that 'g' is "a pointer with tags >>>>>>>>>>>>>>> 'tag2' and >>>>>>>>>>>>>>> 'tag3', >>>>>>>>>>>>>>> to a pointer with tag 'tag1' to an int". i.e.: >>>>>>>>>>>>>> >>>>>>>>>>>>>> That's not a correct expectation for either GNU __attribute__ or >>>>>>>>>>>>>> C2x [[]] >>>>>>>>>>>>>> attribute syntax.  In either syntax, __typetag2 __typetag3 should >>>>>>>>>>>>>> apply to >>>>>>>>>>>>>> the type to which g points, not to g or its type, just as if >>>>>>>>>>>>>> you had a >>>>>>>>>>>>>> type qualifier there.  You'd need to put the attributes (or >>>>>>>>>>>>>> qualifier) >>>>>>>>>>>>>> after the *, not before, to make them apply to the pointer >>>>>>>>>>>>>> type. See >>>>>>>>>>>>>> "Attribute Syntax" in the GCC manual for how the syntax is >>>>>>>>>>>>>> defined for >>>>>>>>>>>>>> GNU >>>>>>>>>>>>>> attributes and deduce in turn, for each subsequence of the tokens >>>>>>>>>>>>>> matching >>>>>>>>>>>>>> the syntax for some kind of declarator, what the type for "T D1" >>>>>>>>>>>>>> would be >>>>>>>>>>>>>> as defined there and in the C standard, as deduced from the type for >>>>>>>>>>>>>> "T D" >>>>>>>>>>>>>> for a sub-declarator D. >>>>>>>>>>>>>>    >> But GCC's attribute parsing produces a variable 'g' >>>>>>>>>>>>>> which is "a >>>>>>>>>>>>> pointer with >>>>>>>>>>>>>>> tag 'tag1' to a pointer with tags 'tag2' and 'tag3' to an >>>>>>>>>>>>>>> int", i.e. >>>>>>>>>>>>>> >>>>>>>>>>>>>> In GNU syntax, __typetag1 applies to the declaration, whereas in C2x >>>>>>>>>>>>>> syntax it applies to int.  Again, if you wanted it to apply to the >>>>>>>>>>>>>> pointer >>>>>>>>>>>>>> type it would need to go after the * not before. >>>>>>>>>>>>>> >>>>>>>>>>>>>> If you are concerned with the fine details of what construct an >>>>>>>>>>>>>> attribute >>>>>>>>>>>>>> appertains to, I recommend using C2x syntax not GNU syntax. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Joseph, thank you! This is very helpful. My understanding of >>>>>>>>>>>>> the syntax >>>>>>>>>>>>> was not correct. >>>>>>>>>>>>> >>>>>>>>>>>>> (Actually, I made a bad mistake in paraphrasing this example from the >>>>>>>>>>>>> discussion of it in the series cover letter. But, the reason >>>>>>>>>>>>> why it is >>>>>>>>>>>>> incorrect is the same.) >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Yonghong, is the specific ordering an expectation in BPF programs or >>>>>>>>>>>>> other users of the tags? >>>>>>>>>>>> >>>>>>>>>>>> This is probably a language writing issue. We are saying tags only >>>>>>>>>>>> apply to pointer. We probably should say it only apply to pointee. >>>>>>>>>>>> >>>>>>>>>>>> $ cat t.c >>>>>>>>>>>> int const *ptr; >>>>>>>>>>>> >>>>>>>>>>>> the llvm ir debuginfo: >>>>>>>>>>>> >>>>>>>>>>>> !5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) >>>>>>>>>>>> !6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7) >>>>>>>>>>>> !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) >>>>>>>>>>>> >>>>>>>>>>>> We could replace 'const' with a tag like below: >>>>>>>>>>>> >>>>>>>>>>>> int __attribute__((btf_type_tag("tag"))) *ptr; >>>>>>>>>>>> >>>>>>>>>>>> !5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, >>>>>>>>>>>> annotations: !7) >>>>>>>>>>>> !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) >>>>>>>>>>>> !7 = !{!8} >>>>>>>>>>>> !8 = !{!"btf_type_tag", !"tag"} >>>>>>>>>>>> >>>>>>>>>>>> In the above IR, we generate annotations to pointer_type because >>>>>>>>>>>> we didn't invent a new DI type for encode btf_type_tag. But it is >>>>>>>>>>>> totally okay to have IR looks like >>>>>>>>>>>> >>>>>>>>>>>> !5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64) >>>>>>>>>>>> !11 = !DIBtfTypeTagType(..., baseType: !6, name: !"Tag") >>>>>>>>>>>> !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) >>>>>>>>>>>> >>>>>>>>>>> OK, thanks. >>>>>>>>>>> >>>>>>>>>>> There is still the question of why the DWARF generated for this case >>>>>>>>>>> that I have been concerned about: >>>>>>>>>>> >>>>>>>>>>>     int __typetag1 * __typetag2 __typetag3 * g; >>>>>>>>>>> >>>>>>>>>>> differs between GCC (with this series) and clang. After studying it, >>>>>>>>>>> GCC is doing with the attributes exactly as is described in the >>>>>>>>>>> Attribute Syntax portion of the GCC manual where the GNU syntax is >>>>>>>>>>> described. I do not think there is any problem here. >>>>>>>>>>> >>>>>>>>>>> So the difference in DWARF suggests to me that clang is not handling >>>>>>>>>>> the GNU attribute syntax in this particular case correctly, since it >>>>>>>>>>> seems to be associating __typetag2 and __typetag3 to g's type rather >>>>>>>>>>> than the type to which it points. >>>>>>>>>>> >>>>>>>>>>> I am not sure whether for the use purposes of the tags this difference >>>>>>>>>>> is very important, but it is worth noting. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> As Joseph suggested, it may be better to encourage users of these tags >>>>>>>>>>> to use the C2x attribute syntax if they are concerned with precisely >>>>>>>>>>> which construct the tag applies. >>>>>>>>>>> >>>>>>>>>>> This would also be a way around any issues in handling the attributes >>>>>>>>>>> due to the GNU syntax. >>>>>>>>>>> >>>>>>>>>>> I tried a few test cases using C2x syntax BTF type tags with a >>>>>>>>>>> clang-15 build, but ran into some issues (in particular, some of the >>>>>>>>>>> tag attributes being ignored altogether). I couldn't find confirmation >>>>>>>>>>> whether C2x attribute syntax is fully supported in clang yet, so maybe >>>>>>>>>>> this isn't expected to work. Do you know whether the C2x syntax is >>>>>>>>>>> fully supported in clang yet? >>>>>>>>>> >>>>>>>>>> Actually, I don't know either. But since the btf decl_tag and type_tag >>>>>>>>>> are also used to compile linux kernel and the minimum compiler version >>>>>>>>>> to compile kernel is gcc5.1 and clang11. I am not sure whether gcc5.1 >>>>>>>>>> supports c2x or not, I guess probably not. So I think we most likely >>>>>>>>>> cannot use c2x syntax. >>>>>>>>> >>>>>>>>> Okay, I think we can guard btf_tag's with newer compiler versions. >>>>>>>>> What kind of c2x syntax you intend to use? I can help compile kernel >>>>>>>>> with that syntax and llvm15 to see what is the issue and may help >>>>>>>>> fix it in clang if possible. >>>>>>>> >>>>>>>> I am thinking to use the [[]] C2x standard attribute syntax. The >>>>>>>> syntax makes it quite clear to which entity each attribute applies, >>>>>>>> and in my opinion is a little more intuitive/less surprising too. >>>>>>>> It's documented here (PDF): >>>>>>>> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2731.pdf >>>>>>>> See sections 6.7.11 for the syntax and 6.7.6 for >>>>>>>> declarations. Section 6.7.6.1 specifically describes using the >>>>>>>> attribute syntax with pointer declarators. >>>>>>>> The attribute syntax itself for BTF tags is: >>>>>>>>   [[clang::btf_type_tag("tag1")]] >>>>>>>> or >>>>>>>>   [[gnu::btf_type_tag("tag1")]] >>>>>>>> >>>>>>>> I am also looking into whether, with the C2x syntax, we really need two >>>>>>>> separate attributes (type_tag and decl_tag) at the language >>>>>>>> level. It might be possible with C2x syntax to use just one language >>>>>>>> attribute (e.g. just btf_tag). >>>>>>>> >>>>>>>> A simple declaration for a tagged pointer to an int: >>>>>>>>   int * [[gnu::btf_type_tag("tag1")]] x; >>>>>>>> And for the example from this thread: >>>>>>>>   #define __typetag1 [[gnu::btf_type_tag("type-tag-1")]] >>>>>>>>   #define __typetag2 [[gnu::btf_type_tag("type-tag-2")]] >>>>>>>>   #define __typetag3 [[gnu::btf_type_tag("type-tag-3")]] >>>>>>>>   int * __typetag1 * __typetag2 __typetag3 g; >>>>>>>> Here each tag applies to the preceding pointer, so the result is >>>>>>>> unsurprising. >>>>>>>> Actually, this is where I found something that looks like an issue >>>>>>>> with the C2x attribute syntax in clang. The tags 2 and 3 go missing, >>>>>>>> but with no warning nor other indication. >>>>>>>> Compiling this example with gcc: >>>>>>>> $ ~/toolchains/bpf/bin/bpf-unknown-none-gcc -c -gbtf -gdwarf c2x.c >>>>>>>> -o c2x.o --std=c2x >>>>>>>> $ ~/toolchains/llvm/bin/llvm-dwarfdump c2x.o >>>>>>>> 0x0000000c: DW_TAG_compile_unit >>>>>>>>               DW_AT_producer    ("GNU C2X 12.0.1 20220401 >>>>>>>> (experimental) -gbtf -gdwarf -std=c2x") >>>>>>>>               DW_AT_language    (DW_LANG_C11) >>>>>>>>               DW_AT_name    ("c2x.c") >>>>>>>>               DW_AT_comp_dir    ("/home/dfaust/playpen/btf/tags") >>>>>>>>               DW_AT_stmt_list    (0x00000000) >>>>>>>> 0x0000001e:   DW_TAG_variable >>>>>>>>                 DW_AT_name    ("g") >>>>>>>>                 DW_AT_decl_file    ("/home/dfaust/playpen/btf/tags/c2x.c") >>>>>>>>                 DW_AT_decl_line    (16) >>>>>>>>                 DW_AT_decl_column    (0x2a) >>>>>>>>                 DW_AT_type    (0x00000032 "int **") >>>>>>>>                 DW_AT_external    (true) >>>>>>>>                 DW_AT_location    (DW_OP_addr 0x0) >>>>>>>> 0x00000032:   DW_TAG_pointer_type >>>>>>>>                 DW_AT_byte_size    (8) >>>>>>>>                 DW_AT_type    (0x0000004e "int *") >>>>>>>>                 DW_AT_sibling    (0x0000004e) >>>>>>>> 0x0000003b:     DW_TAG_LLVM_annotation >>>>>>>>                   DW_AT_name    ("btf_type_tag") >>>>>>>>                   DW_AT_const_value    ("type-tag-3") >>>>>>>> 0x00000044:     DW_TAG_LLVM_annotation >>>>>>>>                   DW_AT_name    ("btf_type_tag") >>>>>>>>                   DW_AT_const_value    ("type-tag-2") >>>>>>>> 0x0000004d:     NULL >>>>>>>> 0x0000004e:   DW_TAG_pointer_type >>>>>>>>                 DW_AT_byte_size    (8) >>>>>>>>                 DW_AT_type    (0x00000061 "int") >>>>>>>>                 DW_AT_sibling    (0x00000061) >>>>>>>> 0x00000057:     DW_TAG_LLVM_annotation >>>>>>>>                   DW_AT_name    ("btf_type_tag") >>>>>>>>                   DW_AT_const_value    ("type-tag-1") >>>>>>>> 0x00000060:     NULL >>>>>>>> 0x00000061:   DW_TAG_base_type >>>>>>>>                 DW_AT_byte_size    (0x04) >>>>>>>>                 DW_AT_encoding    (DW_ATE_signed) >>>>>>>>                 DW_AT_name    ("int") >>>>>>>> 0x00000068:   NULL >>>>>>>> >>>>>>>> and with clang (changing the attribute prefix to clang:: appropriately): >>>>>>>> $ ~/toolchains/llvm/bin/clang -target bpf -g -c c2x.c -o c2x.o.ll >>>>>>>> --std=c2x >>>>>>>> $ ~/toolchains/llvm/bin/llvm-dwarfdump c2x.o.ll >>>>>>>> 0x0000000c: DW_TAG_compile_unit >>>>>>>>               DW_AT_producer    ("clang version 15.0.0 >>>>>>>> (https://github.com/llvm/llvm-project.git >>>>>>>> f80e369f61ebd33dd9377bb42fcab64d17072b18)") >>>>>>>>               DW_AT_language    (DW_LANG_C99) >>>>>>>>               DW_AT_name    ("c2x.c") >>>>>>>>               DW_AT_str_offsets_base    (0x00000008) >>>>>>>>               DW_AT_stmt_list    (0x00000000) >>>>>>>>               DW_AT_comp_dir    ("/home/dfaust/playpen/btf/tags") >>>>>>>>               DW_AT_addr_base    (0x00000008) >>>>>>>> 0x0000001e:   DW_TAG_variable >>>>>>>>                 DW_AT_name    ("g") >>>>>>>>                 DW_AT_type    (0x00000029 "int **") >>>>>>>>                 DW_AT_external    (true) >>>>>>>>                 DW_AT_decl_file    ("/home/dfaust/playpen/btf/tags/c2x.c") >>>>>>>>                 DW_AT_decl_line    (12) >>>>>>>>                 DW_AT_location    (DW_OP_addrx 0x0) >>>>>>>> 0x00000029:   DW_TAG_pointer_type >>>>>>>>                 DW_AT_type    (0x00000032 "int *") >>>>>>>> 0x0000002e:     DW_TAG_LLVM_annotation >>>>>>>>                   DW_AT_name    ("btf_type_tag") >>>>>>>>                   DW_AT_const_value    ("type-tag-1") >>>>>>>> 0x00000031:     NULL >>>>>>>> 0x00000032:   DW_TAG_pointer_type >>>>>>>>                 DW_AT_type    (0x00000037 "int") >>>>>>>> 0x00000037:   DW_TAG_base_type >>>>>>>>                 DW_AT_name    ("int") >>>>>>>>                 DW_AT_encoding    (DW_ATE_signed) >>>>>>>>                 DW_AT_byte_size    (0x04) >>>>>>>> 0x0000003b:   NULL >>>>>>> >>>>>>> Thanks. I checked with current clang. The generated code looks >>>>>>> like above. Basically, for code like below >>>>>>> >>>>>>> #define __typetag1 [[clang::btf_type_tag("type-tag-1")]] >>>>>>> #define __typetag2 [[clang::btf_type_tag("type-tag-2")]] >>>>>>> #define __typetag3 [[clang::btf_type_tag("type-tag-3")]] >>>>>>> >>>>>>> int * __typetag1 * __typetag2 __typetag3 g; >>>>>>> >>>>>>> The IR type looks like >>>>>>> __typetag3 -> __typetag2 -> * (ptr1) -> __typetag1 -> * (ptr2) -> int >>>>>>> >>>>>>> The IR is similar to what we did if using >>>>>>> __attribute__((btf_type_tag(""))), but their >>>>>>> semantic interpretation is quite different. >>>>>>> For example, with c2x format, >>>>>>> __typetag1 applies to ptr2 >>>>>>> with __attribute__ format, it applies pointee of ptr1. >>>>>>> >>>>>>> But more importantly, c2x format is incompatible with >>>>>>> the usage of linux kernel. The following are a bunch of kernel >>>>>>> __user usages. Here, __user intends to be replaced with a btf_type_tag. >>>>>>> >>>>>>> vfio_pci_core.h: ssize_t (*rw)(struct vfio_pci_core_device >>>>>>> *vdev, char __user *buf, >>>>>>> vfio_pci_core.h: char __user *buf, >>>>>>> size_t count, >>>>>>> vfio_pci_core.h:extern ssize_t vfio_pci_bar_rw(struct >>>>>>> vfio_pci_core_device *vdev, char __user *buf, >>>>>>> vfio_pci_core.h:extern ssize_t vfio_pci_vga_rw(struct >>>>>>> vfio_pci_core_device *vdev, char __user *buf, >>>>>>> vfio_pci_core.h: char __user >>>>>>> *buf, size_t count, >>>>>>> vfio_pci_core.h: void __user *arg, >>>>>>> size_t argsz); >>>>>>> vfio_pci_core.h:ssize_t vfio_pci_core_read(struct vfio_device >>>>>>> *core_vdev, char __user *buf, >>>>>>> vfio_pci_core.h:ssize_t vfio_pci_core_write(struct vfio_device >>>>>>> *core_vdev, const char __user *buf, >>>>>>> vringh.h: vring_desc_t __user *desc, >>>>>>> vringh.h: vring_avail_t __user *avail, >>>>>>> vringh.h: vring_used_t __user *used); >>>>>>> vt_kern.h:int con_set_cmap(unsigned char __user *cmap); >>>>>>> vt_kern.h:int con_get_cmap(unsigned char __user *cmap); >>>>>>> vt_kern.h:int con_set_trans_old(unsigned char __user * table); >>>>>>> vt_kern.h:int con_get_trans_old(unsigned char __user * table); >>>>>>> vt_kern.h:int con_set_trans_new(unsigned short __user * table); >>>>>>> vt_kern.h:int con_get_trans_new(unsigned short __user * table); >>>>>>> >>>>>>> You can see, we will not able to simply replace __user >>>>>>> with [[clang::btf_type_tag("user")]] because it won't work >>>>>>> according to c2x expectations. >>>>> >>>>> Hi, >>>>> >>>>> Thanks for checking this. I see that we probably cannot use the c2x >>>>> syntax in the kernel, since it will not work as a drop-in replacement >>>>> for the current uses. >>>>> >>>>>> >>>>>> Hi Yongsong. >>>>>> >>>>>> I am a bit confused regarding the GNU attributes problem: our patch >>>>>> supports it, but as David already noted: >>>>>> >>>>>>>>>> There is still the question of why the DWARF generated for this case >>>>>>>>>> that I have been concerned about: >>>>>>>>>> >>>>>>>>>> int __typetag1 * __typetag2 __typetag3 * g; >>>>>>>>>> >>>>>>>>>> differs between GCC (with this series) and clang. After studying it, >>>>>>>>>> GCC is doing with the attributes exactly as is described in the >>>>>>>>>> Attribute Syntax portion of the GCC manual where the GNU syntax is >>>>>>>>>> described. I do not think there is any problem here. >>>>>>>>>> >>>>>>>>>> So the difference in DWARF suggests to me that clang is not handling >>>>>>>>>> the GNU attribute syntax in this particular case correctly, since it >>>>>>>>>> seems to be associating __typetag2 and __typetag3 to g's type rather >>>>>>>>>> than the type to which it points. >>>>>> >>>>>> Note the example he uses is: >>>>>> >>>>>> (a) int __typetag1 * __typetag2 __typetag3 * g; >>>>>> >>>>>> Not >>>>>> >>>>>> (b) int * __typetag1 * __typetag2 __typetag3 g; >>>>>> >>>>>> Apparently for (a) clang is generating DWARF that associates __typetag2 >>>>>> and__typetag3 to g's type (the pointer to pointer) instead of the >>>>>> pointer to int, which contravenes the GNU syntax rules. >>>>>> >>>>>> AFAIK thats is where the DWARF we generate differs, and what is blocking >>>>>> us. David will correct me in the likely case I'm wrong :) >>>>> >>>>> Right. This is what I hoped maybe the C2x syntax could resolve. >>>>> >>>>> The issue I saw is that in the case (a) above, when using the GNU >>>>> attribute syntax, GCC and clang produce different results. I think that >>>>> the underlying cause is some subtle difference in how clang is handling >>>>> the GNU attribute syntax in the case compared to GCC. >>>>> >>>>> >>>>> To remind ourselves, here is the full example. Notice the significant >>>>> difference in which objects the tags are associated with in DWARF. >>>>> >>>>> >>>>> #define __typetag1 __attribute__((btf_type_tag("type-tag-1"))) >>>>> #define __typetag2 __attribute__((btf_type_tag("type-tag-2"))) >>>>> #define __typetag3 __attribute__((btf_type_tag("type-tag-3"))) >>>>> >>>>> int __typetag1 * __typetag2 __typetag3 * g; >>>>> >>>>> >>>>> GCC: bpf-unknown-none-gcc -c -gdwarf -gbtf annotate.c >>>>> >>>>> 0x0000000c: DW_TAG_compile_unit >>>>> DW_AT_producer ("GNU C17 12.0.1 20220401 (experimental) -gdwarf -gbtf") >>>>> DW_AT_language (DW_LANG_C11) >>>>> DW_AT_name ("annotate.c") >>>>> DW_AT_comp_dir ("/home/dfaust/playpen/btf/tags") >>>>> DW_AT_stmt_list (0x00000000) >>>>> >>>>> 0x0000001e: DW_TAG_variable >>>>> DW_AT_name ("g") >>>>> DW_AT_decl_file ("/home/dfaust/playpen/btf/tags/annotate.c") >>>>> DW_AT_decl_line (11) >>>>> DW_AT_decl_column (0x2a) >>>>> DW_AT_type (0x00000032 "int **") >>>>> DW_AT_external (true) >>>>> DW_AT_location (DW_OP_addr 0x0) >>>>> >>>>> 0x00000032: DW_TAG_pointer_type >>>>> DW_AT_byte_size (8) >>>>> DW_AT_type (0x00000045 "int *") >>>>> DW_AT_sibling (0x00000045) >>>>> >>>>> 0x0000003b: DW_TAG_LLVM_annotation >>>>> DW_AT_name ("btf_type_tag") >>>>> DW_AT_const_value ("type-tag-1") >>>>> >>>>> 0x00000044: NULL >>>>> >>>>> 0x00000045: DW_TAG_pointer_type >>>>> DW_AT_byte_size (8) >>>>> DW_AT_type (0x00000061 "int") >>>>> DW_AT_sibling (0x00000061) >>>>> >>>>> 0x0000004e: DW_TAG_LLVM_annotation >>>>> DW_AT_name ("btf_type_tag") >>>>> DW_AT_const_value ("type-tag-3") >>>>> >>>>> 0x00000057: DW_TAG_LLVM_annotation >>>>> DW_AT_name ("btf_type_tag") >>>>> DW_AT_const_value ("type-tag-2") >>>>> >>>>> 0x00000060: NULL >>>>> >>>>> 0x00000061: DW_TAG_base_type >>>>> DW_AT_byte_size (0x04) >>>>> DW_AT_encoding (DW_ATE_signed) >>>>> DW_AT_name ("int") >>>>> >>>>> 0x00000068: NULL >>>> >>>> do you have documentation to show why gnu generates attribute this way? >>>> If dwarf generates >>>> ptr -> tag3 -> tag2 -> ptr -> tag1 -> int >>>> does this help? >>> >>> Okay, I think I see the problem. The internal representations between clang >>> and GCC attach the attributes to different nodes, and as a result they >>> produce different DWARF: >>> >>> !5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, >>> annotations: !10) >>> !6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, >>> annotations: !8) >>> !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) >>> !8 = !{!9} >>> !9 = !{!"btf_type_tag", !"tag1"} >>> !10 = !{!11, !12} >>> !11 = !{!"btf_type_tag", !"tag2"} >>> !12 = !{!"btf_type_tag", !"tag3"} >>> >>> If I am reading this IR right, then the tags "tag2" and "tag3" are being >>> applied to the int**, and "tag1" is applied to the int* >>> >>> But I don't think this lines up with how the attribute syntax is defined. >>> See >>> https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html >>> In particular the "All other attributes" section. (It's a bit dense). >>> Or, as Joseph summed it up nicely earlier in the thread: >>>> In either syntax, __typetag2 __typetag3 should apply to >>>> the type to which g points, not to g or its type, just as if you had a >>>> type qualifier there. You'd need to put the attributes (or qualifier) >>>> after the *, not before, to make them apply to the pointer type. >>> >>> >>> Compare that to GCC's internal representation, from which DWARF is generated: >>> >>> >> type >> type >>> unsigned DI >>> size >>> unit-size >>> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff743f888 >>> attributes >> purpose >>> value >> value >>> readonly constant static "type-tag-3\000">> >>> chain >>> value >> value >>> readonly constant static "type-tag-2\000">>>> >>> pointer_to_this > >>> unsigned DI size unit-size >>> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff74f87e0 >>> attributes >>> value >> value >>> readonly constant static "type-tag-1\000">>>> >>> public static unsigned DI defer-output /home/dfaust/playpen/btf/tags/annotate.c:10:42 size unit-size >>> align:64 warn_if_not_align:0> >>> >>> See how tags "tag2" and "tag3" are associated with the pointer_type 0x7ffff74f8b28, >>> that is, "the type to which g points" >>> >>> From GCC's DWARF the BTF we get currently looks like: >>> VAR(g) -> ptr -> tag1 -> ptr -> tag3 -> tag2 -> int >>> which is obviously quite different and why this case caught my attention. >>> >>> I think this difference is the root of our problems. It might not be >>> specifically related to the BTF tag attributes but they do reveal some >>> discrepency between how clang and GCC handle the attribute syntax. >> >> The btf_type attribute is very similar to address_space attribute. >> For example, >> $ cat t1.c >> int __attribute__((address_space(1))) * p; >> $ clang -g -S -emit-llvm t1.c >> >> In IR, we will have >> @p = dso_local global ptr addrspace(1) null, align 8, !dbg !0 >> ... >> !5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) >> !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) >> >> Replacing address_space with btf_type_tag, we will get >> ptr->type_tag->int in debuginfo. >> >> But it looks like gcc doesn't support address_space attribute >> >> $ gcc -g -S t1.c >> t1.c:1:1: warning: ‘address_space’ attribute directive ignored >> [-Wattributes] >> int __attribute__((address_space(1))) * p; >> ^~~ >> >> Is it possible for gcc to go with address_space attribute >> semantics for btf_type_tag attribute? > > In cases like this the behavior is the same. > $ cat foo.c > int __attribute__((btf_type_tag("tag1"))) * p; > $ gcc -c -gdwarf -gbtf foo.c > > Internally: > type type size > unit-size > align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff74475e8 precision:32 min max > pointer_to_this > > unsigned DI > size > unit-size > align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff744fa80 > attributes purpose > value value > readonly constant static "tag1\000">>>> > public static unsigned DI defer-output /home/dfaust/playpen/btf/tags/foo.c:1:45 size unit-size > align:64 warn_if_not_align:0> > > And the resulting BTF: > > [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED > [2] PTR '(anon)' type_id=3 > [3] TYPE_TAG 'tag1' type_id=1 > [4] VAR 'p' type_id=2, linkage=global > [5] DATASEC '.bss' size=0 vlen=1 > type_id=4 offset=0 size=8 (VAR 'p') > > var(p) -> ptr -> type_tag -> int It would be good if we can generate similar encoding in dwarf. Currently in clang, we generate var(p) -> ptr (type_tag) -> int but I am open to generate var(p) -> ptr -> type_tag -> int in dwarf as well if it is possible. > > >> >>> >>>> >>>>> >>>>> >>>>> clang: clang -target bpf -c -g annotate.c >>>>> >>>>> 0x0000000c: DW_TAG_compile_unit >>>>> DW_AT_producer ("clang version 15.0.0 (https://github.com/llvm/llvm-project.git f80e369f61ebd33dd9377bb42fcab64d17072b18)") >>>>> DW_AT_language (DW_LANG_C99) >>>>> DW_AT_name ("annotate.c") >>>>> DW_AT_str_offsets_base (0x00000008) >>>>> DW_AT_stmt_list (0x00000000) >>>>> DW_AT_comp_dir ("/home/dfaust/playpen/btf/tags") >>>>> DW_AT_addr_base (0x00000008) >>>>> >>>>> 0x0000001e: DW_TAG_variable >>>>> DW_AT_name ("g") >>>>> DW_AT_type (0x00000029 "int **") >>>>> DW_AT_external (true) >>>>> DW_AT_decl_file ("/home/dfaust/playpen/btf/tags/annotate.c") >>>>> DW_AT_decl_line (11) >>>>> DW_AT_location (DW_OP_addrx 0x0) >>>>> >>>>> 0x00000029: DW_TAG_pointer_type >>>>> DW_AT_type (0x00000035 "int *") >>>>> >>>>> 0x0000002e: DW_TAG_LLVM_annotation >>>>> DW_AT_name ("btf_type_tag") >>>>> DW_AT_const_value ("type-tag-2") >>>>> >>>>> 0x00000031: DW_TAG_LLVM_annotation >>>>> DW_AT_name ("btf_type_tag") >>>>> DW_AT_const_value ("type-tag-3") >>>>> >>>>> 0x00000034: NULL >>>>> >>>>> 0x00000035: DW_TAG_pointer_type >>>>> DW_AT_type (0x0000003e "int") >>>>> >>>>> 0x0000003a: DW_TAG_LLVM_annotation >>>>> DW_AT_name ("btf_type_tag") >>>>> DW_AT_const_value ("type-tag-1") >>>>> >>>>> 0x0000003d: NULL >>>>> >>>>> 0x0000003e: DW_TAG_base_type >>>>> DW_AT_name ("int") >>>>> DW_AT_encoding (DW_ATE_signed) >>>>> DW_AT_byte_size (0x04) >>>>> >>>>> 0x00000042: NULL >>>>> >>>>>