summaryrefslogtreecommitdiffstats
path: root/vendor/object/src/read/elf
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/object/src/read/elf
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/object/src/read/elf')
-rw-r--r--vendor/object/src/read/elf/attributes.rs303
-rw-r--r--vendor/object/src/read/elf/comdat.rs2
-rw-r--r--vendor/object/src/read/elf/file.rs25
-rw-r--r--vendor/object/src/read/elf/hash.rs4
-rw-r--r--vendor/object/src/read/elf/mod.rs3
-rw-r--r--vendor/object/src/read/elf/note.rs90
-rw-r--r--vendor/object/src/read/elf/section.rs112
-rw-r--r--vendor/object/src/read/elf/segment.rs1
-rw-r--r--vendor/object/src/read/elf/symbol.rs5
-rw-r--r--vendor/object/src/read/elf/version.rs4
10 files changed, 504 insertions, 45 deletions
diff --git a/vendor/object/src/read/elf/attributes.rs b/vendor/object/src/read/elf/attributes.rs
new file mode 100644
index 000000000..6ec535d72
--- /dev/null
+++ b/vendor/object/src/read/elf/attributes.rs
@@ -0,0 +1,303 @@
+use core::convert::TryInto;
+
+use crate::elf;
+use crate::endian;
+use crate::read::{Bytes, Error, ReadError, Result};
+
+use super::FileHeader;
+
+/// An ELF attributes section.
+///
+/// This may be a GNU attributes section, or an architecture specific attributes section.
+///
+/// An attributes section contains a series of subsections.
+#[derive(Debug, Clone)]
+pub struct AttributesSection<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ version: u8,
+ data: Bytes<'data>,
+}
+
+impl<'data, Elf: FileHeader> AttributesSection<'data, Elf> {
+ /// Parse an ELF attributes section given the section data.
+ pub fn new(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> {
+ let mut data = Bytes(data);
+
+ // Skip the version field that is one byte long.
+ let version = *data
+ .read::<u8>()
+ .read_error("Invalid ELF attributes section offset or size")?;
+
+ Ok(AttributesSection {
+ endian,
+ version,
+ data,
+ })
+ }
+
+ /// Return the version of the attributes section.
+ pub fn version(&self) -> u8 {
+ self.version
+ }
+
+ /// Return an iterator over the subsections.
+ pub fn subsections(&self) -> Result<AttributesSubsectionIterator<'data, Elf>> {
+ // There is currently only one format version.
+ if self.version != b'A' {
+ return Err(Error("Unsupported ELF attributes section version"));
+ }
+
+ Ok(AttributesSubsectionIterator {
+ endian: self.endian,
+ data: self.data,
+ })
+ }
+}
+
+/// An iterator over the subsections in an ELF attributes section.
+#[derive(Debug, Clone)]
+pub struct AttributesSubsectionIterator<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ data: Bytes<'data>,
+}
+
+impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> {
+ /// Return the next subsection.
+ pub fn next(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> {
+ if self.data.is_empty() {
+ return Ok(None);
+ }
+
+ let result = self.parse();
+ if result.is_err() {
+ self.data = Bytes(&[]);
+ }
+ result
+ }
+
+ fn parse(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> {
+ // First read the subsection length.
+ let mut data = self.data;
+ let length = data
+ .read::<endian::U32Bytes<Elf::Endian>>()
+ .read_error("ELF attributes section is too short")?
+ .get(self.endian);
+
+ // Now read the entire subsection, updating self.data.
+ let mut data = self
+ .data
+ .read_bytes(length as usize)
+ .read_error("Invalid ELF attributes subsection length")?;
+ // Skip the subsection length field.
+ data.skip(4)
+ .read_error("Invalid ELF attributes subsection length")?;
+
+ let vendor = data
+ .read_string()
+ .read_error("Invalid ELF attributes vendor")?;
+
+ Ok(Some(AttributesSubsection {
+ endian: self.endian,
+ length,
+ vendor,
+ data,
+ }))
+ }
+}
+
+/// A subsection in an ELF attributes section.
+///
+/// A subsection is identified by a vendor name. It contains a series of sub-subsections.
+#[derive(Debug, Clone)]
+pub struct AttributesSubsection<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ length: u32,
+ vendor: &'data [u8],
+ data: Bytes<'data>,
+}
+
+impl<'data, Elf: FileHeader> AttributesSubsection<'data, Elf> {
+ /// Return the length of the attributes subsection.
+ pub fn length(&self) -> u32 {
+ self.length
+ }
+
+ /// Return the vendor name of the attributes subsection.
+ pub fn vendor(&self) -> &'data [u8] {
+ self.vendor
+ }
+
+ /// Return an iterator over the sub-subsections.
+ pub fn subsubsections(&self) -> AttributesSubsubsectionIterator<'data, Elf> {
+ AttributesSubsubsectionIterator {
+ endian: self.endian,
+ data: self.data,
+ }
+ }
+}
+
+/// An iterator over the sub-subsections in an ELF attributes section.
+#[derive(Debug, Clone)]
+pub struct AttributesSubsubsectionIterator<'data, Elf: FileHeader> {
+ endian: Elf::Endian,
+ data: Bytes<'data>,
+}
+
+impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> {
+ /// Return the next sub-subsection.
+ pub fn next(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> {
+ if self.data.is_empty() {
+ return Ok(None);
+ }
+
+ let result = self.parse();
+ if result.is_err() {
+ self.data = Bytes(&[]);
+ }
+ result
+ }
+
+ fn parse(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> {
+ // The format of a sub-section looks like this:
+ //
+ // <file-tag> <size> <attribute>*
+ // | <section-tag> <size> <section-number>* 0 <attribute>*
+ // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
+ let mut data = self.data;
+ let tag = *data
+ .read::<u8>()
+ .read_error("ELF attributes subsection is too short")?;
+ let length = data
+ .read::<endian::U32Bytes<Elf::Endian>>()
+ .read_error("ELF attributes subsection is too short")?
+ .get(self.endian);
+
+ // Now read the entire sub-subsection, updating self.data.
+ let mut data = self
+ .data
+ .read_bytes(length as usize)
+ .read_error("Invalid ELF attributes sub-subsection length")?;
+ // Skip the tag and sub-subsection size field.
+ data.skip(1 + 4)
+ .read_error("Invalid ELF attributes sub-subsection length")?;
+
+ let indices = if tag == elf::Tag_Section || tag == elf::Tag_Symbol {
+ data.read_string()
+ .map(Bytes)
+ .read_error("Missing ELF attributes sub-subsection indices")?
+ } else if tag == elf::Tag_File {
+ Bytes(&[])
+ } else {
+ return Err(Error("Unimplemented ELF attributes sub-subsection tag"));
+ };
+
+ Ok(Some(AttributesSubsubsection {
+ tag,
+ length,
+ indices,
+ data,
+ }))
+ }
+}
+
+/// A sub-subsection in an ELF attributes section.
+///
+/// A sub-subsection is identified by a tag. It contains an optional series of indices,
+/// followed by a series of attributes.
+#[derive(Debug, Clone)]
+pub struct AttributesSubsubsection<'data> {
+ tag: u8,
+ length: u32,
+ indices: Bytes<'data>,
+ data: Bytes<'data>,
+}
+
+impl<'data> AttributesSubsubsection<'data> {
+ /// Return the tag of the attributes sub-subsection.
+ pub fn tag(&self) -> u8 {
+ self.tag
+ }
+
+ /// Return the length of the attributes sub-subsection.
+ pub fn length(&self) -> u32 {
+ self.length
+ }
+
+ /// Return the data containing the indices.
+ pub fn indices_data(&self) -> &'data [u8] {
+ self.indices.0
+ }
+
+ /// Return the indices.
+ ///
+ /// This will be section indices if the tag is `Tag_Section`,
+ /// or symbol indices if the tag is `Tag_Symbol`,
+ /// and otherwise it will be empty.
+ pub fn indices(&self) -> AttributeIndexIterator<'data> {
+ AttributeIndexIterator { data: self.indices }
+ }
+
+ /// Return the data containing the attributes.
+ pub fn attributes_data(&self) -> &'data [u8] {
+ self.data.0
+ }
+
+ /// Return a parser for the data containing the attributes.
+ pub fn attributes(&self) -> AttributeReader<'data> {
+ AttributeReader { data: self.data }
+ }
+}
+
+/// An iterator over the indices in a sub-subsection in an ELF attributes section.
+#[derive(Debug, Clone)]
+pub struct AttributeIndexIterator<'data> {
+ data: Bytes<'data>,
+}
+
+impl<'data> AttributeIndexIterator<'data> {
+ /// Parse the next index.
+ pub fn next(&mut self) -> Result<Option<u32>> {
+ if self.data.is_empty() {
+ return Ok(None);
+ }
+ let err = "Invalid ELF attribute index";
+ self.data
+ .read_uleb128()
+ .read_error(err)?
+ .try_into()
+ .map_err(|_| ())
+ .read_error(err)
+ .map(Some)
+ }
+}
+
+/// A parser for the attributes in a sub-subsection in an ELF attributes section.
+///
+/// The parser relies on the caller to know the format of the data for each attribute tag.
+#[derive(Debug, Clone)]
+pub struct AttributeReader<'data> {
+ data: Bytes<'data>,
+}
+
+impl<'data> AttributeReader<'data> {
+ /// Parse a tag.
+ pub fn read_tag(&mut self) -> Result<Option<u64>> {
+ if self.data.is_empty() {
+ return Ok(None);
+ }
+ let err = "Invalid ELF attribute tag";
+ self.data.read_uleb128().read_error(err).map(Some)
+ }
+
+ /// Parse an integer value.
+ pub fn read_integer(&mut self) -> Result<u64> {
+ let err = "Invalid ELF attribute integer value";
+ self.data.read_uleb128().read_error(err)
+ }
+
+ /// Parse a string value.
+ pub fn read_string(&mut self) -> Result<&'data [u8]> {
+ let err = "Invalid ELF attribute string value";
+ self.data.read_string().read_error(err)
+ }
+}
diff --git a/vendor/object/src/read/elf/comdat.rs b/vendor/object/src/read/elf/comdat.rs
index 7cee85bb4..1a2f2f44a 100644
--- a/vendor/object/src/read/elf/comdat.rs
+++ b/vendor/object/src/read/elf/comdat.rs
@@ -18,7 +18,6 @@ pub type ElfComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]>
#[derive(Debug)]
pub struct ElfComdatIterator<'data, 'file, Elf, R = &'data [u8]>
where
- 'data: 'file,
Elf: FileHeader,
R: ReadRef<'data>,
{
@@ -140,7 +139,6 @@ pub type ElfComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'dat
#[derive(Debug)]
pub struct ElfComdatSectionIterator<'data, 'file, Elf, R = &'data [u8]>
where
- 'data: 'file,
Elf: FileHeader,
R: ReadRef<'data>,
{
diff --git a/vendor/object/src/read/elf/file.rs b/vendor/object/src/read/elf/file.rs
index 259da7906..aac66e7cc 100644
--- a/vendor/object/src/read/elf/file.rs
+++ b/vendor/object/src/read/elf/file.rs
@@ -456,6 +456,15 @@ pub trait FileHeader: Debug + Pod {
/// This is a property of the type, not a value in the header data.
fn is_type_64(&self) -> bool;
+ /// Return true if this type is a 64-bit header.
+ ///
+ /// This is a property of the type, not a value in the header data.
+ ///
+ /// This is the same as `is_type_64`, but is non-dispatchable.
+ fn is_type_64_sized() -> bool
+ where
+ Self: Sized;
+
fn e_ident(&self) -> &elf::Ident;
fn e_type(&self, endian: Self::Endian) -> u16;
fn e_machine(&self, endian: Self::Endian) -> u16;
@@ -725,6 +734,14 @@ impl<Endian: endian::Endian> FileHeader for elf::FileHeader32<Endian> {
}
#[inline]
+ fn is_type_64_sized() -> bool
+ where
+ Self: Sized,
+ {
+ false
+ }
+
+ #[inline]
fn e_ident(&self) -> &elf::Ident {
&self.e_ident
}
@@ -814,6 +831,14 @@ impl<Endian: endian::Endian> FileHeader for elf::FileHeader64<Endian> {
}
#[inline]
+ fn is_type_64_sized() -> bool
+ where
+ Self: Sized,
+ {
+ true
+ }
+
+ #[inline]
fn e_ident(&self) -> &elf::Ident {
&self.e_ident
}
diff --git a/vendor/object/src/read/elf/hash.rs b/vendor/object/src/read/elf/hash.rs
index aa1039ac1..aadbb9208 100644
--- a/vendor/object/src/read/elf/hash.rs
+++ b/vendor/object/src/read/elf/hash.rs
@@ -45,7 +45,7 @@ impl<'data, Elf: FileHeader> HashTable<'data, Elf> {
endian: Elf::Endian,
name: &[u8],
hash: u32,
- version: Option<&Version>,
+ version: Option<&Version<'_>>,
symbols: &SymbolTable<'data, Elf, R>,
versions: &VersionTable<'data, Elf>,
) -> Option<(usize, &'data Elf::Sym)> {
@@ -160,7 +160,7 @@ impl<'data, Elf: FileHeader> GnuHashTable<'data, Elf> {
endian: Elf::Endian,
name: &[u8],
hash: u32,
- version: Option<&Version>,
+ version: Option<&Version<'_>>,
symbols: &SymbolTable<'data, Elf, R>,
versions: &VersionTable<'data, Elf>,
) -> Option<(usize, &'data Elf::Sym)> {
diff --git a/vendor/object/src/read/elf/mod.rs b/vendor/object/src/read/elf/mod.rs
index 5b7d7f9f7..07db6cd66 100644
--- a/vendor/object/src/read/elf/mod.rs
+++ b/vendor/object/src/read/elf/mod.rs
@@ -37,3 +37,6 @@ pub use hash::*;
mod version;
pub use version::*;
+
+mod attributes;
+pub use attributes::*;
diff --git a/vendor/object/src/read/elf/note.rs b/vendor/object/src/read/elf/note.rs
index 34024dbb8..fc5aa7753 100644
--- a/vendor/object/src/read/elf/note.rs
+++ b/vendor/object/src/read/elf/note.rs
@@ -2,7 +2,7 @@ use core::fmt::Debug;
use core::mem;
use crate::elf;
-use crate::endian;
+use crate::endian::{self, U32};
use crate::pod::Pod;
use crate::read::util;
use crate::read::{self, Bytes, Error, ReadError};
@@ -24,12 +24,15 @@ impl<'data, Elf> NoteIterator<'data, Elf>
where
Elf: FileHeader,
{
+ /// An iterator over the notes in an ELF section or segment.
+ ///
+ /// `align` should be from the `p_align` field of the segment,
+ /// or the `sh_addralign` field of the section. Supported values are
+ /// either 4 or 8, but values less than 4 are treated as 4.
+ /// This matches the behaviour of binutils.
+ ///
/// Returns `Err` if `align` is invalid.
- pub(super) fn new(
- endian: Elf::Endian,
- align: Elf::Word,
- data: &'data [u8],
- ) -> read::Result<Self> {
+ pub fn new(endian: Elf::Endian, align: Elf::Word, data: &'data [u8]) -> read::Result<Self> {
let align = match align.into() {
0u64..=4 => 4,
8 => 8,
@@ -134,6 +137,24 @@ impl<'data, Elf: FileHeader> Note<'data, Elf> {
pub fn desc(&self) -> &'data [u8] {
self.desc
}
+
+ /// Return an iterator for properties if this note's type is `NT_GNU_PROPERTY_TYPE_0`.
+ pub fn gnu_properties(
+ &self,
+ endian: Elf::Endian,
+ ) -> Option<GnuPropertyIterator<'data, Elf::Endian>> {
+ if self.name() != elf::ELF_NOTE_GNU || self.n_type(endian) != elf::NT_GNU_PROPERTY_TYPE_0 {
+ return None;
+ }
+ // Use the ELF class instead of the section alignment.
+ // This matches what other parsers do.
+ let align = if Elf::is_type_64_sized() { 8 } else { 4 };
+ Some(GnuPropertyIterator {
+ endian,
+ align,
+ data: Bytes(self.desc),
+ })
+ }
}
/// A trait for generic access to `NoteHeader32` and `NoteHeader64`.
@@ -183,3 +204,60 @@ impl<Endian: endian::Endian> NoteHeader for elf::NoteHeader64<Endian> {
self.n_type.get(endian)
}
}
+
+/// An iterator over the properties in a `NT_GNU_PROPERTY_TYPE_0` note.
+#[derive(Debug)]
+pub struct GnuPropertyIterator<'data, Endian: endian::Endian> {
+ endian: Endian,
+ align: usize,
+ data: Bytes<'data>,
+}
+
+impl<'data, Endian: endian::Endian> GnuPropertyIterator<'data, Endian> {
+ /// Returns the next property.
+ pub fn next(&mut self) -> read::Result<Option<GnuProperty<'data>>> {
+ let mut data = self.data;
+ if data.is_empty() {
+ return Ok(None);
+ }
+
+ (|| -> Result<_, ()> {
+ let pr_type = data.read_at::<U32<Endian>>(0)?.get(self.endian);
+ let pr_datasz = data.read_at::<U32<Endian>>(4)?.get(self.endian) as usize;
+ let pr_data = data.read_bytes_at(8, pr_datasz)?.0;
+ data.skip(util::align(8 + pr_datasz, self.align))?;
+ self.data = data;
+ Ok(Some(GnuProperty { pr_type, pr_data }))
+ })()
+ .read_error("Invalid ELF GNU property")
+ }
+}
+
+/// A property in a `NT_GNU_PROPERTY_TYPE_0` note.
+#[derive(Debug)]
+pub struct GnuProperty<'data> {
+ pr_type: u32,
+ pr_data: &'data [u8],
+}
+
+impl<'data> GnuProperty<'data> {
+ /// Return the property type.
+ ///
+ /// This is one of the `GNU_PROPERTY_*` constants.
+ pub fn pr_type(&self) -> u32 {
+ self.pr_type
+ }
+
+ /// Return the property data.
+ pub fn pr_data(&self) -> &'data [u8] {
+ self.pr_data
+ }
+
+ /// Parse the property data as an unsigned 32-bit integer.
+ pub fn data_u32<E: endian::Endian>(&self, endian: E) -> read::Result<u32> {
+ Bytes(self.pr_data)
+ .read_at::<U32<E>>(0)
+ .read_error("Invalid ELF GNU property data")
+ .map(|val| val.get(endian))
+ }
+}
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> {
diff --git a/vendor/object/src/read/elf/segment.rs b/vendor/object/src/read/elf/segment.rs
index 445893c8d..3972731ec 100644
--- a/vendor/object/src/read/elf/segment.rs
+++ b/vendor/object/src/read/elf/segment.rs
@@ -57,7 +57,6 @@ pub type ElfSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
#[derive(Debug)]
pub struct ElfSegment<'data, 'file, Elf, R = &'data [u8]>
where
- 'data: 'file,
Elf: FileHeader,
R: ReadRef<'data>,
{
diff --git a/vendor/object/src/read/elf/symbol.rs b/vendor/object/src/read/elf/symbol.rs
index 5d8d29f27..ac1095705 100644
--- a/vendor/object/src/read/elf/symbol.rs
+++ b/vendor/object/src/read/elf/symbol.rs
@@ -208,7 +208,6 @@ pub type ElfSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
#[derive(Debug, Clone, Copy)]
pub struct ElfSymbolTable<'data, 'file, Elf, R = &'data [u8]>
where
- 'data: 'file,
Elf: FileHeader,
R: ReadRef<'data>,
{
@@ -256,7 +255,6 @@ pub type ElfSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]>
/// An iterator over the symbols of an `ElfFile`.
pub struct ElfSymbolIterator<'data, 'file, Elf, R = &'data [u8]>
where
- 'data: 'file,
Elf: FileHeader,
R: ReadRef<'data>,
{
@@ -302,7 +300,6 @@ pub type ElfSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
#[derive(Debug, Clone, Copy)]
pub struct ElfSymbol<'data, 'file, Elf, R = &'data [u8]>
where
- 'data: 'file,
Elf: FileHeader,
R: ReadRef<'data>,
{
@@ -430,7 +427,7 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
}
#[inline]
- fn flags(&self) -> SymbolFlags<SectionIndex> {
+ fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
SymbolFlags::Elf {
st_info: self.symbol.st_info(),
st_other: self.symbol.st_other(),
diff --git a/vendor/object/src/read/elf/version.rs b/vendor/object/src/read/elf/version.rs
index 6d80ba1e3..cc87bbef1 100644
--- a/vendor/object/src/read/elf/version.rs
+++ b/vendor/object/src/read/elf/version.rs
@@ -183,12 +183,12 @@ impl<'data, Elf: FileHeader> VersionTable<'data, Elf> {
.map(Some)
}
- /// Return true if the given symbol index satisifies the requirements of `need`.
+ /// Return true if the given symbol index satisfies the requirements of `need`.
///
/// Returns false for any error.
///
/// Note: this function hasn't been fully tested and is likely to be incomplete.
- pub fn matches(&self, endian: Elf::Endian, index: usize, need: Option<&Version>) -> bool {
+ pub fn matches(&self, endian: Elf::Endian, index: usize, need: Option<&Version<'_>>) -> bool {
let version_index = self.version_index(endian, index);
let def = match self.version(version_index) {
Ok(def) => def,