/// A mapping from section index to associated relocation sections. #[derive(Debug, Default)] pubstruct RelocationSections {
relocations: Vec<usize>,
}
impl RelocationSections { /// Create a new mapping using the section table. /// /// Skips relocation sections that do not use the given symbol table section. pubfn parse<'data, Elf: FileHeader, R: ReadRef<'data>>(
endian: Elf::Endian,
sections: &SectionTable<'data, Elf, R>,
symbol_section: SectionIndex,
) -> read::Result<Self> { letmut relocations = vec![0; sections.len()]; for (index, section) in sections.iter().enumerate().rev() { let sh_type = section.sh_type(endian); if sh_type == elf::SHT_REL || sh_type == elf::SHT_RELA { // The symbol indices used in relocations must be for the symbol table // we are expecting to use. let sh_link = section.link(endian); if sh_link != symbol_section { continue;
}
let sh_info = section.info_link(endian); if sh_info == SectionIndex(0) { // Skip dynamic relocations. continue;
} if sh_info.0 >= relocations.len() { return Err(Error("Invalid ELF sh_info for relocation section"));
}
// We don't support relocations that apply to other relocation sections // because it interferes with the chaining of relocation sections below. let sh_info_type = sections.section(sh_info)?.sh_type(endian); if sh_info_type == elf::SHT_REL || sh_info_type == elf::SHT_RELA { return Err(Error("Unsupported ELF sh_info for relocation section"));
}
// Handle multiple relocation sections by chaining them. let next = relocations[sh_info.0];
relocations[sh_info.0] = index;
relocations[index] = next;
}
}
Ok(Self { relocations })
}
/// Given a section index, return the section index of the associated relocation section. /// /// This may also be called with a relocation section index, and it will return the /// next associated relocation section. pubfn get(&self, index: SectionIndex) -> Option<SectionIndex> { self.relocations
.get(index.0)
.cloned()
.filter(|x| *x != 0)
.map(SectionIndex)
}
}
/// An iterator for the dynamic relocations in an [`ElfFile32`](super::ElfFile32). pubtype ElfDynamicRelocationIterator32<'data, 'file, Endian = Endianness, R = &'color:blue'>'data [u8]> =
ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>; /// An iterator for the dynamic relocations in an [`ElfFile64`](super::ElfFile64). pubtype ElfDynamicRelocationIterator64<'data, 'file, Endian = Endianness, R = &'color:blue'>'data [u8]> =
ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
/// An iterator for the dynamic relocations in an [`ElfFile`]. pubstruct ElfDynamicRelocationIterator<'data, 'file, Elf, R = &'data [u8]> where
Elf: FileHeader,
R: ReadRef<'data>,
{ /// The current relocation section index. pub(super) section_index: SectionIndex, pub(super) file: &'file ElfFile<'data, Elf, R>, pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
}
impl<'data, 'file, Elf, R> Iterator for ElfDynamicRelocationIterator<'data, 'file, Elf, R> where
Elf: FileHeader,
R: ReadRef<'data>,
{ type Item = (u64, Relocation);
/// An iterator for the relocations for an [`ElfSection32`](super::ElfSection32). pubtype ElfSectionRelocationIterator32<'data, 'file, Endian = Endianness, R = &'color:blue'>'data [u8]> =
ElfSectionRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>; /// An iterator for the relocations for an [`ElfSection64`](super::ElfSection64). pubtype ElfSectionRelocationIterator64<'data, 'file, Endian = Endianness, R = &'color:blue'>'data [u8]> =
ElfSectionRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
/// An iterator for the relocations for an [`ElfSection`](super::ElfSection). pubstruct ElfSectionRelocationIterator<'data, 'file, Elf, R = &'data [u8]> where
Elf: FileHeader,
R: ReadRef<'data>,
{ /// The current pointer in the chain of relocation sections. pub(super) section_index: SectionIndex, pub(super) file: &'file ElfFile<'data, Elf, R>, pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
}
impl<'data, 'file, Elf, R> Iterator for ElfSectionRelocationIterator<'data, 'file, Elf, R> where
Elf: FileHeader,
R: ReadRef<'data>,
{ type Item = (u64, Relocation);
/// A trait for generic access to [`elf::Rel32`] and [`elf::Rel64`]. #[allow(missing_docs)] pubtrait Rel: Debug + Pod + Clone { type Word: Into<u64>; type Sword: Into<i64>; type Endian: endian::Endian;
/// Get the symbol index referenced by the relocation. /// /// Returns `None` for the null symbol index. fn symbol(&self, endian: Self::Endian) -> Option<SymbolIndex> { let sym = self.r_sym(endian); if sym == 0 {
None
} else {
Some(SymbolIndex(sym as usize))
}
}
}
impl<Endian: endian::Endian> Rel for elf::Rel32<Endian> { type Word = u32; type Sword = i32; type Endian = Endian;
/// A trait for generic access to [`elf::Rela32`] and [`elf::Rela64`]. #[allow(missing_docs)] pubtrait Rela: Debug + Pod + Clone { type Word: Into<u64>; type Sword: Into<i64>; type Endian: endian::Endian;
/// Get the symbol index referenced by the relocation. /// /// Returns `None` for the null symbol index. fn symbol(&self, endian: Self::Endian, is_mips64el: bool) -> Option<SymbolIndex> { let sym = self.r_sym(endian, is_mips64el); if sym == 0 {
None
} else {
Some(SymbolIndex(sym as usize))
}
}
}
impl<Endian: endian::Endian> Rela for elf::Rela32<Endian> { type Word = u32; type Sword = i32; type Endian = 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.