diff options
Diffstat (limited to 'vendor/object/src/read/xcoff/section.rs')
-rw-r--r-- | vendor/object/src/read/xcoff/section.rs | 431 |
1 files changed, 0 insertions, 431 deletions
diff --git a/vendor/object/src/read/xcoff/section.rs b/vendor/object/src/read/xcoff/section.rs deleted file mode 100644 index 8a36bcf..0000000 --- a/vendor/object/src/read/xcoff/section.rs +++ /dev/null @@ -1,431 +0,0 @@ -use core::fmt::Debug; -use core::{iter, result, slice, str}; - -use crate::{ - xcoff, BigEndian as BE, CompressedData, CompressedFileRange, Pod, SectionFlags, SectionKind, -}; - -use crate::read::{self, Error, ObjectSection, ReadError, ReadRef, Result, SectionIndex}; - -use super::{AuxHeader, FileHeader, Rel, XcoffFile, XcoffRelocationIterator}; - -/// An iterator for the sections in an [`XcoffFile32`](super::XcoffFile32). -pub type XcoffSectionIterator32<'data, 'file, R = &'data [u8]> = - XcoffSectionIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator for the sections in an [`XcoffFile64`](super::XcoffFile64). -pub type XcoffSectionIterator64<'data, 'file, R = &'data [u8]> = - XcoffSectionIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator for the sections in an [`XcoffFile`]. -#[derive(Debug)] -pub struct XcoffSectionIterator<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - pub(super) file: &'file XcoffFile<'data, Xcoff, R>, - pub(super) iter: iter::Enumerate<slice::Iter<'data, Xcoff::SectionHeader>>, -} - -impl<'data, 'file, Xcoff, R> Iterator for XcoffSectionIterator<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - type Item = XcoffSection<'data, 'file, Xcoff, R>; - - fn next(&mut self) -> Option<Self::Item> { - self.iter.next().map(|(index, section)| XcoffSection { - index: SectionIndex(index + 1), - file: self.file, - section, - }) - } -} - -/// A section in an [`XcoffFile32`](super::XcoffFile32). -pub type XcoffSection32<'data, 'file, R = &'data [u8]> = - XcoffSection<'data, 'file, xcoff::FileHeader32, R>; -/// A section in an [`XcoffFile64`](super::XcoffFile64). -pub type XcoffSection64<'data, 'file, R = &'data [u8]> = - XcoffSection<'data, 'file, xcoff::FileHeader64, R>; - -/// A section in an [`XcoffFile`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -#[derive(Debug)] -pub struct XcoffSection<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - pub(super) file: &'file XcoffFile<'data, Xcoff, R>, - pub(super) section: &'data Xcoff::SectionHeader, - pub(super) index: SectionIndex, -} - -impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> XcoffSection<'data, 'file, Xcoff, R> { - fn bytes(&self) -> Result<&'data [u8]> { - self.section - .data(self.file.data) - .read_error("Invalid XCOFF section offset or size") - } -} - -impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffSection<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Xcoff, R> ObjectSection<'data> for XcoffSection<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - type RelocationIterator = XcoffRelocationIterator<'data, 'file, Xcoff, R>; - - fn index(&self) -> SectionIndex { - self.index - } - - fn address(&self) -> u64 { - self.section.s_paddr().into() - } - - fn size(&self) -> u64 { - self.section.s_size().into() - } - - fn align(&self) -> u64 { - // The default section alignment is 4. - if let Some(aux_header) = self.file.aux_header { - match self.kind() { - SectionKind::Text => aux_header.o_algntext().into(), - SectionKind::Data => aux_header.o_algndata().into(), - _ => 4, - } - } else { - 4 - } - } - - fn file_range(&self) -> Option<(u64, u64)> { - self.section.file_range() - } - - fn data(&self) -> Result<&'data [u8]> { - self.bytes() - } - - fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> { - Ok(read::util::data_range( - self.bytes()?, - self.address(), - address, - size, - )) - } - - fn compressed_file_range(&self) -> Result<CompressedFileRange> { - Ok(CompressedFileRange::none(self.file_range())) - } - - fn compressed_data(&self) -> Result<CompressedData<'data>> { - self.data().map(CompressedData::none) - } - - fn name_bytes(&self) -> read::Result<&[u8]> { - Ok(self.section.name()) - } - - fn name(&self) -> read::Result<&str> { - let name = self.name_bytes()?; - str::from_utf8(name) - .ok() - .read_error("Non UTF-8 XCOFF section name") - } - - fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { - Ok(None) - } - - fn segment_name(&self) -> Result<Option<&str>> { - Ok(None) - } - - fn kind(&self) -> SectionKind { - let section_type = self.section.s_flags() as u16; - if section_type & xcoff::STYP_TEXT != 0 { - SectionKind::Text - } else if section_type & xcoff::STYP_DATA != 0 { - SectionKind::Data - } else if section_type & xcoff::STYP_TDATA != 0 { - SectionKind::Tls - } else if section_type & xcoff::STYP_BSS != 0 { - SectionKind::UninitializedData - } else if section_type & xcoff::STYP_TBSS != 0 { - SectionKind::UninitializedTls - } else if section_type & (xcoff::STYP_DEBUG | xcoff::STYP_DWARF) != 0 { - SectionKind::Debug - } else if section_type & (xcoff::STYP_LOADER | xcoff::STYP_OVRFLO) != 0 { - SectionKind::Metadata - } else if section_type - & (xcoff::STYP_INFO | xcoff::STYP_EXCEPT | xcoff::STYP_PAD | xcoff::STYP_TYPCHK) - != 0 - { - SectionKind::Other - } else { - SectionKind::Unknown - } - } - - fn relocations(&self) -> Self::RelocationIterator { - let rel = self.section.relocations(self.file.data).unwrap_or(&[]); - XcoffRelocationIterator { - file: self.file, - relocations: rel.iter(), - } - } - - fn flags(&self) -> SectionFlags { - SectionFlags::Xcoff { - s_flags: self.section.s_flags(), - } - } - - fn uncompressed_data(&self) -> Result<alloc::borrow::Cow<'data, [u8]>> { - self.compressed_data()?.decompress() - } -} - -/// The table of section headers in an XCOFF file. -/// -/// Returned by [`FileHeader::sections`]. -#[derive(Debug, Clone, Copy)] -pub struct SectionTable<'data, Xcoff: FileHeader> { - sections: &'data [Xcoff::SectionHeader], -} - -impl<'data, Xcoff> Default for SectionTable<'data, Xcoff> -where - Xcoff: FileHeader, -{ - fn default() -> Self { - Self { sections: &[] } - } -} - -impl<'data, Xcoff> SectionTable<'data, Xcoff> -where - Xcoff: FileHeader, -{ - /// Parse the section table. - /// - /// `data` must be the entire file data. - /// `offset` must be after the optional file header. - pub fn parse<R: ReadRef<'data>>(header: &Xcoff, data: R, offset: &mut u64) -> Result<Self> { - let section_num = header.f_nscns(); - if section_num == 0 { - return Ok(SectionTable::default()); - } - let sections = data - .read_slice(offset, section_num as usize) - .read_error("Invalid XCOFF section headers")?; - Ok(SectionTable { sections }) - } - - /// Iterate over the section headers. - #[inline] - pub fn iter(&self) -> slice::Iter<'data, Xcoff::SectionHeader> { - self.sections.iter() - } - - /// Return true if the section table is empty. - #[inline] - pub fn is_empty(&self) -> bool { - self.sections.is_empty() - } - - /// The number of section headers. - #[inline] - pub fn len(&self) -> usize { - self.sections.len() - } - - /// Return the section header at the given index. - /// - /// The index is 1-based. - pub fn section(&self, index: SectionIndex) -> read::Result<&'data Xcoff::SectionHeader> { - self.sections - .get(index.0.wrapping_sub(1)) - .read_error("Invalid XCOFF section index") - } -} - -/// A trait for generic access to [`xcoff::SectionHeader32`] and [`xcoff::SectionHeader64`]. -#[allow(missing_docs)] -pub trait SectionHeader: Debug + Pod { - type Word: Into<u64>; - type HalfWord: Into<u32>; - type Xcoff: FileHeader<SectionHeader = Self, Word = Self::Word>; - type Rel: Rel<Word = Self::Word>; - - fn s_name(&self) -> &[u8; 8]; - fn s_paddr(&self) -> Self::Word; - fn s_vaddr(&self) -> Self::Word; - fn s_size(&self) -> Self::Word; - fn s_scnptr(&self) -> Self::Word; - fn s_relptr(&self) -> Self::Word; - fn s_lnnoptr(&self) -> Self::Word; - fn s_nreloc(&self) -> Self::HalfWord; - fn s_nlnno(&self) -> Self::HalfWord; - fn s_flags(&self) -> u32; - - /// Return the section name. - fn name(&self) -> &[u8] { - let sectname = &self.s_name()[..]; - match memchr::memchr(b'\0', sectname) { - Some(end) => §name[..end], - None => sectname, - } - } - - /// Return the offset and size of the section in the file. - fn file_range(&self) -> Option<(u64, u64)> { - Some((self.s_scnptr().into(), self.s_size().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, data: R) -> result::Result<&'data [u8], ()> { - if let Some((offset, size)) = self.file_range() { - data.read_bytes_at(offset, size) - } else { - Ok(&[]) - } - } - - /// Read the relocations. - fn relocations<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [Self::Rel]>; -} - -impl SectionHeader for xcoff::SectionHeader32 { - type Word = u32; - type HalfWord = u16; - type Xcoff = xcoff::FileHeader32; - type Rel = xcoff::Rel32; - - fn s_name(&self) -> &[u8; 8] { - &self.s_name - } - - fn s_paddr(&self) -> Self::Word { - self.s_paddr.get(BE) - } - - fn s_vaddr(&self) -> Self::Word { - self.s_vaddr.get(BE) - } - - fn s_size(&self) -> Self::Word { - self.s_size.get(BE) - } - - fn s_scnptr(&self) -> Self::Word { - self.s_scnptr.get(BE) - } - - fn s_relptr(&self) -> Self::Word { - self.s_relptr.get(BE) - } - - fn s_lnnoptr(&self) -> Self::Word { - self.s_lnnoptr.get(BE) - } - - fn s_nreloc(&self) -> Self::HalfWord { - self.s_nreloc.get(BE) - } - - fn s_nlnno(&self) -> Self::HalfWord { - self.s_nlnno.get(BE) - } - - fn s_flags(&self) -> u32 { - self.s_flags.get(BE) - } - - /// Read the relocations in a XCOFF32 file. - /// - /// `data` must be the entire file data. - fn relocations<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [Self::Rel]> { - let reloc_num = self.s_nreloc() as usize; - // TODO: If more than 65,534 relocation entries are required, the field value will be 65535, - // and an STYP_OVRFLO section header will contain the actual count of relocation entries in - // the s_paddr field. - if reloc_num == 65535 { - return Err(Error("Overflow section is not supported yet.")); - } - data.read_slice_at(self.s_relptr().into(), reloc_num) - .read_error("Invalid XCOFF relocation offset or number") - } -} - -impl SectionHeader for xcoff::SectionHeader64 { - type Word = u64; - type HalfWord = u32; - type Xcoff = xcoff::FileHeader64; - type Rel = xcoff::Rel64; - - fn s_name(&self) -> &[u8; 8] { - &self.s_name - } - - fn s_paddr(&self) -> Self::Word { - self.s_paddr.get(BE) - } - - fn s_vaddr(&self) -> Self::Word { - self.s_vaddr.get(BE) - } - - fn s_size(&self) -> Self::Word { - self.s_size.get(BE) - } - - fn s_scnptr(&self) -> Self::Word { - self.s_scnptr.get(BE) - } - - fn s_relptr(&self) -> Self::Word { - self.s_relptr.get(BE) - } - - fn s_lnnoptr(&self) -> Self::Word { - self.s_lnnoptr.get(BE) - } - - fn s_nreloc(&self) -> Self::HalfWord { - self.s_nreloc.get(BE) - } - - fn s_nlnno(&self) -> Self::HalfWord { - self.s_nlnno.get(BE) - } - - fn s_flags(&self) -> u32 { - self.s_flags.get(BE) - } - - /// Read the relocations in a XCOFF64 file. - /// - /// `data` must be the entire file data. - fn relocations<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [Self::Rel]> { - data.read_slice_at(self.s_relptr(), self.s_nreloc() as usize) - .read_error("Invalid XCOFF relocation offset or number") - } -} |