From patchwork Wed Apr 9 14:07:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeny Karpov X-Patchwork-Id: 110117 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 323DB3851C05 for ; Wed, 9 Apr 2025 14:07:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 323DB3851C05 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=microsoft.com header.i=@microsoft.com header.a=rsa-sha256 header.s=selector2 header.b=JrllPw9U X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2070a.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::70a]) by sourceware.org (Postfix) with ESMTPS id 767DB3858D39 for ; Wed, 9 Apr 2025 14:07:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 767DB3858D39 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=microsoft.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=microsoft.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 767DB3858D39 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=2a01:111:f403:2613::70a ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1744207628; cv=pass; b=Z18rxlH1hw+kewpu5DPItijnQSaWlWLzeGdVmEpPxw5suq7s5oxhX/QZMWhm/pyiAOJeLje+9gFSO0ZugRItVG1YaL65dnJSWpVNIaW1tvMbZKyDONn4U+/MdJTuxePvMoN7737GZO1G/8Bfmu1ZqghW0qAd6SRfUZOn6V3eBPQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1744207628; c=relaxed/simple; bh=0UW/rs43pAeLL03bVr4r9i0aOYEH2oBgPmr/0UrrPbA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=U3DQnhudMaBgkPx8pk91d84SnTYfYyDqNpKsoz4Cf9sfPyb0d6/olhgIb+xhAU4a8yYXTfh+SD9IoY2bNWUOm9Nf5qxOfY+ZGDb1f1bWgVInp+huwqsOzCEdwK1YYmbIdzTNBd/rJpQ7m2HYb2fh0a5SMir6Rn5PUfTzvViGTUo= ARC-Authentication-Results: i=2; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 767DB3858D39 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=IZObFFi6M3gTkD/wmIiveOHb+7OB9l8ABLjfJ9ibX9n06rYvtH/aLIbH7uVkzq6BjW7PiiHkZE5ojnCgqxyK2APXhd0YzViuge2vems2z+hCiOI3RVqMO3OQx0iXxQrbSN/Gd6rJ4Czp6HVCOHpqjy7R1/uBAEY1J7BCFDcOjJRbkfx5wpikBzowR+HtIa+0IBNmOl3kazpDfMxMBtkutz94uTKLqKKQo5XpQkGimQEklS7Hjw2irqyBsE0aJCnYkPnVee1fWABSicScrCgHGeBpnBy/sIyorM5Vny5F6l54PrFOFMVuS7DHg5AfO4g2QjKuAIVGGDOffE32jobRJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=7flSpL9F8xcV66hBBETeu1ZC2q2c7rnQK3TNxPzO/aM=; b=iSlzjTu6P8GTmHPOfUNLzeETNuAwerrVy1k9i/UIO881gJMAoZh+nG+RoPP1uzssiP8e5OjJX78QQibWUI6PU6x06yWENPWQSko6YBPLDMsZFpoxn8dENdeAc4rDmgpPX6Jp4/+repSlhp5pzKll2lwJaXOfmUudT2rm1zr96k+rJcdHf5jQktHCC8c0/ps+vX9dQh5RMcsZKg6F19MSzT12NflzZLPWl/tEpnjcZ6Y1XZQIrXwV46+UAIe6E9N5sisdOarSl434hl1d6cd16RumtQ6iC8NVCSPe5m+54COn3iMjVkp1P/HTJp5Ss3iAq2zYvNA8Ji94HwSOh18jNA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7flSpL9F8xcV66hBBETeu1ZC2q2c7rnQK3TNxPzO/aM=; b=JrllPw9UfHLRIi5lvAIXtioc5AUpoNz0Om7pgD7ODqGuvvrSA2IGmYkyN8HOB5XtAa+0hmTKS2NRYOK10KNdvwpCPbbtIrZjCsMSmMiWjhFyCy/vUtiBxbE06Qii6mQxqDGQO1HGHZlO6ZQypC5k2Yj+qal0e1gSypTBw3x7QE8= Received: from VI2PR83MB0718.EURPRD83.prod.outlook.com (2603:10a6:800:270::12) by GV2PR83MB0901.EURPRD83.prod.outlook.com (2603:10a6:150:277::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8655.5; Wed, 9 Apr 2025 14:07:04 +0000 Received: from VI2PR83MB0718.EURPRD83.prod.outlook.com ([fe80::9b44:280f:9a72:cfb]) by VI2PR83MB0718.EURPRD83.prod.outlook.com ([fe80::9b44:280f:9a72:cfb%5]) with mapi id 15.20.8655.002; Wed, 9 Apr 2025 14:07:03 +0000 From: Evgeny Karpov To: Binutils CC: "Richard Earnshaw (lists)" , "amodra@gmail.com" , Radek Barton Subject: [PATCH v1 3/7] Adjust x64 SEH implementation for AArch64 Thread-Topic: [PATCH v1 3/7] Adjust x64 SEH implementation for AArch64 Thread-Index: AQHbqVirovY6BTqWIker5aIMvodP2w== Date: Wed, 9 Apr 2025 14:07:03 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=True; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2025-04-09T14:06:41.640Z; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name=General; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ContentBits=0; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Method=Standard; authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=microsoft.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: VI2PR83MB0718:EE_|GV2PR83MB0901:EE_ x-ms-office365-filtering-correlation-id: 6178bd7e-1ddf-40cc-3d26-08dd776fcdcc x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; ARA:13230040|376014|366016|1800799024|38070700018; x-microsoft-antispam-message-info: =?iso-8859-1?q?rrTEHlNlfBvzRVXs4Ni1KwetVU?= =?iso-8859-1?q?f2JgOLE/BFvR25e/K1nTD0KF04rdwb7US8nspnXmhtlm9Gu99u3NyTuIzBnK?= =?iso-8859-1?q?VcdV53lh0BEnt+Df0C/X2BP/M00eO1mOu8oKkVrYUVkEyX3RMQns66TY8LeF?= =?iso-8859-1?q?alCcHj8T15Oh4Wz2DyS+fgWvfSxRh5tLw4/0l8CejmAt8fBS+RT4mqQBLN//?= =?iso-8859-1?q?6OCJUNmBkMBlCSYehbZkHR3d9S6XHdOHMoBqcPrpr8xHqkFuqLKezqhp6Rhq?= =?iso-8859-1?q?K3oz+LJR0NzWSFoYb486JJyI9IMlMBlqDcqZ+MiDusofGrCNgWFD6mO44Ks2?= =?iso-8859-1?q?s9RiPcV0fRCURYSJkvQEG/qf4WSLtM45uyLGuVC2oWkUggaGDWOFKj6QQ1xJ?= =?iso-8859-1?q?AtKKdSr6CHDA8+MY+Rmio27PT2Fv9AJ21vh3rKJw1awLpA259kwdRqnpQ2lF?= =?iso-8859-1?q?WxdyZofH6tmDPBNp0oFnYqbMGoNprje8xp+Xs6W9fD/xNgzdbKMB/xiKzwIX?= =?iso-8859-1?q?d98L5uSQnKXA6whC6PCZkXze3iATqagOfEuzl4nUtX6Kk97SbeL8+3U8j5PP?= =?iso-8859-1?q?p9LUjR+T/hupqIFQ7duKE2L60VqaJxJmVjKYA3wOiyBYll70SLrffdXr4QjS?= =?iso-8859-1?q?zHNZJXIS9mcyeCStfaZVgW/1qCY2Kgr0khO44kR7dwg3UuVExwZTuR/ksL07?= =?iso-8859-1?q?nmoFzWaB9hvYd0dexOWK2Yqx5YB0vYjxJPMLbFTW/5OAJHfwwuF+k2hQnxFO?= =?iso-8859-1?q?OKSRoNarsriSFn7TaKHf6Y1UtoqSBjemwPYm1IvpmPjZmSxYL3ocYELjiOgw?= =?iso-8859-1?q?hTtGNgs6+/nzAnNDuag8OexQ7zY1EEX4B14xq3TY69/zqT1zB4cfvvXJfSNj?= =?iso-8859-1?q?SuMaLpwv9aHayDlnl1z3NcBuUSZb4O0oG/vtwJb4JGKcqUBCfWxtPRiueD6s?= =?iso-8859-1?q?G9Zj6izGMwQGyR4Bnh3I7n/ElqvMcrf3i/58oEbHsTydpeOYbqEhCdnJqDR0?= =?iso-8859-1?q?TRbz9/ahJaWjVPEQNMXBKZ+/ho2oziGSV8OCFbA9Z7AUPBZDkg81Y+NMQloZ?= =?iso-8859-1?q?vGjpoouGXBlgZLqjfrAPh4c6yXNNqnHFDaDB6GiaesIH9B6Lye2FVKLnvYES?= =?iso-8859-1?q?cLLVLkZgnVLrJqt4VU/Q185a8bHy1DeQZdZBLUSQ+sh+Vqz7eG4siv5Bo/uL?= =?iso-8859-1?q?GmMlmDtSAsHvE9W3+9bfBrexZwipFDrrZN+RmLe42WGphufFCAC/z+pAOj1R?= =?iso-8859-1?q?sYPbXnbvmaLkEPv8HZNuVX1Eke3/oxMhZUIxfYPqtstCG8Au3NtVVndg7aGR?= =?iso-8859-1?q?1bq56X5M0jKHK878/oBDvAJTz1Ndd8Ll48vmHqtJokYbXR/M8s7MtGRUL5VS?= =?iso-8859-1?q?aEFbW05G6BH2MKGH8EGZS/d5n6Sb8EAALLQt/uBKil+/kNQeYnFSWH/CifOR?= =?iso-8859-1?q?z8093MVMPEefCLoeAwwX3PyFNsHyvf2BK34IumSEWeMl0NYgPMr08r1z7pt6?= =?iso-8859-1?q?E6Qv9ABlLjZwNlz8NtijPgEHZG6Yche/5oS8/EOQBfkN8rWgY=3D?= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI2PR83MB0718.EURPRD83.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(376014)(366016)(1800799024)(38070700018); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-1?q?Qx+fOmZ24O8UVLDWglwnFx3?= =?iso-8859-1?q?W6Px8KQQyGIhx8tgO9Tc5nCQuHXOo/hfP0JednzA4PiGXTt5zUSv2ycSWEel?= =?iso-8859-1?q?s/lPuF4TItcbcHHVo+c15mdrlHuIrW2SoEWHrrSEqjqoPEMyevYC0KpIj4Tq?= =?iso-8859-1?q?ASTJ01/LrtLPCFxN1FIXBxmZZsRYknXr7gf7cRMMTAnN6OnXLoEPai3QwUww?= =?iso-8859-1?q?Z5aYk7SCxolNM0C6XKrgwKDGLcoMvosP28wFPFzm1R2EyWj6NRrDs9bFjnzd?= =?iso-8859-1?q?0P3GAQXnQGLmIS3hfSzojM9I9iHtcyVxkvwRcVACoYnXQP2/0qpg3gnIHWOU?= =?iso-8859-1?q?3kESOv1d3pMb09mbbXq1To4bJIqJSvJ4l6gSC1x9zaLG6mYaitdsV+lKKrHe?= =?iso-8859-1?q?Df+gH1qfPGeGrj/e3rQT+IgYDpCR9GnrXASwVFYNYkYEU+Yse2U8at6Y7liE?= =?iso-8859-1?q?sxrQXFtbd+dVn3UmpRIL2JOrz8LINI1pLHBWUDIRe7vlcwOqW9tRA3a2l0/W?= =?iso-8859-1?q?IAs5W3rkV0wG/dRlD5UBP3uvlbXFsMT6OaixrKj+FPANTP5ZzDJy6x9FNYEH?= =?iso-8859-1?q?Xn/IhafNmJm3Nh3LVRT1A/SQDnYFfrtYMsZZPb02oqxiqQ4CK4mxNbRGwYxY?= =?iso-8859-1?q?BFTuDy1GrVzXeG3wyKFEoAIlhE9ehCzpI1iM3rM7WuZMJxDXS+LWJgwE78CX?= =?iso-8859-1?q?KBjJm3eTB3fZfewifVbzOaDYUq65hZcyL/S2TpnpZeVaBXCfyYORt0DPF/Mw?= =?iso-8859-1?q?OPzIKN3dsbCGCSwTEJGX2EwtUSfwTlji70AaBnbSdCcezf6Hh16yWr7MOXXp?= =?iso-8859-1?q?+V1llPuf/4sJZOpBZkLQ/dZzJvU+BvcfRlCDOQzAA2bhIsV3TcgO+1dj4714?= =?iso-8859-1?q?TlZjXJ34QPKsM0bXPKFl15r+KqA3JvRLpQn1fIJY6wq1kwyYeFUvrE+Ng2+Q?= =?iso-8859-1?q?/HWSE3iRb4hzCiiknCAekUy+mqUmQUu8McyBkCiCD+XZtJP3DJfIsdg15qj+?= =?iso-8859-1?q?PFq0+QmRjnslKhfsaISnMtxh4ivOaRyrR9ZT/b/Yh2clpaUoHqQVXlMenW+j?= =?iso-8859-1?q?dkHyBLX+9cI3ekLw/Q7/PNQPE1j8YykyXtlNPfj0ValiFKlyLEXW+cm002QL?= =?iso-8859-1?q?HXwuRqSQd3dmHqsDRUPXf2+8+6R9eAGo/hg0yeGglgL+p89MaCo+4xYcpGvY?= =?iso-8859-1?q?YzjxRe5ggH2x/7jVA2XwCDZRjvtUcfYKI3cMeCy1v4H11uSUi0YkATvjddZz?= =?iso-8859-1?q?dcv6B81C3KBhdgrdXI+ZlsMBUk2vxOTZwUTQBY3HIIBA1TvpPgrOgbikolaQ?= =?iso-8859-1?q?fE3xv/5V9Vvb61rr8ZBjdgqzGqkFpkULJbm/au8PlC1Ax+TQP5I//S1aTw76?= =?iso-8859-1?q?bF6ZZjJKR6KkLv1s0EkP5uBSp9GvpqAqk2JARV7LO63w7yYQkGgvuaTuU8Bi?= =?iso-8859-1?q?AijaoyyzdXVwPU+YipMIcHnNIZjqXT2XxjmMJ/acmzorBM7R9DYW7/pVoLuh?= =?iso-8859-1?q?+PwPmBwMIjcL6W2mfZ+7QaUsi2YJRrjFNQusEavQGiabPhFMwkmrle1AL9YA?= =?iso-8859-1?q?xBiVeFzpKpa3oI4A2NJwy4rlLYJDYetNcXMqEQvMP8soLgBBUtZrRH3PIaP2?= =?iso-8859-1?q?Ssa8psTxMSmoctgNm?= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: VI2PR83MB0718.EURPRD83.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6178bd7e-1ddf-40cc-3d26-08dd776fcdcc X-MS-Exchange-CrossTenant-originalarrivaltime: 09 Apr 2025 14:07:03.4220 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 5yl04yTrPEDvD1Q/640dT6cW5TEhTZGjNEYrkdmT6LD/QO7sHHL38DtdL9AgHoVypRmRRaJNbg5yCN9PF7Uebw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV2PR83MB0901 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FORGED_SPF_HELO, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_NONE, TXREP 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: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patchwork=sourceware.org@sourceware.org This patch defines the required unwind codes for AArch64 and updates handlers for SEH commands that are used by both x64 and AArch64. It implements encoding for unwind elements that will be emitted to pdata/xdata sections. gas/ChangeLog: * config/obj-coff-seh.c (struct unwind_code_pack_info): New. (seh_get_target_kind): New. (verify_context_and_targets): Update. (obj_coff_seh_handler): Update. (obj_coff_seh_handlerdata): Update. (seh_arm64_add_unwind_element): New. (obj_coff_seh_proc): Update. (obj_coff_seh_endprologue): Update. (obj_coff_seh_stackalloc): Update. --- gas/config/obj-coff-seh.c | 245 ++++++++++++++++++++++++++++++++++---- 1 file changed, 222 insertions(+), 23 deletions(-) diff --git a/gas/config/obj-coff-seh.c b/gas/config/obj-coff-seh.c index 70cb4e4aa64..250cbc236ef 100644 --- a/gas/config/obj-coff-seh.c +++ b/gas/config/obj-coff-seh.c @@ -28,6 +28,20 @@ struct seh_seg_list { char *seg_name; }; +struct unwind_code_pack_info { + const char* directive; + int offset_bits; + int reg_bits; + int code_bits; + int code; + int offset_right_shift; + int offset; + int reg_right_shift; + int reg_offset; + int type; + int size; +}; + /* Local data. */ static seh_context *seh_ctx_cur = NULL; @@ -36,6 +50,51 @@ static htab_t seh_hash; static struct seh_seg_list *x_segcur = NULL; static struct seh_seg_list *p_segcur = NULL; +const struct unwind_code_pack_info unwind_code_pack_infos[] = { + {NULL, 5, 0, 3, ARM64_UNOP_ALLOCS, 4, 0, 0, 0, + alloc_s, 1}, + {NULL, 11, 0, 5, ARM64_UNOP_ALLOCM, 4, 0, 0, 0, + alloc_m, 2}, + {NULL, 24, 0, 8, ARM64_UNOP_ALLOCL, 4, 0, 0, 0, + alloc_l, 4}, + {".seh_save_reg", 6, 4, 6, ARM64_UNOP_SAVEREG, 3, 0, 0, 19, + save_reg, 2}, + {".seh_save_reg_x", 5, 4, 7, ARM64_UNOP_SAVEREGX, 3, 1, 0, 19, + save_reg_x, 2}, + {".seh_save_regp", 6, 4, 6, ARM64_UNOP_SAVEREGP, 3, 0, 0, 19, + save_regp, 2}, + {".seh_save_regp_x", 6, 4, 6, ARM64_UNOP_SAVEREGPX, 3, 1, 0, 19, + save_regp_x, 2}, + {".seh_save_lrpair", 6, 3, 7, ARM64_UNOP_SAVELRPAIR, 3, 0, 1, 19, + save_lrpair, 2}, + {".seh_save_fregp", 6, 3, 7, ARM64_UNOP_SAVEFREGP, 3, 0, 0, 8, + save_fregp, 2}, + {".seh_save_fregp_x", 6, 3, 7, ARM64_UNOP_SAVEFREGPX, 3, 1, 0, 8, + save_fregp_x, 2}, + {".seh_save_freg", 6, 3, 7, ARM64_UNOP_SAVEFREG, 3, 0, 0, 8, + save_freg, 2}, + {".seh_save_freg_x", 5, 3, 8, ARM64_UNOP_SAVEFREGX, 3, 1, 0, 8, + save_freg_x, 2}, + {".seh_save_fplr", 6, 0, 2, ARM64_UNOP_SAVEFPLR, 3, 0, 0, 0, + save_fplr, 1}, + {".seh_save_fplr_x", 6, 0, 6, ARM64_UNOP_SAVEFPLRX, 3, 1, 0, 0, + save_fplr_x, 1}, + {".seh_save_r19r20_x", 5, 0, 3, ARM64_UNOP_SAVER19R20X, 3, 0, 0, 0, + save_r19r20_x, 1}, + {".seh_add_fp", 8, 0, 8, ARM64_UNOP_ADDFP, 0, 0, 0, 0, + add_fp, 2}, + {".seh_set_fp", 0, 0, 8, ARM64_UNOP_SETFP, 0, 0, 0, 0, + set_fp, 1}, + {".seh_save_next", 0, 0, 8, ARM64_UNOP_SAVENEXT, 0, 0, 0, 0, + save_next, 1}, + {".seh_nop", 0, 0, 8, ARM64_UNOP_NOP, 0, 0, 0, 0, + nop, 1}, + {".seh_pac_sign_lr", 0, 0, 8, ARM64_UNOP_PACSIGNLR, 0, 0, 0, 0, + pac_sign_lr, 1}, + {NULL, 0, 0, 8, ARM64_UNOP_END, 0, 0, 0, 0, + end, 1}, +}; + static void write_function_xdata (seh_context *); static void write_function_pdata (seh_context *); @@ -200,6 +259,8 @@ seh_get_target_kind (void) switch (bfd_get_arch (stdoutput)) { case bfd_arch_aarch64: + return seh_kind_arm64; + case bfd_arch_arm: case bfd_arch_powerpc: case bfd_arch_sh: @@ -270,6 +331,32 @@ verify_context_and_target (const char *directive, seh_kind target) return verify_context (directive); } +/* Verify mulitple targets. */ + +static int +verify_context_and_targets (const char *directive, const seh_kind targets[], + int count_targets) +{ + bool match = false; + for (int i = 0; i < count_targets; ++i) + { + if (seh_get_target_kind () == targets[i]) + { + match = true; + break; + } + } + + if (!match) + { + as_warn (_("%s ignored for this target"), directive); + ignore_rest_of_line (); + return 0; + } + + return verify_context (directive); +} + /* Skip whitespace and a comma. Error if the comma is not seen. */ static int @@ -362,6 +449,10 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED) else expression (&seh_ctx_cur->handler); + const seh_kind target_kind = seh_get_target_kind (); + if (target_kind == seh_kind_arm64) + seh_ctx_cur->arm64_ctx.xdata_header.x = 1; + seh_ctx_cur->handler_data.X_op = O_constant; seh_ctx_cur->handler_data.X_add_number = 0; seh_ctx_cur->handler_flags = 0; @@ -369,7 +460,7 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED) if (!skip_whitespace_and_comma (0)) return; - if (seh_get_target_kind () == seh_kind_x64) + if (target_kind == seh_kind_x64 || target_kind == seh_kind_arm64) { do { @@ -401,13 +492,65 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED) static void obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED) { - if (!verify_context_and_target (".seh_handlerdata", seh_kind_x64)) + const seh_kind targets[] = { seh_kind_x64, seh_kind_arm64 }; + if (!verify_context_and_targets (".seh_handlerdata", targets, + sizeof (targets) / sizeof (seh_kind))) return; demand_empty_rest_of_line (); switch_xdata (seh_ctx_cur->subsection + 1, seh_ctx_cur->code_seg); } +/* Obtain available unwind element. */ + +static void +seh_arm64_add_unwind_element (seh_arm64_unwind_types unwind_type, int offset, + int reg) +{ + if (seh_ctx_cur == NULL + || seh_ctx_cur->arm64_ctx.unwind_codes_count >= ARM64_MAX_UNWIND_CODES) + { + as_warn (_("no unwind element available.")); + return; + } + + seh_arm64_unwind_code *arm64_element = seh_ctx_cur->arm64_ctx.unwind_codes + + seh_ctx_cur->arm64_ctx.unwind_codes_count++; + const struct unwind_code_pack_info *unwind_code_pack_info; + unwind_code_pack_info = unwind_code_pack_infos + unwind_type; + arm64_element->value = 0; + int value_offset_bits = 0; + + if (unwind_code_pack_info->offset_bits) + { + offset = (offset >> unwind_code_pack_info->offset_right_shift) + - unwind_code_pack_info->offset; + offset &= (1 << unwind_code_pack_info->offset_bits) - 1; + arm64_element->value |= offset << value_offset_bits; + value_offset_bits += unwind_code_pack_info->offset_bits; + } + + if (unwind_code_pack_info->reg_bits) + { + reg = (reg >> unwind_code_pack_info->reg_right_shift) + - unwind_code_pack_info->reg_offset; + reg &= (1 << unwind_code_pack_info->reg_bits) - 1; + arm64_element->value |= reg << value_offset_bits; + value_offset_bits += unwind_code_pack_info->reg_bits; + } + + if (unwind_code_pack_info->code_bits) + { + int code = unwind_code_pack_info->code; + code &= (1 << unwind_code_pack_info->code_bits) - 1; + arm64_element->value |= code << value_offset_bits; + } + + arm64_element->type = unwind_code_pack_info->type; + seh_ctx_cur->arm64_ctx.unwind_codes_byte_count += unwind_code_pack_info->size; +} + + /* Mark end of current context. */ static void @@ -465,11 +608,18 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED) seh_ctx_cur->code_seg = now_seg; - if (seh_get_target_kind () == seh_kind_x64) + seh_kind kind = seh_get_target_kind (); + if (kind == seh_kind_x64 || kind == seh_kind_arm64) { x_segcur = seh_hash_find_or_make (seh_ctx_cur->code_seg, ".xdata"); seh_ctx_cur->subsection = x_segcur->subseg; x_segcur->subseg += 2; + + if (kind == seh_kind_arm64) + { + seh_ctx_cur->arm64_ctx.unwind_codes_count = 0; + seh_ctx_cur->arm64_ctx.epilogue_scopes_count = 0; + } } SKIP_WHITESPACE (); @@ -498,6 +648,23 @@ obj_coff_seh_endprologue (int what ATTRIBUTE_UNUSED) as_warn (_("duplicate .seh_endprologue in .seh_proc block")); else seh_ctx_cur->endprologue_addr = symbol_temp_new_now (); + + if (seh_get_target_kind () == seh_kind_arm64) + { + const int n = seh_ctx_cur->arm64_ctx.unwind_codes_count; + + /* Unwind codes need to be reversed. */ + for (int i = 0; i < n / 2; ++i) + { + seh_arm64_unwind_code *unwind_codes; + unwind_codes = seh_ctx_cur->arm64_ctx.unwind_codes; + seh_arm64_unwind_code temp = unwind_codes[i]; + unwind_codes[i] = unwind_codes[n-i-1]; + unwind_codes[n-i-1] = temp; + } + + seh_arm64_add_unwind_element (end, 0, 0); + } } /* End-of-file hook. */ @@ -691,34 +858,66 @@ obj_coff_seh_stackalloc (int what ATTRIBUTE_UNUSED) offsetT off; int code, info; - if (!verify_context_and_target (".seh_stackalloc", seh_kind_x64) + const seh_kind targets[] = { seh_kind_x64, seh_kind_arm64 }; + if (!verify_context_and_targets (".seh_stackalloc", targets, + sizeof (targets) / sizeof (seh_kind)) || !seh_validate_seg (".seh_stackalloc")) return; off = get_absolute_expression (); demand_empty_rest_of_line (); - if (off == 0) - return; - if (off < 0) - { - as_bad (_(".seh_stackalloc offset is negative")); - return; - } + switch (seh_get_target_kind ()) + { + case seh_kind_x64: + if (off == 0) + return; + if (off < 0) + { + as_bad (_(".seh_stackalloc offset is negative")); + return; + } - if ((off & 7) == 0 && off <= 128) - code = UWOP_ALLOC_SMALL, info = (off - 8) >> 3, off = 0; - else if ((off & 7) == 0 && off <= (offsetT) (0xffff * 8)) - code = UWOP_ALLOC_LARGE, info = 0, off >>= 3; - else if (off <= (offsetT) 0xffffffff) - code = UWOP_ALLOC_LARGE, info = 1; - else - { - as_bad (_(".seh_stackalloc offset out of range")); - return; - } + if ((off & 7) == 0 && off <= 128) + code = UWOP_ALLOC_SMALL, info = (off - 8) >> 3, off = 0; + else if ((off & 7) == 0 && off <= (offsetT) (0xffff * 8)) + code = UWOP_ALLOC_LARGE, info = 0, off >>= 3; + else if (off <= (offsetT) 0xffffffff) + code = UWOP_ALLOC_LARGE, info = 1; + else + { + as_bad (_(".seh_stackalloc offset out of range")); + return; + } - seh_x64_make_prologue_element (code, info, off); + seh_x64_make_prologue_element (code, info, off); + break; + + case seh_kind_arm64: + /* arm64 offset should be encoded in multiples of sixteen. */ + if ((off & 0xf) != 0) + { + as_bad (_(".seh_stackalloc offset < 16-byte stack alignment")); + return; + } + + if (off < 0x200) + seh_arm64_add_unwind_element (alloc_s, off, 0); + else if (off < 0x8000) + seh_arm64_add_unwind_element (alloc_m, off, 0); + else if (off < 0x10000000) + seh_arm64_add_unwind_element (alloc_l, off, 0); + else + { + as_bad (_(".seh_stackalloc offset out of range")); + return; + } + break; + + default: + as_bad (_(".seh_stackalloc invalid target")); + return; + } } /* Add a frame-pointer token to current context. */