/// The table of section headers in an ELF file. /// /// Also includes the string table used for the section names. /// /// Returned by [`FileHeader::sections`]. #[derive(Debug, Clone, Copy)] pubstruct SectionTable<'data, Elf: FileHeader, R = &'data [u8]> where
R: ReadRef<'data>,
{
sections: &'data [Elf::SectionHeader],
strings: StringTable<'data, R>,
}
/// Iterate over the section headers. /// /// This includes the null section at index 0, which you will usually need to skip. #[inline] pubfn iter(&self) -> slice::Iter<'data, Elf::SectionHeader> { self.sections.iter()
}
/// Iterate over the section headers and their indices. /// /// This includes the null section at index 0, which you will usually need to skip. #[inline] pubfn enumerate(&self) -> impl Iterator<Item = (SectionIndex, &style='color:blue'>'data Elf::SectionHeader)> { self.sections
.iter()
.enumerate()
.map(|(i, section)| (SectionIndex(i), section))
}
/// Return true if the section table is empty. #[inline] pubfn is_empty(&self) -> bool { self.sections.is_empty()
}
/// The number of section headers. #[inline] pubfn len(&self) -> usize { self.sections.len()
}
/// Get the section header at the given index. /// /// Returns an error for the null section at index 0. pubfn section(&self, index: SectionIndex) -> read::Result<&yle='color:blue'>'data Elf::SectionHeader> { if index == SectionIndex(0) { return Err(read::Error("Invalid ELF section index"));
} self.sections
.get(index.0)
.read_error("Invalid ELF section index")
}
/// Return the section header with the given name. /// /// Ignores sections with invalid names. pubfn section_by_name(
&self,
endian: Elf::Endian,
name: &[u8],
) -> Option<(SectionIndex, &'data Elf::SectionHeader)> { self.enumerate()
.find(|(_, section)| self.section_name(endian, section) == Ok(name))
}
/// Return the section name for the given section header. pubfn section_name(
&self,
endian: Elf::Endian,
section: &Elf::SectionHeader,
) -> read::Result<&'data [u8]> {
section.name(endian, self.strings)
}
/// Return the string table at the given section index. /// /// Returns an empty string table if the index is 0. /// Returns an error if the section is not a string table. #[inline] pubfn strings(
&self,
endian: Elf::Endian,
data: R,
index: SectionIndex,
) -> read::Result<StringTable<'data, R>> { if index == SectionIndex(0) { return Ok(StringTable::default());
} self.section(index)?
.strings(endian, data)?
.read_error("Invalid ELF string section type")
}
/// Return the symbol table of the given section type. /// /// Returns an empty symbol table if the symbol table does not exist. #[inline] pubfn symbols(
&self,
endian: Elf::Endian,
data: R,
sh_type: u32,
) -> read::Result<SymbolTable<'data, Elf, R>> {
debug_assert!(sh_type == elf::SHT_DYNSYM || sh_type == elf::SHT_SYMTAB);
/// Return the symbol table at the given section index. /// /// Returns an error if the section is not a symbol table. #[inline] pubfn symbol_table_by_index(
&self,
endian: Elf::Endian,
data: R,
index: SectionIndex,
) -> read::Result<SymbolTable<'data, Elf, R>> { let section = self.section(index)?; match section.sh_type(endian) {
elf::SHT_DYNSYM | elf::SHT_SYMTAB => {}
_ => return Err(Error("Invalid ELF symbol table section type")),
}
SymbolTable::parse(endian, data, self, index, section)
}
/// Create a mapping from section index to associated relocation sections. #[inline] pubfn relocation_sections(
&self,
endian: Elf::Endian,
symbol_section: SectionIndex,
) -> read::Result<RelocationSections> {
RelocationSections::parse(endian, self, symbol_section)
}
/// Return the contents of a dynamic section. /// /// Also returns the linked string table index. /// /// Returns `Ok(None)` if there is no `SHT_DYNAMIC` section. /// Returns `Err` for invalid values. pubfn dynamic(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<(&'data [Elf::Dyn], SectionIndex)>> { for section inself.sections { iflet Some(dynamic) = section.dynamic(endian, data)? { return Ok(Some(dynamic));
}
}
Ok(None)
}
/// Return the header of a SysV hash section. /// /// Returns `Ok(None)` if there is no SysV GNU hash section. /// Returns `Err` for invalid values. pubfn hash_header(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<&'data elf::HashHeader<Elf::Endian>>> { for section inself.sections { iflet Some(hash) = section.hash_header(endian, data)? { return Ok(Some(hash));
}
}
Ok(None)
}
/// Return the contents of a SysV hash section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if there is no SysV hash section. /// Returns `Err` for invalid values. pubfn hash(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<(HashTable<'data, Elf>, SectionIndex)>> { for section inself.sections { iflet Some(hash) = section.hash(endian, data)? { return Ok(Some(hash));
}
}
Ok(None)
}
/// Return the header of a GNU hash section. /// /// Returns `Ok(None)` if there is no GNU hash section. /// Returns `Err` for invalid values. pubfn gnu_hash_header(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<&'data elf::GnuHashHeader<Elf::Endian>>> { for section inself.sections { iflet Some(hash) = section.gnu_hash_header(endian, data)? { return Ok(Some(hash));
}
}
Ok(None)
}
/// Return the contents of a GNU hash section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if there is no GNU hash section. /// Returns `Err` for invalid values. pubfn gnu_hash(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<(GnuHashTable<'data, Elf>, SectionIndex)>> { for section inself.sections { iflet Some(hash) = section.gnu_hash(endian, data)? { return Ok(Some(hash));
}
}
Ok(None)
}
/// Return the contents of a `SHT_GNU_VERSYM` section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if there is no `SHT_GNU_VERSYM` section. /// Returns `Err` for invalid values. pubfn gnu_versym(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<(&'data [elf::Versym<Elf::Endian>], SectionIndex)>> { for section inself.sections { iflet Some(syms) = section.gnu_versym(endian, data)? { return Ok(Some(syms));
}
}
Ok(None)
}
/// Return the contents of a `SHT_GNU_VERDEF` section. /// /// Also returns the linked string table index. /// /// Returns `Ok(None)` if there is no `SHT_GNU_VERDEF` section. /// Returns `Err` for invalid values. pubfn gnu_verdef(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<(VerdefIterator<'data, Elf>, SectionIndex)>> { for section inself.sections { iflet Some(defs) = section.gnu_verdef(endian, data)? { return Ok(Some(defs));
}
}
Ok(None)
}
/// Return the contents of a `SHT_GNU_VERNEED` section. /// /// Also returns the linked string table index. /// /// Returns `Ok(None)` if there is no `SHT_GNU_VERNEED` section. /// Returns `Err` for invalid values. pubfn gnu_verneed(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<(VerneedIterator<'data, Elf>, SectionIndex)>> { for section inself.sections { iflet Some(needs) = section.gnu_verneed(endian, data)? { return Ok(Some(needs));
}
}
Ok(None)
}
/// Returns the symbol version table. /// /// Returns `Ok(None)` if there is no `SHT_GNU_VERSYM` section. /// Returns `Err` for invalid values. pubfn versions(
&self,
endian: Elf::Endian,
data: R,
) -> read::Result<Option<VersionTable<'data, Elf>>> { let (versyms, link) = matchself.gnu_versym(endian, data)? {
Some(val) => val,
None => return Ok(None),
}; let strings = self.symbol_table_by_index(endian, data, link)?.strings(); // TODO: check links? let verdefs = self.gnu_verdef(endian, data)?.map(|x| x.0); let verneeds = self.gnu_verneed(endian, data)?.map(|x| x.0);
VersionTable::parse(endian, versyms, verdefs, verneeds, strings).map(Some)
}
}
/// An iterator for the sections in an [`ElfFile32`](super::ElfFile32). pubtype ElfSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSectionIterator<'data, 'file, elf::FileHeader32<Endian>, R>; /// An iterator for the sections in an [`ElfFile64`](super::ElfFile64). pubtype ElfSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSectionIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
/// An iterator for the sections in an [`ElfFile`]. #[derive(Debug)] pubstruct ElfSectionIterator<'data, 'file, Elf, R = &'data [u8]> where
Elf: FileHeader,
R: ReadRef<'data>,
{
file: &'file ElfFile<'data, Elf, R>,
iter: iter::Enumerate<slice::Iter<'data, Elf::SectionHeader>>,
}
/// A section in an [`ElfFile32`](super::ElfFile32). pubtype ElfSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSection<'data, 'file, elf::FileHeader32<Endian>, R>; /// A section in an [`ElfFile64`](super::ElfFile64). pubtype ElfSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSection<'data, 'file, elf::FileHeader64<Endian>, R>;
/// A section in an [`ElfFile`]. /// /// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pubstruct ElfSection<'data, 'file, Elf, R = &'data [u8]> where
Elf: FileHeader,
R: ReadRef<'data>,
{ pub(super) file: &'file ElfFile<'data, Elf, R>, pub(super) index: SectionIndex, pub(super) section: &'data Elf::SectionHeader,
}
impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSection<'data, 'file, Elf, R> { /// Get the ELF file containing this section. pubfn elf_file(&self) -> &'file ElfFile<'data, Elf, R> { self.file
}
/// Get the raw ELF section header. pubfn elf_section_header(&self) -> &'data Elf::SectionHeader { self.section
}
/// Get the index of the relocation section that references this section. /// /// Returns `None` if there are no relocations. /// Returns an error if there are multiple relocation sections that reference this section. pubfn elf_relocation_section_index(&self) -> read::Result<Option<SectionIndex>> { let Some(relocation_index) = self.file.relocations.get(self.index) else { return Ok(None);
}; ifself.file.relocations.get(relocation_index).is_some() { return Err(Error( "Unsupported ELF section with multiple relocation sections",
));
}
Ok(Some(relocation_index))
}
/// Get the relocation section that references this section. /// /// Returns `None` if there are no relocations. /// Returns an error if there are multiple relocation sections that reference this section. pubfn elf_relocation_section(&self) -> read::Result<Option<&style='color:blue'>'data Elf::SectionHeader>> { let Some(relocation_index) = self.elf_relocation_section_index()? else { return Ok(None);
}; self.file.sections.section(relocation_index).map(Some)
}
/// Get the `Elf::Rel` entries that apply to this section. /// /// Returns an empty slice if there are no relocations. /// Returns an error if there are multiple relocation sections that reference this section. pubfn elf_linked_rel(&self) -> read::Result<&'data [Elf::Rel]> { let Some(relocation_section) = self.elf_relocation_section()? else { return Ok(&[]);
}; // The linked symbol table was already checked when self.file.relocations was created. let Some((rel, _)) = relocation_section.rel(self.file.endian, self.file.data)? else { return Ok(&[]);
};
Ok(rel)
}
/// Get the `Elf::Rela` entries that apply to this section. /// /// Returns an empty slice if there are no relocations. /// Returns an error if there are multiple relocation sections that reference this section. pubfn elf_linked_rela(&self) -> read::Result<&'data [Elf::Rela]> { let Some(relocation_section) = self.elf_relocation_section()? else { return Ok(&[]);
}; // The linked symbol table was already checked when self.file.relocations was created. let Some((rela, _)) = relocation_section.rela(self.file.endian, self.file.data)? else { return Ok(&[]);
};
Ok(rela)
}
/// A trait for generic access to [`elf::SectionHeader32`] and [`elf::SectionHeader64`]. #[allow(missing_docs)] pubtrait SectionHeader: Debug + Pod { type Elf: FileHeader<SectionHeader = Self, Endian = Self::Endian, Word = Self::Word>; type Word: Into<u64>; type Endian: endian::Endian;
/// Parse the section name from the string table. fn name<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
strings: StringTable<'data, R>,
) -> read::Result<&'data [u8]> {
strings
.get(self.sh_name(endian))
.read_error("Invalid ELF section name offset")
}
/// Get the `sh_link` field as a section index. /// /// This may return a null section index, and does not check for validity. fn link(&self, endian: Self::Endian) -> SectionIndex {
SectionIndex(self.sh_link(endian) as usize)
}
/// Return true if the `SHF_INFO_LINK` flag is set. fn has_info_link(&self, endian: Self::Endian) -> bool { self.sh_flags(endian).into() & u64::from(elf::SHF_INFO_LINK) != 0
}
/// Get the `sh_info` field as a section index. /// /// This does not check the `SHF_INFO_LINK` flag. /// This may return a null section index, and does not check for validity. fn info_link(&self, endian: Self::Endian) -> SectionIndex {
SectionIndex(self.sh_info(endian) as usize)
}
/// Return the offset and size of the section in the file. /// /// Returns `None` for sections that have no data in the file. fn file_range(&self, endian: Self::Endian) -> Option<(u64, u64)> { ifself.sh_type(endian) == elf::SHT_NOBITS {
None
} else {
Some((self.sh_offset(endian).into(), self.sh_size(endian).into()))
}
}
/// Return the section data. /// /// Returns `Ok(&[])` if the section has no data. /// Returns `Err` for invalid values. fn data<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<&'data [u8]> { iflet Some((offset, size)) = self.file_range(endian) {
data.read_bytes_at(offset, size)
.read_error("Invalid ELF section size or offset")
} else {
Ok(&[])
}
}
/// Return the section data as a slice of the given type. /// /// Allows padding at the end of the data. /// Returns `Ok(&[])` if the section has no data. /// Returns `Err` for invalid values, including bad alignment. fn data_as_array<'data, T: Pod, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<&'data [T]> {
pod::slice_from_all_bytes(self.data(endian, data)?)
.read_error("Invalid ELF section size or offset")
}
/// Return the strings in the section. /// /// Returns `Ok(None)` if the section does not contain strings. /// Returns `Err` for invalid values. fn strings<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<StringTable<'data, R>>> { ifself.sh_type(endian) != elf::SHT_STRTAB { return Ok(None);
} let str_offset = self.sh_offset(endian).into(); let str_size = self.sh_size(endian).into(); let str_end = str_offset
.checked_add(str_size)
.read_error("Invalid ELF string section offset or size")?;
Ok(Some(StringTable::new(data, str_offset, str_end)))
}
/// Return the symbols in the section. /// /// Also finds the linked string table in `sections`. /// /// `section_index` must be the 0-based index of this section, and is used /// to find the corresponding extended section index table in `sections`. /// /// Returns `Ok(None)` if the section does not contain symbols. /// Returns `Err` for invalid values. fn symbols<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
sections: &SectionTable<'data, Self::Elf, R>,
section_index: SectionIndex,
) -> read::Result<Option<SymbolTable<'data, Self::Elf, R>>> { let sh_type = self.sh_type(endian); if sh_type != elf::SHT_SYMTAB && sh_type != elf::SHT_DYNSYM { return Ok(None);
}
SymbolTable::parse(endian, data, sections, section_index, self).map(Some)
}
/// Return the `Elf::Rel` entries in the section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if the section does not contain relocations. /// Returns `Err` for invalid values. fn rel<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(&'data [<Self::Elf as FileHeader>::Rel], SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_REL { return Ok(None);
} let rel = self
.data_as_array(endian, data)
.read_error("Invalid ELF relocation section offset or size")?;
Ok(Some((rel, self.link(endian))))
}
/// Return the `Elf::Rela` entries in the section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if the section does not contain relocations. /// Returns `Err` for invalid values. fn rela<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(&'data [<Self::Elf as FileHeader>::Rela], SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_RELA { return Ok(None);
} let rela = self
.data_as_array(endian, data)
.read_error("Invalid ELF relocation section offset or size")?;
Ok(Some((rela, self.link(endian))))
}
/// Return entries in a dynamic section. /// /// Also returns the linked string table index. /// /// Returns `Ok(None)` if the section type is not `SHT_DYNAMIC`. /// Returns `Err` for invalid values. fn dynamic<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(&'data [<Self::Elf as FileHeader>::Dyn], SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_DYNAMIC { return Ok(None);
} let dynamic = self
.data_as_array(endian, data)
.read_error("Invalid ELF dynamic section offset or size")?;
Ok(Some((dynamic, self.link(endian))))
}
/// Return a note iterator for the section data. /// /// Returns `Ok(None)` if the section does not contain notes. /// Returns `Err` for invalid values. fn notes<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<NoteIterator<'data, Self::Elf>>> { ifself.sh_type(endian) != elf::SHT_NOTE { return Ok(None);
} let data = self
.data(endian, data)
.read_error("Invalid ELF note section offset or size")?; let notes = NoteIterator::new(endian, self.sh_addralign(endian), data)?;
Ok(Some(notes))
}
/// Return the contents of a group section. /// /// The first value is a `GRP_*` value, and the remaining values /// are section indices. /// /// Returns `Ok(None)` if the section does not define a group. /// Returns `Err` for invalid values. fn group<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(u32, &'data [U32Bytes<Self::Endian>])>> { ifself.sh_type(endian) != elf::SHT_GROUP { return Ok(None);
} let msg = "Invalid ELF group section offset or size"; let data = self.data(endian, data).read_error(msg)?; let (flag, data) = pod::from_bytes::<U32Bytes<_>>(data).read_error(msg)?; let sections = pod::slice_from_all_bytes(data).read_error(msg)?;
Ok(Some((flag.get(endian), sections)))
}
/// Return the header of a SysV hash section. /// /// Returns `Ok(None)` if the section does not contain a SysV hash. /// Returns `Err` for invalid values. fn hash_header<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<&'data elf::HashHeader<Self::Endian>>> { ifself.sh_type(endian) != elf::SHT_HASH { return Ok(None);
} let data = self
.data(endian, data)
.read_error("Invalid ELF hash section offset or size")?; let header = data
.read_at::<elf::HashHeader<Self::Endian>>(0)
.read_error("Invalid hash header")?;
Ok(Some(header))
}
/// Return the contents of a SysV hash section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if the section does not contain a SysV hash. /// Returns `Err` for invalid values. fn hash<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(HashTable<'data, Self::Elf>, SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_HASH { return Ok(None);
} let data = self
.data(endian, data)
.read_error("Invalid ELF hash section offset or size")?; let hash = HashTable::parse(endian, data)?;
Ok(Some((hash, self.link(endian))))
}
/// Return the header of a GNU hash section. /// /// Returns `Ok(None)` if the section does not contain a GNU hash. /// Returns `Err` for invalid values. fn gnu_hash_header<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<&'data elf::GnuHashHeader<Self::Endian>>> { ifself.sh_type(endian) != elf::SHT_GNU_HASH { return Ok(None);
} let data = self
.data(endian, data)
.read_error("Invalid ELF GNU hash section offset or size")?; let header = data
.read_at::<elf::GnuHashHeader<Self::Endian>>(0)
.read_error("Invalid GNU hash header")?;
Ok(Some(header))
}
/// Return the contents of a GNU hash section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if the section does not contain a GNU hash. /// Returns `Err` for invalid values. fn gnu_hash<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(GnuHashTable<'data, Self::Elf>, SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_GNU_HASH { return Ok(None);
} let data = self
.data(endian, data)
.read_error("Invalid ELF GNU hash section offset or size")?; let hash = GnuHashTable::parse(endian, data)?;
Ok(Some((hash, self.link(endian))))
}
/// Return the contents of a `SHT_GNU_VERSYM` section. /// /// Also returns the linked symbol table index. /// /// Returns `Ok(None)` if the section type is not `SHT_GNU_VERSYM`. /// Returns `Err` for invalid values. fn gnu_versym<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(&'data [elf::Versym<Self::Endian>], SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_GNU_VERSYM { return Ok(None);
} let versym = self
.data_as_array(endian, data)
.read_error("Invalid ELF GNU versym section offset or size")?;
Ok(Some((versym, self.link(endian))))
}
/// Return an iterator for the entries of a `SHT_GNU_VERDEF` section. /// /// Also returns the linked string table index. /// /// Returns `Ok(None)` if the section type is not `SHT_GNU_VERDEF`. /// Returns `Err` for invalid values. fn gnu_verdef<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(VerdefIterator<'data, Self::Elf>, SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_GNU_VERDEF { return Ok(None);
} let verdef = self
.data(endian, data)
.read_error("Invalid ELF GNU verdef section offset or size")?;
Ok(Some((
VerdefIterator::new(endian, verdef), self.link(endian),
)))
}
/// Return an iterator for the entries of a `SHT_GNU_VERNEED` section. /// /// Also returns the linked string table index. /// /// Returns `Ok(None)` if the section type is not `SHT_GNU_VERNEED`. /// Returns `Err` for invalid values. fn gnu_verneed<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(VerneedIterator<'data, Self::Elf>, SectionIndex)>> { ifself.sh_type(endian) != elf::SHT_GNU_VERNEED { return Ok(None);
} let verneed = self
.data(endian, data)
.read_error("Invalid ELF GNU verneed section offset or size")?;
Ok(Some((
VerneedIterator::new(endian, verneed), self.link(endian),
)))
}
/// 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>>> { ifself.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")?; letmut 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> { type Elf = elf::FileHeader32<Endian>; type Word = u32; type Endian = Endian;
impl<Endian: endian::Endian> SectionHeader for elf::SectionHeader64<Endian> { type Word = u64; type Endian = Endian; type Elf = elf::FileHeader64<Endian>;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.