[PATCH v5 16/38] gpu: nova-core: add auto-detection of 32-bit, 64-bit firmware images

From: John Hubbard

Date: Fri Feb 20 2026 - 21:15:44 EST


Add elf_section() which automatically detects ELF32 vs ELF64 based on
the ELF header's class byte, and dispatches to the appropriate parser.
Switch gsp.rs callers from elf64_section() to elf_section(), making
both elf32_section() and elf64_section() private.

Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx>
---
drivers/gpu/nova-core/firmware.rs | 20 +++++++++++++++++---
drivers/gpu/nova-core/firmware/gsp.rs | 4 ++--
2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
index d94dd3468f3c..57a919b7e0e8 100644
--- a/drivers/gpu/nova-core/firmware.rs
+++ b/drivers/gpu/nova-core/firmware.rs
@@ -596,13 +596,27 @@ fn elf_section_generic<'a, H, S>(elf: &'a [u8], name: &str) -> Option<&'a [u8]>
}

/// Extract the section with name `name` from the ELF64 image `elf`.
- pub(super) fn elf64_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
+ fn elf64_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
elf_section_generic::<Elf64Hdr, Elf64SHdr>(elf, name)
}

/// Extract the section with name `name` from the ELF32 image `elf`.
- #[expect(dead_code)]
- pub(super) fn elf32_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
+ fn elf32_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
elf_section_generic::<Elf32Hdr, Elf32SHdr>(elf, name)
}
+
+ /// Automatically detects ELF32 vs ELF64 based on the ELF header.
+ pub(super) fn elf_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
+ // Check ELF magic.
+ if elf.len() < 5 || elf.get(0..4)? != b"\x7fELF" {
+ return None;
+ }
+
+ // Check ELF class: 1 = 32-bit, 2 = 64-bit.
+ match elf.get(4)? {
+ 1 => elf32_section(elf, name),
+ 2 => elf64_section(elf, name),
+ _ => None,
+ }
+ }
}
diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs
index f247deb06633..52e7337c041c 100644
--- a/drivers/gpu/nova-core/firmware/gsp.rs
+++ b/drivers/gpu/nova-core/firmware/gsp.rs
@@ -105,7 +105,7 @@ pub(crate) fn new<'a>(
pin_init::pin_init_scope(move || {
let firmware = super::request_firmware(dev, chipset, "gsp", ver)?;

- let fw_section = elf::elf64_section(firmware.data(), ".fwimage").ok_or(EINVAL)?;
+ let fw_section = elf::elf_section(firmware.data(), ".fwimage").ok_or(EINVAL)?;

let size = fw_section.len();

@@ -162,7 +162,7 @@ pub(crate) fn new<'a>(
signatures: {
let sigs_section = Self::find_gsp_sigs_section(chipset).ok_or(ENOTSUPP)?;

- elf::elf64_section(firmware.data(), sigs_section)
+ elf::elf_section(firmware.data(), sigs_section)
.ok_or(EINVAL)
.and_then(|data| DmaObject::from_data(dev, data))?
},
--
2.53.0