summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJohn Hubbard <jhubbard@nvidia.com>2026-03-25 18:38:39 -0700
committerAlexandre Courbot <acourbot@nvidia.com>2026-03-30 14:01:53 +0900
commit7c50d748b4a635bc39802ea3f6b120e66b1b9067 (patch)
tree006fa4d17a465bb6499f73a543254ab96ec105e8 /drivers
parentb3d24269b3c7e764b694689b5fd7517546625150 (diff)
gpu: nova-core: firmware: factor out an elf_str() function
Factor out a chunk of complexity into a new subroutine. This is an incremental step in adding ELF32 support to the existing ELF64 section support, for handling GPU firmware. Signed-off-by: John Hubbard <jhubbard@nvidia.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://patch.msgid.link/20260326013902.588242-9-jhubbard@nvidia.com [acourbot: use fuller prefix in commit message.] Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nova-core/firmware.rs40
1 files changed, 15 insertions, 25 deletions
diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
index 177b8ede151c..6c2ab69cb605 100644
--- a/drivers/gpu/nova-core/firmware.rs
+++ b/drivers/gpu/nova-core/firmware.rs
@@ -484,6 +484,13 @@ mod elf {
// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
unsafe impl FromBytes for Elf64SHdr {}
+ /// Returns a NULL-terminated string from the ELF image at `offset`.
+ fn elf_str(elf: &[u8], offset: u64) -> Option<&str> {
+ let idx = usize::try_from(offset).ok()?;
+ let bytes = elf.get(idx..)?;
+ CStr::from_bytes_until_nul(bytes).ok()?.to_str().ok()
+ }
+
/// Tries to extract section with name `name` from the ELF64 image `elf`, and returns it.
pub(super) fn elf64_section<'a, 'b>(elf: &'a [u8], name: &'b str) -> Option<&'a [u8]> {
let hdr = &elf
@@ -510,32 +517,15 @@ mod elf {
.and_then(Elf64SHdr::from_bytes)?;
// Find the section which name matches `name` and return it.
- shdr.find(|&sh| {
- let Some(hdr) = Elf64SHdr::from_bytes(sh) else {
- return false;
- };
-
- let Some(name_idx) = strhdr
- .0
- .sh_offset
- .checked_add(u64::from(hdr.0.sh_name))
- .and_then(|idx| usize::try_from(idx).ok())
- else {
- return false;
- };
-
- // Get the start of the name.
- elf.get(name_idx..)
- .and_then(|nstr| CStr::from_bytes_until_nul(nstr).ok())
- // Convert into str.
- .and_then(|c_str| c_str.to_str().ok())
- // Check that the name matches.
- .map(|str| str == name)
- .unwrap_or(false)
- })
- // Return the slice containing the section.
- .and_then(|sh| {
+ shdr.find_map(|sh| {
let hdr = Elf64SHdr::from_bytes(sh)?;
+ let name_offset = strhdr.0.sh_offset.checked_add(u64::from(hdr.0.sh_name))?;
+ let section_name = elf_str(elf, name_offset)?;
+
+ if section_name != name {
+ return None;
+ }
+
let start = usize::try_from(hdr.0.sh_offset).ok()?;
let end = usize::try_from(hdr.0.sh_size)
.ok()