aboutsummaryrefslogtreecommitdiff
path: root/vendor/object/src/read/coff/file.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/read/coff/file.rs')
-rw-r--r--vendor/object/src/read/coff/file.rs381
1 files changed, 0 insertions, 381 deletions
diff --git a/vendor/object/src/read/coff/file.rs b/vendor/object/src/read/coff/file.rs
deleted file mode 100644
index 40b9e70..0000000
--- a/vendor/object/src/read/coff/file.rs
+++ /dev/null
@@ -1,381 +0,0 @@
-use alloc::vec::Vec;
-use core::fmt::Debug;
-
-use crate::read::{
- self, Architecture, Export, FileFlags, Import, NoDynamicRelocationIterator, Object, ObjectKind,
- ObjectSection, ReadError, ReadRef, Result, SectionIndex, SubArchitecture, SymbolIndex,
-};
-use crate::{pe, LittleEndian as LE, Pod};
-
-use super::{
- CoffComdat, CoffComdatIterator, CoffSection, CoffSectionIterator, CoffSegment,
- CoffSegmentIterator, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, ImageSymbol,
- SectionTable, SymbolTable,
-};
-
-/// The common parts of `PeFile` and `CoffFile`.
-#[derive(Debug)]
-pub(crate) struct CoffCommon<'data, R: ReadRef<'data>, Coff: CoffHeader = pe::ImageFileHeader> {
- pub(crate) sections: SectionTable<'data>,
- pub(crate) symbols: SymbolTable<'data, R, Coff>,
- pub(crate) image_base: u64,
-}
-
-/// A COFF bigobj object file with 32-bit section numbers.
-///
-/// This is a file that starts with [`pe::AnonObjectHeaderBigobj`], and corresponds
-/// to [`crate::FileKind::CoffBig`].
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-pub type CoffBigFile<'data, R = &'data [u8]> = CoffFile<'data, R, pe::AnonObjectHeaderBigobj>;
-
-/// A COFF object file.
-///
-/// This is a file that starts with [`pe::ImageFileHeader`], and corresponds
-/// to [`crate::FileKind::Coff`].
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-#[derive(Debug)]
-pub struct CoffFile<'data, R: ReadRef<'data> = &'data [u8], Coff: CoffHeader = pe::ImageFileHeader>
-{
- pub(super) header: &'data Coff,
- pub(super) common: CoffCommon<'data, R, Coff>,
- pub(super) data: R,
-}
-
-impl<'data, R: ReadRef<'data>, Coff: CoffHeader> CoffFile<'data, R, Coff> {
- /// Parse the raw COFF file data.
- pub fn parse(data: R) -> Result<Self> {
- let mut offset = 0;
- let header = Coff::parse(data, &mut offset)?;
- let sections = header.sections(data, offset)?;
- let symbols = header.symbols(data)?;
-
- Ok(CoffFile {
- header,
- common: CoffCommon {
- sections,
- symbols,
- image_base: 0,
- },
- data,
- })
- }
-}
-
-impl<'data, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
- for CoffFile<'data, R, Coff>
-{
-}
-
-impl<'data, 'file, R, Coff> Object<'data, 'file> for CoffFile<'data, R, Coff>
-where
- 'data: 'file,
- R: 'file + ReadRef<'data>,
- Coff: CoffHeader,
-{
- type Segment = CoffSegment<'data, 'file, R, Coff>;
- type SegmentIterator = CoffSegmentIterator<'data, 'file, R, Coff>;
- type Section = CoffSection<'data, 'file, R, Coff>;
- type SectionIterator = CoffSectionIterator<'data, 'file, R, Coff>;
- type Comdat = CoffComdat<'data, 'file, R, Coff>;
- type ComdatIterator = CoffComdatIterator<'data, 'file, R, Coff>;
- type Symbol = CoffSymbol<'data, 'file, R, Coff>;
- type SymbolIterator = CoffSymbolIterator<'data, 'file, R, Coff>;
- type SymbolTable = CoffSymbolTable<'data, 'file, R, Coff>;
- type DynamicRelocationIterator = NoDynamicRelocationIterator;
-
- fn architecture(&self) -> Architecture {
- match self.header.machine() {
- pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
- pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => Architecture::Aarch64,
- pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
- pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
- _ => Architecture::Unknown,
- }
- }
-
- fn sub_architecture(&self) -> Option<SubArchitecture> {
- match self.header.machine() {
- pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC),
- _ => None,
- }
- }
-
- #[inline]
- fn is_little_endian(&self) -> bool {
- true
- }
-
- #[inline]
- fn is_64(&self) -> bool {
- // Windows COFF is always 32-bit, even for 64-bit architectures. This could be confusing.
- false
- }
-
- fn kind(&self) -> ObjectKind {
- ObjectKind::Relocatable
- }
-
- fn segments(&'file self) -> CoffSegmentIterator<'data, 'file, R, Coff> {
- CoffSegmentIterator {
- file: self,
- iter: self.common.sections.iter(),
- }
- }
-
- fn section_by_name_bytes(
- &'file self,
- section_name: &[u8],
- ) -> Option<CoffSection<'data, 'file, R, Coff>> {
- self.sections()
- .find(|section| section.name_bytes() == Ok(section_name))
- }
-
- fn section_by_index(
- &'file self,
- index: SectionIndex,
- ) -> Result<CoffSection<'data, 'file, R, Coff>> {
- let section = self.common.sections.section(index.0)?;
- Ok(CoffSection {
- file: self,
- index,
- section,
- })
- }
-
- fn sections(&'file self) -> CoffSectionIterator<'data, 'file, R, Coff> {
- CoffSectionIterator {
- file: self,
- iter: self.common.sections.iter().enumerate(),
- }
- }
-
- fn comdats(&'file self) -> CoffComdatIterator<'data, 'file, R, Coff> {
- CoffComdatIterator {
- file: self,
- index: 0,
- }
- }
-
- fn symbol_by_index(
- &'file self,
- index: SymbolIndex,
- ) -> Result<CoffSymbol<'data, 'file, R, Coff>> {
- let symbol = self.common.symbols.symbol(index.0)?;
- Ok(CoffSymbol {
- file: &self.common,
- index,
- symbol,
- })
- }
-
- fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R, Coff> {
- CoffSymbolIterator {
- file: &self.common,
- index: 0,
- }
- }
-
- #[inline]
- fn symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R, Coff>> {
- Some(CoffSymbolTable { file: &self.common })
- }
-
- fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R, Coff> {
- CoffSymbolIterator {
- file: &self.common,
- // Hack: don't return any.
- index: self.common.symbols.len(),
- }
- }
-
- #[inline]
- fn dynamic_symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R, Coff>> {
- None
- }
-
- #[inline]
- fn dynamic_relocations(&'file self) -> Option<NoDynamicRelocationIterator> {
- None
- }
-
- #[inline]
- fn imports(&self) -> Result<Vec<Import<'data>>> {
- // TODO: this could return undefined symbols, but not needed yet.
- Ok(Vec::new())
- }
-
- #[inline]
- fn exports(&self) -> Result<Vec<Export<'data>>> {
- // TODO: this could return global symbols, but not needed yet.
- Ok(Vec::new())
- }
-
- fn has_debug_symbols(&self) -> bool {
- self.section_by_name(".debug_info").is_some()
- }
-
- fn relative_address_base(&self) -> u64 {
- 0
- }
-
- #[inline]
- fn entry(&self) -> u64 {
- 0
- }
-
- fn flags(&self) -> FileFlags {
- FileFlags::Coff {
- characteristics: self.header.characteristics(),
- }
- }
-}
-
-/// Read the `class_id` field from a [`pe::AnonObjectHeader`].
-///
-/// This can be used to determine the format of the header.
-pub fn anon_object_class_id<'data, R: ReadRef<'data>>(data: R) -> Result<pe::ClsId> {
- let header = data
- .read_at::<pe::AnonObjectHeader>(0)
- .read_error("Invalid anon object header size or alignment")?;
- Ok(header.class_id)
-}
-
-/// A trait for generic access to [`pe::ImageFileHeader`] and [`pe::AnonObjectHeaderBigobj`].
-#[allow(missing_docs)]
-pub trait CoffHeader: Debug + Pod {
- type ImageSymbol: ImageSymbol;
- type ImageSymbolBytes: Debug + Pod;
-
- /// Return true if this type is [`pe::AnonObjectHeaderBigobj`].
- ///
- /// This is a property of the type, not a value in the header data.
- fn is_type_bigobj() -> bool;
-
- fn machine(&self) -> u16;
- fn number_of_sections(&self) -> u32;
- fn pointer_to_symbol_table(&self) -> u32;
- fn number_of_symbols(&self) -> u32;
- fn characteristics(&self) -> u16;
-
- /// Read the file header.
- ///
- /// `data` must be the entire file data.
- /// `offset` must be the file header offset. It is updated to point after the optional header,
- /// which is where the section headers are located.
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self>;
-
- /// Read the section table.
- ///
- /// `data` must be the entire file data.
- /// `offset` must be after the optional file header.
- #[inline]
- fn sections<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- offset: u64,
- ) -> read::Result<SectionTable<'data>> {
- SectionTable::parse(self, data, offset)
- }
-
- /// Read the symbol table and string table.
- ///
- /// `data` must be the entire file data.
- #[inline]
- fn symbols<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- ) -> read::Result<SymbolTable<'data, R, Self>> {
- SymbolTable::parse(self, data)
- }
-}
-
-impl CoffHeader for pe::ImageFileHeader {
- type ImageSymbol = pe::ImageSymbol;
- type ImageSymbolBytes = pe::ImageSymbolBytes;
-
- fn is_type_bigobj() -> bool {
- false
- }
-
- fn machine(&self) -> u16 {
- self.machine.get(LE)
- }
-
- fn number_of_sections(&self) -> u32 {
- self.number_of_sections.get(LE).into()
- }
-
- fn pointer_to_symbol_table(&self) -> u32 {
- self.pointer_to_symbol_table.get(LE)
- }
-
- fn number_of_symbols(&self) -> u32 {
- self.number_of_symbols.get(LE)
- }
-
- fn characteristics(&self) -> u16 {
- self.characteristics.get(LE)
- }
-
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self> {
- let header = data
- .read::<pe::ImageFileHeader>(offset)
- .read_error("Invalid COFF file header size or alignment")?;
-
- // Skip over the optional header.
- *offset = offset
- .checked_add(header.size_of_optional_header.get(LE).into())
- .read_error("Invalid COFF optional header size")?;
-
- // TODO: maybe validate that the machine is known?
- Ok(header)
- }
-}
-
-impl CoffHeader for pe::AnonObjectHeaderBigobj {
- type ImageSymbol = pe::ImageSymbolEx;
- type ImageSymbolBytes = pe::ImageSymbolExBytes;
-
- fn is_type_bigobj() -> bool {
- true
- }
-
- fn machine(&self) -> u16 {
- self.machine.get(LE)
- }
-
- fn number_of_sections(&self) -> u32 {
- self.number_of_sections.get(LE)
- }
-
- fn pointer_to_symbol_table(&self) -> u32 {
- self.pointer_to_symbol_table.get(LE)
- }
-
- fn number_of_symbols(&self) -> u32 {
- self.number_of_symbols.get(LE)
- }
-
- fn characteristics(&self) -> u16 {
- 0
- }
-
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self> {
- let header = data
- .read::<pe::AnonObjectHeaderBigobj>(offset)
- .read_error("Invalid COFF bigobj file header size or alignment")?;
-
- if header.sig1.get(LE) != pe::IMAGE_FILE_MACHINE_UNKNOWN
- || header.sig2.get(LE) != 0xffff
- || header.version.get(LE) < 2
- || header.class_id != pe::ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID
- {
- return Err(read::Error("Invalid COFF bigobj header values"));
- }
-
- // TODO: maybe validate that the machine is known?
- Ok(header)
- }
-}