Commit 7c50d748 authored by John Hubbard's avatar John Hubbard Committed by Alexandre Courbot
Browse files

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: default avatarJohn Hubbard <jhubbard@nvidia.com>
Acked-by: default avatarDanilo 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: default avatarAlexandre Courbot <acourbot@nvidia.com>
parent b3d24269
Loading
Loading
Loading
Loading
+15 −25
Original line number Diff line number Diff line
@@ -484,6 +484,13 @@ unsafe impl FromBytes for Elf64Hdr {}
    // 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 @@ pub(super) fn elf64_section<'a, 'b>(elf: &'a [u8], name: &'b str) -> Option<&'a
            .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;
            };
        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)?;

            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;
            };
            if section_name != name {
                return None;
            }

            // 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| {
            let hdr = Elf64SHdr::from_bytes(sh)?;
            let start = usize::try_from(hdr.0.sh_offset).ok()?;
            let end = usize::try_from(hdr.0.sh_size)
                .ok()