From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5651C77B7E for ; Tue, 2 May 2023 05:08:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232985AbjEBFIE (ORCPT ); Tue, 2 May 2023 01:08:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231808AbjEBFID (ORCPT ); Tue, 2 May 2023 01:08:03 -0400 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B853083 for ; Mon, 1 May 2023 22:07:59 -0700 (PDT) Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 341LO68w008837; Tue, 2 May 2023 05:07:52 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=message-id : date : subject : to : cc : references : from : in-reply-to : content-type : content-transfer-encoding : mime-version; s=corp-2023-03-30; bh=uHoVZSuPrgqqrY72JMFO0w+js1QYNRfc2ZagC6tQIII=; b=XZ+/fSYpxzSgs30aj32yoe65IRRMnVC9d8tvG75YGH81j2m0fwDYPCG1BD0ngGuXDz6i WNglTlgAAscrsAP/NDljDyZ31q/bTwvNP3tritqIldpbg5+S6Bd6uL+leZTtSs5Es6sK hJaeEhzvhKy3q8JXifjkjWWTL2BebLZlklBI6cRFEUKevcQBb92gTBJ9H3rtgNaQNuCb jSahNIrZs3peIOzUnvQP+D40qUY7GtJI1SY9K4bGe0TrkBOi7iKo+nlYttR31TM5CRPn k1auCsDVT96nFs+Vrvkn5afMbTryQzmaeVTKt5GZva0a720Hk1Q3Kce3cm5Nwkm8C+cW WQ== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3q8tuu3rfm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 02 May 2023 05:07:52 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3423A8Cl002397; Tue, 2 May 2023 05:07:51 GMT Received: from nam12-dm6-obe.outbound.protection.outlook.com (mail-dm6nam12lp2172.outbound.protection.outlook.com [104.47.59.172]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3q8spbg73w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 02 May 2023 05:07:51 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DIEacd5AlKDUDJe3BKZ8Apt7EK9i8lL1YYSUFSYTwK1jekJP/DZESpYeQtrsRck7XWA0pm0DaLAK6EM083gLJLkXNF66szR7jPVeXnKSMmnHBHRhURLkadwBB8bEIbe8cpQodDfqyLbSbyE//4EGBe69E08Bk80JOlhrU5zmC4fKAnZTjM9M/hIbRFQiYMPP+DHIxgSLTI9O/sdqzmc8C3B6KRMcsPEJesCdEz0LDqB0q7yDshPD9I71eFmCOhTDs0jMk23BbIXssdn9WKW5WkYtTLGkgQ1jRQRWX6Ms5gdvHx8z6zgBpCqytZ8rIJN7l94AE8G8/f9UtRPUb2uLag== 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=uHoVZSuPrgqqrY72JMFO0w+js1QYNRfc2ZagC6tQIII=; b=A45C2KyzjrhqZ2O2m/iPWp+yI1aK8TLqeaLKlDD6l1/mfJe7x8w0fr/K1wxs5Q3J2O0di1RgVk2C0QnLOEQSRYIC7eQElzCCOV6ZFV89wdvMLe5aVHou2/1hfyOvfEGomhBYag/kAOtFOPCqUIVOH4xZ+RLjzc3lpQu3TdTIquN0S8t2LLYD3BUuHA569iVARqo7KsZXI90n0L8A9Wc7V7DXEjUuR6zNxjuHPZYeIMUUcJc4cPt61Kp0GD9uCLtkDGhXlcDWvmy4R6evR0Htu1/ro0j9OF5iLN7qDLZguZUwl0bSE+wZZEvdYQM9Cp08z90HltC4giBKUqHBZ7oO+g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uHoVZSuPrgqqrY72JMFO0w+js1QYNRfc2ZagC6tQIII=; b=GQS6q/eNybwu5lnCA48cKTNC7rzWtIdglf6451lduDisLRvcp5RbKUbyLx7wJkdJUi8FTtEezTdU+r19l24mlK9bjsv93ts5UJZdYHwCPW7FQWzu3G2P0K4XkxSeL+aDo7fvYjoo+tNGV9wIwNGSUT9iLjCWq5hmn3FT9l9miS8= Received: from MWHPR1001MB2158.namprd10.prod.outlook.com (2603:10b6:301:2d::17) by MN2PR10MB4253.namprd10.prod.outlook.com (2603:10b6:208:1d6::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6340.30; Tue, 2 May 2023 05:07:48 +0000 Received: from MWHPR1001MB2158.namprd10.prod.outlook.com ([fe80::ff1c:f1fb:8db9:22e2]) by MWHPR1001MB2158.namprd10.prod.outlook.com ([fe80::ff1c:f1fb:8db9:22e2%6]) with mapi id 15.20.6340.030; Tue, 2 May 2023 05:07:47 +0000 Message-ID: Date: Mon, 1 May 2023 22:07:44 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0 Subject: Re: [POC 3/5] sframe: add new SFrame library Content-Language: en-US To: Steven Rostedt Cc: linux-toolchains@vger.kernel.org, daandemeyer@meta.com, andrii@kernel.org, kris.van.hees@oracle.com, elena.zannoni@oracle.com, nick.alcock@oracle.com References: <20230501200410.3973453-1-indu.bhagat@oracle.com> <20230501200410.3973453-4-indu.bhagat@oracle.com> <20230501184008.319fdd6f@gandalf.local.home> From: Indu Bhagat In-Reply-To: <20230501184008.319fdd6f@gandalf.local.home> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-ClientProxiedBy: MW4PR04CA0270.namprd04.prod.outlook.com (2603:10b6:303:88::35) To MWHPR1001MB2158.namprd10.prod.outlook.com (2603:10b6:301:2d::17) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MWHPR1001MB2158:EE_|MN2PR10MB4253:EE_ X-MS-Office365-Filtering-Correlation-Id: b9bb47e8-8f95-4102-ca47-08db4acb2bb4 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Fi6on6LDIiKIK04LjOQeoTV6WtWaGZXKPEtmTd9upG34lj3z0wcAbdor4QkKCtPzI47Cctg+dP4lyA3GcX7oVzgwfZQsZ/5z5kGDdWRC5vmlwPaEEroqDill7k6jIp/KW9sJ4U4jj306cfmRsM6ytZf2iWeZW5aTgZzt/BJnbEWS6hpV4BQ/ZkV4+7YU4bmx7jWwyqT8iXLt4Mu9n6UCa0zr/l0jtoKuy1RKgDNS+VNABlpzacCJ55ThayTKOaeX0PyrY9VskGpdhbIz1s//NsQRDGgw81sNtLpGuNVXkWxjCQztXzm54x/EKBWtJPqtVOIkbxDWmTlflV+m/1YICB0YSSo4bRMlT8jHfMXO6t3LzM/o+X2/pbBaCuhIXz/9OeN/sMwXQivXz5HIn9lgD3HU7WhFL+ltPM+BWPqI49Zi+JNrQODv1tvOEJSqMkDB+hWMBNB2Swv7wcHPKh/1M2s17iCqu8X9PLD5jxJLTWgzbiwiN71OI2obDSn9Um7u4/Ug+vmLLldHG2RFTvUKNdzY0cYg3xvcteQxRmJaq5wMg1fcVx3gDr4k8TcYwbS3Klw6H5pChcLN1pP1oYZxSX9zTBxlOL0lCPvBQmWpiwF4+oGxmOpMmxwqeSiFeW3ZwO361Z9kYhDGOsY7gEQItQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR1001MB2158.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(136003)(396003)(366004)(39860400002)(346002)(376002)(451199021)(38100700002)(36756003)(31686004)(83380400001)(186003)(6512007)(6506007)(53546011)(966005)(2616005)(6486002)(107886003)(6666004)(30864003)(478600001)(66946007)(8936002)(4326008)(66476007)(66556008)(6916009)(86362001)(8676002)(31696002)(41300700001)(44832011)(2906002)(316002)(5660300002)(43740500002)(45980500001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?dlFnaHgrV0sxSkh3eTdYVWI5eVpZSHRxRkFLZWs1WktUdVNpTXArbnYrMXJr?= =?utf-8?B?WWwzNDd5RWlyOGZpd0RieXlHQ2QvVENtYnFjWTRDaThyay9jRnVjUHNVZzNV?= =?utf-8?B?MUdhV3FOSFFxU1loNzRQWldHb21ySlhQNlY3dnRoNVoyeWZZZUloc1EyT3Bv?= =?utf-8?B?enVkUlZ1d0VPRGo4UHJmZ01yTnQydHlKUkd5elpKTHZRREJwVzMwVmRlTlhm?= =?utf-8?B?RFNSN25vTXJGdlpxZzc0UkxpMUxLZHQ2S0cyOHRCRldQUEVKcHNDR0tveXRh?= =?utf-8?B?NXFNL2pXUHhTc016dVVjM0JIMjFuVkJnZGZUeXZmY2NHMmtmUnFuQ0RKeERH?= =?utf-8?B?Y3NzZHZJcEJEc04wSFhNWUhacHlVZVRtcmFmTERlTHhGS3Rjclg5M3g1NjJM?= =?utf-8?B?VVBPdkN1TEVBSmdvK1BuMjVsNHBYV2FzRDRuaHhBWVlsdVhwQmEwN3VycDEw?= =?utf-8?B?ekpwZ3Z6ekFEWms4NTRVS3JrSzY5NGRXZjFUY3h4NEE1d0g3dmxoNk9ERjZz?= =?utf-8?B?ZzJNZlpVSXZKejR4MDd4bHQzOFdVTkNTM1lYTjE2WjhlemY5MksydUY1eEM1?= =?utf-8?B?ZHJJN2lwdzFMckw0UDBqQVZFM1NOWi8zUzdFMXZvcmxMWW0wbGZoRmpMbk0y?= =?utf-8?B?di9iQjFDR1g1UWdvNGV5eVQ2TzhSYTNmN1M3TEVPZmc1RTNBaHU3RDViVXlw?= =?utf-8?B?WFBDZElZTTZOUkQxdHcwV08zV3hnVEMyUmE0MjZScUkvVkdNcTFPMytjb2sy?= =?utf-8?B?RmVxTGVhdEM1ZzAwaXdtTEVEWklvVkdLS010Znc1cUdWUnlMMUNGbThjTEcw?= =?utf-8?B?SGFtNDQ1Wnp2dUtpZ3lNZlNDMDhoN3V2NFl6d1d3Y1pkVHRDQ2QvZ3lGb092?= =?utf-8?B?MXF2d0J4OWZxNUk5TjlCQ3pwK09jMVBwd01HZS9LNUFXakN1VjJ2eURuaElv?= =?utf-8?B?VjRvRWJZU2s3SHJGSmthOHU0VmtFYitabVhMYmFVcmJNdUJ3VUpZV1pManhV?= =?utf-8?B?a2g4UDY5Rm5KQUJ4dy8ydGl0T1JkRXpkcGlLRjlNaFpTQzNZNXFuNVNpZ3R6?= =?utf-8?B?eW51cWdxbU5oemVQMTVqSk5RNEhWNXFkVytmNVFXbUdCeVpoeDJBWENlM2tR?= =?utf-8?B?aUhLSUs4bWZJRkl0ZHBzWlVDaXp1VkwrMHk0ZnkyVVgvdkUrQXNPV0hyNXZr?= =?utf-8?B?bVFYSGFvQksweEQ0VmRFVk1iaS9OaldJdlhEZTdQMlpiOWNWUm82VlJDU3pt?= =?utf-8?B?RnpkcDh1M1lGM0dwM0VCQkh1elo3dFpvYVM4YkZnLzdyREtYMWNMUHlPM0hP?= =?utf-8?B?Q0NNMWlRdzVWY01MSGt5MzBYNDN6SGw4QlpycXNFcDlSVFdST3d2Q0NwTC9G?= =?utf-8?B?RllZN0REdHFVTUtPTkxnQldpVUVrZW4wcHdQUGp4bFNwNGkxSUlncm5Cc2lx?= =?utf-8?B?MTZUZGg0ZFdxU3UvZFNlR2hZQ1QvdTdaRUdWS2VSb1pXMWNjSzFSZUErRm1R?= =?utf-8?B?WEpYZ0hjWk1UWVNhTTV5endwM0s3TWZQcHZjcGdaWVkyWnRlZUU3T3V0aGF3?= =?utf-8?B?RGRBRTZCd2ZaV0NsdjBkQ1BPeldzWWhvWVZ6RTl6WmpCUnFXYzBOZlJzNG43?= =?utf-8?B?d2tzK2h1Q21GZXJ3MnphOE5QajF1QzMwdnUzcFdxaUN6SEdFekRCY0ZOczV4?= =?utf-8?B?cjZ1WExyeEI2NlBYUkNUYUdiNUd6eTZxRkNPUU5Oblg1TTN6eDhlMzRkaEVp?= =?utf-8?B?UDFXMk9pdFIxeER5ZmMxR1J1dWhSeHpIeHE4bTJLb2E2MkxFb3JiZnZDemlL?= =?utf-8?B?eVBIOUFBem0zRGVRWEV1cEZsRG10UUZWbDE2SVVOK1RqUnlpdEZIeW15bUd1?= =?utf-8?B?cDErWE1QMVBaK21JSlpTdDUxNkREbnpxaTA0eFJXM0NMa2pneHYxZFhXUk1G?= =?utf-8?B?VUFQQnFXa2pKYTVoTDNrd2tTRTZONDdZT3dack15cEh1aC84Wkkzc3dxYXY4?= =?utf-8?B?RFpZNXNKVXAvTEV5bG05K05JWFRZY0djZUxVeUM2R0NDZEVKRUlXN0J4MlpY?= =?utf-8?B?TUNTUi85aDZ0Um5ab1lqQ1ZrdzRlM2lPbDdrYlBmNE1LNnBjUkx2QVlVRno2?= =?utf-8?B?d1QxZkIzZ0RMbUM3ZXNYYkVaY0g3TEhnUWgvQVY5WUNyRndJWDh2YjAxRldn?= =?utf-8?Q?bxI0BJqaxfDd35EsH+lDDeA=3D?= X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: iuwdwlj/4WywbhctrdfiGi3T+HIwJs98qunJAuIUHpATUfZAcqrghIE7034SSzb9uotLExauLTwQCzBGlsPNgsdlU3083ROsXG/NgfPUA3cjsp7gyQeY47YPM41/MD1bP879BO1gpeLLcQJ9GgemueKPp0ST5tZceOoYnHTW6yM/PojlDsHxc1tKbgPvFLy+YBQ+ACbCegqdXba0ek9iqTmlXPoAK8N1jjsiRxWbF+w+euid73SsXyUtI8ak+dUNClVzfTTYploCizDq1bXO0D0GsPsPDo5cjETrUeI3RpH1GfOjWvGNI9ZEmw/Y3AGoWiKhHaiDhONQEU0peUBXD+jIn2APGAZbRoZJTDaSsI87EJ1ZuseCHaw117/8BxQavA/0ZEFtTkNxPohj/UxwVrIFd3kzzuTT57S32oI9YHN3chKUxTqSf+HkDSz7hgQ7Csykd+qvcBIdotcYRP5IFbUITyrMPanSEZmom4OD6wdK48nL8nWKItKMls60EBCmBewO+kz+aBLAb4aHh1GBrL2P9EwG7AuOR80qFFnp1AjMGbmpGEzZb/93EgRugT4cqf3i3YQWXqXjyQsr9ytGj/7WdY9OavNqPOVyEZewMRNBaIvbni5vfdEs01HBNemTTYctLY/taTFYj73uqkDbty+3EqyH7fa74MZBl+91R9WfuEUrVhom17mkTAyrl+fqwN8gfPYN8tiSg1WLmrZWnCjFX154axETj2kP4ap64VkzO5B4JuESP95dikdU0LNCyFVXQTtIc12JgqIUq7y0xD37+MgGLjAZq/TTyjCrLc9OodwrWKZ7P9Ufw6Da0WXqU0a0nJceYcBRyQrDrOID1A== X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9bb47e8-8f95-4102-ca47-08db4acb2bb4 X-MS-Exchange-CrossTenant-AuthSource: MWHPR1001MB2158.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 May 2023 05:07:47.6702 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: MFbBa/Th86d1Zn4YA/6ZSkXVkIK1mPcGeZzpgzIkmwVRqmJ58WyyuDuDnFjzuIVIeLHjJqQR4KepXTaNd9+pPA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR10MB4253 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-05-02_02,2023-04-27_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 bulkscore=0 spamscore=0 mlxlogscore=999 mlxscore=0 adultscore=0 phishscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2303200000 definitions=main-2305020043 X-Proofpoint-GUID: KiOYLaUnHc9rdFtmQriJLoR4-hGsrg0A X-Proofpoint-ORIG-GUID: KiOYLaUnHc9rdFtmQriJLoR4-hGsrg0A Precedence: bulk List-ID: X-Mailing-List: linux-toolchains@vger.kernel.org On 5/1/23 15:40, Steven Rostedt wrote: > On Mon, 1 May 2023 13:04:08 -0700 > Indu Bhagat wrote: > >> This patch adds an implementation to read SFrame stack trace data from >> a .sframe section. Some APIs are also provided to find stack tracing >> information per PC, e.g., given a PC, find the SFrame FRE. >> >> These routines are provided in the sframe_read.h and sframe_read.c. >> >> This implmentation is malloc-free. >> >> Signed-off-by: Indu Bhagat >> --- >> lib/Makefile | 1 + >> lib/sframe/Makefile | 5 + >> lib/sframe/sframe.h | 263 +++++++++++++++++++++ >> lib/sframe/sframe_read.c | 498 +++++++++++++++++++++++++++++++++++++++ >> lib/sframe/sframe_read.h | 75 ++++++ >> 5 files changed, 842 insertions(+) >> create mode 100644 lib/sframe/Makefile >> create mode 100644 lib/sframe/sframe.h >> create mode 100644 lib/sframe/sframe_read.c >> create mode 100644 lib/sframe/sframe_read.h >> >> diff --git a/lib/Makefile b/lib/Makefile >> index 876fcdeae34e..cb02d16dbffd 100644 >> --- a/lib/Makefile >> +++ b/lib/Makefile >> @@ -198,6 +198,7 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ >> obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ >> obj-$(CONFIG_XZ_DEC) += xz/ >> obj-$(CONFIG_RAID6_PQ) += raid6/ >> +obj-$(CONFIG_USER_UNWINDER_SFRAME) += sframe/ >> >> lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o >> lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o >> diff --git a/lib/sframe/Makefile b/lib/sframe/Makefile >> new file mode 100644 >> index 000000000000..4e4291d9294f >> --- /dev/null >> +++ b/lib/sframe/Makefile >> @@ -0,0 +1,5 @@ >> +# SPDX-License-Identifier: GPL-2.0 >> +################################## >> +obj-$(CONFIG_USER_UNWINDER_SFRAME) += sframe_read.o \ > > The ending backslash is only needed if there's a line wrap, which you don't > have here. > >> + >> +CFLAGS_sframe_read.o += -I $(srctree)/lib/sframe/ >> diff --git a/lib/sframe/sframe.h b/lib/sframe/sframe.h >> new file mode 100644 >> index 000000000000..b1290e92839a >> --- /dev/null >> +++ b/lib/sframe/sframe.h >> @@ -0,0 +1,263 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * Copyright (C) 2023, Oracle and/or its affiliates. >> + */ >> + >> +#ifndef SFRAME_H >> +#define SFRAME_H >> + >> +#include >> + >> +/* This file contains definitions for the SFrame stack tracing format, which is >> + * documented at https://sourceware.org/binutils/docs */ >> + >> +#define SFRAME_VERSION_1 1 >> +#define SFRAME_MAGIC 0xdee2 >> +#define SFRAME_VERSION SFRAME_VERSION_1 >> + >> +/* Function Descriptor Entries are sorted on PC. */ >> +#define SFRAME_F_FDE_SORTED 0x1 >> +/* Frame-pointer based stack tracing. Defined, but not set. */ >> +#define SFRAME_F_FRAME_POINTER 0x2 >> + >> +#define SFRAME_CFA_FIXED_FP_INVALID 0 >> +#define SFRAME_CFA_FIXED_RA_INVALID 0 >> + >> +/* Supported ABIs/Arch. */ >> +#define SFRAME_ABI_AARCH64_ENDIAN_BIG 1 /* AARCH64 big endian. */ >> +#define SFRAME_ABI_AARCH64_ENDIAN_LITTLE 2 /* AARCH64 little endian. */ >> +#define SFRAME_ABI_AMD64_ENDIAN_LITTLE 3 /* AMD64 little endian. */ >> + >> +/* SFrame FRE types. */ >> +#define SFRAME_FRE_TYPE_ADDR1 0 >> +#define SFRAME_FRE_TYPE_ADDR2 1 >> +#define SFRAME_FRE_TYPE_ADDR4 2 >> + >> +/* >> + * SFrame Function Descriptor Entry types. >> + * >> + * The SFrame format has two possible representations for functions. The >> + * choice of which type to use is made according to the instruction patterns >> + * in the relevant program stub. >> + */ >> + >> +/* Unwinders perform a (PC >= FRE_START_ADDR) to look up a matching FRE. */ >> +#define SFRAME_FDE_TYPE_PCINC 0 >> +/* >> + * Unwinders perform a (PC & FRE_START_ADDR_AS_MASK >= FRE_START_ADDR_AS_MASK) >> + * to look up a matching FRE. Typical usecases are pltN entries, trampolines >> + * etc. >> + */ >> +#define SFRAME_FDE_TYPE_PCMASK 1 >> + >> +struct sframe_preamble >> +{ > > Note, for Linux coding style, structs should have the '{' on the same line: > > struct sframe_preamble { > > This is required because a common way to find a struct definition is to > search the name followed by a '{'. > > >> + /* Magic number (SFRAME_MAGIC). */ >> + uint16_t magic; >> + /* Data format version number (SFRAME_VERSION). */ >> + uint8_t version; >> + /* Various flags. */ >> + uint8_t flags; >> +} __packed; >> + >> +struct sframe_header >> +{ > > Here too. > >> + struct sframe_preamble preamble; >> + /* Information about the arch (endianness) and ABI. */ >> + uint8_t abi_arch; >> + /* >> + * Offset for the Frame Pointer (FP) from CFA may be fixed for some >> + * ABIs (e.g, in AMD64 when -fno-omit-frame-pointer is used). When fixed, >> + * this field specifies the fixed stack frame offset and the individual >> + * FREs do not need to track it. When not fixed, it is set to >> + * SFRAME_CFA_FIXED_FP_INVALID, and the individual FREs may provide >> + * the applicable stack frame offset, if any. >> + */ >> + int8_t cfa_fixed_fp_offset; >> + /* >> + * Offset for the Return Address from CFA is fixed for some ABIs >> + * (e.g., AMD64 has it as CFA-8). When fixed, the header specifies the >> + * fixed stack frame offset and the individual FREs do not track it. When >> + * not fixed, it is set to SFRAME_CFA_FIXED_RA_INVALID, and individual >> + * FREs provide the applicable stack frame offset, if any. >> + */ >> + int8_t cfa_fixed_ra_offset; >> + /* >> + * Number of bytes making up the auxiliary header, if any. >> + * Some ABI/arch, in the future, may use this space for extending the >> + * information in SFrame header. Auxiliary header is contained in >> + * bytes sequentially following the sframe_header. >> + */ >> + uint8_t auxhdr_len; >> + /* Number of SFrame FDEs in this SFrame section. */ >> + uint32_t num_fdes; >> + /* Number of SFrame Frame Row Entries. */ >> + uint32_t num_fres; >> + /* Number of bytes in the SFrame Frame Row Entry section. */ >> + uint32_t fre_len; >> + /* Offset of SFrame Function Descriptor Entry section. */ >> + uint32_t fdeoff; >> + /* Offset of SFrame Frame Row Entry section. */ >> + uint32_t freoff; >> +} __packed; >> + >> +#define SFRAME_V1_HDR_SIZE(sframe_hdr) \ >> + ((sizeof (struct sframe_header) + (sframe_hdr).auxhdr_len)) >> + >> +/* Two possible keys for executable (instruction) pointers signing. */ >> +#define SFRAME_AARCH64_PAUTH_KEY_A 0 /* Key A. */ >> +#define SFRAME_AARCH64_PAUTH_KEY_B 1 /* Key B. */ >> + >> +struct sframe_func_desc_entry >> +{ > > Basically all of them. > >> + /* >> + * Function start address. Encoded as a signed offset, relative to the >> + * beginning of the current FDE. >> + */ >> + int32_t func_start_address; >> + /* Size of the function in bytes. */ >> + uint32_t func_size; >> + /* >> + * Offset of the first SFrame Frame Row Entry of the function, relative to the >> + * beginning of the SFrame Frame Row Entry sub-section. >> + */ >> + uint32_t func_start_fre_off; >> + /* Number of frame row entries for the function. */ >> + uint32_t func_num_fres; >> + /* >> + * Additional information for deciphering the unwind information for the >> + * function. >> + * - 4-bits: Identify the FRE type used for the function. >> + * - 1-bit: Identify the FDE type of the function - mask or inc. >> + * - 1-bit: PAC authorization A/B key (aarch64). >> + * - 2-bits: Unused. >> + * -------------------------------------------------------------------------- >> + * | Unused | PAC auth A/B key (aarch64) | FDE type | FRE type | >> + * | | Unused (amd64) | | | >> + * -------------------------------------------------------------------------- >> + * 8 6 5 4 0 >> + */ >> + uint8_t func_info; >> +} __packed; >> + >> +/* Note: Set PAC auth key to SFRAME_AARCH64_PAUTH_KEY_A by default. */ >> +#define SFRAME_V1_FUNC_INFO(fde_type, fre_enc_type) \ >> + (((SFRAME_AARCH64_PAUTH_KEY_A & 0x1) << 5) | \ >> + (((fde_type) & 0x1) << 4) | ((fre_enc_type) & 0xf)) >> + >> +#define SFRAME_V1_FUNC_FRE_TYPE(data) ((data) & 0xf) >> +#define SFRAME_V1_FUNC_FDE_TYPE(data) (((data) >> 4) & 0x1) >> +#define SFRAME_V1_FUNC_PAUTH_KEY(data) (((data) >> 5) & 0x1) >> + >> +/* >> + * Size of stack frame offsets in an SFrame Frame Row Entry. A single >> + * SFrame FRE has all offsets of the same size. Offset size may vary >> + * across frame row entries. >> + */ >> +#define SFRAME_FRE_OFFSET_1B 0 >> +#define SFRAME_FRE_OFFSET_2B 1 >> +#define SFRAME_FRE_OFFSET_4B 2 >> + >> +/* An SFrame Frame Row Entry can be SP or FP based. */ >> +#define SFRAME_BASE_REG_FP 0 >> +#define SFRAME_BASE_REG_SP 1 >> + >> +/* >> + * The index at which a specific offset is presented in the variable length >> + * bytes of an FRE. >> + */ >> +#define SFRAME_FRE_CFA_OFFSET_IDX 0 >> +/* >> + * The RA stack offset, if present, will always be at index 1 in the variable >> + * length bytes of the FRE. >> + */ >> +#define SFRAME_FRE_RA_OFFSET_IDX 1 >> +/* >> + * The FP stack offset may appear at offset 1 or 2, depending on the ABI as RA >> + * may or may not be tracked. >> + */ >> +#define SFRAME_FRE_FP_OFFSET_IDX 2 >> + >> +struct sframe_fre_info >> +{ >> + /* Information about >> + * - 1 bit: base reg for CFA >> + * - 4 bits: Number of offsets (N). A value of upto 3 is allowed to track >> + * all three of CFA, FP and RA (fixed implicit order). >> + * - 2 bits: information about size of the offsets (S) in bytes. >> + * Valid values are SFRAME_FRE_OFFSET_1B, SFRAME_FRE_OFFSET_2B, >> + * SFRAME_FRE_OFFSET_4B >> + * - 1 bit: Mangled RA state bit (aarch64 only). >> + * ----------------------------------------------------------------------------------- >> + * | Mangled-RA (aarch64) | Size of offsets | Number of offsets | base_reg | >> + * | Unused (amd64) | | | | >> + * ----------------------------------------------------------------------------------- >> + * 8 7 5 1 0 >> + */ >> + uint8_t fre_info; >> +}; >> + >> +/* Macros to compose and decompose FRE info. */ >> + >> +/* Note: Set mangled_ra_p to zero by default. */ >> +#define SFRAME_V1_FRE_INFO(base_reg_id, offset_num, offset_size) \ >> + (((0 & 0x1) << 7) | (((offset_size) & 0x3) << 5) | \ >> + (((offset_num) & 0xf) << 1) | ((base_reg_id) & 0x1)) >> + >> +/* Set the mangled_ra_p bit as indicated. */ >> +#define SFRAME_V1_FRE_INFO_UPDATE_MANGLED_RA_P(mangled_ra_p, fre_info) \ >> + ((((mangled_ra_p) & 0x1) << 7) | ((fre_info) & 0x7f)) >> + >> +#define SFRAME_V1_FRE_CFA_BASE_REG_ID(data) ((data) & 0x1) >> +#define SFRAME_V1_FRE_OFFSET_COUNT(data) (((data) >> 1) & 0xf) >> +#define SFRAME_V1_FRE_OFFSET_SIZE(data) (((data) >> 5) & 0x3) >> +#define SFRAME_V1_FRE_MANGLED_RA_P(data) (((data) >> 7) & 0x1) >> + >> +/* SFrame Frame Row Entry definitions. */ >> + >> +/* >> + * Used when SFRAME_FRE_TYPE_ADDR1 is specified as FRE type. >> + * Upper limit of start address in sframe_frame_row_entry_addr1 if 0x100 (not >> + * inclusive). >> + */ >> +struct sframe_frame_row_entry_addr1 >> +{ >> + /* >> + * Start address of the frame row entry. Encoded as an 1-byte unsigned >> + * offset, relative to the start address of the function. >> + */ >> + uint8_t fre_start_ip_offset; >> + struct sframe_fre_info fre_info; >> +} __packed; >> + >> +/* >> + * Used when SFRAME_FRE_TYPE_ADDR2 is specified as FRE type. >> + * Upper limit of start address in sframe_frame_row_entry_addr2 is 0x10000 (not >> + * inclusive). >> + */ >> +struct sframe_frame_row_entry_addr2 >> +{ >> + /* >> + * Start address of the frame row entry. Encoded as an 2-byte unsigned >> + * offset, relative to the start address of the function. >> + */ >> + uint16_t fre_start_ip_offset; >> + struct sframe_fre_info fre_info; >> +} __packed; >> + >> +/* >> + * Used when SFRAME_FRE_TYPE_ADDR4 is specified as FRE type. >> + * Upper limit of start address in sframe_frame_row_entry_addr2 >> + * is 0x100000000 (not inclusive). >> + */ >> +struct sframe_frame_row_entry_addr4 >> +{ >> + /* >> + * Start address of the frame row entry. Encoded as a 4-byte unsigned >> + * offset, relative to the start address of the function. >> + */ >> + uint32_t fre_start_ip_offset; >> + struct sframe_fre_info fre_info; >> +} __packed; >> + >> +#endif /* SFRAME_H */ >> diff --git a/lib/sframe/sframe_read.c b/lib/sframe/sframe_read.c >> new file mode 100644 >> index 000000000000..9d6558d62c54 >> --- /dev/null >> +++ b/lib/sframe/sframe_read.c >> @@ -0,0 +1,498 @@ >> +// SPDX-License-Identifier: GPL-2.0-or-later >> +/* >> + * Copyright (C) 2023, Oracle and/or its affiliates. >> + */ >> + >> +#include >> + >> +#include "sframe_read.h" >> + >> +struct sframe_sec { >> + /* SFrame header. */ >> + struct sframe_header header; >> + /* SFrame Function Desc Entries. */ >> + void *fdes; >> + /* SFrame Frame Row Entries. */ >> + void *fres; >> + /* Number of bytes needed for SFrame FREs. */ >> + uint32_t fre_nbytes; >> +}; >> + >> +static int sframe_set_errno(int *errp, int error) >> +{ >> + if (errp != NULL) >> + *errp = error; >> + return SFRAME_ERR; >> +} >> + >> +static uint32_t sframe_sec_get_hdr_size(struct sframe_header *sfh) >> +{ >> + return SFRAME_V1_HDR_SIZE(*sfh); >> +} >> + >> +static unsigned int sframe_fre_get_offset_count(unsigned char fre_info) >> +{ >> + return SFRAME_V1_FRE_OFFSET_COUNT(fre_info); >> +} >> + >> +static unsigned int sframe_fre_get_offset_size(unsigned char fre_info) >> +{ >> + return SFRAME_V1_FRE_OFFSET_SIZE(fre_info); >> +} >> + >> +static unsigned int sframe_get_fre_type(struct sframe_func_desc_entry *fdep) >> +{ >> + return (fdep) ? SFRAME_V1_FUNC_FRE_TYPE(fdep->func_info) : 0; >> +} >> + >> +static unsigned int sframe_get_fde_type(struct sframe_func_desc_entry *fdep) >> +{ >> + return (fdep) ? SFRAME_V1_FUNC_FDE_TYPE(fdep->func_info) : 0; >> +} >> + >> +static bool sframe_header_sanity_check_p(struct sframe_header *hp) >> +{ >> + unsigned char all_flags = SFRAME_F_FDE_SORTED | SFRAME_F_FRAME_POINTER; > > Add a space here. > >> + /* Check that the preamble is valid. */ >> + if ((hp->preamble.magic != SFRAME_MAGIC) >> + || (hp->preamble.version != SFRAME_VERSION) >> + || ((hp->preamble.flags | all_flags) != all_flags)) >> + return false; >> + >> + /* Check that the offsets are valid. */ >> + if (hp->fdeoff > hp->freoff) >> + return false; >> + >> + return true; >> +} >> + >> +static bool sframe_fre_sanity_check_p(struct sframe_fre *frep) >> +{ >> + unsigned int offset_size, offset_cnt; >> + >> + if (frep == NULL) >> + return false; >> + >> + offset_size = sframe_fre_get_offset_size(frep->fre_info); >> + >> + if (offset_size != SFRAME_FRE_OFFSET_1B >> + && offset_size != SFRAME_FRE_OFFSET_2B >> + && offset_size != SFRAME_FRE_OFFSET_4B) >> + return false; >> + >> + offset_cnt = sframe_fre_get_offset_count(frep->fre_info); >> + if (offset_cnt > MAX_NUM_STACK_OFFSETS) >> + return false; >> + >> + return true; >> +} >> + >> +static int32_t sframe_get_fre_offset(struct sframe_fre *frep, uint32_t idx, >> + int *errp) >> +{ >> + int offset_cnt, offset_size; >> + >> + if (frep == NULL || !sframe_fre_sanity_check_p(frep)) >> + return sframe_set_errno(errp, SFRAME_ERR_FRE_INVAL); >> + >> + offset_cnt = sframe_fre_get_offset_count(frep->fre_info); >> + offset_size = sframe_fre_get_offset_size(frep->fre_info); >> + >> + if (offset_cnt < idx + 1) >> + return sframe_set_errno(errp, SFRAME_ERR_FREOFFSET_NOPRESENT); >> + >> + if (errp != NULL) >> + *errp = 0; /* Offset Valid. */ >> + >> + if (offset_size == SFRAME_FRE_OFFSET_1B) { >> + int8_t *stack_offsets = (int8_t *)frep->fre_offsets; >> + return stack_offsets[idx]; >> + } else if (offset_size == SFRAME_FRE_OFFSET_2B) { >> + int16_t *stack_offsets = (int16_t *)frep->fre_offsets; >> + return stack_offsets[idx]; >> + } else { >> + int32_t *stack_offsets = (int32_t *)frep->fre_offsets; >> + return stack_offsets[idx]; >> + } >> +} >> + >> +static struct sframe_header *sframe_sec_get_header(struct sframe_sec *sfsec) >> +{ >> + return sfsec ? &sfsec->header : NULL; >> +} >> + >> +static int sframe_fre_copy(struct sframe_fre *dst, >> + struct sframe_fre *src) >> +{ >> + if (dst == NULL || src == NULL) >> + return SFRAME_ERR; >> + >> + memcpy(dst, src, sizeof(struct sframe_fre)); >> + return 0; >> +} >> + >> +static int sframe_decode_start_ip_offset(const char *fre_buf, >> + uint32_t *start_ip_offset, >> + unsigned int fre_type) >> +{ >> + uint32_t saddr = 0; >> + >> + if (fre_type == SFRAME_FRE_TYPE_ADDR1) { >> + uint8_t *uc = (uint8_t *)fre_buf; >> + saddr = (uint32_t)*uc; >> + } else if (fre_type == SFRAME_FRE_TYPE_ADDR2) { >> + uint16_t *ust = (uint16_t *)fre_buf; >> + saddr = (uint32_t)*ust; >> + } else if (fre_type == SFRAME_FRE_TYPE_ADDR4) { >> + uint32_t *uit = (uint32_t *)fre_buf; >> + saddr = (uint32_t)*uit; >> + } else { >> + return SFRAME_ERR_INVAL; >> + } >> + >> + *start_ip_offset = saddr; >> + return 0; >> +} >> + >> +/* Get the total size in bytes for the stack offsets. */ >> +static size_t sframe_fre_stack_offsets_size(unsigned char fre_info) >> +{ >> + unsigned int offset_size, offset_cnt; >> + >> + offset_size = sframe_fre_get_offset_size(fre_info); >> + offset_cnt = sframe_fre_get_offset_count(fre_info); >> + >> + if (offset_size == SFRAME_FRE_OFFSET_2B >> + || offset_size == SFRAME_FRE_OFFSET_4B) /* 2 or 4 bytes. */ >> + return (offset_cnt * (offset_size * 2)); >> + >> + return offset_cnt; >> +} >> + >> +static size_t sframe_fre_get_start_address_tsize(unsigned int fre_type) >> +{ >> + /* Type size of the start_addr in an FRE. */ >> + size_t saddr_tsize = 0; >> + >> + switch (fre_type) { >> + case SFRAME_FRE_TYPE_ADDR1: >> + saddr_tsize = sizeof(uint8_t); >> + break; >> + case SFRAME_FRE_TYPE_ADDR2: >> + saddr_tsize = sizeof(uint16_t); >> + break; >> + case SFRAME_FRE_TYPE_ADDR4: >> + saddr_tsize = sizeof(uint32_t); >> + break; >> + default: >> + /* No other value is expected. */ >> + break; >> + } >> + return saddr_tsize; >> +} >> + >> +static size_t sframe_fre_vlen_size(struct sframe_fre *frep, >> + unsigned int fre_type) >> +{ >> + unsigned char fre_info; >> + size_t ip_offset_tsize; >> + >> + if (frep == NULL) >> + return 0; >> + >> + fre_info = frep->fre_info; >> + ip_offset_tsize = sframe_fre_get_start_address_tsize(fre_type); >> + >> + /* >> + * An SFrame FRE is a variable length structure. It includes the start >> + * IP offset, FRE info field, and all trailing the stack offsets. >> + */ >> + return (ip_offset_tsize + sizeof(fre_info) >> + + sframe_fre_stack_offsets_size(fre_info)); >> +} >> + >> +/* >> + * Read an SFrame FRE which starts at location FRE_BUF. The function >> + * updates FRE_SIZE to the size of the FRE as stored in the binary format. >> + * >> + * Returns SFRAME_ERR if failure. >> + */ >> +static int sframe_sec_read_fre(const char *fre_buf, struct sframe_fre *frep, >> + unsigned int fre_type, size_t *fre_size) >> +{ >> + void *stack_offsets; >> + size_t stack_offsets_sz; >> + size_t ip_offset_tsize; >> + size_t esz; >> + >> + if (fre_buf == NULL || frep == NULL || fre_size == NULL) >> + return SFRAME_ERR_INVAL; >> + >> + /* Copy over the FRE start address. */ >> + sframe_decode_start_ip_offset(fre_buf, &frep->start_ip_offset, >> + fre_type); >> + >> + ip_offset_tsize = sframe_fre_get_start_address_tsize(fre_type); >> + /* PS: Note how this API works closely with SFrame binary format. */ >> + frep->fre_info = *(unsigned char *)(fre_buf + ip_offset_tsize); >> + >> + memset(frep->fre_offsets, 0, MAX_STACK_OFFSET_NBYTES); >> + /* Get stack offsets. */ >> + stack_offsets_sz = sframe_fre_stack_offsets_size(frep->fre_info); >> + stack_offsets = ((unsigned char *)fre_buf + ip_offset_tsize >> + + sizeof(frep->fre_info)); >> + memcpy(frep->fre_offsets, stack_offsets, stack_offsets_sz); >> + >> + esz = sframe_fre_vlen_size(frep, fre_type); >> + *fre_size = esz; >> + >> + return 0; >> +} >> + >> +static struct sframe_func_desc_entry * >> +sframe_sec_find_fde(struct sframe_sec *sfsec, int32_t addr, int *errp) >> +{ >> + struct sframe_header *header; >> + struct sframe_func_desc_entry *fde; >> + int low, high, cnt; >> + >> + if (sfsec == NULL) { >> + sframe_set_errno(errp, SFRAME_ERR_INVAL); >> + return NULL; >> + } >> + >> + header = sframe_sec_get_header(sfsec); >> + if (header == NULL || header->num_fdes == 0 || sfsec->fdes == NULL) { >> + sframe_set_errno(errp, SFRAME_ERR_INIT_INVAL); >> + return NULL; >> + } >> + /* >> + * Skip binary search if FDE sub-section is not sorted on PCs. GNU ld >> + * sorts the FDEs on start PC by default though. >> + */ >> + if ((header->preamble.flags & SFRAME_F_FDE_SORTED) == 0) { >> + sframe_set_errno(errp, SFRAME_ERR_FDE_NOTSORTED); >> + return NULL; >> + } >> + >> + /* Find the FDE that may contain the addr. */ >> + fde = (struct sframe_func_desc_entry *)sfsec->fdes; >> + low = 0; >> + high = header->num_fdes; >> + cnt = high; >> + while (low <= high) { >> + int mid = low + (high - low) / 2; >> + >> + if (fde[mid].func_start_address == addr) >> + return fde + mid; >> + >> + if (fde[mid].func_start_address < addr) { >> + if (mid == (cnt - 1)) >> + return fde + (cnt - 1); >> + else if (fde[mid+1].func_start_address > addr) >> + return fde + mid; >> + low = mid + 1; >> + } else >> + high = mid - 1; >> + } >> + >> + sframe_set_errno(errp, SFRAME_ERR_FDE_NOTFOUND); >> + return NULL; >> +} >> + >> +static int8_t sframe_sec_get_fixed_fp_offset(struct sframe_sec *sfsec) >> +{ >> + struct sframe_header *header = sframe_sec_get_header(sfsec); >> + return header->cfa_fixed_fp_offset; >> +} >> + >> +static int8_t sframe_sec_get_fixed_ra_offset(struct sframe_sec *sfsec) >> +{ >> + struct sframe_header *header = sframe_sec_get_header(sfsec); >> + return header->cfa_fixed_ra_offset; >> +} >> + >> +size_t sframe_sec_sizeof(void) >> +{ >> + return sizeof (struct sframe_sec); >> +} >> + >> +int sframe_sec_init(struct sframe_sec *sfsec, const char *sf_buf, >> + size_t sf_size) >> +{ >> + char *frame_buf; >> + const struct sframe_preamble *preamble; >> + struct sframe_header *header; >> + >> + if ((sf_buf == NULL) || (sf_size < sizeof(struct sframe_header))) >> + return SFRAME_ERR_INVAL; >> + >> + /* Check for foreign endianness. */ >> + preamble = (const struct sframe_preamble *) sf_buf; >> + if (preamble->magic != SFRAME_MAGIC) >> + return SFRAME_ERR_INVAL; >> + >> + /* Reset the SFrame section object. */ >> + memset(sfsec, 0, sizeof(struct sframe_sec)); >> + >> + frame_buf = (char *)sf_buf; >> + >> + /* Initialize the reference to the SFrame header. */ >> + sfsec->header = *(struct sframe_header *) frame_buf; >> + header = &sfsec->header; >> + if (!sframe_header_sanity_check_p(header)) >> + return SFRAME_ERR_INVAL; >> + >> + /* Initialize the referece to the SFrame FDE section. */ >> + frame_buf += sframe_sec_get_hdr_size(header); >> + sfsec->fdes = frame_buf; >> + >> + /* Initialize the reference to the the SFrame FRE section. */ >> + frame_buf += (header->num_fdes * sizeof(struct sframe_func_desc_entry)); >> + sfsec->fres = frame_buf; >> + >> + sfsec->fre_nbytes = header->fre_len; >> + >> + return 0; >> +} >> + >> +/* >> + * Find the SFrame Frame Row Entry which contains the PC. >> + * Returns error code if failure. >> + */ >> +int sframe_sec_find_fre(struct sframe_sec *sfsec, int32_t pc, >> + struct sframe_fre *frep) >> +{ >> + struct sframe_func_desc_entry *fdep; >> + uint32_t start_address, i; >> + struct sframe_fre cur_fre, next_fre; > > Although the sframe_fre structure is relatively small, I always get nervous > when I see structures defined on the kernel stack. > > Also, I personally prefer to keep items defined themselves. That is, one > variable per line. > >> + unsigned char *fres; >> + unsigned int fre_type, fde_type; >> + size_t esz; >> + int err = 0; >> + size_t size = 0; > > And to organize it in an "upside-down x-mas" tree fashion: > > struct sframe_func_desc_entry *fdep; > struct sframe_fre next_fre; > struct sframe_fre cur_fre > uint32_t start_address, i; > unsigned int fre_type; > unsigned int fde_type; > unsigned char *fres; > size_t size = 0; > size_t esz; > int err = 0; > > Looks much nicer and easier to read that way ;-) > > -- Steve > OK. I can work these out. At some point I was running the script/checkpatch.pl but forgot about it over time. Will fix these issues. Thanks