From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id EaThGRkk32p6xxsAWB0awg (envelope-from ) for ; Mon, 26 Oct 2026 05:57:45 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=kINc/iHN; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 5523F378004; Mon, 26 Oct 2026 05:57:45 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-4.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FORGED_GMAIL_RCVD,FREEMAIL_FROM, LOTS_OF_MONEY,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 850F51E007 for ; Mon, 26 Oct 2026 05:57:41 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 175A74BA23C1 for ; Mon, 26 Oct 2026 09:57:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 175A74BA23C1 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=kINc/iHN Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by sourceware.org (Postfix) with ESMTPS id 4AE284BA2E15 for ; Mon, 26 Oct 2026 09:57:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4AE284BA2E15 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4AE284BA2E15 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::434 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1793008627; cv=none; b=uHAstNA8HSOZWXkDvu2X4e024Hs1M51n3MK/jgwwtC+AtAeeaBdMRbZPhIE75CbLEA/t1WXA/Y3zfVAbxugajnf/plSHloDWTnGZ6nJPvzabmddygAmJV7YdeY/ADgNSGeuyK9UyEztCrdwHo6FEjvdDOQwhsgDeRCDsDHYdBEw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1793008627; c=relaxed/simple; bh=5scORP3HkxpvWK8H5UggAGIykYOIY8TELWLHTukVOWk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=I2w6emdY8MxTa8ZyZ9IzvleOCgX3IAW7t0k1xXho29izcPaVUOrDnvwntq2nlEgLO8ZFmbv1v9bufgM0pRu5T4UqwbDwebw3GS8iSErlvoffSTrcTNOlEEkYVZiPMhhHkdWQUKtewQe8/uqcI7/s1icALpBVIgkU21cEQ2Ibm74= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=kINc/iHN DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4AE284BA2E15 Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-48c4649b35bso2861294f8f.3 for ; Mon, 26 Oct 2026 02:57:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1793008626; x=1793613426; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=U15TuKvWCA33kDcciwI/DW9r2B5zZHScjvpsfUWB/fY=; b=kINc/iHNo/D//DZjkUggOMQqi09KBT9Tqb7ykk4PonQMyzvI7OI/uoKZ3AUoVZmMAW jeujX9dYdLV3y5Ei6LPL3lt5IAYYoP9O4mVv8AhevFa4XbCuegFUhjyxCRkCbFaslT9D 9TPa0gwHM+kuGEaddnt6v1geLeRMFw+vA2RmMzoLP4QYvnZm9Zslds4SrbWInERC0lwK ruPriTqvJiNIUEVsw55T5louUJk1jE5fqWUevu2as65q0kXFaPnKCPi0Edin5kfYMeK0 ZlaT4hNrrmyMEWAFcK3nqfqw4NzYxbHC9nDSw/SNEj6Z00GEPqRirKvm0auRa6NR7NuR f/dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793008626; x=1793613426; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=U15TuKvWCA33kDcciwI/DW9r2B5zZHScjvpsfUWB/fY=; b=rWORDWQ/Ngbd7iHRGzUP5dhyG1AcALiB5EpAhPA2BFACuOIHy1E22BeMu/yDeGMcvz laSFZAHD+DENXgNZXPVBhfjuFRJVmOsYP7ELWcYy6jz+Da8sYNEL9zF7l6SXBCs71jn6 9xtugCFAyIFOIj4CqnxGAEmdvRY8WptQOCkUWN+ypnPksRhij4Y0czK2Osjj+8zRGFMD uj10WWHq9lBvWHwDRzM4vlulywOgPbsP7MfXDeG/meIDIptq+tITmiYpTV/tz5hujQF6 yNJYQTB74VQuphXgKxL1efbgnG4V+L0hlPdDC/bHMtllO6BMzBUZaEQxw517E9em5gTo LtEQ== X-Gm-Message-State: AFq9FYKTlU2pWUujFGj1LRLcTn6T/Iwq+mcA06Q1OxCdRHY6T51ALqjz u9Z9xuuipmwTinvjemfuhJxvDSCB9usYSP3fKmmqAHE93Adm6w8RcVeg8CihSvlnoAg4QPVBUlY = X-Gm-Gg: AYBFou2FY53zh7JRh/JzEdpLb7Sz12iWa+Oo1zqyhb7HJHplI8KX7WyBfZSzzXkGAVB VK7dBqPRDNyDDOrE+8+k2I3X6FlCfMJfvEHlUGvWwZIGtxMtJjnw/dm4SFYzLU1LJ9P7iZ6aW7y Z//qcvy0MonfJes9zQE4PT9QuG+Hw+0l/8E9LVrzxq1l9XMt+YBkMypwxLUKE37sRSOj5Opkuju KaDpIXfs/b+RSZWPMT4qj+2UuuUULL4t8Ph/6dfxwweDWNHte+K6vzuSfZLMj1Vkq4LqhDkjflX ykio0VxQ3wrOskDn9SXjQX7cHddZzPsJnvQbyygOjqqz5DVF8dw2PhhwubOnxndd2MgAkToXMui L64iH4K2SGO+QOPwSZrTYPjKmwHi9x+Y72iSVspe0gK8HR/Igy/3W2SQMol3ePFsvjyNWwZOFqW wYrJ9kEXYg+izmTC3mEf2IoQd2GnagsQlt43GJzI0AvQLE3ZEXFhl1FNZJwbF6ouWzaQ7JF7pik jK3zf26JkCIa7N0U4At9nS6ofKVBPKG/qgrNAAy8GHEJsqnBq5OrAAEuAFl2wNu5dwwnBATFXpX OJ/wgnm+/Rp1LzES1QeuIETjo8ePIoE0H3qGooZ55LHepWKDcC7V+WxbwExHV7+LYRd4E6gz X-Received: by 2002:a5d:5d0a:0:b0:488:7b66:140c with SMTP id ffacd0b85a97d-48e3eb6f72bmr9095561f8f.28.1793008625884; Mon, 26 Oct 2026 02:57:05 -0700 (PDT) Received: from localhost.localdomain ([178.64.143.40]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48e3eb8f387sm15080682f8f.4.2026.10.26.02.57.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Oct 2026 02:57:05 -0700 (PDT) From: Farid Khaidari To: gdb-patches@sourceware.org Cc: Andrew Burgess , Palmer Dabbelt , Timur Golubovich , Kevin Buettner Subject: [PATCH v2 1/4] gdb/riscv: recover FLEN from the NT_FPREGSET note size in core files Date: Mon, 26 Oct 2026 12:56:43 +0300 Message-ID: <20261026095647.3035166-2-khaidari.fg@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261026095647.3035166-1-khaidari.fg@gmail.com> References: <20261022154417.235510-1-khaidari.fg@gmail.com> <20261026095647.3035166-1-khaidari.fg@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org A core dumped by the Linux kernel has no float ABI in e_flags and no RISC-V attributes. Opened without the executable, it gets an integer-only target description, and "p $fa0" fails with "Invalid register 'fa0'" even though the core holds the FP state. Add a core_read_description hook for RISC-V Linux. When e_flags says nothing, it takes FLEN from the size of the NT_FPREGSET note: 32 registers of FLEN bytes plus fcsr padded to 8 bytes. The size formula moves out of riscv_linux_iterate_over_regset_sections into a helper that both use. The layout is Linux-specific (FreeBSD, for one, always uses 16-byte slots), so the hook lives in riscv-linux-tdep.c. If the note gives nothing, the hook returns no description and GDB behaves as before. riscv_features_from_bfd is exported for it. The test core is a real Linux core dump with a 264-byte NT_FPREGSET, i.e. FLEN = 8. Signed-off-by: Farid Khaidari --- gdb/riscv-linux-tdep.c | 93 +++++++++++++++++- gdb/riscv-tdep.c | 9 +- gdb/riscv-tdep.h | 10 ++ .../gdb.arch/riscv-core-fpregset.core.bz2 | Bin 0 -> 3204 bytes .../gdb.arch/riscv-core-fpregset.exp | 73 ++++++++++++++ 5 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 gdb/testsuite/gdb.arch/riscv-core-fpregset.core.bz2 create mode 100644 gdb/testsuite/gdb.arch/riscv-core-fpregset.exp diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c index fcfa5f98ea4..594f6a36f89 100644 --- a/gdb/riscv-linux-tdep.c +++ b/gdb/riscv-linux-tdep.c @@ -31,6 +31,7 @@ #include "linux-record.h" #include "riscv-linux-tdep.h" #include "inferior.h" +#include "gdbsupport/selftest.h" extern unsigned int record_debug; @@ -74,6 +75,16 @@ static const struct regset riscv_linux_fregset = riscv_linux_fregmap, riscv_supply_regset, regcache_collect_regset }; +/* Return the size of the FP register regset for FP registers of FLEN + bytes: 32 registers followed by FCSR, which the kernel pads to 8 + bytes. */ + +static constexpr int +riscv_linux_fregset_size (int flen) +{ + return 32 * flen + 8; +} + /* Define hook for core file support. */ static void @@ -84,9 +95,8 @@ riscv_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, { cb (".reg", (32 * riscv_isa_xlen (gdbarch)), (32 * riscv_isa_xlen (gdbarch)), &riscv_linux_gregset, NULL, cb_data); - /* The kernel is adding 8 bytes for FCSR. */ - cb (".reg2", (32 * riscv_isa_flen (gdbarch)) + 8, - (32 * riscv_isa_flen (gdbarch)) + 8, + cb (".reg2", riscv_linux_fregset_size (riscv_isa_flen (gdbarch)), + riscv_linux_fregset_size (riscv_isa_flen (gdbarch)), &riscv_linux_fregset, NULL, cb_data); } @@ -523,6 +533,52 @@ riscv_linux_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread) return ret; } +/* Return the FLEN implied by SIZE, the size of an NT_FPREGSET note, or 0 + if SIZE matches no known layout. This inverts + riscv_linux_fregset_size. */ + +static int +riscv_linux_flen_from_fpregset_size (bfd_size_type size) +{ + for (int flen : { riscv_flen_d, riscv_flen_f }) + if (size == riscv_linux_fregset_size (flen)) + return flen; + + return 0; +} + +/* Implement the "core_read_description" gdbarch method. + + A core dumped by the Linux kernel has no float ABI in its e_flags, so + if ABFD has an NT_FPREGSET note (the ".reg2" pseudo-section), recover + the FLEN from its size. A core with an NT_GDB_TDESC note never gets + here; the core target uses that note directly. */ + +static const struct target_desc * +riscv_linux_core_read_description (struct gdbarch *gdbarch, + struct target_ops *target, bfd *abfd) +{ + auto features = riscv_features_from_bfd (abfd); + + asection *fpregs = bfd_get_section_by_name (abfd, ".reg2"); + if (features.flen == 0 && fpregs != nullptr) + { + bfd_size_type size = bfd_section_size (fpregs); + features.flen = riscv_linux_flen_from_fpregset_size (size); + if (features.flen == 0) + warning (_("unrecognized .reg2 note size %s in core file; " + "FLEN left unknown"), + pulongest (size)); + } + + /* Nothing was learnt beyond the ELF header. Let GDB fall back to its + default description, which also takes the executable into account. */ + if (features.flen == 0) + return nullptr; + + return riscv_lookup_target_description (features); +} + /* Initialize RISC-V Linux ABI info. */ static void @@ -555,6 +611,9 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_iterate_over_regset_sections (gdbarch, riscv_linux_iterate_over_regset_sections); + set_gdbarch_core_read_description (gdbarch, + riscv_linux_core_read_description); + tramp_frame_prepend_unwinder (gdbarch, &riscv_linux_sigframe); tdep->syscall_next_pc = riscv_linux_syscall_next_pc; @@ -567,10 +626,38 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_get_syscall_number (gdbarch, riscv_linux_get_syscall_number); } +#if GDB_SELF_TEST +namespace selftests +{ + +/* Check that an NT_FPREGSET note size maps to the right FLEN. */ + +static void +riscv_linux_flen_from_fpregset_size_test () +{ + for (int flen : { riscv_flen_d, riscv_flen_f }) + SELF_CHECK (riscv_linux_flen_from_fpregset_size + (riscv_linux_fregset_size (flen)) == flen); + + /* Anything else leaves the FLEN unknown. */ + SELF_CHECK (riscv_linux_flen_from_fpregset_size (0) == 0); + SELF_CHECK (riscv_linux_flen_from_fpregset_size (32 * 8) == 0); + SELF_CHECK (riscv_linux_flen_from_fpregset_size (32 * 16 + 8) == 0); +} + +} /* namespace selftests */ +#endif /* GDB_SELF_TEST */ + /* Initialize RISC-V Linux target support. */ INIT_GDB_FILE (riscv_linux_tdep) { gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_LINUX, riscv_linux_init_abi); + +#if GDB_SELF_TEST + selftests::register_test + ("riscv-linux-flen-from-fpregset-size", + selftests::riscv_linux_flen_from_fpregset_size_test); +#endif } diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 68c56fbafb3..0a997231abc 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -3923,10 +3923,9 @@ static const struct frame_unwind_legacy riscv_frame_unwind ( /*.prev_arch =*/ NULL ); -/* Extract a set of required target features out of ABFD. If ABFD is - nullptr then a RISCV_GDBARCH_FEATURES is returned in its default state. */ +/* See riscv-tdep.h. */ -static struct riscv_gdbarch_features +struct riscv_gdbarch_features riscv_features_from_bfd (const bfd *abfd) { struct riscv_gdbarch_features features; @@ -3950,9 +3949,9 @@ riscv_features_from_bfd (const bfd *abfd) internal_error (_("unknown ELF header class %d"), eclass); if (e_flags & EF_RISCV_FLOAT_ABI_DOUBLE) - features.flen = 8; + features.flen = riscv_flen_d; else if (e_flags & EF_RISCV_FLOAT_ABI_SINGLE) - features.flen = 4; + features.flen = riscv_flen_f; if (e_flags & EF_RISCV_RVE) { diff --git a/gdb/riscv-tdep.h b/gdb/riscv-tdep.h index 344a995a680..01cb515dfbd 100644 --- a/gdb/riscv-tdep.h +++ b/gdb/riscv-tdep.h @@ -158,6 +158,16 @@ extern int riscv_abi_flen (struct gdbarch *gdbarch); argument registers. */ extern bool riscv_abi_embedded (struct gdbarch *gdbarch); +/* FP register width, in bytes, implied by the D and F extensions. */ +constexpr int riscv_flen_d = 8; +constexpr int riscv_flen_f = 4; + +/* Extract a set of required target features out of ABFD. If ABFD is + nullptr then a RISCV_GDBARCH_FEATURES is returned in its default + state. */ +extern struct riscv_gdbarch_features riscv_features_from_bfd + (const bfd *abfd); + /* Single step based on where the current instruction will take us. */ extern std::vector riscv_software_single_step (struct regcache *regcache); diff --git a/gdb/testsuite/gdb.arch/riscv-core-fpregset.core.bz2 b/gdb/testsuite/gdb.arch/riscv-core-fpregset.core.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..497db069ac76a81e74b7ba676b3ddf3e3a64a014 GIT binary patch literal 3204 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 literal 0 HcmV?d00001 diff --git a/gdb/testsuite/gdb.arch/riscv-core-fpregset.exp b/gdb/testsuite/gdb.arch/riscv-core-fpregset.exp new file mode 100644 index 00000000000..57e63756f77 --- /dev/null +++ b/gdb/testsuite/gdb.arch/riscv-core-fpregset.exp @@ -0,0 +1,73 @@ +# Copyright 2026 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check that GDB recovers the FP registers from a core file dumped by +# the Linux kernel and opened without the executable. Such a core has +# no NT_GDB_TDESC note, no .riscv.attributes, and zero e_flags, so the +# size of the NT_FPREGSET note is the only evidence of the FLEN. The +# kernel dumps the FP state in the D layout: 32 doubles plus 8 bytes for +# fcsr, 264 bytes in total. +# +# The bundled core (riscv-core-fpregset.core.bz2) was dumped by a stock +# Linux 6.8 kernel. Its PT_NOTE carries NT_FPREGSET (264 bytes) but +# neither NT_GDB_TDESC nor any RISC-V attributes, and its e_flags are +# zero. The dumped program never touched the FP unit, so every FP +# register in the note is zero. +# +# The test checks that, with no executable loaded: +# 1. the FP registers exist in the target description at all, rather +# than GDB reporting "Invalid register 'fa0'"; +# 2. their contents are supplied from the note rather than left +# ("(raw 0x...)" in the output proves that); +# 3. the FP registers are 8 bytes wide, i.e. the FLEN really came from +# the 264-byte note size. +# +# Only the D layout is exercised here, since that is what the bundled +# core carries. The size-to-FLEN mapping itself, including the F +# layout, is covered by the "riscv-linux-flen-from-fpregset-size" selftest. +# +# How to regenerate the fixture: run any RV64 program on a Linux system +# under "ulimit -c unlimited" with kernel.core_pattern=core, make it +# dump core, and bzip2 the result. Check with "readelf -n" that the +# core carries a 264-byte NT_FPREGSET and neither an NT_GDB_TDESC note +# nor RISC-V attributes. + +# The fixture is an ELF64 Linux core and the FLEN assertions are +# RV64-specific. +require {istarget "riscv64-*-linux*"} + +set core [decompress_bz2 $srcdir/$subdir/riscv-core-fpregset.core.bz2] +if {$core == ""} { + untested "failed to decompress core file" + return -1 +} +set core [gdb_remote_download host $core] + +clean_restart + +if {[gdb_core_cmd $core "load core without executable"] != 1} { + return -1 +} + +# The size of the NT_FPREGSET note implies FLEN, hence the FP registers. +# The value must come from the note: a raw hex dump in the output means +# the register bytes were supplied, not left . +gdb_test "info registers \$fa0" \ + "fa0\[ \t\]+\\{float = 0, double = 0\\}\[ \t\]+\\(raw 0x0+\\)" \ + "fp register value supplied from fpregset note" + +# 264 bytes = 32 doubles + fcsr, so the FLEN must be 8. +gdb_test "print sizeof (\$fa0)" "= 8" \ + "flen recovered from fpregset note size" -- 2.43.0