summaryrefslogtreecommitdiffstats
path: root/vendor/object/src/read/elf/section.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/read/elf/section.rs')
-rw-r--r--vendor/object/src/read/elf/section.rs112
1 files changed, 84 insertions, 28 deletions
diff --git a/vendor/object/src/read/elf/section.rs b/vendor/object/src/read/elf/section.rs
index 3f8a08216..df08f9e3e 100644
--- a/vendor/object/src/read/elf/section.rs
+++ b/vendor/object/src/read/elf/section.rs
@@ -10,8 +10,9 @@ use crate::read::{
};
use super::{
- CompressionHeader, ElfFile, ElfSectionRelocationIterator, FileHeader, GnuHashTable, HashTable,
- NoteIterator, RelocationSections, SymbolTable, VerdefIterator, VerneedIterator, VersionTable,
+ AttributesSection, CompressionHeader, ElfFile, ElfSectionRelocationIterator, FileHeader,
+ GnuHashTable, HashTable, NoteIterator, RelocationSections, SymbolTable, VerdefIterator,
+ VerneedIterator, VersionTable,
};
/// The table of section headers in an ELF file.
@@ -362,7 +363,6 @@ pub type ElfSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
#[derive(Debug)]
pub struct ElfSection<'data, 'file, Elf, R = &'data [u8]>
where
- 'data: 'file,
Elf: FileHeader,
R: ReadRef<'data>,
{
@@ -380,32 +380,24 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSection<'data, 'file,
fn maybe_compressed(&self) -> read::Result<Option<CompressedFileRange>> {
let endian = self.file.endian;
- if (self.section.sh_flags(endian).into() & u64::from(elf::SHF_COMPRESSED)) == 0 {
- return Ok(None);
- }
- let (section_offset, section_size) = self
- .section
- .file_range(endian)
- .read_error("Invalid ELF compressed section type")?;
- let mut offset = section_offset;
- let header = self
- .file
- .data
- .read::<Elf::CompressionHeader>(&mut offset)
- .read_error("Invalid ELF compressed section offset")?;
- if header.ch_type(endian) != elf::ELFCOMPRESS_ZLIB {
- return Err(Error("Unsupported ELF compression type"));
+ if let Some((header, offset, compressed_size)) =
+ self.section.compression(endian, self.file.data)?
+ {
+ let format = match header.ch_type(endian) {
+ elf::ELFCOMPRESS_ZLIB => CompressionFormat::Zlib,
+ elf::ELFCOMPRESS_ZSTD => CompressionFormat::Zstandard,
+ _ => return Err(Error("Unsupported ELF compression type")),
+ };
+ let uncompressed_size = header.ch_size(endian).into();
+ Ok(Some(CompressedFileRange {
+ format,
+ offset,
+ compressed_size,
+ uncompressed_size,
+ }))
+ } else {
+ Ok(None)
}
- let uncompressed_size = header.ch_size(endian).into();
- let compressed_size = section_size
- .checked_sub(offset - section_offset)
- .read_error("Invalid ELF compressed section size")?;
- Ok(Some(CompressedFileRange {
- format: CompressionFormat::Zlib,
- offset,
- compressed_size,
- uncompressed_size,
- }))
}
/// Try GNU-style "ZLIB" header decompression.
@@ -975,6 +967,70 @@ pub trait SectionHeader: Debug + Pod {
let link = SectionIndex(self.sh_link(endian) as usize);
Ok(Some((VerneedIterator::new(endian, verneed), link)))
}
+
+ /// Return the contents of a `SHT_GNU_ATTRIBUTES` section.
+ ///
+ /// Returns `Ok(None)` if the section type is not `SHT_GNU_ATTRIBUTES`.
+ /// Returns `Err` for invalid values.
+ fn gnu_attributes<'data, R: ReadRef<'data>>(
+ &self,
+ endian: Self::Endian,
+ data: R,
+ ) -> read::Result<Option<AttributesSection<'data, Self::Elf>>> {
+ if self.sh_type(endian) != elf::SHT_GNU_ATTRIBUTES {
+ return Ok(None);
+ }
+ self.attributes(endian, data).map(Some)
+ }
+
+ /// Parse the contents of the section as attributes.
+ ///
+ /// This function does not check whether section type corresponds
+ /// to a section that contains attributes.
+ ///
+ /// Returns `Err` for invalid values.
+ fn attributes<'data, R: ReadRef<'data>>(
+ &self,
+ endian: Self::Endian,
+ data: R,
+ ) -> read::Result<AttributesSection<'data, Self::Elf>> {
+ let data = self.data(endian, data)?;
+ AttributesSection::new(endian, data)
+ }
+
+ /// Parse the compression header if present.
+ ///
+ /// Returns the header, and the offset and size of the compressed section data
+ /// in the file.
+ ///
+ /// Returns `Ok(None)` if the section flags do not have `SHF_COMPRESSED`.
+ /// Returns `Err` for invalid values.
+ fn compression<'data, R: ReadRef<'data>>(
+ &self,
+ endian: Self::Endian,
+ data: R,
+ ) -> read::Result<
+ Option<(
+ &'data <Self::Elf as FileHeader>::CompressionHeader,
+ u64,
+ u64,
+ )>,
+ > {
+ if (self.sh_flags(endian).into() & u64::from(elf::SHF_COMPRESSED)) == 0 {
+ return Ok(None);
+ }
+ let (section_offset, section_size) = self
+ .file_range(endian)
+ .read_error("Invalid ELF compressed section type")?;
+ let mut offset = section_offset;
+ let header = data
+ .read::<<Self::Elf as FileHeader>::CompressionHeader>(&mut offset)
+ .read_error("Invalid ELF compressed section offset")?;
+ let compressed_size = section_size
+ .checked_sub(offset - section_offset)
+ .read_error("Invalid ELF compressed section size")?;
+ Ok(Some((header, offset, compressed_size)))
+ }
}
impl<Endian: endian::Endian> SectionHeader for elf::SectionHeader32<Endian> {