diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/object-0.31.1/src/read/xcoff | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/object-0.31.1/src/read/xcoff')
-rw-r--r-- | vendor/object-0.31.1/src/read/xcoff/comdat.rs | 129 | ||||
-rw-r--r-- | vendor/object-0.31.1/src/read/xcoff/file.rs | 629 | ||||
-rw-r--r-- | vendor/object-0.31.1/src/read/xcoff/mod.rs | 21 | ||||
-rw-r--r-- | vendor/object-0.31.1/src/read/xcoff/relocation.rs | 127 | ||||
-rw-r--r-- | vendor/object-0.31.1/src/read/xcoff/section.rs | 427 | ||||
-rw-r--r-- | vendor/object-0.31.1/src/read/xcoff/segment.rs | 113 | ||||
-rw-r--r-- | vendor/object-0.31.1/src/read/xcoff/symbol.rs | 695 |
7 files changed, 0 insertions, 2141 deletions
diff --git a/vendor/object-0.31.1/src/read/xcoff/comdat.rs b/vendor/object-0.31.1/src/read/xcoff/comdat.rs deleted file mode 100644 index 2b23d1dba..000000000 --- a/vendor/object-0.31.1/src/read/xcoff/comdat.rs +++ /dev/null @@ -1,129 +0,0 @@ -//! XCOFF doesn't support the COMDAT section. - -use core::fmt::Debug; - -use crate::xcoff; - -use crate::read::{self, ComdatKind, ObjectComdat, ReadRef, Result, SectionIndex, SymbolIndex}; - -use super::{FileHeader, XcoffFile}; - -/// An iterator over the COMDAT section groups of a `XcoffFile32`. -pub type XcoffComdatIterator32<'data, 'file, R = &'data [u8]> = - XcoffComdatIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the COMDAT section groups of a `XcoffFile64`. -pub type XcoffComdatIterator64<'data, 'file, R = &'data [u8]> = - XcoffComdatIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator over the COMDAT section groups of a `XcoffFile`. -#[derive(Debug)] -pub struct XcoffComdatIterator<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - #[allow(unused)] - pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, -} - -impl<'data, 'file, Xcoff, R> Iterator for XcoffComdatIterator<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - type Item = XcoffComdat<'data, 'file, Xcoff, R>; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - None - } -} - -/// A COMDAT section group of a `XcoffFile32`. -pub type XcoffComdat32<'data, 'file, R = &'data [u8]> = - XcoffComdat<'data, 'file, xcoff::FileHeader32, R>; - -/// A COMDAT section group of a `XcoffFile64`. -pub type XcoffComdat64<'data, 'file, R = &'data [u8]> = - XcoffComdat<'data, 'file, xcoff::FileHeader64, R>; - -/// A COMDAT section group of a `XcoffFile`. -#[derive(Debug)] -pub struct XcoffComdat<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - #[allow(unused)] - file: &'file XcoffFile<'data, Xcoff, R>, -} - -impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffComdat<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Xcoff, R> ObjectComdat<'data> for XcoffComdat<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - type SectionIterator = XcoffComdatSectionIterator<'data, 'file, Xcoff, R>; - - #[inline] - fn kind(&self) -> ComdatKind { - unreachable!(); - } - - #[inline] - fn symbol(&self) -> SymbolIndex { - unreachable!(); - } - - #[inline] - fn name_bytes(&self) -> Result<&[u8]> { - unreachable!(); - } - - #[inline] - fn name(&self) -> Result<&str> { - unreachable!(); - } - - #[inline] - fn sections(&self) -> Self::SectionIterator { - unreachable!(); - } -} - -/// An iterator over the sections in a COMDAT section group of a `XcoffFile32`. -pub type XcoffComdatSectionIterator32<'data, 'file, R = &'data [u8]> = - XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the sections in a COMDAT section group of a `XcoffFile64`. -pub type XcoffComdatSectionIterator64<'data, 'file, R = &'data [u8]> = - XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator over the sections in a COMDAT section group of a `XcoffFile`. -#[derive(Debug)] -pub struct XcoffComdatSectionIterator<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - #[allow(unused)] - file: &'file XcoffFile<'data, Xcoff, R>, -} - -impl<'data, 'file, Xcoff, R> Iterator for XcoffComdatSectionIterator<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - type Item = SectionIndex; - - fn next(&mut self) -> Option<Self::Item> { - None - } -} diff --git a/vendor/object-0.31.1/src/read/xcoff/file.rs b/vendor/object-0.31.1/src/read/xcoff/file.rs deleted file mode 100644 index bac9e7075..000000000 --- a/vendor/object-0.31.1/src/read/xcoff/file.rs +++ /dev/null @@ -1,629 +0,0 @@ -use core::fmt::Debug; -use core::mem; - -use alloc::vec::Vec; - -use crate::read::{self, Error, NoDynamicRelocationIterator, Object, ReadError, ReadRef, Result}; - -use crate::{ - xcoff, Architecture, BigEndian as BE, FileFlags, ObjectKind, ObjectSection, Pod, SectionIndex, - SymbolIndex, -}; - -use super::{ - CsectAux, FileAux, SectionHeader, SectionTable, Symbol, SymbolTable, XcoffComdat, - XcoffComdatIterator, XcoffSection, XcoffSectionIterator, XcoffSegment, XcoffSegmentIterator, - XcoffSymbol, XcoffSymbolIterator, XcoffSymbolTable, -}; - -/// A 32-bit XCOFF object file. -pub type XcoffFile32<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader32, R>; -/// A 64-bit XCOFF object file. -pub type XcoffFile64<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader64, R>; - -/// A partially parsed XCOFF file. -/// -/// Most of the functionality of this type is provided by the `Object` trait implementation. -#[derive(Debug)] -pub struct XcoffFile<'data, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - pub(super) data: R, - pub(super) header: &'data Xcoff, - pub(super) aux_header: Option<&'data Xcoff::AuxHeader>, - pub(super) sections: SectionTable<'data, Xcoff>, - pub(super) symbols: SymbolTable<'data, Xcoff, R>, -} - -impl<'data, Xcoff, R> XcoffFile<'data, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - /// Parse the raw XCOFF file data. - pub fn parse(data: R) -> Result<Self> { - let mut offset = 0; - let header = Xcoff::parse(data, &mut offset)?; - let aux_header = header.aux_header(data, &mut offset)?; - let sections = header.sections(data, &mut offset)?; - let symbols = header.symbols(data)?; - - Ok(XcoffFile { - data, - header, - aux_header, - sections, - symbols, - }) - } - - /// Returns the raw data. - pub fn data(&self) -> R { - self.data - } - - /// Returns the raw XCOFF file header. - pub fn raw_header(&self) -> &'data Xcoff { - self.header - } -} - -impl<'data, Xcoff, R> read::private::Sealed for XcoffFile<'data, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Xcoff, R> Object<'data, 'file> for XcoffFile<'data, Xcoff, R> -where - 'data: 'file, - Xcoff: FileHeader, - R: 'file + ReadRef<'data>, -{ - type Segment = XcoffSegment<'data, 'file, Xcoff, R>; - type SegmentIterator = XcoffSegmentIterator<'data, 'file, Xcoff, R>; - type Section = XcoffSection<'data, 'file, Xcoff, R>; - type SectionIterator = XcoffSectionIterator<'data, 'file, Xcoff, R>; - type Comdat = XcoffComdat<'data, 'file, Xcoff, R>; - type ComdatIterator = XcoffComdatIterator<'data, 'file, Xcoff, R>; - type Symbol = XcoffSymbol<'data, 'file, Xcoff, R>; - type SymbolIterator = XcoffSymbolIterator<'data, 'file, Xcoff, R>; - type SymbolTable = XcoffSymbolTable<'data, 'file, Xcoff, R>; - type DynamicRelocationIterator = NoDynamicRelocationIterator; - - fn architecture(&self) -> crate::Architecture { - if self.is_64() { - Architecture::PowerPc64 - } else { - Architecture::PowerPc - } - } - - fn is_little_endian(&self) -> bool { - false - } - - fn is_64(&self) -> bool { - self.header.is_type_64() - } - - fn kind(&self) -> ObjectKind { - let flags = self.header.f_flags(); - if flags & xcoff::F_EXEC != 0 { - ObjectKind::Executable - } else if flags & xcoff::F_SHROBJ != 0 { - ObjectKind::Dynamic - } else if flags & xcoff::F_RELFLG == 0 { - ObjectKind::Relocatable - } else { - ObjectKind::Unknown - } - } - - fn segments(&'file self) -> XcoffSegmentIterator<'data, 'file, Xcoff, R> { - XcoffSegmentIterator { file: self } - } - - fn section_by_name_bytes( - &'file self, - section_name: &[u8], - ) -> Option<XcoffSection<'data, 'file, Xcoff, R>> { - self.sections() - .find(|section| section.name_bytes() == Ok(section_name)) - } - - fn section_by_index( - &'file self, - index: SectionIndex, - ) -> Result<XcoffSection<'data, 'file, Xcoff, R>> { - let section = self.sections.section(index)?; - Ok(XcoffSection { - file: self, - section, - index, - }) - } - - fn sections(&'file self) -> XcoffSectionIterator<'data, 'file, Xcoff, R> { - XcoffSectionIterator { - file: self, - iter: self.sections.iter().enumerate(), - } - } - - fn comdats(&'file self) -> XcoffComdatIterator<'data, 'file, Xcoff, R> { - XcoffComdatIterator { file: self } - } - - fn symbol_table(&'file self) -> Option<XcoffSymbolTable<'data, 'file, Xcoff, R>> { - if self.symbols.is_empty() { - return None; - } - Some(XcoffSymbolTable { - symbols: &self.symbols, - file: self, - }) - } - - fn symbol_by_index( - &'file self, - index: SymbolIndex, - ) -> Result<XcoffSymbol<'data, 'file, Xcoff, R>> { - let symbol = self.symbols.symbol(index.0)?; - Ok(XcoffSymbol { - symbols: &self.symbols, - index, - symbol, - file: self, - }) - } - - fn symbols(&'file self) -> XcoffSymbolIterator<'data, 'file, Xcoff, R> { - XcoffSymbolIterator { - symbols: &self.symbols, - index: 0, - file: self, - } - } - - fn dynamic_symbol_table(&'file self) -> Option<XcoffSymbolTable<'data, 'file, Xcoff, R>> { - None - } - - fn dynamic_symbols(&'file self) -> XcoffSymbolIterator<'data, 'file, Xcoff, R> { - // TODO: return the symbols in the STYP_LOADER section. - XcoffSymbolIterator { - file: self, - symbols: &self.symbols, - // Hack: don't return any. - index: self.symbols.len(), - } - } - - fn dynamic_relocations(&'file self) -> Option<Self::DynamicRelocationIterator> { - // TODO: return the relocations in the STYP_LOADER section. - None - } - - fn imports(&self) -> Result<alloc::vec::Vec<crate::Import<'data>>> { - // TODO: return the imports in the STYP_LOADER section. - Ok(Vec::new()) - } - - fn exports(&self) -> Result<alloc::vec::Vec<crate::Export<'data>>> { - // TODO: return the exports in the STYP_LOADER section. - Ok(Vec::new()) - } - - fn has_debug_symbols(&self) -> bool { - self.section_by_name(".debug").is_some() || self.section_by_name(".dwinfo").is_some() - } - - fn relative_address_base(&'file self) -> u64 { - 0 - } - - fn entry(&'file self) -> u64 { - if let Some(aux_header) = self.aux_header { - aux_header.o_entry().into() - } else { - 0 - } - } - - fn flags(&self) -> FileFlags { - FileFlags::Xcoff { - f_flags: self.header.f_flags(), - } - } -} - -/// A trait for generic access to `FileHeader32` and `FileHeader64`. -#[allow(missing_docs)] -pub trait FileHeader: Debug + Pod { - type Word: Into<u64>; - type AuxHeader: AuxHeader<Word = Self::Word>; - type SectionHeader: SectionHeader<Word = Self::Word>; - type Symbol: Symbol<Word = Self::Word>; - type FileAux: FileAux; - type CsectAux: CsectAux; - - /// Return true if this type is a 64-bit header. - fn is_type_64(&self) -> bool; - - fn f_magic(&self) -> u16; - fn f_nscns(&self) -> u16; - fn f_timdat(&self) -> u32; - fn f_symptr(&self) -> Self::Word; - fn f_nsyms(&self) -> u32; - fn f_opthdr(&self) -> u16; - fn f_flags(&self) -> u16; - - // Provided methods. - - /// Read the file header. - /// - /// Also checks that the magic field in the file header is a supported format. - fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> Result<&'data Self> { - let header = data - .read::<Self>(offset) - .read_error("Invalid XCOFF header size or alignment")?; - if !header.is_supported() { - return Err(Error("Unsupported XCOFF header")); - } - Ok(header) - } - - fn is_supported(&self) -> bool { - (self.is_type_64() && self.f_magic() == xcoff::MAGIC_64) - || (!self.is_type_64() && self.f_magic() == xcoff::MAGIC_32) - } - - /// Read the auxiliary file header. - fn aux_header<'data, R: ReadRef<'data>>( - &self, - data: R, - offset: &mut u64, - ) -> Result<Option<&'data Self::AuxHeader>> { - let aux_header_size = self.f_opthdr(); - if self.f_flags() & xcoff::F_EXEC == 0 { - // No auxiliary header is required for an object file that is not an executable. - // TODO: Some AIX programs generate auxiliary headers for 32-bit object files - // that end after the data_start field. - *offset += u64::from(aux_header_size); - return Ok(None); - } - // Executables, however, must have auxiliary headers that include the - // full structure definitions. - if aux_header_size != mem::size_of::<Self::AuxHeader>() as u16 { - *offset += u64::from(aux_header_size); - return Ok(None); - } - let aux_header = data - .read::<Self::AuxHeader>(offset) - .read_error("Invalid XCOFF auxiliary header size")?; - Ok(Some(aux_header)) - } - - /// Read the section table. - #[inline] - fn sections<'data, R: ReadRef<'data>>( - &self, - data: R, - offset: &mut u64, - ) -> Result<SectionTable<'data, Self>> { - SectionTable::parse(self, data, offset) - } - - /// Return the symbol table. - #[inline] - fn symbols<'data, R: ReadRef<'data>>(&self, data: R) -> Result<SymbolTable<'data, Self, R>> { - SymbolTable::parse(*self, data) - } -} - -impl FileHeader for xcoff::FileHeader32 { - type Word = u32; - type AuxHeader = xcoff::AuxHeader32; - type SectionHeader = xcoff::SectionHeader32; - type Symbol = xcoff::Symbol32; - type FileAux = xcoff::FileAux32; - type CsectAux = xcoff::CsectAux32; - - fn is_type_64(&self) -> bool { - false - } - - fn f_magic(&self) -> u16 { - self.f_magic.get(BE) - } - - fn f_nscns(&self) -> u16 { - self.f_nscns.get(BE) - } - - fn f_timdat(&self) -> u32 { - self.f_timdat.get(BE) - } - - fn f_symptr(&self) -> Self::Word { - self.f_symptr.get(BE) - } - - fn f_nsyms(&self) -> u32 { - self.f_nsyms.get(BE) - } - - fn f_opthdr(&self) -> u16 { - self.f_opthdr.get(BE) - } - - fn f_flags(&self) -> u16 { - self.f_flags.get(BE) - } -} - -impl FileHeader for xcoff::FileHeader64 { - type Word = u64; - type AuxHeader = xcoff::AuxHeader64; - type SectionHeader = xcoff::SectionHeader64; - type Symbol = xcoff::Symbol64; - type FileAux = xcoff::FileAux64; - type CsectAux = xcoff::CsectAux64; - - fn is_type_64(&self) -> bool { - true - } - - fn f_magic(&self) -> u16 { - self.f_magic.get(BE) - } - - fn f_nscns(&self) -> u16 { - self.f_nscns.get(BE) - } - - fn f_timdat(&self) -> u32 { - self.f_timdat.get(BE) - } - - fn f_symptr(&self) -> Self::Word { - self.f_symptr.get(BE) - } - - fn f_nsyms(&self) -> u32 { - self.f_nsyms.get(BE) - } - - fn f_opthdr(&self) -> u16 { - self.f_opthdr.get(BE) - } - - fn f_flags(&self) -> u16 { - self.f_flags.get(BE) - } -} - -#[allow(missing_docs)] -pub trait AuxHeader: Debug + Pod { - type Word: Into<u64>; - - fn o_vstamp(&self) -> u16; - fn o_tsize(&self) -> Self::Word; - fn o_dsize(&self) -> Self::Word; - fn o_bsize(&self) -> Self::Word; - fn o_entry(&self) -> Self::Word; - fn o_text_start(&self) -> Self::Word; - fn o_data_start(&self) -> Self::Word; - fn o_toc(&self) -> Self::Word; - fn o_snentry(&self) -> u16; - fn o_sntext(&self) -> u16; - fn o_sndata(&self) -> u16; - fn o_sntoc(&self) -> u16; - fn o_snloader(&self) -> u16; - fn o_snbss(&self) -> u16; - fn o_sntdata(&self) -> u16; - fn o_sntbss(&self) -> u16; - fn o_algntext(&self) -> u16; - fn o_algndata(&self) -> u16; - fn o_maxstack(&self) -> Self::Word; - fn o_maxdata(&self) -> Self::Word; - fn o_textpsize(&self) -> u8; - fn o_datapsize(&self) -> u8; - fn o_stackpsize(&self) -> u8; -} - -impl AuxHeader for xcoff::AuxHeader32 { - type Word = u32; - - fn o_vstamp(&self) -> u16 { - self.o_vstamp.get(BE) - } - - fn o_tsize(&self) -> Self::Word { - self.o_tsize.get(BE) - } - - fn o_dsize(&self) -> Self::Word { - self.o_dsize.get(BE) - } - - fn o_bsize(&self) -> Self::Word { - self.o_bsize.get(BE) - } - - fn o_entry(&self) -> Self::Word { - self.o_entry.get(BE) - } - - fn o_text_start(&self) -> Self::Word { - self.o_text_start.get(BE) - } - - fn o_data_start(&self) -> Self::Word { - self.o_data_start.get(BE) - } - - fn o_toc(&self) -> Self::Word { - self.o_toc.get(BE) - } - - fn o_snentry(&self) -> u16 { - self.o_snentry.get(BE) - } - - fn o_sntext(&self) -> u16 { - self.o_sntext.get(BE) - } - - fn o_sndata(&self) -> u16 { - self.o_sndata.get(BE) - } - - fn o_sntoc(&self) -> u16 { - self.o_sntoc.get(BE) - } - - fn o_snloader(&self) -> u16 { - self.o_snloader.get(BE) - } - - fn o_snbss(&self) -> u16 { - self.o_snbss.get(BE) - } - - fn o_sntdata(&self) -> u16 { - self.o_sntdata.get(BE) - } - - fn o_sntbss(&self) -> u16 { - self.o_sntbss.get(BE) - } - - fn o_algntext(&self) -> u16 { - self.o_algntext.get(BE) - } - - fn o_algndata(&self) -> u16 { - self.o_algndata.get(BE) - } - - fn o_maxstack(&self) -> Self::Word { - self.o_maxstack.get(BE) - } - - fn o_maxdata(&self) -> Self::Word { - self.o_maxdata.get(BE) - } - - fn o_textpsize(&self) -> u8 { - self.o_textpsize - } - - fn o_datapsize(&self) -> u8 { - self.o_datapsize - } - - fn o_stackpsize(&self) -> u8 { - self.o_stackpsize - } -} - -impl AuxHeader for xcoff::AuxHeader64 { - type Word = u64; - - fn o_vstamp(&self) -> u16 { - self.o_vstamp.get(BE) - } - - fn o_tsize(&self) -> Self::Word { - self.o_tsize.get(BE) - } - - fn o_dsize(&self) -> Self::Word { - self.o_dsize.get(BE) - } - - fn o_bsize(&self) -> Self::Word { - self.o_bsize.get(BE) - } - - fn o_entry(&self) -> Self::Word { - self.o_entry.get(BE) - } - - fn o_text_start(&self) -> Self::Word { - self.o_text_start.get(BE) - } - - fn o_data_start(&self) -> Self::Word { - self.o_data_start.get(BE) - } - - fn o_toc(&self) -> Self::Word { - self.o_toc.get(BE) - } - - fn o_snentry(&self) -> u16 { - self.o_snentry.get(BE) - } - - fn o_sntext(&self) -> u16 { - self.o_sntext.get(BE) - } - - fn o_sndata(&self) -> u16 { - self.o_sndata.get(BE) - } - - fn o_sntoc(&self) -> u16 { - self.o_sntoc.get(BE) - } - - fn o_snloader(&self) -> u16 { - self.o_snloader.get(BE) - } - - fn o_snbss(&self) -> u16 { - self.o_snbss.get(BE) - } - - fn o_sntdata(&self) -> u16 { - self.o_sntdata.get(BE) - } - - fn o_sntbss(&self) -> u16 { - self.o_sntbss.get(BE) - } - - fn o_algntext(&self) -> u16 { - self.o_algntext.get(BE) - } - - fn o_algndata(&self) -> u16 { - self.o_algndata.get(BE) - } - - fn o_maxstack(&self) -> Self::Word { - self.o_maxstack.get(BE) - } - - fn o_maxdata(&self) -> Self::Word { - self.o_maxdata.get(BE) - } - - fn o_textpsize(&self) -> u8 { - self.o_textpsize - } - - fn o_datapsize(&self) -> u8 { - self.o_datapsize - } - - fn o_stackpsize(&self) -> u8 { - self.o_stackpsize - } -} diff --git a/vendor/object-0.31.1/src/read/xcoff/mod.rs b/vendor/object-0.31.1/src/read/xcoff/mod.rs deleted file mode 100644 index 136e31073..000000000 --- a/vendor/object-0.31.1/src/read/xcoff/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Support for reading AIX XCOFF files. -//! -//! Provides `XcoffFile` and related types which implement the `Object` trait. - -mod file; -pub use file::*; - -mod section; -pub use section::*; - -mod symbol; -pub use symbol::*; - -mod relocation; -pub use relocation::*; - -mod comdat; -pub use comdat::*; - -mod segment; -pub use segment::*; diff --git a/vendor/object-0.31.1/src/read/xcoff/relocation.rs b/vendor/object-0.31.1/src/read/xcoff/relocation.rs deleted file mode 100644 index 78c6acfc7..000000000 --- a/vendor/object-0.31.1/src/read/xcoff/relocation.rs +++ /dev/null @@ -1,127 +0,0 @@ -use alloc::fmt; -use core::fmt::Debug; -use core::slice; - -use crate::pod::Pod; -use crate::{xcoff, BigEndian as BE, Relocation}; - -use crate::read::{ReadRef, RelocationEncoding, RelocationKind, RelocationTarget, SymbolIndex}; - -use super::{FileHeader, SectionHeader, XcoffFile}; - -/// An iterator over the relocations in a `XcoffSection32`. -pub type XcoffRelocationIterator32<'data, 'file, R = &'data [u8]> = - XcoffRelocationIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the relocations in a `XcoffSection64`. -pub type XcoffRelocationIterator64<'data, 'file, R = &'data [u8]> = - XcoffRelocationIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator over the relocations in a `XcoffSection`. -pub struct XcoffRelocationIterator<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - #[allow(unused)] - pub(super) file: &'file XcoffFile<'data, Xcoff, R>, - pub(super) relocations: - slice::Iter<'data, <<Xcoff as FileHeader>::SectionHeader as SectionHeader>::Rel>, -} - -impl<'data, 'file, Xcoff, R> Iterator for XcoffRelocationIterator<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - type Item = (u64, Relocation); - - fn next(&mut self) -> Option<Self::Item> { - self.relocations.next().map(|relocation| { - let encoding = RelocationEncoding::Generic; - let (kind, addend) = match relocation.r_rtype() { - xcoff::R_POS - | xcoff::R_RL - | xcoff::R_RLA - | xcoff::R_BA - | xcoff::R_RBA - | xcoff::R_TLS => (RelocationKind::Absolute, 0), - xcoff::R_REL | xcoff::R_BR | xcoff::R_RBR => (RelocationKind::Relative, -4), - xcoff::R_TOC | xcoff::R_TOCL | xcoff::R_TOCU => (RelocationKind::Got, 0), - r_type => (RelocationKind::Xcoff(r_type), 0), - }; - let size = (relocation.r_rsize() & 0x3F) + 1; - let target = RelocationTarget::Symbol(SymbolIndex(relocation.r_symndx() as usize)); - ( - relocation.r_vaddr().into(), - Relocation { - kind, - encoding, - size, - target, - addend, - implicit_addend: true, - }, - ) - }) - } -} - -impl<'data, 'file, Xcoff, R> fmt::Debug for XcoffRelocationIterator<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("XcoffRelocationIterator").finish() - } -} - -/// A trait for generic access to `Rel32` and `Rel64`. -#[allow(missing_docs)] -pub trait Rel: Debug + Pod { - type Word: Into<u64>; - fn r_vaddr(&self) -> Self::Word; - fn r_symndx(&self) -> u32; - fn r_rsize(&self) -> u8; - fn r_rtype(&self) -> u8; -} - -impl Rel for xcoff::Rel32 { - type Word = u32; - - fn r_vaddr(&self) -> Self::Word { - self.r_vaddr.get(BE) - } - - fn r_symndx(&self) -> u32 { - self.r_symndx.get(BE) - } - - fn r_rsize(&self) -> u8 { - self.r_rsize - } - - fn r_rtype(&self) -> u8 { - self.r_rtype - } -} - -impl Rel for xcoff::Rel64 { - type Word = u64; - - fn r_vaddr(&self) -> Self::Word { - self.r_vaddr.get(BE) - } - - fn r_symndx(&self) -> u32 { - self.r_symndx.get(BE) - } - - fn r_rsize(&self) -> u8 { - self.r_rsize - } - - fn r_rtype(&self) -> u8 { - self.r_rtype - } -} diff --git a/vendor/object-0.31.1/src/read/xcoff/section.rs b/vendor/object-0.31.1/src/read/xcoff/section.rs deleted file mode 100644 index 77453fcd2..000000000 --- a/vendor/object-0.31.1/src/read/xcoff/section.rs +++ /dev/null @@ -1,427 +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 over the sections of an `XcoffFile32`. -pub type XcoffSectionIterator32<'data, 'file, R = &'data [u8]> = - XcoffSectionIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the sections of an `XcoffFile64`. -pub type XcoffSectionIterator64<'data, 'file, R = &'data [u8]> = - XcoffSectionIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator over the sections of 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 of an `XcoffFile32`. -pub type XcoffSection32<'data, 'file, R = &'data [u8]> = - XcoffSection<'data, 'file, xcoff::FileHeader32, R>; -/// A section of an `XcoffFile64`. -pub type XcoffSection64<'data, 'file, R = &'data [u8]> = - XcoffSection<'data, 'file, xcoff::FileHeader64, R>; - -/// A section of an `XcoffFile`. -#[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. -#[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 `SectionHeader32` and `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") - } -} diff --git a/vendor/object-0.31.1/src/read/xcoff/segment.rs b/vendor/object-0.31.1/src/read/xcoff/segment.rs deleted file mode 100644 index 7eca72367..000000000 --- a/vendor/object-0.31.1/src/read/xcoff/segment.rs +++ /dev/null @@ -1,113 +0,0 @@ -//! TODO: Support the segment for XCOFF when auxiliary file header and loader section is ready. - -use core::fmt::Debug; -use core::str; - -use crate::read::{self, ObjectSegment, ReadRef, Result}; -use crate::xcoff; - -use super::{FileHeader, XcoffFile}; - -/// An iterator over the segments of an `XcoffFile32`. -pub type XcoffSegmentIterator32<'data, 'file, R = &'data [u8]> = - XcoffSegmentIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the segments of an `XcoffFile64`. -pub type XcoffSegmentIterator64<'data, 'file, R = &'data [u8]> = - XcoffSegmentIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator over the segments of an `XcoffFile`. -#[derive(Debug)] -pub struct XcoffSegmentIterator<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - #[allow(unused)] - pub(super) file: &'file XcoffFile<'data, Xcoff, R>, -} - -impl<'data, 'file, Xcoff, R> Iterator for XcoffSegmentIterator<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - type Item = XcoffSegment<'data, 'file, Xcoff, R>; - - fn next(&mut self) -> Option<Self::Item> { - None - } -} - -/// A segment of an `XcoffFile32`. -pub type XcoffSegment32<'data, 'file, R = &'data [u8]> = - XcoffSegment<'data, 'file, xcoff::FileHeader32, R>; -/// A segment of an `XcoffFile64`. -pub type XcoffSegment64<'data, 'file, R = &'data [u8]> = - XcoffSegment<'data, 'file, xcoff::FileHeader64, R>; - -/// A loadable section of an `XcoffFile`. -#[derive(Debug)] -pub struct XcoffSegment<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - #[allow(unused)] - pub(super) file: &'file XcoffFile<'data, Xcoff, R>, -} - -impl<'data, 'file, Xcoff, R> XcoffSegment<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffSegment<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Xcoff, R> ObjectSegment<'data> for XcoffSegment<'data, 'file, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - fn address(&self) -> u64 { - unreachable!(); - } - - fn size(&self) -> u64 { - unreachable!(); - } - - fn align(&self) -> u64 { - unreachable!(); - } - - fn file_range(&self) -> (u64, u64) { - unreachable!(); - } - - fn data(&self) -> Result<&'data [u8]> { - unreachable!(); - } - - fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> { - unreachable!(); - } - - fn name_bytes(&self) -> Result<Option<&[u8]>> { - unreachable!(); - } - - fn name(&self) -> Result<Option<&str>> { - unreachable!(); - } - - fn flags(&self) -> crate::SegmentFlags { - unreachable!(); - } -} diff --git a/vendor/object-0.31.1/src/read/xcoff/symbol.rs b/vendor/object-0.31.1/src/read/xcoff/symbol.rs deleted file mode 100644 index 7ce215fac..000000000 --- a/vendor/object-0.31.1/src/read/xcoff/symbol.rs +++ /dev/null @@ -1,695 +0,0 @@ -use alloc::fmt; -use core::convert::TryInto; -use core::fmt::Debug; -use core::marker::PhantomData; -use core::str; - -use crate::endian::{BigEndian as BE, U32Bytes}; -use crate::pod::{bytes_of, Pod}; -use crate::read::util::StringTable; -use crate::xcoff; - -use crate::read::{ - self, Bytes, Error, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex, - SymbolFlags, SymbolIndex, SymbolKind, SymbolScope, SymbolSection, -}; - -use super::{FileHeader, XcoffFile}; - -/// A table of symbol entries in an XCOFF file. -/// -/// Also includes the string table used for the symbol names. -#[derive(Debug)] -pub struct SymbolTable<'data, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - symbols: &'data [xcoff::SymbolBytes], - strings: StringTable<'data, R>, - header: PhantomData<Xcoff>, -} - -impl<'data, Xcoff, R> Default for SymbolTable<'data, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - fn default() -> Self { - Self { - symbols: &[], - strings: StringTable::default(), - header: PhantomData, - } - } -} - -impl<'data, Xcoff, R> SymbolTable<'data, Xcoff, R> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - /// Parse the symbol table. - pub fn parse(header: Xcoff, data: R) -> Result<Self> { - let mut offset = header.f_symptr().into(); - let (symbols, strings) = if offset != 0 { - let symbols = data - .read_slice(&mut offset, header.f_nsyms() as usize) - .read_error("Invalid XCOFF symbol table offset or size")?; - - // Parse the string table. - // Note: don't update data when reading length; the length includes itself. - let length = data - .read_at::<U32Bytes<_>>(offset) - .read_error("Missing XCOFF string table")? - .get(BE); - let str_end = offset - .checked_add(length as u64) - .read_error("Invalid XCOFF string table length")?; - let strings = StringTable::new(data, offset, str_end); - - (symbols, strings) - } else { - (&[][..], StringTable::default()) - }; - - Ok(SymbolTable { - symbols, - strings, - header: PhantomData, - }) - } - - /// Return the symbol entry at the given index and offset. - pub fn get<T: Pod>(&self, index: usize, offset: usize) -> Result<&'data T> { - let entry = index - .checked_add(offset) - .and_then(|x| self.symbols.get(x)) - .read_error("Invalid XCOFF symbol index")?; - let bytes = bytes_of(entry); - Bytes(bytes).read().read_error("Invalid XCOFF symbol data") - } - - /// Return the symbol at the given index. - pub fn symbol(&self, index: usize) -> Result<&'data Xcoff::Symbol> { - self.get::<Xcoff::Symbol>(index, 0) - } - - /// Return a file auxiliary symbol. - pub fn aux_file(&self, index: usize, offset: usize) -> Result<&'data Xcoff::FileAux> { - debug_assert!(self.symbol(index)?.has_aux_file()); - let aux_file = self.get::<Xcoff::FileAux>(index, offset)?; - if let Some(aux_type) = aux_file.x_auxtype() { - if aux_type != xcoff::AUX_FILE { - return Err(Error("Invalid index for file auxiliary symbol.")); - } - } - Ok(aux_file) - } - - /// Return the csect auxiliary symbol. - pub fn aux_csect(&self, index: usize, offset: usize) -> Result<&'data Xcoff::CsectAux> { - debug_assert!(self.symbol(index)?.has_aux_csect()); - let aux_csect = self.get::<Xcoff::CsectAux>(index, offset)?; - if let Some(aux_type) = aux_csect.x_auxtype() { - if aux_type != xcoff::AUX_CSECT { - return Err(Error("Invalid index/offset for csect auxiliary symbol.")); - } - } - Ok(aux_csect) - } - - /// Return true if the symbol table is empty. - #[inline] - pub fn is_empty(&self) -> bool { - self.symbols.is_empty() - } - - /// The number of symbol table entries. - /// - /// This includes auxiliary symbol table entries. - #[inline] - pub fn len(&self) -> usize { - self.symbols.len() - } -} - -/// A symbol table of an `XcoffFile32`. -pub type XcoffSymbolTable32<'data, 'file, R = &'data [u8]> = - XcoffSymbolTable<'data, 'file, xcoff::FileHeader32, R>; -/// A symbol table of an `XcoffFile64`. -pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> = - XcoffSymbolTable<'data, 'file, xcoff::FileHeader64, R>; - -/// A symbol table of an `XcoffFile`. -#[derive(Debug, Clone, Copy)] -pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, - pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>, -} - -impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed - for XcoffSymbolTable<'data, 'file, Xcoff, R> -{ -} - -impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data> - for XcoffSymbolTable<'data, 'file, Xcoff, R> -{ - type Symbol = XcoffSymbol<'data, 'file, Xcoff, R>; - type SymbolIterator = XcoffSymbolIterator<'data, 'file, Xcoff, R>; - - fn symbols(&self) -> Self::SymbolIterator { - XcoffSymbolIterator { - file: self.file, - symbols: self.symbols, - index: 0, - } - } - - fn symbol_by_index(&self, index: SymbolIndex) -> read::Result<Self::Symbol> { - let symbol = self.symbols.symbol(index.0)?; - Ok(XcoffSymbol { - file: self.file, - symbols: self.symbols, - index, - symbol, - }) - } -} - -/// An iterator over the symbols of an `XcoffFile32`. -pub type XcoffSymbolIterator32<'data, 'file, R = &'data [u8]> = - XcoffSymbolIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the symbols of an `XcoffFile64`. -pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> = - XcoffSymbolIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator over the symbols of an `XcoffFile`. -pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, - pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>, - pub(super) index: usize, -} - -impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> fmt::Debug - for XcoffSymbolIterator<'data, 'file, Xcoff, R> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("XcoffSymbolIterator").finish() - } -} - -impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> Iterator - for XcoffSymbolIterator<'data, 'file, Xcoff, R> -{ - type Item = XcoffSymbol<'data, 'file, Xcoff, R>; - - fn next(&mut self) -> Option<Self::Item> { - let index = self.index; - let symbol = self.symbols.symbol(index).ok()?; - // TODO: skip over the auxiliary symbols for now. - self.index += 1 + symbol.n_numaux() as usize; - Some(XcoffSymbol { - file: self.file, - symbols: self.symbols, - index: SymbolIndex(index), - symbol, - }) - } -} - -/// A symbol of an `XcoffFile32`. -pub type XcoffSymbol32<'data, 'file, R = &'data [u8]> = - XcoffSymbol<'data, 'file, xcoff::FileHeader32, R>; -/// A symbol of an `XcoffFile64`. -pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> = - XcoffSymbol<'data, 'file, xcoff::FileHeader64, R>; - -/// A symbol of an `XcoffFile`. -#[derive(Debug, Clone, Copy)] -pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]> -where - Xcoff: FileHeader, - R: ReadRef<'data>, -{ - pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, - pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>, - pub(super) index: SymbolIndex, - pub(super) symbol: &'data Xcoff::Symbol, -} - -impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed - for XcoffSymbol<'data, 'file, Xcoff, R> -{ -} - -impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> - for XcoffSymbol<'data, 'file, Xcoff, R> -{ - #[inline] - fn index(&self) -> SymbolIndex { - self.index - } - - fn name_bytes(&self) -> Result<&'data [u8]> { - if self.symbol.has_aux_file() { - // By convention the file name is in the first auxiliary entry. - self.symbols - .aux_file(self.index.0, 1)? - .fname(self.symbols.strings) - } else { - self.symbol.name(self.symbols.strings) - } - } - - fn name(&self) -> Result<&'data str> { - let name = self.name_bytes()?; - str::from_utf8(name) - .ok() - .read_error("Non UTF-8 XCOFF symbol name") - } - - #[inline] - fn address(&self) -> u64 { - match self.symbol.n_sclass() { - // Relocatable address. - xcoff::C_EXT - | xcoff::C_WEAKEXT - | xcoff::C_HIDEXT - | xcoff::C_FCN - | xcoff::C_BLOCK - | xcoff::C_STAT - | xcoff::C_INFO => self.symbol.n_value().into(), - _ => 0, - } - } - - #[inline] - fn size(&self) -> u64 { - if self.symbol.has_aux_csect() { - // XCOFF32 must have the csect auxiliary entry as the last auxiliary entry. - // XCOFF64 doesn't require this, but conventionally does. - if let Ok(aux_csect) = self - .file - .symbols - .aux_csect(self.index.0, self.symbol.n_numaux() as usize) - { - let sym_type = aux_csect.sym_type() & 0x07; - if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM { - return aux_csect.x_scnlen(); - } - } - } - 0 - } - - fn kind(&self) -> SymbolKind { - if self.symbol.has_aux_csect() { - if let Ok(aux_csect) = self - .file - .symbols - .aux_csect(self.index.0, self.symbol.n_numaux() as usize) - { - let sym_type = aux_csect.sym_type() & 0x07; - if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM { - return match aux_csect.x_smclas() { - xcoff::XMC_PR | xcoff::XMC_GL => SymbolKind::Text, - xcoff::XMC_RO | xcoff::XMC_RW | xcoff::XMC_TD | xcoff::XMC_BS => { - SymbolKind::Data - } - xcoff::XMC_TL | xcoff::XMC_UL => SymbolKind::Tls, - xcoff::XMC_DS | xcoff::XMC_TC0 | xcoff::XMC_TC => { - // `Metadata` might be a better kind for these if we had it. - SymbolKind::Data - } - _ => SymbolKind::Unknown, - }; - } else if sym_type == xcoff::XTY_LD { - // A function entry point. Neither `Text` nor `Label` are a good fit for this. - return SymbolKind::Text; - } else if sym_type == xcoff::XTY_ER { - return SymbolKind::Unknown; - } - } - } - match self.symbol.n_sclass() { - xcoff::C_NULL => SymbolKind::Null, - xcoff::C_FILE => SymbolKind::File, - _ => SymbolKind::Unknown, - } - } - - fn section(&self) -> SymbolSection { - match self.symbol.n_scnum() { - xcoff::N_ABS => SymbolSection::Absolute, - xcoff::N_UNDEF => SymbolSection::Undefined, - xcoff::N_DEBUG => SymbolSection::None, - index if index > 0 => SymbolSection::Section(SectionIndex(index as usize)), - _ => SymbolSection::Unknown, - } - } - - #[inline] - fn is_undefined(&self) -> bool { - self.symbol.is_undefined() - } - - /// Return true if the symbol is a definition of a function or data object. - #[inline] - fn is_definition(&self) -> bool { - if self.symbol.has_aux_csect() { - if let Ok(aux_csect) = self - .symbols - .aux_csect(self.index.0, self.symbol.n_numaux() as usize) - { - let smclas = aux_csect.x_smclas(); - self.symbol.n_scnum() != xcoff::N_UNDEF - && (smclas == xcoff::XMC_PR - || smclas == xcoff::XMC_RW - || smclas == xcoff::XMC_RO) - } else { - false - } - } else { - false - } - } - - #[inline] - fn is_common(&self) -> bool { - self.symbol.n_sclass() == xcoff::C_EXT && self.symbol.n_scnum() == xcoff::N_UNDEF - } - - #[inline] - fn is_weak(&self) -> bool { - self.symbol.n_sclass() == xcoff::C_WEAKEXT - } - - fn scope(&self) -> SymbolScope { - if self.symbol.n_scnum() == xcoff::N_UNDEF { - SymbolScope::Unknown - } else { - match self.symbol.n_sclass() { - xcoff::C_EXT | xcoff::C_WEAKEXT | xcoff::C_HIDEXT => { - let visibility = self.symbol.n_type() & xcoff::SYM_V_MASK; - if visibility == xcoff::SYM_V_HIDDEN { - SymbolScope::Linkage - } else { - SymbolScope::Dynamic - } - } - _ => SymbolScope::Compilation, - } - } - } - - #[inline] - fn is_global(&self) -> bool { - match self.symbol.n_sclass() { - xcoff::C_EXT | xcoff::C_WEAKEXT => true, - _ => false, - } - } - - #[inline] - fn is_local(&self) -> bool { - !self.is_global() - } - - #[inline] - fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> { - let mut x_smtyp = 0; - let mut x_smclas = 0; - let mut containing_csect = None; - if self.symbol.has_aux_csect() { - if let Ok(aux_csect) = self - .file - .symbols - .aux_csect(self.index.0, self.symbol.n_numaux() as usize) - { - x_smtyp = aux_csect.x_smtyp(); - x_smclas = aux_csect.x_smclas(); - if x_smtyp == xcoff::XTY_LD { - containing_csect = Some(SymbolIndex(aux_csect.x_scnlen() as usize)) - } - } - } - SymbolFlags::Xcoff { - n_sclass: self.symbol.n_sclass(), - x_smtyp, - x_smclas, - containing_csect, - } - } -} - -/// A trait for generic access to `Symbol32` and `Symbol64`. -#[allow(missing_docs)] -pub trait Symbol: Debug + Pod { - type Word: Into<u64>; - - fn n_value(&self) -> Self::Word; - fn n_scnum(&self) -> i16; - fn n_type(&self) -> u16; - fn n_sclass(&self) -> u8; - fn n_numaux(&self) -> u8; - - fn name<'data, R: ReadRef<'data>>( - &'data self, - strings: StringTable<'data, R>, - ) -> Result<&'data [u8]>; - - /// Return true if the symbol is undefined. - #[inline] - fn is_undefined(&self) -> bool { - let n_sclass = self.n_sclass(); - (n_sclass == xcoff::C_EXT || n_sclass == xcoff::C_WEAKEXT) - && self.n_scnum() == xcoff::N_UNDEF - } - - /// Return true if the symbol has file auxiliary entry. - fn has_aux_file(&self) -> bool { - self.n_numaux() > 0 && self.n_sclass() == xcoff::C_FILE - } - - /// Return true if the symbol has csect auxiliary entry. - /// - /// A csect auxiliary entry is required for each symbol table entry that has - /// a storage class value of C_EXT, C_WEAKEXT, or C_HIDEXT. - fn has_aux_csect(&self) -> bool { - let sclass = self.n_sclass(); - self.n_numaux() > 0 - && (sclass == xcoff::C_EXT || sclass == xcoff::C_WEAKEXT || sclass == xcoff::C_HIDEXT) - } -} - -impl Symbol for xcoff::Symbol64 { - type Word = u64; - - fn n_value(&self) -> Self::Word { - self.n_value.get(BE) - } - - fn n_scnum(&self) -> i16 { - self.n_scnum.get(BE) - } - - fn n_type(&self) -> u16 { - self.n_type.get(BE) - } - - fn n_sclass(&self) -> u8 { - self.n_sclass - } - - fn n_numaux(&self) -> u8 { - self.n_numaux - } - - /// Parse the symbol name for XCOFF64. - fn name<'data, R: ReadRef<'data>>( - &'data self, - strings: StringTable<'data, R>, - ) -> Result<&'data [u8]> { - strings - .get(self.n_offset.get(BE)) - .read_error("Invalid XCOFF symbol name offset") - } -} - -impl Symbol for xcoff::Symbol32 { - type Word = u32; - - fn n_value(&self) -> Self::Word { - self.n_value.get(BE) - } - - fn n_scnum(&self) -> i16 { - self.n_scnum.get(BE) - } - - fn n_type(&self) -> u16 { - self.n_type.get(BE) - } - - fn n_sclass(&self) -> u8 { - self.n_sclass - } - - fn n_numaux(&self) -> u8 { - self.n_numaux - } - - /// Parse the symbol name for XCOFF32. - fn name<'data, R: ReadRef<'data>>( - &'data self, - strings: StringTable<'data, R>, - ) -> Result<&'data [u8]> { - if self.n_name[0] == 0 { - // If the name starts with 0 then the last 4 bytes are a string table offset. - let offset = u32::from_be_bytes(self.n_name[4..8].try_into().unwrap()); - strings - .get(offset) - .read_error("Invalid XCOFF symbol name offset") - } else { - // The name is inline and padded with nulls. - Ok(match memchr::memchr(b'\0', &self.n_name) { - Some(end) => &self.n_name[..end], - None => &self.n_name, - }) - } - } -} - -/// A trait for generic access to `FileAux32` and `FileAux64`. -#[allow(missing_docs)] -pub trait FileAux: Debug + Pod { - fn x_fname(&self) -> &[u8; 8]; - fn x_ftype(&self) -> u8; - fn x_auxtype(&self) -> Option<u8>; - - /// Parse the x_fname field, which may be an inline string or a string table offset. - fn fname<'data, R: ReadRef<'data>>( - &'data self, - strings: StringTable<'data, R>, - ) -> Result<&'data [u8]> { - let x_fname = self.x_fname(); - if x_fname[0] == 0 { - // If the name starts with 0 then the last 4 bytes are a string table offset. - let offset = u32::from_be_bytes(x_fname[4..8].try_into().unwrap()); - strings - .get(offset) - .read_error("Invalid XCOFF symbol name offset") - } else { - // The name is inline and padded with nulls. - Ok(match memchr::memchr(b'\0', x_fname) { - Some(end) => &x_fname[..end], - None => x_fname, - }) - } - } -} - -impl FileAux for xcoff::FileAux64 { - fn x_fname(&self) -> &[u8; 8] { - &self.x_fname - } - - fn x_ftype(&self) -> u8 { - self.x_ftype - } - - fn x_auxtype(&self) -> Option<u8> { - Some(self.x_auxtype) - } -} - -impl FileAux for xcoff::FileAux32 { - fn x_fname(&self) -> &[u8; 8] { - &self.x_fname - } - - fn x_ftype(&self) -> u8 { - self.x_ftype - } - - fn x_auxtype(&self) -> Option<u8> { - None - } -} - -/// A trait for generic access to `CsectAux32` and `CsectAux64`. -#[allow(missing_docs)] -pub trait CsectAux: Debug + Pod { - fn x_scnlen(&self) -> u64; - fn x_parmhash(&self) -> u32; - fn x_snhash(&self) -> u16; - fn x_smtyp(&self) -> u8; - fn x_smclas(&self) -> u8; - fn x_auxtype(&self) -> Option<u8>; - - fn sym_type(&self) -> u8 { - self.x_smtyp() & 0x07 - } -} - -impl CsectAux for xcoff::CsectAux64 { - fn x_scnlen(&self) -> u64 { - self.x_scnlen_lo.get(BE) as u64 | ((self.x_scnlen_hi.get(BE) as u64) << 32) - } - - fn x_parmhash(&self) -> u32 { - self.x_parmhash.get(BE) - } - - fn x_snhash(&self) -> u16 { - self.x_snhash.get(BE) - } - - fn x_smtyp(&self) -> u8 { - self.x_smtyp - } - - fn x_smclas(&self) -> u8 { - self.x_smclas - } - - fn x_auxtype(&self) -> Option<u8> { - Some(self.x_auxtype) - } -} - -impl CsectAux for xcoff::CsectAux32 { - fn x_scnlen(&self) -> u64 { - self.x_scnlen.get(BE) as u64 - } - - fn x_parmhash(&self) -> u32 { - self.x_parmhash.get(BE) - } - - fn x_snhash(&self) -> u16 { - self.x_snhash.get(BE) - } - - fn x_smtyp(&self) -> u8 { - self.x_smtyp - } - - fn x_smclas(&self) -> u8 { - self.x_smclas - } - - fn x_auxtype(&self) -> Option<u8> { - None - } -} |