From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-vi1eur04on2048.outbound.protection.outlook.com [40.107.8.48]) by sourceware.org (Postfix) with ESMTPS id 178BB3858D35 for ; Thu, 3 Aug 2023 11:38:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 178BB3858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=s/4WgZUVaPS8nK8GJ4z3peFnDS5RKTvXMy6CATSc7A0=; b=Ai2WR0jvA++dOVdPRGX8sND/R1ZNg0WcoSI/ssrDClr8fHwHQz5XuTiP6VUMhJGiHmcIMmc67es3RFTz3v9P3vzfDmY/tlWT7SWy4rMc71VfMQd8gCu1NH7v2DvMcGua+mDVrxrAJG5534y19Um7WC5nRUv68DBEIG8u7c3FXaw= Received: from AM5PR0301CA0029.eurprd03.prod.outlook.com (2603:10a6:206:14::42) by AS8PR08MB9840.eurprd08.prod.outlook.com (2603:10a6:20b:613::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.47; Thu, 3 Aug 2023 11:38:13 +0000 Received: from AM7EUR03FT060.eop-EUR03.prod.protection.outlook.com (2603:10a6:206:14:cafe::b2) by AM5PR0301CA0029.outlook.office365.com (2603:10a6:206:14::42) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44 via Frontend Transport; Thu, 3 Aug 2023 11:38:13 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM7EUR03FT060.mail.protection.outlook.com (100.127.140.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.47 via Frontend Transport; Thu, 3 Aug 2023 11:38:13 +0000 Received: ("Tessian outbound 997ae1cc9f47:v145"); Thu, 03 Aug 2023 11:38:13 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 988e83b9d239c790 X-CR-MTA-TID: 64aa7808 Received: from fd80d6969b87.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 6E2A57AD-D127-442D-982C-8DA60DE367CE.1; Thu, 03 Aug 2023 11:38:07 +0000 Received: from EUR04-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id fd80d6969b87.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 03 Aug 2023 11:38:07 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=II3c0Qn5fsBZOJ0Uz9SjZqdvBomvxfR5bosIY3HaeRMbeatdvscIY6Oy9lsVCAlvOIkWV8UrXrNxATPe2+u9E7JMq3xQvpndZxdWSrfickFWurYemaCywbebGICYHgMvJnq6dN0pvnA+wvC3QYe8c5lBmQuwBZZjGQN9KoTQHRBQl6Tkq+JxIqkKjodeMpy6pY6K5xJWnlaNKMjVIvakJx1/pmRjExhEs0JRGeqDdb6JBGaHsePdtxU1db10iHhpeDJDOtXkBuzRozwAaLxFuLJnpA1nXEix+x5tdjkgVUkzvbsqMHrUYbCYzAj2q0kpIxD/CqJ4j0HQFe77i5sGjg== 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=s/4WgZUVaPS8nK8GJ4z3peFnDS5RKTvXMy6CATSc7A0=; b=l/urlr53+VbF7NuvfKnr5HG0w+k+EanxQnJLFMgsCwrQrbuQqCF5MIDSInVcaxo9qUJcEJizk+o3OowwXzlpWvkx+m0GirdZ/sJ3rfDPcTMpyB2sA3LHjMXaqUQ294JXjiTRttCY2sORTe+N58VLJ+tbG5Fdqchxt4JxiVIyIe4Dw6tqX3FGbi91dMpJamc7BdHsJ+3ygYUaTx77EG4mv0UJILWCLJaWlaolhRJW9s1jRSAju8NuPRQa2NxGBnMxsvS/y59lWkIe0RuP+pt90EPvNfcHmNiorUnSSbnbMSI8wxZRRp6YL3GuP5vv7e+GM6yMUHQmwMqQqv48E2L3rA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=s/4WgZUVaPS8nK8GJ4z3peFnDS5RKTvXMy6CATSc7A0=; b=Ai2WR0jvA++dOVdPRGX8sND/R1ZNg0WcoSI/ssrDClr8fHwHQz5XuTiP6VUMhJGiHmcIMmc67es3RFTz3v9P3vzfDmY/tlWT7SWy4rMc71VfMQd8gCu1NH7v2DvMcGua+mDVrxrAJG5534y19Um7WC5nRUv68DBEIG8u7c3FXaw= Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB3919.eurprd08.prod.outlook.com (2603:10a6:803:c4::31) by PAWPR08MB9029.eurprd08.prod.outlook.com (2603:10a6:102:341::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.47; Thu, 3 Aug 2023 11:38:00 +0000 Received: from VI1PR08MB3919.eurprd08.prod.outlook.com ([fe80::d216:34d8:ae2a:fe17]) by VI1PR08MB3919.eurprd08.prod.outlook.com ([fe80::d216:34d8:ae2a:fe17%4]) with mapi id 15.20.6631.045; Thu, 3 Aug 2023 11:38:00 +0000 Message-ID: <4fec3ac7-1dcb-3cd3-4059-3b101b5fd1f2@arm.com> Date: Thu, 3 Aug 2023 12:37:51 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 Subject: Re: [PATCH v3 14/16] [gdb/aarch64] sme: Core file support for Linux To: Thiago Jung Bauermann Cc: gdb-patches@sourceware.org References: <20230630134616.1238105-1-luis.machado@arm.com> <20230630134616.1238105-15-luis.machado@arm.com> <874jlh2d39.fsf@linaro.org> Content-Language: en-US From: Luis Machado In-Reply-To: <874jlh2d39.fsf@linaro.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-ClientProxiedBy: SA1P222CA0088.NAMP222.PROD.OUTLOOK.COM (2603:10b6:806:35e::15) To VI1PR08MB3919.eurprd08.prod.outlook.com (2603:10a6:803:c4::31) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI1PR08MB3919:EE_|PAWPR08MB9029:EE_|AM7EUR03FT060:EE_|AS8PR08MB9840:EE_ X-MS-Office365-Filtering-Correlation-Id: da83154a-d7de-4477-0ddc-08db94161f38 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: 0TZyusIm/v3guquhD6nuAH0iokoslZ9BOjQVQNpugK8uL9BqkWwIvhntrPFCCWUCyvBiDsOGpPg3h7lUAOjUlDrGt5zcpfZxtcpjTD4Gd3MEBfI3oTH2zysqkXVuDPCfmcxiH+kL69jFSdgIQT5Mtrqaux6w5vsaFtJEv79ZkvoSW278WPogFNi3WHC/V0ccaZAaGjE6uxcPxZArNyztkZImvzcJ+ZK7y4z5S1ecCDhkzpPLWuoYR+ABRMdGewPBJx8hg30C0ByeqzfCurwYpr6PcUipMZp5s1w7oTBLSa7HofgAjr7m4J12H8Kxy6T91QC1IKGPy4+4L688AbEy3Js1eMcOS0eUWQ8vRhu1KptKpp2XknyINBTJ9KHnM8OMKDnoboJ611HwICsjZ0BY7eQMwuWExgkKe+OVOxaFICXDbx/utzhoF7+yf7XvFDAA4AVH2ORTFoR3g5bpOf+xTHdJJBVXybbLCgDeYylJRK6tFbubOpumYV1GyPPgAvoP8qt2CUmtZXF/Zi5fHX/CI12ZxHrV3SvRF9QC+OiY5oq4TS5PEVBrnNBnj+Z4sKHVCc6eoQBx097/EYAltu82/tbN2QgBxEvruEmVtkHr8EmyYSd6WbrR4FyKPiDa4uyKhyunuUeOI8XXCWACqfkK1g== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI1PR08MB3919.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(136003)(346002)(366004)(396003)(39860400002)(376002)(451199021)(186003)(41300700001)(6486002)(6666004)(478600001)(38100700002)(26005)(2616005)(83380400001)(6512007)(6506007)(53546011)(30864003)(316002)(2906002)(31696002)(86362001)(4326008)(6916009)(36756003)(66946007)(66556008)(66476007)(31686004)(8676002)(8936002)(5660300002)(44832011)(43740500002)(45980500001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR08MB9029 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM7EUR03FT060.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 9452c8ac-b20b-49a4-196a-08db94161662 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: rka9q5Dp5zqvlIE1vIkM5Nsku6r+CHjUHXPW34iK3TlIFEU3faoSEbKP91MDS0B41pSzh6qNztRjwlWu/NMKusK+SQRMUsJUQ12yKlq4rZ1xa9JvL0yyVfjE0/6roaHXtXxCOoEkZdR3pdN1gTb0GVct1DMPAdIDPaRoLr+fYJVflWw14doPzCyNwCAuS1LR8+5El9+oWhFN6u2OZLw6EP5m21ct4fE4Gh1fZ8gZLGoBuuNGbuA3dFyDWKhhoX2I9sBtfYGSGNIgsm6frikVvY6yrjyCxyYvMP4wye37BIS5jPsw4fpKEK5iVc3zj/C11BvXSUzwn6QqOGskLG0pP38c5+ibHYQuR40q8kChalnC9TpA5z1OIpDJ/fVFwceiMe9a6sRsvCVRdZQ0AXQpKhi2qIZjyFg2zuMIdKXxgYdENKHg+GwQ2scFOoIxRNs0aKMzvkad3bkOABa04wVcuAnm3Oli6OcsamwrG6y+GVk18G0PTxSv/nPo8Eb1d1kn+d0Y/orjyrIq12Mqd1WBO7fdyi7uAGUTgAbm7uHyIHShqenGCbSBw7oGSEwUCNbAOnuSuOQJqf637KSARUq0vZB1Q8VtK5iBMlgU44gMlBnbYiPMG384CQv+WJcSCNFqpIAs8sOrRN0S0fc3uojIqZZhmO4VR+tB4CKsUltISp3r3wKTY7tWtpHH5C1UbPBy3jSNtU/z0Kjx9QzgD7v39lX5b4W6x/+EM+d/Yluqc+MQhEcU174B5OfzfbF77mU49u4F0t+0fmI4LxBymDbO4A== X-Forefront-Antispam-Report: CIP:63.35.35.123;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:64aa7808-outbound-1.mta.getcheckrecipient.com;PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com;CAT:NONE;SFS:(13230028)(4636009)(376002)(136003)(39860400002)(396003)(346002)(82310400008)(451199021)(46966006)(36840700001)(40470700004)(40460700003)(2616005)(336012)(53546011)(83380400001)(6506007)(26005)(186003)(47076005)(41300700001)(36860700001)(30864003)(70586007)(2906002)(70206006)(4326008)(5660300002)(316002)(44832011)(8676002)(8936002)(6666004)(6486002)(6862004)(6512007)(478600001)(40480700001)(356005)(81166007)(31696002)(86362001)(36756003)(31686004)(82740400003)(43740500002);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Aug 2023 11:38:13.6234 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: da83154a-d7de-4477-0ddc-08db94161f38 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AM7EUR03FT060.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB9840 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,FORGED_SPF_HELO,GIT_PATCH_0,KAM_DMARC_NONE,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 8/3/23 01:18, Thiago Jung Bauermann wrote: > > Luis Machado via Gdb-patches writes: > >> This patch enables dumping SME state via gdb's gcore command and also >> enables gdb to read SME state from a core file generated by the Linux >> Kernel. >> >> Regression-tested on aarch64-linux Ubuntu 22.04/20.04. >> --- >> gdb/aarch64-linux-tdep.c | 532 ++++++++++++++++++++++++++++-- >> gdb/arch/aarch64-scalable-linux.c | 34 ++ >> gdb/arch/aarch64-scalable-linux.h | 15 + >> 3 files changed, 548 insertions(+), 33 deletions(-) >> >> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c >> index 7ce34ee6846..0bd75daa994 100644 >> --- a/gdb/aarch64-linux-tdep.c >> +++ b/gdb/aarch64-linux-tdep.c >> @@ -57,6 +57,10 @@ >> >> #include "elf/common.h" >> #include "elf/aarch64.h" >> +#include "arch/aarch64-insn.h" >> + >> +/* For std::sqrt */ > > s/sqrt/pow/ > Fixed. >> +#include > >> @@ -853,14 +901,89 @@ aarch64_linux_supply_sve_regset (const struct regset *regset, >> } >> } >> >> +/* Collect an inactive SVE register set state. This is equivalent to a >> + fpsimd layout. >> + >> + Collect the data from REGCACHE to BUF, using the register >> + map in REGSET. */ >> + >> +static void >> +collect_inactive_sve_regset (const struct regcache *regcache, >> + void *buf, size_t size, int vg_regnum) >> +{ >> + gdb_byte *header = (gdb_byte *) buf; >> + struct gdbarch *gdbarch = regcache->arch (); >> + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); >> + >> + gdb_assert (buf != nullptr); >> + gdb_assert (size > SVE_HEADER_SIZE); > > This assert should check for SVE_CORE_DUMMY_SIZE. > Fixed. >> + >> + /* Zero out everything first. */ >> + memset ((gdb_byte *) buf, 0, SVE_CORE_DUMMY_SIZE); >> + >> + /* BUF starts with a SVE header prior to the register dump. */ >> + >> + /* Dump the default size of an empty SVE payload. */ >> + uint32_t real_size = SVE_CORE_DUMMY_SIZE; >> + store_unsigned_integer (header + SVE_HEADER_SIZE_OFFSET, >> + SVE_HEADER_SIZE_LENGTH, byte_order, real_size); >> + >> + /* Dump a dummy max size. */ >> + uint32_t max_size = SVE_CORE_DUMMY_MAX_SIZE; >> + store_unsigned_integer (header + SVE_HEADER_MAX_SIZE_OFFSET, >> + SVE_HEADER_MAX_SIZE_LENGTH, byte_order, max_size); >> + >> + /* Dump the vector length. */ >> + ULONGEST vg = 0; >> + regcache->raw_collect (vg_regnum, &vg); >> + uint16_t vl = sve_vl_from_vg (vg); >> + store_unsigned_integer (header + SVE_HEADER_VL_OFFSET, SVE_HEADER_VL_LENGTH, >> + byte_order, vl); >> + >> + /* Dump the standard maximum vector length. */ >> + uint16_t max_vl = SVE_CORE_DUMMY_MAX_VL; >> + store_unsigned_integer (header + SVE_HEADER_MAX_VL_OFFSET, >> + SVE_HEADER_MAX_VL_LENGTH, byte_order, >> + max_vl); >> + >> + /* The rest of the fields is zero. */ > > s/is/are/ > Fixed. >> + uint16_t flags = SVE_CORE_DUMMY_FLAGS; >> + store_unsigned_integer (header + SVE_HEADER_FLAGS_OFFSET, >> + SVE_HEADER_FLAGS_LENGTH, byte_order, >> + flags); >> + uint16_t reserved = SVE_CORE_DUMMY_RESERVED; >> + store_unsigned_integer (header + SVE_HEADER_RESERVED_OFFSET, >> + SVE_HEADER_RESERVED_LENGTH, byte_order, reserved); >> + >> + /* We are done with the header part of it. Now dump the register state >> + in the FPSIMD format. */ >> + >> + /* Dump the first 128 bits of each of the Z registers. */ >> + header += AARCH64_SVE_CONTEXT_REGS_OFFSET; >> + for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++) >> + regcache->raw_collect_part (AARCH64_SVE_Z0_REGNUM + i, 0, V_REGISTER_SIZE, >> + header + V_REGISTER_SIZE * i); >> + >> + /* Dump FPSR and FPCR. */ >> + header += 32 * V_REGISTER_SIZE; >> + regcache->raw_collect (AARCH64_FPSR_REGNUM, header); >> + regcache->raw_collect (AARCH64_FPCR_REGNUM, header); > > Header needs to be incremented before writing FPCR, otherwise > raw_collect() will just overwrite FPSR. > Fixed. >> + >> + /* Dump two reserved empty fields of 4 bytes. */ >> + header += 8; >> + memset (header, 0, 8); >> + >> + /* We should have a FPSIMD-formatted register dump now. */ >> +} > >> +/* Supply register REGNUM from BUF to REGCACHE, using the register map >> + in REGSET. If REGNUM is -1, do this for all registers in REGSET. >> + If BUF is NULL, set the registers to "unavailable" status. */ >> + >> +static void >> +aarch64_linux_supply_sve_regset (const struct regset *regset, >> + struct regcache *regcache, >> + int regnum, const void *buf, size_t size) >> +{ >> + struct gdbarch *gdbarch = regcache->arch (); >> + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); >> + >> + if (tdep->has_sme ()) >> + { >> + ULONGEST svcr = 0; >> + regcache->raw_collect (tdep->sme_svcr_regnum, &svcr); > > Instead of relying on parsing the SSVE section before the SVE section to > ensure that the SVCR register is valid by the time we arrive here, isn't > it more robust to read the flags field from the SVE header in buf, as is > done in suply_sve_regset()? Also, it's what the SSE version does. > Did you mean s/SSE/SME? I'm not sure I understand. We need to process the SSVE entry first to make sure we have the right values for SVCR, and the SVE entry may be inactive. Could you please expand on your idea? >> + >> + /* Is streaming mode enabled? */ >> + if (svcr & SVCR_SM_BIT) >> + /* If so, don't load SVE data from the SVE section. The data to be >> + used is in the SSVE section. */ >> + return; >> + } >> + /* If streaming mode is not enabled, load the SVE regcache data from the SVE >> + section. */ >> + supply_sve_regset (regset, regcache, regnum, buf, size); >> +} >> + >> +/* Collect register REGNUM from REGCACHE to BUF, using the register >> + map in REGSET. If REGNUM is -1, do this for all registers in >> + REGSET. */ >> + >> +static void >> +aarch64_linux_collect_sve_regset (const struct regset *regset, >> + const struct regcache *regcache, >> + int regnum, void *buf, size_t size) >> +{ >> + struct gdbarch *gdbarch = regcache->arch (); >> + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); >> + bool streaming_mode = false; >> + >> + if (tdep->has_sme ()) >> + { >> + ULONGEST svcr = 0; >> + regcache->raw_collect (tdep->sme_svcr_regnum, &svcr); >> + >> + /* Is streaming mode enabled? */ >> + if (svcr & SVCR_SM_BIT) >> + { >> + /* If so, don't dump SVE regcache data to the SVE section. The SVE >> + data should be dumped to the SSVE section. Dump an empty SVE >> + block instead. */ >> + streaming_mode = true; >> + } >> + } >> + >> + /* If streaming mode is not enabled or there is no SME support, dump the >> + SVE regcache data to the SVE section. */ >> + >> + /* Check if we have an active SVE state (non-zero Z/P/FFR registers). >> + If so, then we need to dump registers in the SVE format. >> + >> + Otherwise we should dump the registers in the FPSIMD format. */ >> + if (sve_state_is_empty (regcache) || streaming_mode) >> + collect_inactive_sve_regset (regcache, buf, size, AARCH64_SVE_VG_REGNUM); > > If regnum != -1, collect_inactive_sve_regset () will still dump the > entirety of the fpsimd regset. Shouldn't it get the regnum as an > argument and dump just the requested register? > > Same comment in aarch64_linux_collect_ssve_regset (). > That is a bit strange, but I don't see this function being called with a specified regnum other than -1. For instance, in gcore-elf.c:gcore_elf_build_thread_register_notes, we fetch all registers. Also, in corelow.c:core_target::get_core_register_section, supply is also explicitly called with -1. Maybe this was updated at some point, and we don't fetch single registers from core files anymore. Do you see any paths calling this with regnum != -1? >> + else >> + collect_sve_regset (regset, regcache, regnum, buf, size); >> +} > >> +/* Collect register REGNUM from REGCACHE to BUF, using the register >> + map in REGSET. If REGNUM is -1, do this for all registers in >> + REGSET. */ >> + >> +static void >> +aarch64_linux_collect_ssve_regset (const struct regset *regset, >> + const struct regcache *regcache, >> + int regnum, void *buf, size_t size) >> +{ >> + struct gdbarch *gdbarch = regcache->arch (); >> + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); >> + ULONGEST svcr = 0; >> + regcache->raw_collect (tdep->sme_svcr_regnum, &svcr); >> + >> + /* Is streaming mode enabled? */ >> + if (svcr & SVCR_SM_BIT) >> + { >> + /* If so, dump SVE regcache data to the SSVE section. */ >> + collect_sve_regset (regset, regcache, regnum, buf, size); >> + } >> + else >> + { >> + /* Otherwise dump an empty SVE block to the SSVE section with the >> + streaming vector length. */ >> + collect_inactive_sve_regset (regcache, buf, size, tdep->sme_svg_regnum); > > Same argument here about regnum != -1 as in > aarch64_linux_collect_sve_regset(). > See above. >> + } >> +} >> + >> +/* Supply register REGNUM from BUF to REGCACHE, using the register map >> + in REGSET. If REGNUM is -1, do this for all registers in REGSET. >> + If BUF is NULL, set the registers to "unavailable" status. */ >> + >> +static void >> +aarch64_linux_supply_za_regset (const struct regset *regset, >> + struct regcache *regcache, >> + int regnum, const void *buf, size_t size) >> +{ >> + gdb_byte *header = (gdb_byte *) buf; >> + struct gdbarch *gdbarch = regcache->arch (); >> + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); >> + >> + /* Handle an empty buffer. */ >> + if (buf == nullptr) >> + return regcache->supply_regset (regset, regnum, nullptr, size); >> + >> + if (size < SVE_HEADER_SIZE) >> + warning (_("ZA state header size (%s) invalid. Should be at least %s."), >> + pulongest (size), pulongest (SVE_HEADER_SIZE)); > > If the header is truncated, I don't think the rest of this function > works correctly. I'd suggest either changing the warning to an error, or > treating this case in the same way as the buf == nullptr case above. > Yeah, this should be an error. I think at some point I used to handle it more gracefully, but it wasn't worth it. >> + >> + /* The ZA register note in a core file can have a couple of states: >> + >> + 1 - Just the header without the payload. This means that there is no >> + ZA data, and we should populate only SVCR and SVG registers on GDB's >> + side. The ZA data should be marked as unavailable. >> + >> + 2 - The header with an additional data payload. This means there is >> + actual ZA data, and we should populate ZA, SVCR and SVG. */ >> + >> + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); >> + >> + /* Populate SVG. */ >> + ULONGEST svg >> + = sve_vg_from_vl (extract_unsigned_integer (header + SVE_HEADER_VL_OFFSET, >> + SVE_HEADER_VL_LENGTH, >> + byte_order)); >> + regcache->raw_supply (tdep->sme_svg_regnum, &svg); >> + >> + size_t data_size >> + = extract_unsigned_integer (header + SVE_HEADER_SIZE_OFFSET, >> + SVE_HEADER_SIZE_LENGTH, byte_order) >> + - SVE_HEADER_SIZE; >> + >> + /* Populate SVCR. */ >> + bool has_za_payload = (data_size > 0); >> + ULONGEST svcr; >> + regcache->raw_collect (tdep->sme_svcr_regnum, &svcr); >> + >> + /* If we have a ZA payload, enable bit 2 of SVCR, otherwise clear it. This >> + register gets updated by the SVE/SSVE-handling functions as well, as they >> + report the SM bit 1. */ >> + if (has_za_payload) >> + svcr |= SVCR_ZA_BIT; >> + else >> + svcr &= ~SVCR_ZA_BIT; >> + >> + /* Update SVCR in the register buffer. */ >> + regcache->raw_supply (tdep->sme_svcr_regnum, &svcr); >> + >> + /* Populate the register cache with ZA register contents, if we have any. */ >> + buf = has_za_payload ? (gdb_byte *) buf + SVE_HEADER_SIZE : nullptr; >> + >> + /* Update ZA in the register buffer. */ >> + if (has_za_payload) >> + regcache->raw_supply (tdep->sme_za_regnum, buf); > > Do we need to make sure that buf is big enough to supply the whole > contents of the ZA register? Otherwise, the memcpy() in raw_supply() will > copy garbage. > Probably. Unlikely it would be wrong, but worth a check. >> + else >> + { >> + size_t za_bytes = std::pow (sve_vl_from_vg (svg), 2); >> + gdb_byte za_zeroed[za_bytes]; >> + memset (za_zeroed, 0, za_bytes); >> + regcache->raw_supply (tdep->sme_za_regnum, za_zeroed); >> + } >> +} >> + >> +/* Collect register REGNUM from REGCACHE to BUF, using the register >> + map in REGSET. If REGNUM is -1, do this for all registers in >> + REGSET. */ >> + >> +static void >> +aarch64_linux_collect_za_regset (const struct regset *regset, >> + const struct regcache *regcache, >> + int regnum, void *buf, size_t size) >> +{ >> + gdb_assert (buf != nullptr); >> + >> + if (size < SVE_HEADER_SIZE) >> + warning (_("ZA state header size (%s) invalid. Should be at least %s."), >> + pulongest (size), pulongest (SVE_HEADER_SIZE)); > > Here too, if size < SVE_HEADER_SIZE I don't think it makes sense to try > to continue. Perhaps put this condition in a gdb_assert()? > Agreed. Fixed. >> + >> + /* The ZA register note in a core file can have a couple of states: >> + >> + 1 - Just the header without the payload. This means that there is no >> + ZA data, and we should dump just the header. >> + >> + 2 - The header with an additional data payload. This means there is >> + actual ZA data, and we should dump both the header and the ZA data >> + payload. */ >> + >> + aarch64_gdbarch_tdep *tdep >> + = gdbarch_tdep (regcache->arch ()); >> + >> + /* Determine if we have ZA state from the SVCR register ZA bit. */ >> + ULONGEST svcr; >> + regcache->raw_collect (tdep->sme_svcr_regnum, &svcr); >> + >> + /* Check the ZA payload. */ >> + bool has_za_payload = (svcr & SVCR_ZA_BIT) != 0; >> + size = has_za_payload ? size : SVE_HEADER_SIZE; >> + >> + /* Write the size and max_size fields. */ >> + gdb_byte *header = (gdb_byte *) buf; >> + enum bfd_endian byte_order = gdbarch_byte_order (regcache->arch ()); >> + store_unsigned_integer (header + SVE_HEADER_SIZE_OFFSET, >> + SVE_HEADER_SIZE_LENGTH, byte_order, size); >> + >> + uint32_t max_size >> + = SVE_HEADER_SIZE + std::pow (sve_vl_from_vq (tdep->sme_svq), 2); >> + store_unsigned_integer (header + SVE_HEADER_MAX_SIZE_OFFSET, >> + SVE_HEADER_MAX_SIZE_LENGTH, byte_order, max_size); >> + >> + /* Output the other fields of the ZA header (vl, max_vl, flags and >> + reserved). */ >> + uint64_t svq = tdep->sme_svq; >> + store_unsigned_integer (header + SVE_HEADER_VL_OFFSET, SVE_HEADER_VL_LENGTH, >> + byte_order, sve_vl_from_vq (svq)); >> + >> + uint16_t max_vl = SVE_CORE_DUMMY_MAX_VL; >> + store_unsigned_integer (header + SVE_HEADER_MAX_VL_OFFSET, >> + SVE_HEADER_MAX_VL_LENGTH, byte_order, >> + max_vl); >> + >> + uint16_t flags = SVE_CORE_DUMMY_FLAGS; >> + store_unsigned_integer (header + SVE_HEADER_FLAGS_OFFSET, >> + SVE_HEADER_FLAGS_LENGTH, byte_order, flags); >> + >> + uint16_t reserved = SVE_CORE_DUMMY_RESERVED; >> + store_unsigned_integer (header + SVE_HEADER_RESERVED_OFFSET, >> + SVE_HEADER_RESERVED_LENGTH, byte_order, reserved); >> + >> + buf = has_za_payload ? (gdb_byte *) buf + SVE_HEADER_SIZE : nullptr; >> + >> + /* Dump the register cache contents for the ZA register to the buffer. */ >> + regcache->collect_regset (regset, regnum, (gdb_byte *) buf, >> + size - SVE_HEADER_SIZE); > > Calling collect with buf == nullptr will invalidate the regset. Is that > the intention? > Yes. It will be invalidated and memset-ed to 0. Though that behavior might not be a strong guarantee. >> +} >