diff options
Diffstat (limited to 'vendor/object/src')
74 files changed, 0 insertions, 44300 deletions
diff --git a/vendor/object/src/archive.rs b/vendor/object/src/archive.rs deleted file mode 100644 index 6271d07..0000000 --- a/vendor/object/src/archive.rs +++ /dev/null @@ -1,91 +0,0 @@ -//! Archive definitions. -//! -//! These definitions are independent of read/write support, although we do implement -//! some traits useful for those. - -use crate::pod::Pod; - -/// File identification bytes stored at the beginning of the file. -pub const MAGIC: [u8; 8] = *b"!<arch>\n"; - -/// File identification bytes at the beginning of AIX big archive. -pub const AIX_BIG_MAGIC: [u8; 8] = *b"<bigaf>\n"; - -/// File identification bytes stored at the beginning of a thin archive. -/// -/// A thin archive only contains a symbol table and file names. -pub const THIN_MAGIC: [u8; 8] = *b"!<thin>\n"; - -/// The terminator for each archive member header. -pub const TERMINATOR: [u8; 2] = *b"`\n"; - -/// The header at the start of an archive member. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Header { -    /// The file name. -    pub name: [u8; 16], -    /// File modification timestamp in decimal. -    pub date: [u8; 12], -    /// User ID in decimal. -    pub uid: [u8; 6], -    /// Group ID in decimal. -    pub gid: [u8; 6], -    /// File mode in octal. -    pub mode: [u8; 8], -    /// File size in decimal. -    pub size: [u8; 10], -    /// Must be equal to `TERMINATOR`. -    pub terminator: [u8; 2], -} - -/// The header at the start of an AIX big archive member, without name. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AixHeader { -    /// File member size in decimal. -    pub size: [u8; 20], -    /// Next member offset in decimal. -    pub nxtmem: [u8; 20], -    /// Previous member offset in decimal. -    pub prvmem: [u8; 20], -    /// File member date in decimal. -    pub date: [u8; 12], -    /// File member user id in decimal. -    pub uid: [u8; 12], -    /// File member group id in decimal. -    pub gid: [u8; 12], -    /// File member mode in octal. -    pub mode: [u8; 12], -    /// File member name length in decimal. -    pub namlen: [u8; 4], -} - -/// The AIX big archive's fixed length header at file beginning. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AixFileHeader { -    /// Archive magic string. -    pub magic: [u8; 8], -    /// Offset of member table. -    pub memoff: [u8; 20], -    /// Offset of global symbol table. -    pub gstoff: [u8; 20], -    /// Offset of global symbol table for 64-bit objects. -    pub gst64off: [u8; 20], -    /// Offset of first member. -    pub fstmoff: [u8; 20], -    /// Offset of last member. -    pub lstmoff: [u8; 20], -    /// Offset of first member on free list. -    pub freeoff: [u8; 20], -} - -/// Offset of a member in an AIX big archive. -/// -/// This is used in the member index. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AixMemberOffset(pub [u8; 20]); - -unsafe_impl_pod!(Header, AixHeader, AixFileHeader, AixMemberOffset,); diff --git a/vendor/object/src/common.rs b/vendor/object/src/common.rs deleted file mode 100644 index 36f6656..0000000 --- a/vendor/object/src/common.rs +++ /dev/null @@ -1,536 +0,0 @@ -/// A CPU architecture. -#[allow(missing_docs)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum Architecture { -    Unknown, -    Aarch64, -    #[allow(non_camel_case_types)] -    Aarch64_Ilp32, -    Arm, -    Avr, -    Bpf, -    Csky, -    I386, -    X86_64, -    #[allow(non_camel_case_types)] -    X86_64_X32, -    Hexagon, -    LoongArch64, -    Mips, -    Mips64, -    Msp430, -    PowerPc, -    PowerPc64, -    Riscv32, -    Riscv64, -    S390x, -    Sbf, -    Sharc, -    Sparc64, -    Wasm32, -    Wasm64, -    Xtensa, -} - -/// A CPU sub-architecture. -#[allow(missing_docs)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SubArchitecture { -    Arm64E, -    Arm64EC, -} - -impl Architecture { -    /// The size of an address value for this architecture. -    /// -    /// Returns `None` for unknown architectures. -    pub fn address_size(self) -> Option<AddressSize> { -        match self { -            Architecture::Unknown => None, -            Architecture::Aarch64 => Some(AddressSize::U64), -            Architecture::Aarch64_Ilp32 => Some(AddressSize::U32), -            Architecture::Arm => Some(AddressSize::U32), -            Architecture::Avr => Some(AddressSize::U8), -            Architecture::Bpf => Some(AddressSize::U64), -            Architecture::Csky => Some(AddressSize::U32), -            Architecture::I386 => Some(AddressSize::U32), -            Architecture::X86_64 => Some(AddressSize::U64), -            Architecture::X86_64_X32 => Some(AddressSize::U32), -            Architecture::Hexagon => Some(AddressSize::U32), -            Architecture::LoongArch64 => Some(AddressSize::U64), -            Architecture::Mips => Some(AddressSize::U32), -            Architecture::Mips64 => Some(AddressSize::U64), -            Architecture::Msp430 => Some(AddressSize::U16), -            Architecture::PowerPc => Some(AddressSize::U32), -            Architecture::PowerPc64 => Some(AddressSize::U64), -            Architecture::Riscv32 => Some(AddressSize::U32), -            Architecture::Riscv64 => Some(AddressSize::U64), -            Architecture::S390x => Some(AddressSize::U64), -            Architecture::Sbf => Some(AddressSize::U64), -            Architecture::Sharc => Some(AddressSize::U32), -            Architecture::Sparc64 => Some(AddressSize::U64), -            Architecture::Wasm32 => Some(AddressSize::U32), -            Architecture::Wasm64 => Some(AddressSize::U64), -            Architecture::Xtensa => Some(AddressSize::U32), -        } -    } -} - -/// The size of an address value for an architecture. -/// -/// This may differ from the address size supported by the file format (such as for COFF). -#[allow(missing_docs)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -#[repr(u8)] -pub enum AddressSize { -    U8 = 1, -    U16 = 2, -    U32 = 4, -    U64 = 8, -} - -impl AddressSize { -    /// The size in bytes of an address value. -    #[inline] -    pub fn bytes(self) -> u8 { -        self as u8 -    } -} - -/// A binary file format. -#[allow(missing_docs)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum BinaryFormat { -    Coff, -    Elf, -    MachO, -    Pe, -    Wasm, -    Xcoff, -} - -/// The kind of a section. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SectionKind { -    /// The section kind is unknown. -    Unknown, -    /// An executable code section. -    /// -    /// Example ELF sections: `.text` -    /// -    /// Example Mach-O sections: `__TEXT/__text` -    Text, -    /// A data section. -    /// -    /// Example ELF sections: `.data` -    /// -    /// Example Mach-O sections: `__DATA/__data` -    Data, -    /// A read only data section. -    /// -    /// Example ELF sections: `.rodata` -    /// -    /// Example Mach-O sections: `__TEXT/__const`, `__DATA/__const`, `__TEXT/__literal4` -    ReadOnlyData, -    /// A read only data section with relocations. -    /// -    /// This is the same as either `Data` or `ReadOnlyData`, depending on the file format. -    /// This value is only used in the API for writing files. It is never returned when reading files. -    ReadOnlyDataWithRel, -    /// A loadable string section. -    /// -    /// Example ELF sections: `.rodata.str` -    /// -    /// Example Mach-O sections: `__TEXT/__cstring` -    ReadOnlyString, -    /// An uninitialized data section. -    /// -    /// Example ELF sections: `.bss` -    /// -    /// Example Mach-O sections: `__DATA/__bss` -    UninitializedData, -    /// An uninitialized common data section. -    /// -    /// Example Mach-O sections: `__DATA/__common` -    Common, -    /// A TLS data section. -    /// -    /// Example ELF sections: `.tdata` -    /// -    /// Example Mach-O sections: `__DATA/__thread_data` -    Tls, -    /// An uninitialized TLS data section. -    /// -    /// Example ELF sections: `.tbss` -    /// -    /// Example Mach-O sections: `__DATA/__thread_bss` -    UninitializedTls, -    /// A TLS variables section. -    /// -    /// This contains TLS variable structures, rather than the variable initializers. -    /// -    /// Example Mach-O sections: `__DATA/__thread_vars` -    TlsVariables, -    /// A non-loadable string section. -    /// -    /// Example ELF sections: `.comment`, `.debug_str` -    OtherString, -    /// Some other non-loadable section. -    /// -    /// Example ELF sections: `.debug_info` -    Other, -    /// Debug information. -    /// -    /// Example Mach-O sections: `__DWARF/__debug_info` -    Debug, -    /// Information for the linker. -    /// -    /// Example COFF sections: `.drectve` -    Linker, -    /// ELF note section. -    Note, -    /// Metadata such as symbols or relocations. -    /// -    /// Example ELF sections: `.symtab`, `.strtab`, `.group` -    Metadata, -    /// Some other ELF section type. -    /// -    /// This is the `sh_type` field in the section header. -    /// The meaning may be dependent on the architecture. -    Elf(u32), -} - -impl SectionKind { -    /// Return true if this section contains zerofill data. -    pub fn is_bss(self) -> bool { -        self == SectionKind::UninitializedData -            || self == SectionKind::UninitializedTls -            || self == SectionKind::Common -    } -} - -/// The selection kind for a COMDAT section group. -/// -/// This determines the way in which the linker resolves multiple definitions of the COMDAT -/// sections. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum ComdatKind { -    /// The selection kind is unknown. -    Unknown, -    /// Multiple definitions are allowed. -    /// -    /// An arbitrary definition is selected, and the rest are removed. -    /// -    /// This is the only supported selection kind for ELF. -    Any, -    /// Multiple definitions are not allowed. -    /// -    /// This is used to group sections without allowing duplicates. -    NoDuplicates, -    /// Multiple definitions must have the same size. -    /// -    /// An arbitrary definition is selected, and the rest are removed. -    SameSize, -    /// Multiple definitions must match exactly. -    /// -    /// An arbitrary definition is selected, and the rest are removed. -    ExactMatch, -    /// Multiple definitions are allowed, and the largest is selected. -    /// -    /// An arbitrary definition with the largest size is selected, and the rest are removed. -    Largest, -    /// Multiple definitions are allowed, and the newest is selected. -    Newest, -} - -/// The kind of a symbol. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SymbolKind { -    /// The symbol kind is unknown. -    Unknown, -    /// The symbol is a null placeholder. -    Null, -    /// The symbol is for executable code. -    Text, -    /// The symbol is for a data object. -    Data, -    /// The symbol is for a section. -    Section, -    /// The symbol is the name of a file. It precedes symbols within that file. -    File, -    /// The symbol is for a code label. -    Label, -    /// The symbol is for a thread local storage entity. -    Tls, -} - -/// A symbol scope. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum SymbolScope { -    /// Unknown scope. -    Unknown, -    /// Symbol is visible to the compilation unit. -    Compilation, -    /// Symbol is visible to the static linkage unit. -    Linkage, -    /// Symbol is visible to dynamically linked objects. -    Dynamic, -} - -/// The operation used to calculate the result of the relocation. -/// -/// The relocation descriptions use the following definitions. Note that -/// these definitions probably don't match any ELF ABI. -/// -/// * A - The value of the addend. -/// * G - The address of the symbol's entry within the global offset table. -/// * L - The address of the symbol's entry within the procedure linkage table. -/// * P - The address of the place of the relocation. -/// * S - The address of the symbol. -/// * GotBase - The address of the global offset table. -/// * Image - The base address of the image. -/// * Section - The address of the section containing the symbol. -/// -/// 'XxxRelative' means 'Xxx + A - P'.  'XxxOffset' means 'S + A - Xxx'. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum RelocationKind { -    /// S + A -    Absolute, -    /// S + A - P -    Relative, -    /// G + A - GotBase -    Got, -    /// G + A - P -    GotRelative, -    /// GotBase + A - P -    GotBaseRelative, -    /// S + A - GotBase -    GotBaseOffset, -    /// L + A - P -    PltRelative, -    /// S + A - Image -    ImageOffset, -    /// S + A - Section -    SectionOffset, -    /// The index of the section containing the symbol. -    SectionIndex, -    /// Some other ELF relocation. The value is dependent on the architecture. -    Elf(u32), -    /// Some other Mach-O relocation. The value is dependent on the architecture. -    MachO { -        /// The relocation type. -        value: u8, -        /// Whether the relocation is relative to the place. -        relative: bool, -    }, -    /// Some other COFF relocation. The value is dependent on the architecture. -    Coff(u16), -    /// Some other XCOFF relocation. -    Xcoff(u8), -} - -/// Information about how the result of the relocation operation is encoded in the place. -/// -/// This is usually architecture specific, such as specifying an addressing mode or -/// a specific instruction. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum RelocationEncoding { -    /// Generic encoding. -    Generic, - -    /// x86 sign extension at runtime. -    /// -    /// Used with `RelocationKind::Absolute`. -    X86Signed, -    /// x86 rip-relative addressing. -    /// -    /// The `RelocationKind` must be PC relative. -    X86RipRelative, -    /// x86 rip-relative addressing in movq instruction. -    /// -    /// The `RelocationKind` must be PC relative. -    X86RipRelativeMovq, -    /// x86 branch instruction. -    /// -    /// The `RelocationKind` must be PC relative. -    X86Branch, - -    /// s390x PC-relative offset shifted right by one bit. -    /// -    /// The `RelocationKind` must be PC relative. -    S390xDbl, - -    /// AArch64 call target. -    /// -    /// The `RelocationKind` must be PC relative. -    AArch64Call, - -    /// LoongArch branch offset with two trailing zeros. -    /// -    /// The `RelocationKind` must be PC relative. -    LoongArchBranch, - -    /// SHARC+ 48-bit Type A instruction -    /// -    /// Represents these possible variants, each with a corresponding -    /// `R_SHARC_*` constant: -    /// -    /// * 24-bit absolute address -    /// * 32-bit absolute address -    /// * 6-bit relative address -    /// * 24-bit relative address -    /// * 6-bit absolute address in the immediate value field -    /// * 16-bit absolute address in the immediate value field -    SharcTypeA, - -    /// SHARC+ 32-bit Type B instruction -    /// -    /// Represents these possible variants, each with a corresponding -    /// `R_SHARC_*` constant: -    /// -    /// * 6-bit absolute address in the immediate value field -    /// * 7-bit absolute address in the immediate value field -    /// * 16-bit absolute address -    /// * 6-bit relative address -    SharcTypeB, -} - -/// File flags that are specific to each file format. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum FileFlags { -    /// No file flags. -    None, -    /// ELF file flags. -    Elf { -        /// `os_abi` field in the ELF file header. -        os_abi: u8, -        /// `abi_version` field in the ELF file header. -        abi_version: u8, -        /// `e_flags` field in the ELF file header. -        e_flags: u32, -    }, -    /// Mach-O file flags. -    MachO { -        /// `flags` field in the Mach-O file header. -        flags: u32, -    }, -    /// COFF file flags. -    Coff { -        /// `Characteristics` field in the COFF file header. -        characteristics: u16, -    }, -    /// XCOFF file flags. -    Xcoff { -        /// `f_flags` field in the XCOFF file header. -        f_flags: u16, -    }, -} - -/// Segment flags that are specific to each file format. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SegmentFlags { -    /// No segment flags. -    None, -    /// ELF segment flags. -    Elf { -        /// `p_flags` field in the segment header. -        p_flags: u32, -    }, -    /// Mach-O segment flags. -    MachO { -        /// `flags` field in the segment header. -        flags: u32, -        /// `maxprot` field in the segment header. -        maxprot: u32, -        /// `initprot` field in the segment header. -        initprot: u32, -    }, -    /// COFF segment flags. -    Coff { -        /// `Characteristics` field in the segment header. -        characteristics: u32, -    }, -} - -/// Section flags that are specific to each file format. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SectionFlags { -    /// No section flags. -    None, -    /// ELF section flags. -    Elf { -        /// `sh_flags` field in the section header. -        sh_flags: u64, -    }, -    /// Mach-O section flags. -    MachO { -        /// `flags` field in the section header. -        flags: u32, -    }, -    /// COFF section flags. -    Coff { -        /// `Characteristics` field in the section header. -        characteristics: u32, -    }, -    /// XCOFF section flags. -    Xcoff { -        /// `s_flags` field in the section header. -        s_flags: u32, -    }, -} - -/// Symbol flags that are specific to each file format. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SymbolFlags<Section, Symbol> { -    /// No symbol flags. -    None, -    /// ELF symbol flags. -    Elf { -        /// `st_info` field in the ELF symbol. -        st_info: u8, -        /// `st_other` field in the ELF symbol. -        st_other: u8, -    }, -    /// Mach-O symbol flags. -    MachO { -        /// `n_desc` field in the Mach-O symbol. -        n_desc: u16, -    }, -    /// COFF flags for a section symbol. -    CoffSection { -        /// `Selection` field in the auxiliary symbol for the section. -        selection: u8, -        /// `Number` field in the auxiliary symbol for the section. -        associative_section: Option<Section>, -    }, -    /// XCOFF symbol flags. -    Xcoff { -        /// `n_sclass` field in the XCOFF symbol. -        n_sclass: u8, -        /// `x_smtyp` field in the CSECT auxiliary symbol. -        /// -        /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`. -        x_smtyp: u8, -        /// `x_smclas` field in the CSECT auxiliary symbol. -        /// -        /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`. -        x_smclas: u8, -        /// The containing csect for the symbol. -        /// -        /// Only valid if `x_smtyp` is `XTY_LD`. -        containing_csect: Option<Symbol>, -    }, -} diff --git a/vendor/object/src/elf.rs b/vendor/object/src/elf.rs deleted file mode 100644 index f620171..0000000 --- a/vendor/object/src/elf.rs +++ /dev/null @@ -1,6287 +0,0 @@ -//! ELF definitions. -//! -//! These definitions are independent of read/write support, although we do implement -//! some traits useful for those. -//! -//! This module is the equivalent of /usr/include/elf.h, and is based heavily on it. - -#![allow(missing_docs)] -#![allow(clippy::identity_op)] - -use crate::endian::{Endian, U32Bytes, U64Bytes, I32, I64, U16, U32, U64}; -use crate::pod::Pod; - -/// The header at the start of every 32-bit ELF file. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FileHeader32<E: Endian> { -    /// Magic number and other information. -    pub e_ident: Ident, -    /// Object file type. One of the `ET_*` constants. -    pub e_type: U16<E>, -    /// Architecture. One of the `EM_*` constants. -    pub e_machine: U16<E>, -    /// Object file version. Must be `EV_CURRENT`. -    pub e_version: U32<E>, -    /// Entry point virtual address. -    pub e_entry: U32<E>, -    /// Program header table file offset. -    pub e_phoff: U32<E>, -    /// Section header table file offset. -    pub e_shoff: U32<E>, -    /// Processor-specific flags. -    /// -    /// A combination of the `EF_*` constants. -    pub e_flags: U32<E>, -    /// Size in bytes of this header. -    pub e_ehsize: U16<E>, -    /// Program header table entry size. -    pub e_phentsize: U16<E>, -    /// Program header table entry count. -    /// -    /// If the count is greater than or equal to `PN_XNUM` then this field is set to -    /// `PN_XNUM` and the count is stored in the `sh_info` field of section 0. -    pub e_phnum: U16<E>, -    /// Section header table entry size. -    pub e_shentsize: U16<E>, -    /// Section header table entry count. -    /// -    /// If the count is greater than or equal to `SHN_LORESERVE` then this field is set to -    /// `0` and the count is stored in the `sh_size` field of section 0. -    /// first section header. -    pub e_shnum: U16<E>, -    /// Section header string table index. -    /// -    /// If the index is greater than or equal to `SHN_LORESERVE` then this field is set to -    /// `SHN_XINDEX` and the index is stored in the `sh_link` field of section 0. -    pub e_shstrndx: U16<E>, -} - -/// The header at the start of every 64-bit ELF file. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FileHeader64<E: Endian> { -    /// Magic number and other information. -    pub e_ident: Ident, -    /// Object file type. One of the `ET_*` constants. -    pub e_type: U16<E>, -    /// Architecture. One of the `EM_*` constants. -    pub e_machine: U16<E>, -    /// Object file version. Must be `EV_CURRENT`. -    pub e_version: U32<E>, -    /// Entry point virtual address. -    pub e_entry: U64<E>, -    /// Program header table file offset. -    pub e_phoff: U64<E>, -    /// Section header table file offset. -    pub e_shoff: U64<E>, -    /// Processor-specific flags. -    /// -    /// A combination of the `EF_*` constants. -    pub e_flags: U32<E>, -    /// Size in bytes of this header. -    pub e_ehsize: U16<E>, -    /// Program header table entry size. -    pub e_phentsize: U16<E>, -    /// Program header table entry count. -    /// -    /// If the count is greater than or equal to `PN_XNUM` then this field is set to -    /// `PN_XNUM` and the count is stored in the `sh_info` field of section 0. -    pub e_phnum: U16<E>, -    /// Section header table entry size. -    pub e_shentsize: U16<E>, -    /// Section header table entry count. -    /// -    /// If the count is greater than or equal to `SHN_LORESERVE` then this field is set to -    /// `0` and the count is stored in the `sh_size` field of section 0. -    /// first section header. -    pub e_shnum: U16<E>, -    /// Section header string table index. -    /// -    /// If the index is greater than or equal to `SHN_LORESERVE` then this field is set to -    /// `SHN_XINDEX` and the index is stored in the `sh_link` field of section 0. -    pub e_shstrndx: U16<E>, -} - -/// Magic number and other information. -/// -/// Contained in the file header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Ident { -    /// Magic number. Must be `ELFMAG`. -    pub magic: [u8; 4], -    /// File class. One of the `ELFCLASS*` constants. -    pub class: u8, -    /// Data encoding. One of the `ELFDATA*` constants. -    pub data: u8, -    /// ELF version. Must be `EV_CURRENT`. -    pub version: u8, -    /// OS ABI identification. One of the `ELFOSABI*` constants. -    pub os_abi: u8, -    /// ABI version. -    /// -    /// The meaning of this field depends on the `os_abi` value. -    pub abi_version: u8, -    /// Padding bytes. -    pub padding: [u8; 7], -} - -/// File identification bytes stored in `Ident::magic`. -pub const ELFMAG: [u8; 4] = [0x7f, b'E', b'L', b'F']; - -// Values for `Ident::class`. -/// Invalid class. -pub const ELFCLASSNONE: u8 = 0; -/// 32-bit object. -pub const ELFCLASS32: u8 = 1; -/// 64-bit object. -pub const ELFCLASS64: u8 = 2; - -// Values for `Ident::data`. -/// Invalid data encoding. -pub const ELFDATANONE: u8 = 0; -/// 2's complement, little endian. -pub const ELFDATA2LSB: u8 = 1; -/// 2's complement, big endian. -pub const ELFDATA2MSB: u8 = 2; - -// Values for `Ident::os_abi`. -/// UNIX System V ABI. -pub const ELFOSABI_NONE: u8 = 0; -/// UNIX System V ABI. -/// -/// Alias. -pub const ELFOSABI_SYSV: u8 = 0; -/// HP-UX. -pub const ELFOSABI_HPUX: u8 = 1; -/// NetBSD. -pub const ELFOSABI_NETBSD: u8 = 2; -/// Object uses GNU ELF extensions. -pub const ELFOSABI_GNU: u8 = 3; -/// Object uses GNU ELF extensions. -/// -/// Compatibility alias. -pub const ELFOSABI_LINUX: u8 = ELFOSABI_GNU; -/// GNU/Hurd. -pub const ELFOSABI_HURD: u8 = 4; -/// Sun Solaris. -pub const ELFOSABI_SOLARIS: u8 = 6; -/// IBM AIX. -pub const ELFOSABI_AIX: u8 = 7; -/// SGI Irix. -pub const ELFOSABI_IRIX: u8 = 8; -/// FreeBSD. -pub const ELFOSABI_FREEBSD: u8 = 9; -/// Compaq TRU64 UNIX. -pub const ELFOSABI_TRU64: u8 = 10; -/// Novell Modesto. -pub const ELFOSABI_MODESTO: u8 = 11; -/// OpenBSD. -pub const ELFOSABI_OPENBSD: u8 = 12; -/// OpenVMS. -pub const ELFOSABI_OPENVMS: u8 = 13; -/// Hewlett-Packard Non-Stop Kernel. -pub const ELFOSABI_NSK: u8 = 14; -/// AROS -pub const ELFOSABI_AROS: u8 = 15; -/// FenixOS -pub const ELFOSABI_FENIXOS: u8 = 16; -/// Nuxi CloudABI -pub const ELFOSABI_CLOUDABI: u8 = 17; -/// ARM EABI. -pub const ELFOSABI_ARM_AEABI: u8 = 64; -/// ARM. -pub const ELFOSABI_ARM: u8 = 97; -/// Standalone (embedded) application. -pub const ELFOSABI_STANDALONE: u8 = 255; - -// Values for `FileHeader*::e_type`. -/// No file type. -pub const ET_NONE: u16 = 0; -/// Relocatable file. -pub const ET_REL: u16 = 1; -/// Executable file. -pub const ET_EXEC: u16 = 2; -/// Shared object file. -pub const ET_DYN: u16 = 3; -/// Core file. -pub const ET_CORE: u16 = 4; -/// OS-specific range start. -pub const ET_LOOS: u16 = 0xfe00; -/// OS-specific range end. -pub const ET_HIOS: u16 = 0xfeff; -/// Processor-specific range start. -pub const ET_LOPROC: u16 = 0xff00; -/// Processor-specific range end. -pub const ET_HIPROC: u16 = 0xffff; - -// Values for `FileHeader*::e_machine`. -/// No machine -pub const EM_NONE: u16 = 0; -/// AT&T WE 32100 -pub const EM_M32: u16 = 1; -/// SUN SPARC -pub const EM_SPARC: u16 = 2; -/// Intel 80386 -pub const EM_386: u16 = 3; -/// Motorola m68k family -pub const EM_68K: u16 = 4; -/// Motorola m88k family -pub const EM_88K: u16 = 5; -/// Intel MCU -pub const EM_IAMCU: u16 = 6; -/// Intel 80860 -pub const EM_860: u16 = 7; -/// MIPS R3000 big-endian -pub const EM_MIPS: u16 = 8; -/// IBM System/370 -pub const EM_S370: u16 = 9; -/// MIPS R3000 little-endian -pub const EM_MIPS_RS3_LE: u16 = 10; -/// HPPA -pub const EM_PARISC: u16 = 15; -/// Fujitsu VPP500 -pub const EM_VPP500: u16 = 17; -/// Sun's "v8plus" -pub const EM_SPARC32PLUS: u16 = 18; -/// Intel 80960 -pub const EM_960: u16 = 19; -/// PowerPC -pub const EM_PPC: u16 = 20; -/// PowerPC 64-bit -pub const EM_PPC64: u16 = 21; -/// IBM S390 -pub const EM_S390: u16 = 22; -/// IBM SPU/SPC -pub const EM_SPU: u16 = 23; -/// NEC V800 series -pub const EM_V800: u16 = 36; -/// Fujitsu FR20 -pub const EM_FR20: u16 = 37; -/// TRW RH-32 -pub const EM_RH32: u16 = 38; -/// Motorola RCE -pub const EM_RCE: u16 = 39; -/// ARM -pub const EM_ARM: u16 = 40; -/// Digital Alpha -pub const EM_FAKE_ALPHA: u16 = 41; -/// Hitachi SH -pub const EM_SH: u16 = 42; -/// SPARC v9 64-bit -pub const EM_SPARCV9: u16 = 43; -/// Siemens Tricore -pub const EM_TRICORE: u16 = 44; -/// Argonaut RISC Core -pub const EM_ARC: u16 = 45; -/// Hitachi H8/300 -pub const EM_H8_300: u16 = 46; -/// Hitachi H8/300H -pub const EM_H8_300H: u16 = 47; -/// Hitachi H8S -pub const EM_H8S: u16 = 48; -/// Hitachi H8/500 -pub const EM_H8_500: u16 = 49; -/// Intel Merced -pub const EM_IA_64: u16 = 50; -/// Stanford MIPS-X -pub const EM_MIPS_X: u16 = 51; -/// Motorola Coldfire -pub const EM_COLDFIRE: u16 = 52; -/// Motorola M68HC12 -pub const EM_68HC12: u16 = 53; -/// Fujitsu MMA Multimedia Accelerator -pub const EM_MMA: u16 = 54; -/// Siemens PCP -pub const EM_PCP: u16 = 55; -/// Sony nCPU embeeded RISC -pub const EM_NCPU: u16 = 56; -/// Denso NDR1 microprocessor -pub const EM_NDR1: u16 = 57; -/// Motorola Start*Core processor -pub const EM_STARCORE: u16 = 58; -/// Toyota ME16 processor -pub const EM_ME16: u16 = 59; -/// STMicroelectronic ST100 processor -pub const EM_ST100: u16 = 60; -/// Advanced Logic Corp. Tinyj emb.fam -pub const EM_TINYJ: u16 = 61; -/// AMD x86-64 architecture -pub const EM_X86_64: u16 = 62; -/// Sony DSP Processor -pub const EM_PDSP: u16 = 63; -/// Digital PDP-10 -pub const EM_PDP10: u16 = 64; -/// Digital PDP-11 -pub const EM_PDP11: u16 = 65; -/// Siemens FX66 microcontroller -pub const EM_FX66: u16 = 66; -/// STMicroelectronics ST9+ 8/16 mc -pub const EM_ST9PLUS: u16 = 67; -/// STmicroelectronics ST7 8 bit mc -pub const EM_ST7: u16 = 68; -/// Motorola MC68HC16 microcontroller -pub const EM_68HC16: u16 = 69; -/// Motorola MC68HC11 microcontroller -pub const EM_68HC11: u16 = 70; -/// Motorola MC68HC08 microcontroller -pub const EM_68HC08: u16 = 71; -/// Motorola MC68HC05 microcontroller -pub const EM_68HC05: u16 = 72; -/// Silicon Graphics SVx -pub const EM_SVX: u16 = 73; -/// STMicroelectronics ST19 8 bit mc -pub const EM_ST19: u16 = 74; -/// Digital VAX -pub const EM_VAX: u16 = 75; -/// Axis Communications 32-bit emb.proc -pub const EM_CRIS: u16 = 76; -/// Infineon Technologies 32-bit emb.proc -pub const EM_JAVELIN: u16 = 77; -/// Element 14 64-bit DSP Processor -pub const EM_FIREPATH: u16 = 78; -/// LSI Logic 16-bit DSP Processor -pub const EM_ZSP: u16 = 79; -/// Donald Knuth's educational 64-bit proc -pub const EM_MMIX: u16 = 80; -/// Harvard University machine-independent object files -pub const EM_HUANY: u16 = 81; -/// SiTera Prism -pub const EM_PRISM: u16 = 82; -/// Atmel AVR 8-bit microcontroller -pub const EM_AVR: u16 = 83; -/// Fujitsu FR30 -pub const EM_FR30: u16 = 84; -/// Mitsubishi D10V -pub const EM_D10V: u16 = 85; -/// Mitsubishi D30V -pub const EM_D30V: u16 = 86; -/// NEC v850 -pub const EM_V850: u16 = 87; -/// Mitsubishi M32R -pub const EM_M32R: u16 = 88; -/// Matsushita MN10300 -pub const EM_MN10300: u16 = 89; -/// Matsushita MN10200 -pub const EM_MN10200: u16 = 90; -/// picoJava -pub const EM_PJ: u16 = 91; -/// OpenRISC 32-bit embedded processor -pub const EM_OPENRISC: u16 = 92; -/// ARC International ARCompact -pub const EM_ARC_COMPACT: u16 = 93; -/// Tensilica Xtensa Architecture -pub const EM_XTENSA: u16 = 94; -/// Alphamosaic VideoCore -pub const EM_VIDEOCORE: u16 = 95; -/// Thompson Multimedia General Purpose Proc -pub const EM_TMM_GPP: u16 = 96; -/// National Semi. 32000 -pub const EM_NS32K: u16 = 97; -/// Tenor Network TPC -pub const EM_TPC: u16 = 98; -/// Trebia SNP 1000 -pub const EM_SNP1K: u16 = 99; -/// STMicroelectronics ST200 -pub const EM_ST200: u16 = 100; -/// Ubicom IP2xxx -pub const EM_IP2K: u16 = 101; -/// MAX processor -pub const EM_MAX: u16 = 102; -/// National Semi. CompactRISC -pub const EM_CR: u16 = 103; -/// Fujitsu F2MC16 -pub const EM_F2MC16: u16 = 104; -/// Texas Instruments msp430 -pub const EM_MSP430: u16 = 105; -/// Analog Devices Blackfin DSP -pub const EM_BLACKFIN: u16 = 106; -/// Seiko Epson S1C33 family -pub const EM_SE_C33: u16 = 107; -/// Sharp embedded microprocessor -pub const EM_SEP: u16 = 108; -/// Arca RISC -pub const EM_ARCA: u16 = 109; -/// PKU-Unity & MPRC Peking Uni. mc series -pub const EM_UNICORE: u16 = 110; -/// eXcess configurable cpu -pub const EM_EXCESS: u16 = 111; -/// Icera Semi. Deep Execution Processor -pub const EM_DXP: u16 = 112; -/// Altera Nios II -pub const EM_ALTERA_NIOS2: u16 = 113; -/// National Semi. CompactRISC CRX -pub const EM_CRX: u16 = 114; -/// Motorola XGATE -pub const EM_XGATE: u16 = 115; -/// Infineon C16x/XC16x -pub const EM_C166: u16 = 116; -/// Renesas M16C -pub const EM_M16C: u16 = 117; -/// Microchip Technology dsPIC30F -pub const EM_DSPIC30F: u16 = 118; -/// Freescale Communication Engine RISC -pub const EM_CE: u16 = 119; -/// Renesas M32C -pub const EM_M32C: u16 = 120; -/// Altium TSK3000 -pub const EM_TSK3000: u16 = 131; -/// Freescale RS08 -pub const EM_RS08: u16 = 132; -/// Analog Devices SHARC family -pub const EM_SHARC: u16 = 133; -/// Cyan Technology eCOG2 -pub const EM_ECOG2: u16 = 134; -/// Sunplus S+core7 RISC -pub const EM_SCORE7: u16 = 135; -/// New Japan Radio (NJR) 24-bit DSP -pub const EM_DSP24: u16 = 136; -/// Broadcom VideoCore III -pub const EM_VIDEOCORE3: u16 = 137; -/// RISC for Lattice FPGA -pub const EM_LATTICEMICO32: u16 = 138; -/// Seiko Epson C17 -pub const EM_SE_C17: u16 = 139; -/// Texas Instruments TMS320C6000 DSP -pub const EM_TI_C6000: u16 = 140; -/// Texas Instruments TMS320C2000 DSP -pub const EM_TI_C2000: u16 = 141; -/// Texas Instruments TMS320C55x DSP -pub const EM_TI_C5500: u16 = 142; -/// Texas Instruments App. Specific RISC -pub const EM_TI_ARP32: u16 = 143; -/// Texas Instruments Prog. Realtime Unit -pub const EM_TI_PRU: u16 = 144; -/// STMicroelectronics 64bit VLIW DSP -pub const EM_MMDSP_PLUS: u16 = 160; -/// Cypress M8C -pub const EM_CYPRESS_M8C: u16 = 161; -/// Renesas R32C -pub const EM_R32C: u16 = 162; -/// NXP Semi. TriMedia -pub const EM_TRIMEDIA: u16 = 163; -/// QUALCOMM Hexagon -pub const EM_HEXAGON: u16 = 164; -/// Intel 8051 and variants -pub const EM_8051: u16 = 165; -/// STMicroelectronics STxP7x -pub const EM_STXP7X: u16 = 166; -/// Andes Tech. compact code emb. RISC -pub const EM_NDS32: u16 = 167; -/// Cyan Technology eCOG1X -pub const EM_ECOG1X: u16 = 168; -/// Dallas Semi. MAXQ30 mc -pub const EM_MAXQ30: u16 = 169; -/// New Japan Radio (NJR) 16-bit DSP -pub const EM_XIMO16: u16 = 170; -/// M2000 Reconfigurable RISC -pub const EM_MANIK: u16 = 171; -/// Cray NV2 vector architecture -pub const EM_CRAYNV2: u16 = 172; -/// Renesas RX -pub const EM_RX: u16 = 173; -/// Imagination Tech. META -pub const EM_METAG: u16 = 174; -/// MCST Elbrus -pub const EM_MCST_ELBRUS: u16 = 175; -/// Cyan Technology eCOG16 -pub const EM_ECOG16: u16 = 176; -/// National Semi. CompactRISC CR16 -pub const EM_CR16: u16 = 177; -/// Freescale Extended Time Processing Unit -pub const EM_ETPU: u16 = 178; -/// Infineon Tech. SLE9X -pub const EM_SLE9X: u16 = 179; -/// Intel L10M -pub const EM_L10M: u16 = 180; -/// Intel K10M -pub const EM_K10M: u16 = 181; -/// ARM AARCH64 -pub const EM_AARCH64: u16 = 183; -/// Amtel 32-bit microprocessor -pub const EM_AVR32: u16 = 185; -/// STMicroelectronics STM8 -pub const EM_STM8: u16 = 186; -/// Tileta TILE64 -pub const EM_TILE64: u16 = 187; -/// Tilera TILEPro -pub const EM_TILEPRO: u16 = 188; -/// Xilinx MicroBlaze -pub const EM_MICROBLAZE: u16 = 189; -/// NVIDIA CUDA -pub const EM_CUDA: u16 = 190; -/// Tilera TILE-Gx -pub const EM_TILEGX: u16 = 191; -/// CloudShield -pub const EM_CLOUDSHIELD: u16 = 192; -/// KIPO-KAIST Core-A 1st gen. -pub const EM_COREA_1ST: u16 = 193; -/// KIPO-KAIST Core-A 2nd gen. -pub const EM_COREA_2ND: u16 = 194; -/// Synopsys ARCompact V2 -pub const EM_ARC_COMPACT2: u16 = 195; -/// Open8 RISC -pub const EM_OPEN8: u16 = 196; -/// Renesas RL78 -pub const EM_RL78: u16 = 197; -/// Broadcom VideoCore V -pub const EM_VIDEOCORE5: u16 = 198; -/// Renesas 78KOR -pub const EM_78KOR: u16 = 199; -/// Freescale 56800EX DSC -pub const EM_56800EX: u16 = 200; -/// Beyond BA1 -pub const EM_BA1: u16 = 201; -/// Beyond BA2 -pub const EM_BA2: u16 = 202; -/// XMOS xCORE -pub const EM_XCORE: u16 = 203; -/// Microchip 8-bit PIC(r) -pub const EM_MCHP_PIC: u16 = 204; -/// KM211 KM32 -pub const EM_KM32: u16 = 210; -/// KM211 KMX32 -pub const EM_KMX32: u16 = 211; -/// KM211 KMX16 -pub const EM_EMX16: u16 = 212; -/// KM211 KMX8 -pub const EM_EMX8: u16 = 213; -/// KM211 KVARC -pub const EM_KVARC: u16 = 214; -/// Paneve CDP -pub const EM_CDP: u16 = 215; -/// Cognitive Smart Memory Processor -pub const EM_COGE: u16 = 216; -/// Bluechip CoolEngine -pub const EM_COOL: u16 = 217; -/// Nanoradio Optimized RISC -pub const EM_NORC: u16 = 218; -/// CSR Kalimba -pub const EM_CSR_KALIMBA: u16 = 219; -/// Zilog Z80 -pub const EM_Z80: u16 = 220; -/// Controls and Data Services VISIUMcore -pub const EM_VISIUM: u16 = 221; -/// FTDI Chip FT32 -pub const EM_FT32: u16 = 222; -/// Moxie processor -pub const EM_MOXIE: u16 = 223; -/// AMD GPU -pub const EM_AMDGPU: u16 = 224; -/// RISC-V -pub const EM_RISCV: u16 = 243; -/// Linux BPF -- in-kernel virtual machine -pub const EM_BPF: u16 = 247; -/// C-SKY -pub const EM_CSKY: u16 = 252; -/// Loongson LoongArch -pub const EM_LOONGARCH: u16 = 258; -/// Solana Binary Format -pub const EM_SBF: u16 = 263; -/// Digital Alpha -pub const EM_ALPHA: u16 = 0x9026; - -// Values for `FileHeader*::e_version` and `Ident::version`. -/// Invalid ELF version. -pub const EV_NONE: u8 = 0; -/// Current ELF version. -pub const EV_CURRENT: u8 = 1; - -/// Section header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SectionHeader32<E: Endian> { -    /// Section name. -    /// -    /// This is an offset into the section header string table. -    pub sh_name: U32<E>, -    /// Section type. One of the `SHT_*` constants. -    pub sh_type: U32<E>, -    /// Section flags. A combination of the `SHF_*` constants. -    pub sh_flags: U32<E>, -    /// Section virtual address at execution. -    pub sh_addr: U32<E>, -    /// Section file offset. -    pub sh_offset: U32<E>, -    /// Section size in bytes. -    pub sh_size: U32<E>, -    /// Link to another section. -    /// -    /// The section relationship depends on the `sh_type` value. -    pub sh_link: U32<E>, -    /// Additional section information. -    /// -    /// The meaning of this field depends on the `sh_type` value. -    pub sh_info: U32<E>, -    /// Section alignment. -    pub sh_addralign: U32<E>, -    /// Entry size if the section holds a table. -    pub sh_entsize: U32<E>, -} - -/// Section header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SectionHeader64<E: Endian> { -    /// Section name. -    /// -    /// This is an offset into the section header string table. -    pub sh_name: U32<E>, -    /// Section type. One of the `SHT_*` constants. -    pub sh_type: U32<E>, -    /// Section flags. A combination of the `SHF_*` constants. -    pub sh_flags: U64<E>, -    /// Section virtual address at execution. -    pub sh_addr: U64<E>, -    /// Section file offset. -    pub sh_offset: U64<E>, -    /// Section size in bytes. -    pub sh_size: U64<E>, -    /// Link to another section. -    /// -    /// The section relationship depends on the `sh_type` value. -    pub sh_link: U32<E>, -    /// Additional section information. -    /// -    /// The meaning of this field depends on the `sh_type` value. -    pub sh_info: U32<E>, -    /// Section alignment. -    pub sh_addralign: U64<E>, -    /// Entry size if the section holds a table. -    pub sh_entsize: U64<E>, -} - -// Special values for section indices. -/// Undefined section. -pub const SHN_UNDEF: u16 = 0; -/// OS-specific range start. -/// Start of reserved section indices. -pub const SHN_LORESERVE: u16 = 0xff00; -/// Start of processor-specific section indices. -pub const SHN_LOPROC: u16 = 0xff00; -/// End of processor-specific section indices. -pub const SHN_HIPROC: u16 = 0xff1f; -/// Start of OS-specific section indices. -pub const SHN_LOOS: u16 = 0xff20; -/// End of OS-specific section indices. -pub const SHN_HIOS: u16 = 0xff3f; -/// Associated symbol is absolute. -pub const SHN_ABS: u16 = 0xfff1; -/// Associated symbol is common. -pub const SHN_COMMON: u16 = 0xfff2; -/// Section index is in the `SHT_SYMTAB_SHNDX` section. -pub const SHN_XINDEX: u16 = 0xffff; -/// End of reserved section indices. -pub const SHN_HIRESERVE: u16 = 0xffff; - -// Values for `SectionHeader*::sh_type`. -/// Section header table entry is unused. -pub const SHT_NULL: u32 = 0; -/// Program data. -pub const SHT_PROGBITS: u32 = 1; -/// Symbol table. -pub const SHT_SYMTAB: u32 = 2; -/// String table. -pub const SHT_STRTAB: u32 = 3; -/// Relocation entries with explicit addends. -pub const SHT_RELA: u32 = 4; -/// Symbol hash table. -pub const SHT_HASH: u32 = 5; -/// Dynamic linking information. -pub const SHT_DYNAMIC: u32 = 6; -/// Notes. -pub const SHT_NOTE: u32 = 7; -/// Program space with no data (bss). -pub const SHT_NOBITS: u32 = 8; -/// Relocation entries without explicit addends. -pub const SHT_REL: u32 = 9; -/// Reserved section type. -pub const SHT_SHLIB: u32 = 10; -/// Dynamic linker symbol table. -pub const SHT_DYNSYM: u32 = 11; -/// Array of constructors. -pub const SHT_INIT_ARRAY: u32 = 14; -/// Array of destructors. -pub const SHT_FINI_ARRAY: u32 = 15; -/// Array of pre-constructors. -pub const SHT_PREINIT_ARRAY: u32 = 16; -/// Section group. -pub const SHT_GROUP: u32 = 17; -/// Extended section indices for a symbol table. -pub const SHT_SYMTAB_SHNDX: u32 = 18; -/// Start of OS-specific section types. -pub const SHT_LOOS: u32 = 0x6000_0000; -/// Object attributes. -pub const SHT_GNU_ATTRIBUTES: u32 = 0x6fff_fff5; -/// GNU-style hash table. -pub const SHT_GNU_HASH: u32 = 0x6fff_fff6; -/// Prelink library list -pub const SHT_GNU_LIBLIST: u32 = 0x6fff_fff7; -/// Checksum for DSO content. -pub const SHT_CHECKSUM: u32 = 0x6fff_fff8; -/// Sun-specific low bound. -pub const SHT_LOSUNW: u32 = 0x6fff_fffa; -#[allow(non_upper_case_globals)] -pub const SHT_SUNW_move: u32 = 0x6fff_fffa; -pub const SHT_SUNW_COMDAT: u32 = 0x6fff_fffb; -#[allow(non_upper_case_globals)] -pub const SHT_SUNW_syminfo: u32 = 0x6fff_fffc; -/// Version definition section. -#[allow(non_upper_case_globals)] -pub const SHT_GNU_VERDEF: u32 = 0x6fff_fffd; -/// Version needs section. -#[allow(non_upper_case_globals)] -pub const SHT_GNU_VERNEED: u32 = 0x6fff_fffe; -/// Version symbol table. -#[allow(non_upper_case_globals)] -pub const SHT_GNU_VERSYM: u32 = 0x6fff_ffff; -/// Sun-specific high bound. -pub const SHT_HISUNW: u32 = 0x6fff_ffff; -/// End of OS-specific section types. -pub const SHT_HIOS: u32 = 0x6fff_ffff; -/// Start of processor-specific section types. -pub const SHT_LOPROC: u32 = 0x7000_0000; -/// End of processor-specific section types. -pub const SHT_HIPROC: u32 = 0x7fff_ffff; -/// Start of application-specific section types. -pub const SHT_LOUSER: u32 = 0x8000_0000; -/// End of application-specific section types. -pub const SHT_HIUSER: u32 = 0x8fff_ffff; - -// Values for `SectionHeader*::sh_flags`. -/// Section is writable. -pub const SHF_WRITE: u32 = 1 << 0; -/// Section occupies memory during execution. -pub const SHF_ALLOC: u32 = 1 << 1; -/// Section is executable. -pub const SHF_EXECINSTR: u32 = 1 << 2; -/// Section may be be merged to eliminate duplication. -pub const SHF_MERGE: u32 = 1 << 4; -/// Section contains nul-terminated strings. -pub const SHF_STRINGS: u32 = 1 << 5; -/// The `sh_info` field contains a section header table index. -pub const SHF_INFO_LINK: u32 = 1 << 6; -/// Section has special ordering requirements when combining sections. -pub const SHF_LINK_ORDER: u32 = 1 << 7; -/// Section requires special OS-specific handling. -pub const SHF_OS_NONCONFORMING: u32 = 1 << 8; -/// Section is a member of a group. -pub const SHF_GROUP: u32 = 1 << 9; -/// Section holds thread-local storage. -pub const SHF_TLS: u32 = 1 << 10; -/// Section is compressed. -/// -/// Compressed sections begin with one of the `CompressionHeader*` headers. -pub const SHF_COMPRESSED: u32 = 1 << 11; -/// OS-specific section flags. -pub const SHF_MASKOS: u32 = 0x0ff0_0000; -/// Processor-specific section flags. -pub const SHF_MASKPROC: u32 = 0xf000_0000; -/// This section is excluded from the final executable or shared library. -pub const SHF_EXCLUDE: u32 = 0x8000_0000; - -/// Section compression header. -/// -/// Used when `SHF_COMPRESSED` is set. -/// -/// Note: this type currently allows for misaligned headers, but that may be -/// changed in a future version. -#[derive(Debug, Default, Clone, Copy)] -#[repr(C)] -pub struct CompressionHeader32<E: Endian> { -    /// Compression format. One of the `ELFCOMPRESS_*` values. -    pub ch_type: U32Bytes<E>, -    /// Uncompressed data size. -    pub ch_size: U32Bytes<E>, -    /// Uncompressed data alignment. -    pub ch_addralign: U32Bytes<E>, -} - -/// Section compression header. -/// -/// Used when `SHF_COMPRESSED` is set. -/// -/// Note: this type currently allows for misaligned headers, but that may be -/// changed in a future version. -#[derive(Debug, Default, Clone, Copy)] -#[repr(C)] -pub struct CompressionHeader64<E: Endian> { -    /// Compression format. One of the `ELFCOMPRESS_*` values. -    pub ch_type: U32Bytes<E>, -    /// Reserved. -    pub ch_reserved: U32Bytes<E>, -    /// Uncompressed data size. -    pub ch_size: U64Bytes<E>, -    /// Uncompressed data alignment. -    pub ch_addralign: U64Bytes<E>, -} - -/// ZLIB/DEFLATE algorithm. -pub const ELFCOMPRESS_ZLIB: u32 = 1; -/// Zstandard algorithm. -pub const ELFCOMPRESS_ZSTD: u32 = 2; -/// Start of OS-specific compression types. -pub const ELFCOMPRESS_LOOS: u32 = 0x6000_0000; -/// End of OS-specific compression types. -pub const ELFCOMPRESS_HIOS: u32 = 0x6fff_ffff; -/// Start of processor-specific compression types. -pub const ELFCOMPRESS_LOPROC: u32 = 0x7000_0000; -/// End of processor-specific compression types. -pub const ELFCOMPRESS_HIPROC: u32 = 0x7fff_ffff; - -// Values for the flag entry for section groups. -/// Mark group as COMDAT. -pub const GRP_COMDAT: u32 = 1; - -/// Symbol table entry. -#[derive(Debug, Default, Clone, Copy)] -#[repr(C)] -pub struct Sym32<E: Endian> { -    /// Symbol name. -    /// -    /// This is an offset into the symbol string table. -    pub st_name: U32<E>, -    /// Symbol value. -    pub st_value: U32<E>, -    /// Symbol size. -    pub st_size: U32<E>, -    /// Symbol type and binding. -    /// -    /// Use the `st_type` and `st_bind` methods to access this value. -    pub st_info: u8, -    /// Symbol visibility. -    /// -    /// Use the `st_visibility` method to access this value. -    pub st_other: u8, -    /// Section index or one of the `SHN_*` values. -    pub st_shndx: U16<E>, -} - -impl<E: Endian> Sym32<E> { -    /// Get the `st_bind` component of the `st_info` field. -    #[inline] -    pub fn st_bind(&self) -> u8 { -        self.st_info >> 4 -    } - -    /// Get the `st_type` component of the `st_info` field. -    #[inline] -    pub fn st_type(&self) -> u8 { -        self.st_info & 0xf -    } - -    /// Set the `st_info` field given the `st_bind` and `st_type` components. -    #[inline] -    pub fn set_st_info(&mut self, st_bind: u8, st_type: u8) { -        self.st_info = (st_bind << 4) + (st_type & 0xf); -    } - -    /// Get the `st_visibility` component of the `st_info` field. -    #[inline] -    pub fn st_visibility(&self) -> u8 { -        self.st_other & 0x3 -    } -} - -/// Symbol table entry. -#[derive(Debug, Default, Clone, Copy)] -#[repr(C)] -pub struct Sym64<E: Endian> { -    /// Symbol name. -    /// -    /// This is an offset into the symbol string table. -    pub st_name: U32<E>, -    /// Symbol type and binding. -    /// -    /// Use the `st_bind` and `st_type` methods to access this value. -    pub st_info: u8, -    /// Symbol visibility. -    /// -    /// Use the `st_visibility` method to access this value. -    pub st_other: u8, -    /// Section index or one of the `SHN_*` values. -    pub st_shndx: U16<E>, -    /// Symbol value. -    pub st_value: U64<E>, -    /// Symbol size. -    pub st_size: U64<E>, -} - -impl<E: Endian> Sym64<E> { -    /// Get the `st_bind` component of the `st_info` field. -    #[inline] -    pub fn st_bind(&self) -> u8 { -        self.st_info >> 4 -    } - -    /// Get the `st_type` component of the `st_info` field. -    #[inline] -    pub fn st_type(&self) -> u8 { -        self.st_info & 0xf -    } - -    /// Set the `st_info` field given the `st_bind` and `st_type` components. -    #[inline] -    pub fn set_st_info(&mut self, st_bind: u8, st_type: u8) { -        self.st_info = (st_bind << 4) + (st_type & 0xf); -    } - -    /// Get the `st_visibility` component of the `st_info` field. -    #[inline] -    pub fn st_visibility(&self) -> u8 { -        self.st_other & 0x3 -    } -} - -/// Additional information about a `Sym32`. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Syminfo32<E: Endian> { -    /// Direct bindings, symbol bound to. -    pub si_boundto: U16<E>, -    /// Per symbol flags. -    pub si_flags: U16<E>, -} - -/// Additional information about a `Sym64`. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Syminfo64<E: Endian> { -    /// Direct bindings, symbol bound to. -    pub si_boundto: U16<E>, -    /// Per symbol flags. -    pub si_flags: U16<E>, -} - -// Values for `Syminfo*::si_boundto`. -/// Symbol bound to self -pub const SYMINFO_BT_SELF: u16 = 0xffff; -/// Symbol bound to parent -pub const SYMINFO_BT_PARENT: u16 = 0xfffe; -/// Beginning of reserved entries -pub const SYMINFO_BT_LOWRESERVE: u16 = 0xff00; - -// Values for `Syminfo*::si_flags`. -/// Direct bound symbol -pub const SYMINFO_FLG_DIRECT: u16 = 0x0001; -/// Pass-thru symbol for translator -pub const SYMINFO_FLG_PASSTHRU: u16 = 0x0002; -/// Symbol is a copy-reloc -pub const SYMINFO_FLG_COPY: u16 = 0x0004; -/// Symbol bound to object to be lazy loaded -pub const SYMINFO_FLG_LAZYLOAD: u16 = 0x0008; - -// Syminfo version values. -pub const SYMINFO_NONE: u16 = 0; -pub const SYMINFO_CURRENT: u16 = 1; -pub const SYMINFO_NUM: u16 = 2; - -// Values for bind component of `Sym*::st_info`. -/// Local symbol. -pub const STB_LOCAL: u8 = 0; -/// Global symbol. -pub const STB_GLOBAL: u8 = 1; -/// Weak symbol. -pub const STB_WEAK: u8 = 2; -/// Start of OS-specific symbol binding. -pub const STB_LOOS: u8 = 10; -/// Unique symbol. -pub const STB_GNU_UNIQUE: u8 = 10; -/// End of OS-specific symbol binding. -pub const STB_HIOS: u8 = 12; -/// Start of processor-specific symbol binding. -pub const STB_LOPROC: u8 = 13; -/// End of processor-specific symbol binding. -pub const STB_HIPROC: u8 = 15; - -// Values for type component of `Sym*::st_info`. -/// Symbol type is unspecified. -pub const STT_NOTYPE: u8 = 0; -/// Symbol is a data object. -pub const STT_OBJECT: u8 = 1; -/// Symbol is a code object. -pub const STT_FUNC: u8 = 2; -/// Symbol is associated with a section. -pub const STT_SECTION: u8 = 3; -/// Symbol's name is a file name. -pub const STT_FILE: u8 = 4; -/// Symbol is a common data object. -pub const STT_COMMON: u8 = 5; -/// Symbol is a thread-local storage object. -pub const STT_TLS: u8 = 6; -/// Start of OS-specific symbol types. -pub const STT_LOOS: u8 = 10; -/// Symbol is an indirect code object. -pub const STT_GNU_IFUNC: u8 = 10; -/// End of OS-specific symbol types. -pub const STT_HIOS: u8 = 12; -/// Start of processor-specific symbol types. -pub const STT_LOPROC: u8 = 13; -/// End of processor-specific symbol types. -pub const STT_HIPROC: u8 = 15; - -// Values for visibility component of `Symbol*::st_other`. -/// Default symbol visibility rules. -pub const STV_DEFAULT: u8 = 0; -/// Processor specific hidden class. -pub const STV_INTERNAL: u8 = 1; -/// Symbol is not visible to other components. -pub const STV_HIDDEN: u8 = 2; -/// Symbol is visible to other components, but is not preemptible. -pub const STV_PROTECTED: u8 = 3; - -/// Relocation table entry without explicit addend. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Rel32<E: Endian> { -    /// Relocation address. -    pub r_offset: U32<E>, -    /// Relocation type and symbol index. -    pub r_info: U32<E>, -} - -impl<E: Endian> Rel32<E> { -    /// Get the `r_sym` component of the `r_info` field. -    #[inline] -    pub fn r_sym(&self, endian: E) -> u32 { -        self.r_info.get(endian) >> 8 -    } - -    /// Get the `r_type` component of the `r_info` field. -    #[inline] -    pub fn r_type(&self, endian: E) -> u32 { -        self.r_info.get(endian) & 0xff -    } - -    /// Calculate the `r_info` field given the `r_sym` and `r_type` components. -    pub fn r_info(endian: E, r_sym: u32, r_type: u8) -> U32<E> { -        U32::new(endian, (r_sym << 8) | u32::from(r_type)) -    } - -    /// Set the `r_info` field given the `r_sym` and `r_type` components. -    pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u8) { -        self.r_info = Self::r_info(endian, r_sym, r_type) -    } -} - -/// Relocation table entry with explicit addend. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Rela32<E: Endian> { -    /// Relocation address. -    pub r_offset: U32<E>, -    /// Relocation type and symbol index. -    pub r_info: U32<E>, -    /// Explicit addend. -    pub r_addend: I32<E>, -} - -impl<E: Endian> Rela32<E> { -    /// Get the `r_sym` component of the `r_info` field. -    #[inline] -    pub fn r_sym(&self, endian: E) -> u32 { -        self.r_info.get(endian) >> 8 -    } - -    /// Get the `r_type` component of the `r_info` field. -    #[inline] -    pub fn r_type(&self, endian: E) -> u32 { -        self.r_info.get(endian) & 0xff -    } - -    /// Calculate the `r_info` field given the `r_sym` and `r_type` components. -    pub fn r_info(endian: E, r_sym: u32, r_type: u8) -> U32<E> { -        U32::new(endian, (r_sym << 8) | u32::from(r_type)) -    } - -    /// Set the `r_info` field given the `r_sym` and `r_type` components. -    pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u8) { -        self.r_info = Self::r_info(endian, r_sym, r_type) -    } -} - -impl<E: Endian> From<Rel32<E>> for Rela32<E> { -    fn from(rel: Rel32<E>) -> Self { -        Rela32 { -            r_offset: rel.r_offset, -            r_info: rel.r_info, -            r_addend: I32::default(), -        } -    } -} - -/// Relocation table entry without explicit addend. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Rel64<E: Endian> { -    /// Relocation address. -    pub r_offset: U64<E>, -    /// Relocation type and symbol index. -    pub r_info: U64<E>, -} - -impl<E: Endian> Rel64<E> { -    /// Get the `r_sym` component of the `r_info` field. -    #[inline] -    pub fn r_sym(&self, endian: E) -> u32 { -        (self.r_info.get(endian) >> 32) as u32 -    } - -    /// Get the `r_type` component of the `r_info` field. -    #[inline] -    pub fn r_type(&self, endian: E) -> u32 { -        (self.r_info.get(endian) & 0xffff_ffff) as u32 -    } - -    /// Calculate the `r_info` field given the `r_sym` and `r_type` components. -    pub fn r_info(endian: E, r_sym: u32, r_type: u32) -> U64<E> { -        U64::new(endian, (u64::from(r_sym) << 32) | u64::from(r_type)) -    } - -    /// Set the `r_info` field given the `r_sym` and `r_type` components. -    pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u32) { -        self.r_info = Self::r_info(endian, r_sym, r_type) -    } -} - -impl<E: Endian> From<Rel64<E>> for Rela64<E> { -    fn from(rel: Rel64<E>) -> Self { -        Rela64 { -            r_offset: rel.r_offset, -            r_info: rel.r_info, -            r_addend: I64::default(), -        } -    } -} - -/// Relocation table entry with explicit addend. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Rela64<E: Endian> { -    /// Relocation address. -    pub r_offset: U64<E>, -    /// Relocation type and symbol index. -    pub r_info: U64<E>, -    /// Explicit addend. -    pub r_addend: I64<E>, -} - -impl<E: Endian> Rela64<E> { -    pub(crate) fn get_r_info(&self, endian: E, is_mips64el: bool) -> u64 { -        let mut t = self.r_info.get(endian); -        if is_mips64el { -            t = (t << 32) -                | ((t >> 8) & 0xff000000) -                | ((t >> 24) & 0x00ff0000) -                | ((t >> 40) & 0x0000ff00) -                | ((t >> 56) & 0x000000ff); -        } -        t -    } - -    /// Get the `r_sym` component of the `r_info` field. -    #[inline] -    pub fn r_sym(&self, endian: E, is_mips64el: bool) -> u32 { -        (self.get_r_info(endian, is_mips64el) >> 32) as u32 -    } - -    /// Get the `r_type` component of the `r_info` field. -    #[inline] -    pub fn r_type(&self, endian: E, is_mips64el: bool) -> u32 { -        (self.get_r_info(endian, is_mips64el) & 0xffff_ffff) as u32 -    } - -    /// Calculate the `r_info` field given the `r_sym` and `r_type` components. -    pub fn r_info(endian: E, is_mips64el: bool, r_sym: u32, r_type: u32) -> U64<E> { -        let mut t = (u64::from(r_sym) << 32) | u64::from(r_type); -        if is_mips64el { -            t = (t >> 32) -                | ((t & 0xff000000) << 8) -                | ((t & 0x00ff0000) << 24) -                | ((t & 0x0000ff00) << 40) -                | ((t & 0x000000ff) << 56); -        } -        U64::new(endian, t) -    } - -    /// Set the `r_info` field given the `r_sym` and `r_type` components. -    pub fn set_r_info(&mut self, endian: E, is_mips64el: bool, r_sym: u32, r_type: u32) { -        self.r_info = Self::r_info(endian, is_mips64el, r_sym, r_type); -    } -} - -/// Program segment header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ProgramHeader32<E: Endian> { -    /// Segment type. One of the `PT_*` constants. -    pub p_type: U32<E>, -    /// Segment file offset. -    pub p_offset: U32<E>, -    /// Segment virtual address. -    pub p_vaddr: U32<E>, -    /// Segment physical address. -    pub p_paddr: U32<E>, -    /// Segment size in the file. -    pub p_filesz: U32<E>, -    /// Segment size in memory. -    pub p_memsz: U32<E>, -    /// Segment flags. A combination of the `PF_*` constants. -    pub p_flags: U32<E>, -    /// Segment alignment. -    pub p_align: U32<E>, -} - -/// Program segment header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ProgramHeader64<E: Endian> { -    /// Segment type. One of the `PT_*` constants. -    pub p_type: U32<E>, -    /// Segment flags. A combination of the `PF_*` constants. -    pub p_flags: U32<E>, -    /// Segment file offset. -    pub p_offset: U64<E>, -    /// Segment virtual address. -    pub p_vaddr: U64<E>, -    /// Segment physical address. -    pub p_paddr: U64<E>, -    /// Segment size in the file. -    pub p_filesz: U64<E>, -    /// Segment size in memory. -    pub p_memsz: U64<E>, -    /// Segment alignment. -    pub p_align: U64<E>, -} - -/// Special value for `FileHeader*::e_phnum`. -/// -/// This indicates that the real number of program headers is too large to fit into e_phnum. -/// Instead the real value is in the field `sh_info` of section 0. -pub const PN_XNUM: u16 = 0xffff; - -// Values for `ProgramHeader*::p_type`. -/// Program header table entry is unused. -pub const PT_NULL: u32 = 0; -/// Loadable program segment. -pub const PT_LOAD: u32 = 1; -/// Dynamic linking information. -pub const PT_DYNAMIC: u32 = 2; -/// Program interpreter. -pub const PT_INTERP: u32 = 3; -/// Auxiliary information. -pub const PT_NOTE: u32 = 4; -/// Reserved. -pub const PT_SHLIB: u32 = 5; -/// Segment contains the program header table. -pub const PT_PHDR: u32 = 6; -/// Thread-local storage segment. -pub const PT_TLS: u32 = 7; -/// Start of OS-specific segment types. -pub const PT_LOOS: u32 = 0x6000_0000; -/// GCC `.eh_frame_hdr` segment. -pub const PT_GNU_EH_FRAME: u32 = 0x6474_e550; -/// Indicates stack executability. -pub const PT_GNU_STACK: u32 = 0x6474_e551; -/// Read-only after relocation. -pub const PT_GNU_RELRO: u32 = 0x6474_e552; -/// Segment containing `.note.gnu.property` section. -pub const PT_GNU_PROPERTY: u32 = 0x6474_e553; -/// End of OS-specific segment types. -pub const PT_HIOS: u32 = 0x6fff_ffff; -/// Start of processor-specific segment types. -pub const PT_LOPROC: u32 = 0x7000_0000; -/// End of processor-specific segment types. -pub const PT_HIPROC: u32 = 0x7fff_ffff; - -// Values for `ProgramHeader*::p_flags`. -/// Segment is executable. -pub const PF_X: u32 = 1 << 0; -/// Segment is writable. -pub const PF_W: u32 = 1 << 1; -/// Segment is readable. -pub const PF_R: u32 = 1 << 2; -/// OS-specific segment flags. -pub const PF_MASKOS: u32 = 0x0ff0_0000; -/// Processor-specific segment flags. -pub const PF_MASKPROC: u32 = 0xf000_0000; - -/// Note name for core files. -pub const ELF_NOTE_CORE: &[u8] = b"CORE"; -/// Note name for linux core files. -/// -/// Notes in linux core files may also use `ELF_NOTE_CORE`. -pub const ELF_NOTE_LINUX: &[u8] = b"LINUX"; - -// Values for `NoteHeader*::n_type` in core files. -// -/// Contains copy of prstatus struct. -pub const NT_PRSTATUS: u32 = 1; -/// Contains copy of fpregset struct. -pub const NT_PRFPREG: u32 = 2; -/// Contains copy of fpregset struct. -pub const NT_FPREGSET: u32 = 2; -/// Contains copy of prpsinfo struct. -pub const NT_PRPSINFO: u32 = 3; -/// Contains copy of prxregset struct. -pub const NT_PRXREG: u32 = 4; -/// Contains copy of task structure. -pub const NT_TASKSTRUCT: u32 = 4; -/// String from sysinfo(SI_PLATFORM). -pub const NT_PLATFORM: u32 = 5; -/// Contains copy of auxv array. -pub const NT_AUXV: u32 = 6; -/// Contains copy of gwindows struct. -pub const NT_GWINDOWS: u32 = 7; -/// Contains copy of asrset struct. -pub const NT_ASRS: u32 = 8; -/// Contains copy of pstatus struct. -pub const NT_PSTATUS: u32 = 10; -/// Contains copy of psinfo struct. -pub const NT_PSINFO: u32 = 13; -/// Contains copy of prcred struct. -pub const NT_PRCRED: u32 = 14; -/// Contains copy of utsname struct. -pub const NT_UTSNAME: u32 = 15; -/// Contains copy of lwpstatus struct. -pub const NT_LWPSTATUS: u32 = 16; -/// Contains copy of lwpinfo struct. -pub const NT_LWPSINFO: u32 = 17; -/// Contains copy of fprxregset struct. -pub const NT_PRFPXREG: u32 = 20; -/// Contains copy of siginfo_t, size might increase. -pub const NT_SIGINFO: u32 = 0x5349_4749; -/// Contains information about mapped files. -pub const NT_FILE: u32 = 0x4649_4c45; -/// Contains copy of user_fxsr_struct. -pub const NT_PRXFPREG: u32 = 0x46e6_2b7f; -/// PowerPC Altivec/VMX registers. -pub const NT_PPC_VMX: u32 = 0x100; -/// PowerPC SPE/EVR registers. -pub const NT_PPC_SPE: u32 = 0x101; -/// PowerPC VSX registers. -pub const NT_PPC_VSX: u32 = 0x102; -/// Target Address Register. -pub const NT_PPC_TAR: u32 = 0x103; -/// Program Priority Register. -pub const NT_PPC_PPR: u32 = 0x104; -/// Data Stream Control Register. -pub const NT_PPC_DSCR: u32 = 0x105; -/// Event Based Branch Registers. -pub const NT_PPC_EBB: u32 = 0x106; -/// Performance Monitor Registers. -pub const NT_PPC_PMU: u32 = 0x107; -/// TM checkpointed GPR Registers. -pub const NT_PPC_TM_CGPR: u32 = 0x108; -/// TM checkpointed FPR Registers. -pub const NT_PPC_TM_CFPR: u32 = 0x109; -/// TM checkpointed VMX Registers. -pub const NT_PPC_TM_CVMX: u32 = 0x10a; -/// TM checkpointed VSX Registers. -pub const NT_PPC_TM_CVSX: u32 = 0x10b; -/// TM Special Purpose Registers. -pub const NT_PPC_TM_SPR: u32 = 0x10c; -/// TM checkpointed Target Address Register. -pub const NT_PPC_TM_CTAR: u32 = 0x10d; -/// TM checkpointed Program Priority Register. -pub const NT_PPC_TM_CPPR: u32 = 0x10e; -/// TM checkpointed Data Stream Control Register. -pub const NT_PPC_TM_CDSCR: u32 = 0x10f; -/// Memory Protection Keys registers. -pub const NT_PPC_PKEY: u32 = 0x110; -/// i386 TLS slots (struct user_desc). -pub const NT_386_TLS: u32 = 0x200; -/// x86 io permission bitmap (1=deny). -pub const NT_386_IOPERM: u32 = 0x201; -/// x86 extended state using xsave. -pub const NT_X86_XSTATE: u32 = 0x202; -/// s390 upper register halves. -pub const NT_S390_HIGH_GPRS: u32 = 0x300; -/// s390 timer register. -pub const NT_S390_TIMER: u32 = 0x301; -/// s390 TOD clock comparator register. -pub const NT_S390_TODCMP: u32 = 0x302; -/// s390 TOD programmable register. -pub const NT_S390_TODPREG: u32 = 0x303; -/// s390 control registers. -pub const NT_S390_CTRS: u32 = 0x304; -/// s390 prefix register. -pub const NT_S390_PREFIX: u32 = 0x305; -/// s390 breaking event address. -pub const NT_S390_LAST_BREAK: u32 = 0x306; -/// s390 system call restart data. -pub const NT_S390_SYSTEM_CALL: u32 = 0x307; -/// s390 transaction diagnostic block. -pub const NT_S390_TDB: u32 = 0x308; -/// s390 vector registers 0-15 upper half. -pub const NT_S390_VXRS_LOW: u32 = 0x309; -/// s390 vector registers 16-31. -pub const NT_S390_VXRS_HIGH: u32 = 0x30a; -/// s390 guarded storage registers. -pub const NT_S390_GS_CB: u32 = 0x30b; -/// s390 guarded storage broadcast control block. -pub const NT_S390_GS_BC: u32 = 0x30c; -/// s390 runtime instrumentation. -pub const NT_S390_RI_CB: u32 = 0x30d; -/// ARM VFP/NEON registers. -pub const NT_ARM_VFP: u32 = 0x400; -/// ARM TLS register. -pub const NT_ARM_TLS: u32 = 0x401; -/// ARM hardware breakpoint registers. -pub const NT_ARM_HW_BREAK: u32 = 0x402; -/// ARM hardware watchpoint registers. -pub const NT_ARM_HW_WATCH: u32 = 0x403; -/// ARM system call number. -pub const NT_ARM_SYSTEM_CALL: u32 = 0x404; -/// ARM Scalable Vector Extension registers. -pub const NT_ARM_SVE: u32 = 0x405; -/// Vmcore Device Dump Note. -pub const NT_VMCOREDD: u32 = 0x700; -/// MIPS DSP ASE registers. -pub const NT_MIPS_DSP: u32 = 0x800; -/// MIPS floating-point mode. -pub const NT_MIPS_FP_MODE: u32 = 0x801; - -/// Note type for version string. -/// -/// This note may appear in object files. -/// -/// It must be handled as a special case because it has no descriptor, and instead -/// uses the note name as the version string. -pub const NT_VERSION: u32 = 1; - -/// Dynamic section entry. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Dyn32<E: Endian> { -    /// Dynamic entry type. -    pub d_tag: U32<E>, -    /// Value (integer or address). -    pub d_val: U32<E>, -} - -/// Dynamic section entry. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Dyn64<E: Endian> { -    /// Dynamic entry type. -    pub d_tag: U64<E>, -    /// Value (integer or address). -    pub d_val: U64<E>, -} - -// Values for `Dyn*::d_tag`. - -/// Marks end of dynamic section -pub const DT_NULL: u32 = 0; -/// Name of needed library -pub const DT_NEEDED: u32 = 1; -/// Size in bytes of PLT relocs -pub const DT_PLTRELSZ: u32 = 2; -/// Processor defined value -pub const DT_PLTGOT: u32 = 3; -/// Address of symbol hash table -pub const DT_HASH: u32 = 4; -/// Address of string table -pub const DT_STRTAB: u32 = 5; -/// Address of symbol table -pub const DT_SYMTAB: u32 = 6; -/// Address of Rela relocs -pub const DT_RELA: u32 = 7; -/// Total size of Rela relocs -pub const DT_RELASZ: u32 = 8; -/// Size of one Rela reloc -pub const DT_RELAENT: u32 = 9; -/// Size of string table -pub const DT_STRSZ: u32 = 10; -/// Size of one symbol table entry -pub const DT_SYMENT: u32 = 11; -/// Address of init function -pub const DT_INIT: u32 = 12; -/// Address of termination function -pub const DT_FINI: u32 = 13; -/// Name of shared object -pub const DT_SONAME: u32 = 14; -/// Library search path (deprecated) -pub const DT_RPATH: u32 = 15; -/// Start symbol search here -pub const DT_SYMBOLIC: u32 = 16; -/// Address of Rel relocs -pub const DT_REL: u32 = 17; -/// Total size of Rel relocs -pub const DT_RELSZ: u32 = 18; -/// Size of one Rel reloc -pub const DT_RELENT: u32 = 19; -/// Type of reloc in PLT -pub const DT_PLTREL: u32 = 20; -/// For debugging; unspecified -pub const DT_DEBUG: u32 = 21; -/// Reloc might modify .text -pub const DT_TEXTREL: u32 = 22; -/// Address of PLT relocs -pub const DT_JMPREL: u32 = 23; -/// Process relocations of object -pub const DT_BIND_NOW: u32 = 24; -/// Array with addresses of init fct -pub const DT_INIT_ARRAY: u32 = 25; -/// Array with addresses of fini fct -pub const DT_FINI_ARRAY: u32 = 26; -/// Size in bytes of DT_INIT_ARRAY -pub const DT_INIT_ARRAYSZ: u32 = 27; -/// Size in bytes of DT_FINI_ARRAY -pub const DT_FINI_ARRAYSZ: u32 = 28; -/// Library search path -pub const DT_RUNPATH: u32 = 29; -/// Flags for the object being loaded -pub const DT_FLAGS: u32 = 30; -/// Start of encoded range -pub const DT_ENCODING: u32 = 32; -/// Array with addresses of preinit fct -pub const DT_PREINIT_ARRAY: u32 = 32; -/// size in bytes of DT_PREINIT_ARRAY -pub const DT_PREINIT_ARRAYSZ: u32 = 33; -/// Address of SYMTAB_SHNDX section -pub const DT_SYMTAB_SHNDX: u32 = 34; -/// Start of OS-specific -pub const DT_LOOS: u32 = 0x6000_000d; -/// End of OS-specific -pub const DT_HIOS: u32 = 0x6fff_f000; -/// Start of processor-specific -pub const DT_LOPROC: u32 = 0x7000_0000; -/// End of processor-specific -pub const DT_HIPROC: u32 = 0x7fff_ffff; - -// `DT_*` entries between `DT_VALRNGHI` & `DT_VALRNGLO` use `d_val` as a value. -pub const DT_VALRNGLO: u32 = 0x6fff_fd00; -/// Prelinking timestamp -pub const DT_GNU_PRELINKED: u32 = 0x6fff_fdf5; -/// Size of conflict section -pub const DT_GNU_CONFLICTSZ: u32 = 0x6fff_fdf6; -/// Size of library list -pub const DT_GNU_LIBLISTSZ: u32 = 0x6fff_fdf7; -pub const DT_CHECKSUM: u32 = 0x6fff_fdf8; -pub const DT_PLTPADSZ: u32 = 0x6fff_fdf9; -pub const DT_MOVEENT: u32 = 0x6fff_fdfa; -pub const DT_MOVESZ: u32 = 0x6fff_fdfb; -/// Feature selection (DTF_*). -pub const DT_FEATURE_1: u32 = 0x6fff_fdfc; -/// Flags for DT_* entries, affecting the following DT_* entry. -pub const DT_POSFLAG_1: u32 = 0x6fff_fdfd; -/// Size of syminfo table (in bytes) -pub const DT_SYMINSZ: u32 = 0x6fff_fdfe; -/// Entry size of syminfo -pub const DT_SYMINENT: u32 = 0x6fff_fdff; -pub const DT_VALRNGHI: u32 = 0x6fff_fdff; - -// `DT_*` entries between `DT_ADDRRNGHI` & `DT_ADDRRNGLO` use `d_val` as an address. -// -// If any adjustment is made to the ELF object after it has been -// built these entries will need to be adjusted. -pub const DT_ADDRRNGLO: u32 = 0x6fff_fe00; -/// GNU-style hash table. -pub const DT_GNU_HASH: u32 = 0x6fff_fef5; -pub const DT_TLSDESC_PLT: u32 = 0x6fff_fef6; -pub const DT_TLSDESC_GOT: u32 = 0x6fff_fef7; -/// Start of conflict section -pub const DT_GNU_CONFLICT: u32 = 0x6fff_fef8; -/// Library list -pub const DT_GNU_LIBLIST: u32 = 0x6fff_fef9; -/// Configuration information. -pub const DT_CONFIG: u32 = 0x6fff_fefa; -/// Dependency auditing. -pub const DT_DEPAUDIT: u32 = 0x6fff_fefb; -/// Object auditing. -pub const DT_AUDIT: u32 = 0x6fff_fefc; -/// PLT padding. -pub const DT_PLTPAD: u32 = 0x6fff_fefd; -/// Move table. -pub const DT_MOVETAB: u32 = 0x6fff_fefe; -/// Syminfo table. -pub const DT_SYMINFO: u32 = 0x6fff_feff; -pub const DT_ADDRRNGHI: u32 = 0x6fff_feff; - -// The versioning entry types.  The next are defined as part of the -// GNU extension. -pub const DT_VERSYM: u32 = 0x6fff_fff0; -pub const DT_RELACOUNT: u32 = 0x6fff_fff9; -pub const DT_RELCOUNT: u32 = 0x6fff_fffa; -/// State flags, see DF_1_* below. -pub const DT_FLAGS_1: u32 = 0x6fff_fffb; -/// Address of version definition table -pub const DT_VERDEF: u32 = 0x6fff_fffc; -/// Number of version definitions -pub const DT_VERDEFNUM: u32 = 0x6fff_fffd; -/// Address of table with needed versions -pub const DT_VERNEED: u32 = 0x6fff_fffe; -/// Number of needed versions -pub const DT_VERNEEDNUM: u32 = 0x6fff_ffff; - -// Machine-independent extensions in the "processor-specific" range. -/// Shared object to load before self -pub const DT_AUXILIARY: u32 = 0x7fff_fffd; -/// Shared object to get values from -pub const DT_FILTER: u32 = 0x7fff_ffff; - -// Values of `Dyn*::d_val` in the `DT_FLAGS` entry. -/// Object may use DF_ORIGIN -pub const DF_ORIGIN: u32 = 0x0000_0001; -/// Symbol resolutions starts here -pub const DF_SYMBOLIC: u32 = 0x0000_0002; -/// Object contains text relocations -pub const DF_TEXTREL: u32 = 0x0000_0004; -/// No lazy binding for this object -pub const DF_BIND_NOW: u32 = 0x0000_0008; -/// Module uses the static TLS model -pub const DF_STATIC_TLS: u32 = 0x0000_0010; - -// Values of `Dyn*::d_val` in the `DT_FLAGS_1` entry. -/// Set RTLD_NOW for this object. -pub const DF_1_NOW: u32 = 0x0000_0001; -/// Set RTLD_GLOBAL for this object. -pub const DF_1_GLOBAL: u32 = 0x0000_0002; -/// Set RTLD_GROUP for this object. -pub const DF_1_GROUP: u32 = 0x0000_0004; -/// Set RTLD_NODELETE for this object. -pub const DF_1_NODELETE: u32 = 0x0000_0008; -/// Trigger filtee loading at runtime. -pub const DF_1_LOADFLTR: u32 = 0x0000_0010; -/// Set RTLD_INITFIRST for this object. -pub const DF_1_INITFIRST: u32 = 0x0000_0020; -/// Set RTLD_NOOPEN for this object. -pub const DF_1_NOOPEN: u32 = 0x0000_0040; -/// $ORIGIN must be handled. -pub const DF_1_ORIGIN: u32 = 0x0000_0080; -/// Direct binding enabled. -pub const DF_1_DIRECT: u32 = 0x0000_0100; -pub const DF_1_TRANS: u32 = 0x0000_0200; -/// Object is used to interpose. -pub const DF_1_INTERPOSE: u32 = 0x0000_0400; -/// Ignore default lib search path. -pub const DF_1_NODEFLIB: u32 = 0x0000_0800; -/// Object can't be dldump'ed. -pub const DF_1_NODUMP: u32 = 0x0000_1000; -/// Configuration alternative created. -pub const DF_1_CONFALT: u32 = 0x0000_2000; -/// Filtee terminates filters search. -pub const DF_1_ENDFILTEE: u32 = 0x0000_4000; -/// Disp reloc applied at build time. -pub const DF_1_DISPRELDNE: u32 = 0x0000_8000; -/// Disp reloc applied at run-time. -pub const DF_1_DISPRELPND: u32 = 0x0001_0000; -/// Object has no-direct binding. -pub const DF_1_NODIRECT: u32 = 0x0002_0000; -pub const DF_1_IGNMULDEF: u32 = 0x0004_0000; -pub const DF_1_NOKSYMS: u32 = 0x0008_0000; -pub const DF_1_NOHDR: u32 = 0x0010_0000; -/// Object is modified after built. -pub const DF_1_EDITED: u32 = 0x0020_0000; -pub const DF_1_NORELOC: u32 = 0x0040_0000; -/// Object has individual interposers. -pub const DF_1_SYMINTPOSE: u32 = 0x0080_0000; -/// Global auditing required. -pub const DF_1_GLOBAUDIT: u32 = 0x0100_0000; -/// Singleton symbols are used. -pub const DF_1_SINGLETON: u32 = 0x0200_0000; -pub const DF_1_STUB: u32 = 0x0400_0000; -pub const DF_1_PIE: u32 = 0x0800_0000; - -/// Version symbol information -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Versym<E: Endian>(pub U16<E>); - -/// Symbol is hidden. -pub const VERSYM_HIDDEN: u16 = 0x8000; -/// Symbol version index. -pub const VERSYM_VERSION: u16 = 0x7fff; - -/// Version definition sections -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Verdef<E: Endian> { -    /// Version revision -    pub vd_version: U16<E>, -    /// Version information -    pub vd_flags: U16<E>, -    /// Version Index -    pub vd_ndx: U16<E>, -    /// Number of associated aux entries -    pub vd_cnt: U16<E>, -    /// Version name hash value -    pub vd_hash: U32<E>, -    /// Offset in bytes to verdaux array -    pub vd_aux: U32<E>, -    /// Offset in bytes to next verdef entry -    pub vd_next: U32<E>, -} - -// Legal values for vd_version (version revision). -/// No version -pub const VER_DEF_NONE: u16 = 0; -/// Current version -pub const VER_DEF_CURRENT: u16 = 1; - -// Legal values for vd_flags (version information flags). -/// Version definition of file itself -pub const VER_FLG_BASE: u16 = 0x1; -// Legal values for vd_flags and vna_flags (version information flags). -/// Weak version identifier -pub const VER_FLG_WEAK: u16 = 0x2; - -// Versym symbol index values. -/// Symbol is local. -pub const VER_NDX_LOCAL: u16 = 0; -/// Symbol is global. -pub const VER_NDX_GLOBAL: u16 = 1; - -/// Auxiliary version information. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Verdaux<E: Endian> { -    /// Version or dependency names -    pub vda_name: U32<E>, -    /// Offset in bytes to next verdaux -    pub vda_next: U32<E>, -} - -/// Version dependency. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Verneed<E: Endian> { -    /// Version of structure -    pub vn_version: U16<E>, -    /// Number of associated aux entries -    pub vn_cnt: U16<E>, -    /// Offset of filename for this dependency -    pub vn_file: U32<E>, -    /// Offset in bytes to vernaux array -    pub vn_aux: U32<E>, -    /// Offset in bytes to next verneed entry -    pub vn_next: U32<E>, -} - -// Legal values for vn_version (version revision). -/// No version -pub const VER_NEED_NONE: u16 = 0; -/// Current version -pub const VER_NEED_CURRENT: u16 = 1; - -/// Auxiliary needed version information. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Vernaux<E: Endian> { -    /// Hash value of dependency name -    pub vna_hash: U32<E>, -    /// Dependency specific information -    pub vna_flags: U16<E>, -    /// Version Index -    pub vna_other: U16<E>, -    /// Dependency name string offset -    pub vna_name: U32<E>, -    /// Offset in bytes to next vernaux entry -    pub vna_next: U32<E>, -} - -// TODO: Elf*_auxv_t, AT_* - -/// Note section entry header. -/// -/// A note consists of a header followed by a variable length name and descriptor. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct NoteHeader32<E: Endian> { -    /// Length of the note's name. -    /// -    /// Some known names are defined by the `ELF_NOTE_*` constants. -    pub n_namesz: U32<E>, -    /// Length of the note's descriptor. -    /// -    /// The content of the descriptor depends on the note name and type. -    pub n_descsz: U32<E>, -    /// Type of the note. -    /// -    /// One of the `NT_*` constants. The note name determines which -    /// `NT_*` constants are valid. -    pub n_type: U32<E>, -} - -/// Note section entry header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct NoteHeader64<E: Endian> { -    /// Length of the note's name. -    /// -    /// Some known names are defined by the `ELF_NOTE_*` constants. -    pub n_namesz: U32<E>, -    /// Length of the note's descriptor. -    /// -    /// The content of the descriptor depends on the note name and type. -    pub n_descsz: U32<E>, -    /// Type of the note. -    /// -    /// One of the `NT_*` constants. The note name determines which -    /// `NT_*` constants are valid. -    pub n_type: U32<E>, -} - -/// Solaris entries in the note section have this name. -pub const ELF_NOTE_SOLARIS: &[u8] = b"SUNW Solaris"; - -// Values for `n_type` when the name is `ELF_NOTE_SOLARIS`. -/// Desired pagesize for the binary. -pub const NT_SOLARIS_PAGESIZE_HINT: u32 = 1; - -/// GNU entries in the note section have this name. -pub const ELF_NOTE_GNU: &[u8] = b"GNU"; - -/// Go entries in the note section have this name. -// See https://go-review.googlesource.com/9520 and https://go-review.googlesource.com/10704. -pub const ELF_NOTE_GO: &[u8] = b"Go"; - -// Note types for `ELF_NOTE_GNU`. - -/// ABI information. -/// -/// The descriptor consists of words: -/// - word 0: OS descriptor -/// - word 1: major version of the ABI -/// - word 2: minor version of the ABI -/// - word 3: subminor version of the ABI -pub const NT_GNU_ABI_TAG: u32 = 1; - -/// OS descriptor for `NT_GNU_ABI_TAG`. -pub const ELF_NOTE_OS_LINUX: u32 = 0; -/// OS descriptor for `NT_GNU_ABI_TAG`. -pub const ELF_NOTE_OS_GNU: u32 = 1; -/// OS descriptor for `NT_GNU_ABI_TAG`. -pub const ELF_NOTE_OS_SOLARIS2: u32 = 2; -/// OS descriptor for `NT_GNU_ABI_TAG`. -pub const ELF_NOTE_OS_FREEBSD: u32 = 3; - -/// Synthetic hwcap information. -/// -/// The descriptor begins with two words: -/// - word 0: number of entries -/// - word 1: bitmask of enabled entries -/// Then follow variable-length entries, one byte followed by a -/// '\0'-terminated hwcap name string.  The byte gives the bit -/// number to test if enabled, (1U << bit) & bitmask.  */ -pub const NT_GNU_HWCAP: u32 = 2; - -/// Build ID bits as generated by `ld --build-id`. -/// -/// The descriptor consists of any nonzero number of bytes. -pub const NT_GNU_BUILD_ID: u32 = 3; - -/// Build ID bits as generated by Go's gc compiler. -/// -/// The descriptor consists of any nonzero number of bytes. -// See https://go-review.googlesource.com/10707. -pub const NT_GO_BUILD_ID: u32 = 4; - -/// Version note generated by GNU gold containing a version string. -pub const NT_GNU_GOLD_VERSION: u32 = 4; - -/// Program property. -pub const NT_GNU_PROPERTY_TYPE_0: u32 = 5; - -// Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). - -/// Stack size. -pub const GNU_PROPERTY_STACK_SIZE: u32 = 1; -/// No copy relocation on protected data symbol. -pub const GNU_PROPERTY_NO_COPY_ON_PROTECTED: u32 = 2; - -// A 4-byte unsigned integer property: A bit is set if it is set in all -// relocatable inputs. -pub const GNU_PROPERTY_UINT32_AND_LO: u32 = 0xb0000000; -pub const GNU_PROPERTY_UINT32_AND_HI: u32 = 0xb0007fff; - -// A 4-byte unsigned integer property: A bit is set if it is set in any -// relocatable inputs. -pub const GNU_PROPERTY_UINT32_OR_LO: u32 = 0xb0008000; -pub const GNU_PROPERTY_UINT32_OR_HI: u32 = 0xb000ffff; - -/// The needed properties by the object file.  */ -pub const GNU_PROPERTY_1_NEEDED: u32 = GNU_PROPERTY_UINT32_OR_LO; - -/// Set if the object file requires canonical function pointers and -/// cannot be used with copy relocation. -pub const GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS: u32 = 1 << 0; - -/// Processor-specific semantics, lo -pub const GNU_PROPERTY_LOPROC: u32 = 0xc0000000; -/// Processor-specific semantics, hi -pub const GNU_PROPERTY_HIPROC: u32 = 0xdfffffff; -/// Application-specific semantics, lo -pub const GNU_PROPERTY_LOUSER: u32 = 0xe0000000; -/// Application-specific semantics, hi -pub const GNU_PROPERTY_HIUSER: u32 = 0xffffffff; - -/// AArch64 specific GNU properties. -pub const GNU_PROPERTY_AARCH64_FEATURE_1_AND: u32 = 0xc0000000; -pub const GNU_PROPERTY_AARCH64_FEATURE_PAUTH: u32 = 0xc0000001; - -pub const GNU_PROPERTY_AARCH64_FEATURE_1_BTI: u32 = 1 << 0; -pub const GNU_PROPERTY_AARCH64_FEATURE_1_PAC: u32 = 1 << 1; - -// A 4-byte unsigned integer property: A bit is set if it is set in all -// relocatable inputs. -pub const GNU_PROPERTY_X86_UINT32_AND_LO: u32 = 0xc0000002; -pub const GNU_PROPERTY_X86_UINT32_AND_HI: u32 = 0xc0007fff; - -// A 4-byte unsigned integer property: A bit is set if it is set in any -// relocatable inputs. -pub const GNU_PROPERTY_X86_UINT32_OR_LO: u32 = 0xc0008000; -pub const GNU_PROPERTY_X86_UINT32_OR_HI: u32 = 0xc000ffff; - -// A 4-byte unsigned integer property: A bit is set if it is set in any -// relocatable inputs and the property is present in all relocatable -// inputs. -pub const GNU_PROPERTY_X86_UINT32_OR_AND_LO: u32 = 0xc0010000; -pub const GNU_PROPERTY_X86_UINT32_OR_AND_HI: u32 = 0xc0017fff; - -/// The x86 instruction sets indicated by the corresponding bits are -/// used in program.  Their support in the hardware is optional. -pub const GNU_PROPERTY_X86_ISA_1_USED: u32 = 0xc0010002; -/// The x86 instruction sets indicated by the corresponding bits are -/// used in program and they must be supported by the hardware. -pub const GNU_PROPERTY_X86_ISA_1_NEEDED: u32 = 0xc0008002; -/// X86 processor-specific features used in program. -pub const GNU_PROPERTY_X86_FEATURE_1_AND: u32 = 0xc0000002; - -/// GNU_PROPERTY_X86_ISA_1_BASELINE: CMOV, CX8 (cmpxchg8b), FPU (fld), -/// MMX, OSFXSR (fxsave), SCE (syscall), SSE and SSE2. -pub const GNU_PROPERTY_X86_ISA_1_BASELINE: u32 = 1 << 0; -/// GNU_PROPERTY_X86_ISA_1_V2: GNU_PROPERTY_X86_ISA_1_BASELINE, -/// CMPXCHG16B (cmpxchg16b), LAHF-SAHF (lahf), POPCNT (popcnt), SSE3, -/// SSSE3, SSE4.1 and SSE4.2. -pub const GNU_PROPERTY_X86_ISA_1_V2: u32 = 1 << 1; -/// GNU_PROPERTY_X86_ISA_1_V3: GNU_PROPERTY_X86_ISA_1_V2, AVX, AVX2, BMI1, -/// BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE. -pub const GNU_PROPERTY_X86_ISA_1_V3: u32 = 1 << 2; -/// GNU_PROPERTY_X86_ISA_1_V4: GNU_PROPERTY_X86_ISA_1_V3, AVX512F, -/// AVX512BW, AVX512CD, AVX512DQ and AVX512VL. -pub const GNU_PROPERTY_X86_ISA_1_V4: u32 = 1 << 3; - -/// This indicates that all executable sections are compatible with IBT. -pub const GNU_PROPERTY_X86_FEATURE_1_IBT: u32 = 1 << 0; -/// This indicates that all executable sections are compatible with SHSTK. -pub const GNU_PROPERTY_X86_FEATURE_1_SHSTK: u32 = 1 << 1; - -// TODO: Elf*_Move - -/// Header of `SHT_HASH` section. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct HashHeader<E: Endian> { -    /// The number of hash buckets. -    pub bucket_count: U32<E>, -    /// The number of chain values. -    pub chain_count: U32<E>, -    // Array of hash bucket start indices. -    // buckets: U32<E>[bucket_count] -    // Array of hash chain links. An index of 0 terminates the chain. -    // chains: U32<E>[chain_count] -} - -/// Calculate the SysV hash for a symbol name. -/// -/// Used for `SHT_HASH`. -pub fn hash(name: &[u8]) -> u32 { -    let mut hash = 0u32; -    for byte in name { -        hash = hash.wrapping_mul(16).wrapping_add(u32::from(*byte)); -        hash ^= (hash >> 24) & 0xf0; -    } -    hash & 0xfff_ffff -} - -/// Header of `SHT_GNU_HASH` section. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct GnuHashHeader<E: Endian> { -    /// The number of hash buckets. -    pub bucket_count: U32<E>, -    /// The symbol table index of the first symbol in the hash. -    pub symbol_base: U32<E>, -    /// The number of words in the bloom filter. -    /// -    /// Must be a non-zero power of 2. -    pub bloom_count: U32<E>, -    /// The bit shift count for the bloom filter. -    pub bloom_shift: U32<E>, -    // Array of bloom filter words. -    // bloom_filters: U32<E>[bloom_count] or U64<E>[bloom_count] -    // Array of hash bucket start indices. -    // buckets: U32<E>[bucket_count] -    // Array of hash values, one for each symbol starting at symbol_base. -    // values: U32<E>[symbol_count] -} - -/// Calculate the GNU hash for a symbol name. -/// -/// Used for `SHT_GNU_HASH`. -pub fn gnu_hash(name: &[u8]) -> u32 { -    let mut hash = 5381u32; -    for byte in name { -        hash = hash.wrapping_mul(33).wrapping_add(u32::from(*byte)); -    } -    hash -} - -// Motorola 68k specific definitions. - -// m68k values for `Rel*::r_type`. - -/// No reloc -pub const R_68K_NONE: u32 = 0; -/// Direct 32 bit -pub const R_68K_32: u32 = 1; -/// Direct 16 bit -pub const R_68K_16: u32 = 2; -/// Direct 8 bit -pub const R_68K_8: u32 = 3; -/// PC relative 32 bit -pub const R_68K_PC32: u32 = 4; -/// PC relative 16 bit -pub const R_68K_PC16: u32 = 5; -/// PC relative 8 bit -pub const R_68K_PC8: u32 = 6; -/// 32 bit PC relative GOT entry -pub const R_68K_GOT32: u32 = 7; -/// 16 bit PC relative GOT entry -pub const R_68K_GOT16: u32 = 8; -/// 8 bit PC relative GOT entry -pub const R_68K_GOT8: u32 = 9; -/// 32 bit GOT offset -pub const R_68K_GOT32O: u32 = 10; -/// 16 bit GOT offset -pub const R_68K_GOT16O: u32 = 11; -/// 8 bit GOT offset -pub const R_68K_GOT8O: u32 = 12; -/// 32 bit PC relative PLT address -pub const R_68K_PLT32: u32 = 13; -/// 16 bit PC relative PLT address -pub const R_68K_PLT16: u32 = 14; -/// 8 bit PC relative PLT address -pub const R_68K_PLT8: u32 = 15; -/// 32 bit PLT offset -pub const R_68K_PLT32O: u32 = 16; -/// 16 bit PLT offset -pub const R_68K_PLT16O: u32 = 17; -/// 8 bit PLT offset -pub const R_68K_PLT8O: u32 = 18; -/// Copy symbol at runtime -pub const R_68K_COPY: u32 = 19; -/// Create GOT entry -pub const R_68K_GLOB_DAT: u32 = 20; -/// Create PLT entry -pub const R_68K_JMP_SLOT: u32 = 21; -/// Adjust by program base -pub const R_68K_RELATIVE: u32 = 22; -/// 32 bit GOT offset for GD -pub const R_68K_TLS_GD32: u32 = 25; -/// 16 bit GOT offset for GD -pub const R_68K_TLS_GD16: u32 = 26; -/// 8 bit GOT offset for GD -pub const R_68K_TLS_GD8: u32 = 27; -/// 32 bit GOT offset for LDM -pub const R_68K_TLS_LDM32: u32 = 28; -/// 16 bit GOT offset for LDM -pub const R_68K_TLS_LDM16: u32 = 29; -/// 8 bit GOT offset for LDM -pub const R_68K_TLS_LDM8: u32 = 30; -/// 32 bit module-relative offset -pub const R_68K_TLS_LDO32: u32 = 31; -/// 16 bit module-relative offset -pub const R_68K_TLS_LDO16: u32 = 32; -/// 8 bit module-relative offset -pub const R_68K_TLS_LDO8: u32 = 33; -/// 32 bit GOT offset for IE -pub const R_68K_TLS_IE32: u32 = 34; -/// 16 bit GOT offset for IE -pub const R_68K_TLS_IE16: u32 = 35; -/// 8 bit GOT offset for IE -pub const R_68K_TLS_IE8: u32 = 36; -/// 32 bit offset relative to static TLS block -pub const R_68K_TLS_LE32: u32 = 37; -/// 16 bit offset relative to static TLS block -pub const R_68K_TLS_LE16: u32 = 38; -/// 8 bit offset relative to static TLS block -pub const R_68K_TLS_LE8: u32 = 39; -/// 32 bit module number -pub const R_68K_TLS_DTPMOD32: u32 = 40; -/// 32 bit module-relative offset -pub const R_68K_TLS_DTPREL32: u32 = 41; -/// 32 bit TP-relative offset -pub const R_68K_TLS_TPREL32: u32 = 42; - -// Intel 80386 specific definitions. - -// i386 values for `Rel*::r_type`. - -/// No reloc -pub const R_386_NONE: u32 = 0; -/// Direct 32 bit -pub const R_386_32: u32 = 1; -/// PC relative 32 bit -pub const R_386_PC32: u32 = 2; -/// 32 bit GOT entry -pub const R_386_GOT32: u32 = 3; -/// 32 bit PLT address -pub const R_386_PLT32: u32 = 4; -/// Copy symbol at runtime -pub const R_386_COPY: u32 = 5; -/// Create GOT entry -pub const R_386_GLOB_DAT: u32 = 6; -/// Create PLT entry -pub const R_386_JMP_SLOT: u32 = 7; -/// Adjust by program base -pub const R_386_RELATIVE: u32 = 8; -/// 32 bit offset to GOT -pub const R_386_GOTOFF: u32 = 9; -/// 32 bit PC relative offset to GOT -pub const R_386_GOTPC: u32 = 10; -/// Direct 32 bit PLT address -pub const R_386_32PLT: u32 = 11; -/// Offset in static TLS block -pub const R_386_TLS_TPOFF: u32 = 14; -/// Address of GOT entry for static TLS block offset -pub const R_386_TLS_IE: u32 = 15; -/// GOT entry for static TLS block offset -pub const R_386_TLS_GOTIE: u32 = 16; -/// Offset relative to static TLS block -pub const R_386_TLS_LE: u32 = 17; -/// Direct 32 bit for GNU version of general dynamic thread local data -pub const R_386_TLS_GD: u32 = 18; -/// Direct 32 bit for GNU version of local dynamic thread local data in LE code -pub const R_386_TLS_LDM: u32 = 19; -/// Direct 16 bit -pub const R_386_16: u32 = 20; -/// PC relative 16 bit -pub const R_386_PC16: u32 = 21; -/// Direct 8 bit -pub const R_386_8: u32 = 22; -/// PC relative 8 bit -pub const R_386_PC8: u32 = 23; -/// Direct 32 bit for general dynamic thread local data -pub const R_386_TLS_GD_32: u32 = 24; -/// Tag for pushl in GD TLS code -pub const R_386_TLS_GD_PUSH: u32 = 25; -/// Relocation for call to __tls_get_addr() -pub const R_386_TLS_GD_CALL: u32 = 26; -/// Tag for popl in GD TLS code -pub const R_386_TLS_GD_POP: u32 = 27; -/// Direct 32 bit for local dynamic thread local data in LE code -pub const R_386_TLS_LDM_32: u32 = 28; -/// Tag for pushl in LDM TLS code -pub const R_386_TLS_LDM_PUSH: u32 = 29; -/// Relocation for call to __tls_get_addr() in LDM code -pub const R_386_TLS_LDM_CALL: u32 = 30; -/// Tag for popl in LDM TLS code -pub const R_386_TLS_LDM_POP: u32 = 31; -/// Offset relative to TLS block -pub const R_386_TLS_LDO_32: u32 = 32; -/// GOT entry for negated static TLS block offset -pub const R_386_TLS_IE_32: u32 = 33; -/// Negated offset relative to static TLS block -pub const R_386_TLS_LE_32: u32 = 34; -/// ID of module containing symbol -pub const R_386_TLS_DTPMOD32: u32 = 35; -/// Offset in TLS block -pub const R_386_TLS_DTPOFF32: u32 = 36; -/// Negated offset in static TLS block -pub const R_386_TLS_TPOFF32: u32 = 37; -/// 32-bit symbol size -pub const R_386_SIZE32: u32 = 38; -/// GOT offset for TLS descriptor. -pub const R_386_TLS_GOTDESC: u32 = 39; -/// Marker of call through TLS descriptor for relaxation. -pub const R_386_TLS_DESC_CALL: u32 = 40; -/// TLS descriptor containing pointer to code and to argument, returning the TLS offset for the symbol. -pub const R_386_TLS_DESC: u32 = 41; -/// Adjust indirectly by program base -pub const R_386_IRELATIVE: u32 = 42; -/// Load from 32 bit GOT entry, relaxable. -pub const R_386_GOT32X: u32 = 43; - -// ADI SHARC specific definitions - -// SHARC values for `Rel*::r_type` - -/// 24-bit absolute address in bits 23:0 of a 48-bit instr -/// -/// Targets: -/// -/// * Type 25a (PC_DIRECT) -pub const R_SHARC_ADDR24_V3: u32 = 0x0b; - -/// 32-bit absolute address in bits 31:0 of a 48-bit instr -/// -/// Targets: -/// -/// * Type 14a -/// * Type 14d -/// * Type 15a -/// * Type 16a -/// * Type 17a -/// * Type 18a -/// * Type 19a -pub const R_SHARC_ADDR32_V3: u32 = 0x0c; - -/// 32-bit absolute address in bits 31:0 of a 32-bit data location -/// -/// Represented with `RelocationEncoding::Generic` -pub const R_SHARC_ADDR_VAR_V3: u32 = 0x0d; - -/// 6-bit PC-relative address in bits 32:27 of a 48-bit instr -/// -/// Targets: -/// -/// * Type 9a -/// * Type 10a -pub const R_SHARC_PCRSHORT_V3: u32 = 0x0e; - -/// 24-bit PC-relative address in bits 23:0 of a 48-bit instr -/// -/// Targets: -/// -/// * Type 8a -/// * Type 12a (truncated to 23 bits after relocation) -/// * Type 13a (truncated to 23 bits after relocation) -/// * Type 25a (PC Relative) -pub const R_SHARC_PCRLONG_V3: u32 = 0x0f; - -/// 6-bit absolute address in bits 32:27 of a 48-bit instr -/// -/// Targets: -/// -/// * Type 4a -/// * Type 4b -/// * Type 4d -pub const R_SHARC_DATA6_V3: u32 = 0x10; - -/// 16-bit absolute address in bits 39:24 of a 48-bit instr -/// -/// Targets: -/// -/// * Type 12a -pub const R_SHARC_DATA16_V3: u32 = 0x11; - -/// 6-bit absolute address into bits 16:11 of a 32-bit instr -/// -/// Targets: -/// -/// * Type 4b -pub const R_SHARC_DATA6_VISA_V3: u32 = 0x12; - -/// 7-bit absolute address into bits 6:0 of a 32-bit instr -pub const R_SHARC_DATA7_VISA_V3: u32 = 0x13; - -/// 16-bit absolute address into bits 15:0 of a 32-bit instr -pub const R_SHARC_DATA16_VISA_V3: u32 = 0x14; - -/// 6-bit PC-relative address into bits 16:11 of a Type B -/// -/// Targets: -/// -/// * Type 9b -pub const R_SHARC_PCR6_VISA_V3: u32 = 0x17; - -/// 16-bit absolute address into bits 15:0 of a 16-bit location. -/// -/// Represented with `RelocationEncoding::Generic` -pub const R_SHARC_ADDR_VAR16_V3: u32 = 0x19; - -pub const R_SHARC_CALC_PUSH_ADDR: u32 = 0xe0; -pub const R_SHARC_CALC_PUSH_ADDEND: u32 = 0xe1; -pub const R_SHARC_CALC_ADD: u32 = 0xe2; -pub const R_SHARC_CALC_SUB: u32 = 0xe3; -pub const R_SHARC_CALC_MUL: u32 = 0xe4; -pub const R_SHARC_CALC_DIV: u32 = 0xe5; -pub const R_SHARC_CALC_MOD: u32 = 0xe6; -pub const R_SHARC_CALC_LSHIFT: u32 = 0xe7; -pub const R_SHARC_CALC_RSHIFT: u32 = 0xe8; -pub const R_SHARC_CALC_AND: u32 = 0xe9; -pub const R_SHARC_CALC_OR: u32 = 0xea; -pub const R_SHARC_CALC_XOR: u32 = 0xeb; -pub const R_SHARC_CALC_PUSH_LEN: u32 = 0xec; -pub const R_SHARC_CALC_NOT: u32 = 0xf6; - -// SHARC values for `SectionHeader*::sh_type`. - -/// .adi.attributes -pub const SHT_SHARC_ADI_ATTRIBUTES: u32 = SHT_LOPROC + 0x2; - -// SUN SPARC specific definitions. - -// SPARC values for `st_type` component of `Sym*::st_info`. - -/// Global register reserved to app. -pub const STT_SPARC_REGISTER: u8 = 13; - -// SPARC values for `FileHeader64::e_flags`. - -pub const EF_SPARCV9_MM: u32 = 3; -pub const EF_SPARCV9_TSO: u32 = 0; -pub const EF_SPARCV9_PSO: u32 = 1; -pub const EF_SPARCV9_RMO: u32 = 2; -/// little endian data -pub const EF_SPARC_LEDATA: u32 = 0x80_0000; -pub const EF_SPARC_EXT_MASK: u32 = 0xFF_FF00; -/// generic V8+ features -pub const EF_SPARC_32PLUS: u32 = 0x00_0100; -/// Sun UltraSPARC1 extensions -pub const EF_SPARC_SUN_US1: u32 = 0x00_0200; -/// HAL R1 extensions -pub const EF_SPARC_HAL_R1: u32 = 0x00_0400; -/// Sun UltraSPARCIII extensions -pub const EF_SPARC_SUN_US3: u32 = 0x00_0800; - -// SPARC values for `Rel*::r_type`. - -/// No reloc -pub const R_SPARC_NONE: u32 = 0; -/// Direct 8 bit -pub const R_SPARC_8: u32 = 1; -/// Direct 16 bit -pub const R_SPARC_16: u32 = 2; -/// Direct 32 bit -pub const R_SPARC_32: u32 = 3; -/// PC relative 8 bit -pub const R_SPARC_DISP8: u32 = 4; -/// PC relative 16 bit -pub const R_SPARC_DISP16: u32 = 5; -/// PC relative 32 bit -pub const R_SPARC_DISP32: u32 = 6; -/// PC relative 30 bit shifted -pub const R_SPARC_WDISP30: u32 = 7; -/// PC relative 22 bit shifted -pub const R_SPARC_WDISP22: u32 = 8; -/// High 22 bit -pub const R_SPARC_HI22: u32 = 9; -/// Direct 22 bit -pub const R_SPARC_22: u32 = 10; -/// Direct 13 bit -pub const R_SPARC_13: u32 = 11; -/// Truncated 10 bit -pub const R_SPARC_LO10: u32 = 12; -/// Truncated 10 bit GOT entry -pub const R_SPARC_GOT10: u32 = 13; -/// 13 bit GOT entry -pub const R_SPARC_GOT13: u32 = 14; -/// 22 bit GOT entry shifted -pub const R_SPARC_GOT22: u32 = 15; -/// PC relative 10 bit truncated -pub const R_SPARC_PC10: u32 = 16; -/// PC relative 22 bit shifted -pub const R_SPARC_PC22: u32 = 17; -/// 30 bit PC relative PLT address -pub const R_SPARC_WPLT30: u32 = 18; -/// Copy symbol at runtime -pub const R_SPARC_COPY: u32 = 19; -/// Create GOT entry -pub const R_SPARC_GLOB_DAT: u32 = 20; -/// Create PLT entry -pub const R_SPARC_JMP_SLOT: u32 = 21; -/// Adjust by program base -pub const R_SPARC_RELATIVE: u32 = 22; -/// Direct 32 bit unaligned -pub const R_SPARC_UA32: u32 = 23; - -// Sparc64 values for `Rel*::r_type`. - -/// Direct 32 bit ref to PLT entry -pub const R_SPARC_PLT32: u32 = 24; -/// High 22 bit PLT entry -pub const R_SPARC_HIPLT22: u32 = 25; -/// Truncated 10 bit PLT entry -pub const R_SPARC_LOPLT10: u32 = 26; -/// PC rel 32 bit ref to PLT entry -pub const R_SPARC_PCPLT32: u32 = 27; -/// PC rel high 22 bit PLT entry -pub const R_SPARC_PCPLT22: u32 = 28; -/// PC rel trunc 10 bit PLT entry -pub const R_SPARC_PCPLT10: u32 = 29; -/// Direct 10 bit -pub const R_SPARC_10: u32 = 30; -/// Direct 11 bit -pub const R_SPARC_11: u32 = 31; -/// Direct 64 bit -pub const R_SPARC_64: u32 = 32; -/// 10bit with secondary 13bit addend -pub const R_SPARC_OLO10: u32 = 33; -/// Top 22 bits of direct 64 bit -pub const R_SPARC_HH22: u32 = 34; -/// High middle 10 bits of ... -pub const R_SPARC_HM10: u32 = 35; -/// Low middle 22 bits of ... -pub const R_SPARC_LM22: u32 = 36; -/// Top 22 bits of pc rel 64 bit -pub const R_SPARC_PC_HH22: u32 = 37; -/// High middle 10 bit of ... -pub const R_SPARC_PC_HM10: u32 = 38; -/// Low miggle 22 bits of ... -pub const R_SPARC_PC_LM22: u32 = 39; -/// PC relative 16 bit shifted -pub const R_SPARC_WDISP16: u32 = 40; -/// PC relative 19 bit shifted -pub const R_SPARC_WDISP19: u32 = 41; -/// was part of v9 ABI but was removed -pub const R_SPARC_GLOB_JMP: u32 = 42; -/// Direct 7 bit -pub const R_SPARC_7: u32 = 43; -/// Direct 5 bit -pub const R_SPARC_5: u32 = 44; -/// Direct 6 bit -pub const R_SPARC_6: u32 = 45; -/// PC relative 64 bit -pub const R_SPARC_DISP64: u32 = 46; -/// Direct 64 bit ref to PLT entry -pub const R_SPARC_PLT64: u32 = 47; -/// High 22 bit complemented -pub const R_SPARC_HIX22: u32 = 48; -/// Truncated 11 bit complemented -pub const R_SPARC_LOX10: u32 = 49; -/// Direct high 12 of 44 bit -pub const R_SPARC_H44: u32 = 50; -/// Direct mid 22 of 44 bit -pub const R_SPARC_M44: u32 = 51; -/// Direct low 10 of 44 bit -pub const R_SPARC_L44: u32 = 52; -/// Global register usage -pub const R_SPARC_REGISTER: u32 = 53; -/// Direct 64 bit unaligned -pub const R_SPARC_UA64: u32 = 54; -/// Direct 16 bit unaligned -pub const R_SPARC_UA16: u32 = 55; -pub const R_SPARC_TLS_GD_HI22: u32 = 56; -pub const R_SPARC_TLS_GD_LO10: u32 = 57; -pub const R_SPARC_TLS_GD_ADD: u32 = 58; -pub const R_SPARC_TLS_GD_CALL: u32 = 59; -pub const R_SPARC_TLS_LDM_HI22: u32 = 60; -pub const R_SPARC_TLS_LDM_LO10: u32 = 61; -pub const R_SPARC_TLS_LDM_ADD: u32 = 62; -pub const R_SPARC_TLS_LDM_CALL: u32 = 63; -pub const R_SPARC_TLS_LDO_HIX22: u32 = 64; -pub const R_SPARC_TLS_LDO_LOX10: u32 = 65; -pub const R_SPARC_TLS_LDO_ADD: u32 = 66; -pub const R_SPARC_TLS_IE_HI22: u32 = 67; -pub const R_SPARC_TLS_IE_LO10: u32 = 68; -pub const R_SPARC_TLS_IE_LD: u32 = 69; -pub const R_SPARC_TLS_IE_LDX: u32 = 70; -pub const R_SPARC_TLS_IE_ADD: u32 = 71; -pub const R_SPARC_TLS_LE_HIX22: u32 = 72; -pub const R_SPARC_TLS_LE_LOX10: u32 = 73; -pub const R_SPARC_TLS_DTPMOD32: u32 = 74; -pub const R_SPARC_TLS_DTPMOD64: u32 = 75; -pub const R_SPARC_TLS_DTPOFF32: u32 = 76; -pub const R_SPARC_TLS_DTPOFF64: u32 = 77; -pub const R_SPARC_TLS_TPOFF32: u32 = 78; -pub const R_SPARC_TLS_TPOFF64: u32 = 79; -pub const R_SPARC_GOTDATA_HIX22: u32 = 80; -pub const R_SPARC_GOTDATA_LOX10: u32 = 81; -pub const R_SPARC_GOTDATA_OP_HIX22: u32 = 82; -pub const R_SPARC_GOTDATA_OP_LOX10: u32 = 83; -pub const R_SPARC_GOTDATA_OP: u32 = 84; -pub const R_SPARC_H34: u32 = 85; -pub const R_SPARC_SIZE32: u32 = 86; -pub const R_SPARC_SIZE64: u32 = 87; -pub const R_SPARC_WDISP10: u32 = 88; -pub const R_SPARC_JMP_IREL: u32 = 248; -pub const R_SPARC_IRELATIVE: u32 = 249; -pub const R_SPARC_GNU_VTINHERIT: u32 = 250; -pub const R_SPARC_GNU_VTENTRY: u32 = 251; -pub const R_SPARC_REV32: u32 = 252; - -// Sparc64 values for `Dyn32::d_tag`. - -pub const DT_SPARC_REGISTER: u32 = 0x7000_0001; - -// MIPS R3000 specific definitions. - -// MIPS values for `FileHeader32::e_flags`. - -/// A .noreorder directive was used. -pub const EF_MIPS_NOREORDER: u32 = 1; -/// Contains PIC code. -pub const EF_MIPS_PIC: u32 = 2; -/// Uses PIC calling sequence. -pub const EF_MIPS_CPIC: u32 = 4; -pub const EF_MIPS_XGOT: u32 = 8; -pub const EF_MIPS_64BIT_WHIRL: u32 = 16; -pub const EF_MIPS_ABI2: u32 = 32; -pub const EF_MIPS_ABI_ON32: u32 = 64; -/// Uses FP64 (12 callee-saved). -pub const EF_MIPS_FP64: u32 = 512; -/// Uses IEEE 754-2008 NaN encoding. -pub const EF_MIPS_NAN2008: u32 = 1024; -/// MIPS architecture level. -pub const EF_MIPS_ARCH: u32 = 0xf000_0000; - -/// The first MIPS 32 bit ABI -pub const EF_MIPS_ABI_O32: u32 = 0x0000_1000; -/// O32 ABI extended for 64-bit architectures -pub const EF_MIPS_ABI_O64: u32 = 0x0000_2000; -/// EABI in 32-bit mode -pub const EF_MIPS_ABI_EABI32: u32 = 0x0000_3000; -/// EABI in 64-bit mode -pub const EF_MIPS_ABI_EABI64: u32 = 0x0000_4000; -/// Mask for selecting EF_MIPS_ABI_ variant -pub const EF_MIPS_ABI: u32 = 0x0000_f000; - -// Legal values for MIPS architecture level. - -/// -mips1 code. -pub const EF_MIPS_ARCH_1: u32 = 0x0000_0000; -/// -mips2 code. -pub const EF_MIPS_ARCH_2: u32 = 0x1000_0000; -/// -mips3 code. -pub const EF_MIPS_ARCH_3: u32 = 0x2000_0000; -/// -mips4 code. -pub const EF_MIPS_ARCH_4: u32 = 0x3000_0000; -/// -mips5 code. -pub const EF_MIPS_ARCH_5: u32 = 0x4000_0000; -/// MIPS32 code. -pub const EF_MIPS_ARCH_32: u32 = 0x5000_0000; -/// MIPS64 code. -pub const EF_MIPS_ARCH_64: u32 = 0x6000_0000; -/// MIPS32r2 code. -pub const EF_MIPS_ARCH_32R2: u32 = 0x7000_0000; -/// MIPS64r2 code. -pub const EF_MIPS_ARCH_64R2: u32 = 0x8000_0000; -/// MIPS32r6 code -pub const EF_MIPS_ARCH_32R6: u32 = 0x9000_0000; -/// MIPS64r6 code -pub const EF_MIPS_ARCH_64R6: u32 = 0xa000_0000; - -// MIPS values for `Sym32::st_shndx`. - -/// Allocated common symbols. -pub const SHN_MIPS_ACOMMON: u16 = 0xff00; -/// Allocated test symbols. -pub const SHN_MIPS_TEXT: u16 = 0xff01; -/// Allocated data symbols. -pub const SHN_MIPS_DATA: u16 = 0xff02; -/// Small common symbols. -pub const SHN_MIPS_SCOMMON: u16 = 0xff03; -/// Small undefined symbols. -pub const SHN_MIPS_SUNDEFINED: u16 = 0xff04; - -// MIPS values for `SectionHeader32::sh_type`. - -/// Shared objects used in link. -pub const SHT_MIPS_LIBLIST: u32 = 0x7000_0000; -pub const SHT_MIPS_MSYM: u32 = 0x7000_0001; -/// Conflicting symbols. -pub const SHT_MIPS_CONFLICT: u32 = 0x7000_0002; -/// Global data area sizes. -pub const SHT_MIPS_GPTAB: u32 = 0x7000_0003; -/// Reserved for SGI/MIPS compilers -pub const SHT_MIPS_UCODE: u32 = 0x7000_0004; -/// MIPS ECOFF debugging info. -pub const SHT_MIPS_DEBUG: u32 = 0x7000_0005; -/// Register usage information. -pub const SHT_MIPS_REGINFO: u32 = 0x7000_0006; -pub const SHT_MIPS_PACKAGE: u32 = 0x7000_0007; -pub const SHT_MIPS_PACKSYM: u32 = 0x7000_0008; -pub const SHT_MIPS_RELD: u32 = 0x7000_0009; -pub const SHT_MIPS_IFACE: u32 = 0x7000_000b; -pub const SHT_MIPS_CONTENT: u32 = 0x7000_000c; -/// Miscellaneous options. -pub const SHT_MIPS_OPTIONS: u32 = 0x7000_000d; -pub const SHT_MIPS_SHDR: u32 = 0x7000_0010; -pub const SHT_MIPS_FDESC: u32 = 0x7000_0011; -pub const SHT_MIPS_EXTSYM: u32 = 0x7000_0012; -pub const SHT_MIPS_DENSE: u32 = 0x7000_0013; -pub const SHT_MIPS_PDESC: u32 = 0x7000_0014; -pub const SHT_MIPS_LOCSYM: u32 = 0x7000_0015; -pub const SHT_MIPS_AUXSYM: u32 = 0x7000_0016; -pub const SHT_MIPS_OPTSYM: u32 = 0x7000_0017; -pub const SHT_MIPS_LOCSTR: u32 = 0x7000_0018; -pub const SHT_MIPS_LINE: u32 = 0x7000_0019; -pub const SHT_MIPS_RFDESC: u32 = 0x7000_001a; -pub const SHT_MIPS_DELTASYM: u32 = 0x7000_001b; -pub const SHT_MIPS_DELTAINST: u32 = 0x7000_001c; -pub const SHT_MIPS_DELTACLASS: u32 = 0x7000_001d; -/// DWARF debugging information. -pub const SHT_MIPS_DWARF: u32 = 0x7000_001e; -pub const SHT_MIPS_DELTADECL: u32 = 0x7000_001f; -pub const SHT_MIPS_SYMBOL_LIB: u32 = 0x7000_0020; -/// Event section. -pub const SHT_MIPS_EVENTS: u32 = 0x7000_0021; -pub const SHT_MIPS_TRANSLATE: u32 = 0x7000_0022; -pub const SHT_MIPS_PIXIE: u32 = 0x7000_0023; -pub const SHT_MIPS_XLATE: u32 = 0x7000_0024; -pub const SHT_MIPS_XLATE_DEBUG: u32 = 0x7000_0025; -pub const SHT_MIPS_WHIRL: u32 = 0x7000_0026; -pub const SHT_MIPS_EH_REGION: u32 = 0x7000_0027; -pub const SHT_MIPS_XLATE_OLD: u32 = 0x7000_0028; -pub const SHT_MIPS_PDR_EXCEPTION: u32 = 0x7000_0029; - -// MIPS values for `SectionHeader32::sh_flags`. - -/// Must be in global data area. -pub const SHF_MIPS_GPREL: u32 = 0x1000_0000; -pub const SHF_MIPS_MERGE: u32 = 0x2000_0000; -pub const SHF_MIPS_ADDR: u32 = 0x4000_0000; -pub const SHF_MIPS_STRINGS: u32 = 0x8000_0000; -pub const SHF_MIPS_NOSTRIP: u32 = 0x0800_0000; -pub const SHF_MIPS_LOCAL: u32 = 0x0400_0000; -pub const SHF_MIPS_NAMES: u32 = 0x0200_0000; -pub const SHF_MIPS_NODUPE: u32 = 0x0100_0000; - -// MIPS values for `Sym32::st_other`. - -pub const STO_MIPS_PLT: u8 = 0x8; -/// Only valid for `STB_MIPS_SPLIT_COMMON`. -pub const STO_MIPS_SC_ALIGN_UNUSED: u8 = 0xff; - -// MIPS values for `Sym32::st_info'. -pub const STB_MIPS_SPLIT_COMMON: u8 = 13; - -// Entries found in sections of type `SHT_MIPS_GPTAB`. - -// TODO: Elf32_gptab, Elf32_RegInfo, Elf_Options - -// Values for `Elf_Options::kind`. - -/// Undefined. -pub const ODK_NULL: u32 = 0; -/// Register usage information. -pub const ODK_REGINFO: u32 = 1; -/// Exception processing options. -pub const ODK_EXCEPTIONS: u32 = 2; -/// Section padding options. -pub const ODK_PAD: u32 = 3; -/// Hardware workarounds performed -pub const ODK_HWPATCH: u32 = 4; -/// record the fill value used by the linker. -pub const ODK_FILL: u32 = 5; -/// reserve space for desktop tools to write. -pub const ODK_TAGS: u32 = 6; -/// HW workarounds.  'AND' bits when merging. -pub const ODK_HWAND: u32 = 7; -/// HW workarounds.  'OR' bits when merging. -pub const ODK_HWOR: u32 = 8; - -// Values for `Elf_Options::info` for `ODK_EXCEPTIONS` entries. - -/// FPE's which MUST be enabled. -pub const OEX_FPU_MIN: u32 = 0x1f; -/// FPE's which MAY be enabled. -pub const OEX_FPU_MAX: u32 = 0x1f00; -/// page zero must be mapped. -pub const OEX_PAGE0: u32 = 0x10000; -/// Force sequential memory mode? -pub const OEX_SMM: u32 = 0x20000; -/// Force floating point debug mode? -pub const OEX_FPDBUG: u32 = 0x40000; -pub const OEX_PRECISEFP: u32 = OEX_FPDBUG; -/// Dismiss invalid address faults? -pub const OEX_DISMISS: u32 = 0x80000; - -pub const OEX_FPU_INVAL: u32 = 0x10; -pub const OEX_FPU_DIV0: u32 = 0x08; -pub const OEX_FPU_OFLO: u32 = 0x04; -pub const OEX_FPU_UFLO: u32 = 0x02; -pub const OEX_FPU_INEX: u32 = 0x01; - -// Masks for `Elf_Options::info` for an `ODK_HWPATCH` entry.  */ -/// R4000 end-of-page patch. -pub const OHW_R4KEOP: u32 = 0x1; -/// may need R8000 prefetch patch. -pub const OHW_R8KPFETCH: u32 = 0x2; -/// R5000 end-of-page patch. -pub const OHW_R5KEOP: u32 = 0x4; -/// R5000 cvt.\[ds\].l bug.  clean=1. -pub const OHW_R5KCVTL: u32 = 0x8; - -pub const OPAD_PREFIX: u32 = 0x1; -pub const OPAD_POSTFIX: u32 = 0x2; -pub const OPAD_SYMBOL: u32 = 0x4; - -// Entries found in sections of type `SHT_MIPS_OPTIONS`. - -// TODO: Elf_Options_Hw - -// Masks for `ElfOptions::info` for `ODK_HWAND` and `ODK_HWOR` entries. - -pub const OHWA0_R4KEOP_CHECKED: u32 = 0x0000_0001; -pub const OHWA1_R4KEOP_CLEAN: u32 = 0x0000_0002; - -// MIPS values for `Rel*::r_type`. - -/// No reloc -pub const R_MIPS_NONE: u32 = 0; -/// Direct 16 bit -pub const R_MIPS_16: u32 = 1; -/// Direct 32 bit -pub const R_MIPS_32: u32 = 2; -/// PC relative 32 bit -pub const R_MIPS_REL32: u32 = 3; -/// Direct 26 bit shifted -pub const R_MIPS_26: u32 = 4; -/// High 16 bit -pub const R_MIPS_HI16: u32 = 5; -/// Low 16 bit -pub const R_MIPS_LO16: u32 = 6; -/// GP relative 16 bit -pub const R_MIPS_GPREL16: u32 = 7; -/// 16 bit literal entry -pub const R_MIPS_LITERAL: u32 = 8; -/// 16 bit GOT entry -pub const R_MIPS_GOT16: u32 = 9; -/// PC relative 16 bit -pub const R_MIPS_PC16: u32 = 10; -/// 16 bit GOT entry for function -pub const R_MIPS_CALL16: u32 = 11; -/// GP relative 32 bit -pub const R_MIPS_GPREL32: u32 = 12; - -pub const R_MIPS_SHIFT5: u32 = 16; -pub const R_MIPS_SHIFT6: u32 = 17; -pub const R_MIPS_64: u32 = 18; -pub const R_MIPS_GOT_DISP: u32 = 19; -pub const R_MIPS_GOT_PAGE: u32 = 20; -pub const R_MIPS_GOT_OFST: u32 = 21; -pub const R_MIPS_GOT_HI16: u32 = 22; -pub const R_MIPS_GOT_LO16: u32 = 23; -pub const R_MIPS_SUB: u32 = 24; -pub const R_MIPS_INSERT_A: u32 = 25; -pub const R_MIPS_INSERT_B: u32 = 26; -pub const R_MIPS_DELETE: u32 = 27; -pub const R_MIPS_HIGHER: u32 = 28; -pub const R_MIPS_HIGHEST: u32 = 29; -pub const R_MIPS_CALL_HI16: u32 = 30; -pub const R_MIPS_CALL_LO16: u32 = 31; -pub const R_MIPS_SCN_DISP: u32 = 32; -pub const R_MIPS_REL16: u32 = 33; -pub const R_MIPS_ADD_IMMEDIATE: u32 = 34; -pub const R_MIPS_PJUMP: u32 = 35; -pub const R_MIPS_RELGOT: u32 = 36; -pub const R_MIPS_JALR: u32 = 37; -/// Module number 32 bit -pub const R_MIPS_TLS_DTPMOD32: u32 = 38; -/// Module-relative offset 32 bit -pub const R_MIPS_TLS_DTPREL32: u32 = 39; -/// Module number 64 bit -pub const R_MIPS_TLS_DTPMOD64: u32 = 40; -/// Module-relative offset 64 bit -pub const R_MIPS_TLS_DTPREL64: u32 = 41; -/// 16 bit GOT offset for GD -pub const R_MIPS_TLS_GD: u32 = 42; -/// 16 bit GOT offset for LDM -pub const R_MIPS_TLS_LDM: u32 = 43; -/// Module-relative offset, high 16 bits -pub const R_MIPS_TLS_DTPREL_HI16: u32 = 44; -/// Module-relative offset, low 16 bits -pub const R_MIPS_TLS_DTPREL_LO16: u32 = 45; -/// 16 bit GOT offset for IE -pub const R_MIPS_TLS_GOTTPREL: u32 = 46; -/// TP-relative offset, 32 bit -pub const R_MIPS_TLS_TPREL32: u32 = 47; -/// TP-relative offset, 64 bit -pub const R_MIPS_TLS_TPREL64: u32 = 48; -/// TP-relative offset, high 16 bits -pub const R_MIPS_TLS_TPREL_HI16: u32 = 49; -/// TP-relative offset, low 16 bits -pub const R_MIPS_TLS_TPREL_LO16: u32 = 50; -pub const R_MIPS_GLOB_DAT: u32 = 51; -pub const R_MIPS_COPY: u32 = 126; -pub const R_MIPS_JUMP_SLOT: u32 = 127; - -// MIPS values for `ProgramHeader32::p_type`. - -/// Register usage information. -pub const PT_MIPS_REGINFO: u32 = 0x7000_0000; -/// Runtime procedure table. -pub const PT_MIPS_RTPROC: u32 = 0x7000_0001; -pub const PT_MIPS_OPTIONS: u32 = 0x7000_0002; -/// FP mode requirement. -pub const PT_MIPS_ABIFLAGS: u32 = 0x7000_0003; - -// MIPS values for `ProgramHeader32::p_flags`. - -pub const PF_MIPS_LOCAL: u32 = 0x1000_0000; - -// MIPS values for `Dyn32::d_tag`. - -/// Runtime linker interface version -pub const DT_MIPS_RLD_VERSION: u32 = 0x7000_0001; -/// Timestamp -pub const DT_MIPS_TIME_STAMP: u32 = 0x7000_0002; -/// Checksum -pub const DT_MIPS_ICHECKSUM: u32 = 0x7000_0003; -/// Version string (string tbl index) -pub const DT_MIPS_IVERSION: u32 = 0x7000_0004; -/// Flags -pub const DT_MIPS_FLAGS: u32 = 0x7000_0005; -/// Base address -pub const DT_MIPS_BASE_ADDRESS: u32 = 0x7000_0006; -pub const DT_MIPS_MSYM: u32 = 0x7000_0007; -/// Address of CONFLICT section -pub const DT_MIPS_CONFLICT: u32 = 0x7000_0008; -/// Address of LIBLIST section -pub const DT_MIPS_LIBLIST: u32 = 0x7000_0009; -/// Number of local GOT entries -pub const DT_MIPS_LOCAL_GOTNO: u32 = 0x7000_000a; -/// Number of CONFLICT entries -pub const DT_MIPS_CONFLICTNO: u32 = 0x7000_000b; -/// Number of LIBLIST entries -pub const DT_MIPS_LIBLISTNO: u32 = 0x7000_0010; -/// Number of DYNSYM entries -pub const DT_MIPS_SYMTABNO: u32 = 0x7000_0011; -/// First external DYNSYM -pub const DT_MIPS_UNREFEXTNO: u32 = 0x7000_0012; -/// First GOT entry in DYNSYM -pub const DT_MIPS_GOTSYM: u32 = 0x7000_0013; -/// Number of GOT page table entries -pub const DT_MIPS_HIPAGENO: u32 = 0x7000_0014; -/// Address of run time loader map. -pub const DT_MIPS_RLD_MAP: u32 = 0x7000_0016; -/// Delta C++ class definition. -pub const DT_MIPS_DELTA_CLASS: u32 = 0x7000_0017; -/// Number of entries in DT_MIPS_DELTA_CLASS. -pub const DT_MIPS_DELTA_CLASS_NO: u32 = 0x7000_0018; -/// Delta C++ class instances. -pub const DT_MIPS_DELTA_INSTANCE: u32 = 0x7000_0019; -/// Number of entries in DT_MIPS_DELTA_INSTANCE. -pub const DT_MIPS_DELTA_INSTANCE_NO: u32 = 0x7000_001a; -/// Delta relocations. -pub const DT_MIPS_DELTA_RELOC: u32 = 0x7000_001b; -/// Number of entries in DT_MIPS_DELTA_RELOC. -pub const DT_MIPS_DELTA_RELOC_NO: u32 = 0x7000_001c; -/// Delta symbols that Delta relocations refer to. -pub const DT_MIPS_DELTA_SYM: u32 = 0x7000_001d; -/// Number of entries in DT_MIPS_DELTA_SYM. -pub const DT_MIPS_DELTA_SYM_NO: u32 = 0x7000_001e; -/// Delta symbols that hold the class declaration. -pub const DT_MIPS_DELTA_CLASSSYM: u32 = 0x7000_0020; -/// Number of entries in DT_MIPS_DELTA_CLASSSYM. -pub const DT_MIPS_DELTA_CLASSSYM_NO: u32 = 0x7000_0021; -/// Flags indicating for C++ flavor. -pub const DT_MIPS_CXX_FLAGS: u32 = 0x7000_0022; -pub const DT_MIPS_PIXIE_INIT: u32 = 0x7000_0023; -pub const DT_MIPS_SYMBOL_LIB: u32 = 0x7000_0024; -pub const DT_MIPS_LOCALPAGE_GOTIDX: u32 = 0x7000_0025; -pub const DT_MIPS_LOCAL_GOTIDX: u32 = 0x7000_0026; -pub const DT_MIPS_HIDDEN_GOTIDX: u32 = 0x7000_0027; -pub const DT_MIPS_PROTECTED_GOTIDX: u32 = 0x7000_0028; -/// Address of .options. -pub const DT_MIPS_OPTIONS: u32 = 0x7000_0029; -/// Address of .interface. -pub const DT_MIPS_INTERFACE: u32 = 0x7000_002a; -pub const DT_MIPS_DYNSTR_ALIGN: u32 = 0x7000_002b; -/// Size of the .interface section. -pub const DT_MIPS_INTERFACE_SIZE: u32 = 0x7000_002c; -/// Address of rld_text_rsolve function stored in GOT. -pub const DT_MIPS_RLD_TEXT_RESOLVE_ADDR: u32 = 0x7000_002d; -/// Default suffix of dso to be added by rld on dlopen() calls. -pub const DT_MIPS_PERF_SUFFIX: u32 = 0x7000_002e; -/// (O32)Size of compact rel section. -pub const DT_MIPS_COMPACT_SIZE: u32 = 0x7000_002f; -/// GP value for aux GOTs. -pub const DT_MIPS_GP_VALUE: u32 = 0x7000_0030; -/// Address of aux .dynamic. -pub const DT_MIPS_AUX_DYNAMIC: u32 = 0x7000_0031; -/// The address of .got.plt in an executable using the new non-PIC ABI. -pub const DT_MIPS_PLTGOT: u32 = 0x7000_0032; -/// The base of the PLT in an executable using the new non-PIC ABI if that PLT is writable.  For a non-writable PLT, this is omitted or has a zero value. -pub const DT_MIPS_RWPLT: u32 = 0x7000_0034; -/// An alternative description of the classic MIPS RLD_MAP that is usable in a PIE as it stores a relative offset from the address of the tag rather than an absolute address. -pub const DT_MIPS_RLD_MAP_REL: u32 = 0x7000_0035; - -// Values for `DT_MIPS_FLAGS` `Dyn32` entry. - -/// No flags -pub const RHF_NONE: u32 = 0; -/// Use quickstart -pub const RHF_QUICKSTART: u32 = 1 << 0; -/// Hash size not power of 2 -pub const RHF_NOTPOT: u32 = 1 << 1; -/// Ignore LD_LIBRARY_PATH -pub const RHF_NO_LIBRARY_REPLACEMENT: u32 = 1 << 2; -pub const RHF_NO_MOVE: u32 = 1 << 3; -pub const RHF_SGI_ONLY: u32 = 1 << 4; -pub const RHF_GUARANTEE_INIT: u32 = 1 << 5; -pub const RHF_DELTA_C_PLUS_PLUS: u32 = 1 << 6; -pub const RHF_GUARANTEE_START_INIT: u32 = 1 << 7; -pub const RHF_PIXIE: u32 = 1 << 8; -pub const RHF_DEFAULT_DELAY_LOAD: u32 = 1 << 9; -pub const RHF_REQUICKSTART: u32 = 1 << 10; -pub const RHF_REQUICKSTARTED: u32 = 1 << 11; -pub const RHF_CORD: u32 = 1 << 12; -pub const RHF_NO_UNRES_UNDEF: u32 = 1 << 13; -pub const RHF_RLD_ORDER_SAFE: u32 = 1 << 14; - -// Entries found in sections of type `SHT_MIPS_LIBLIST`. - -// TODO: Elf32_Lib, Elf64_Lib - -// Values for `Lib*::l_flags`. - -pub const LL_NONE: u32 = 0; -/// Require exact match -pub const LL_EXACT_MATCH: u32 = 1 << 0; -/// Ignore interface version -pub const LL_IGNORE_INT_VER: u32 = 1 << 1; -pub const LL_REQUIRE_MINOR: u32 = 1 << 2; -pub const LL_EXPORTS: u32 = 1 << 3; -pub const LL_DELAY_LOAD: u32 = 1 << 4; -pub const LL_DELTA: u32 = 1 << 5; - -// TODO: MIPS ABI flags - -// PA-RISC specific definitions. - -// PA-RISC values for `FileHeader32::e_flags`. - -/// Trap nil pointer dereference. -pub const EF_PARISC_TRAPNIL: u32 = 0x0001_0000; -/// Program uses arch. extensions. -pub const EF_PARISC_EXT: u32 = 0x0002_0000; -/// Program expects little endian. -pub const EF_PARISC_LSB: u32 = 0x0004_0000; -/// Program expects wide mode. -pub const EF_PARISC_WIDE: u32 = 0x0008_0000; -/// No kernel assisted branch prediction. -pub const EF_PARISC_NO_KABP: u32 = 0x0010_0000; -/// Allow lazy swapping. -pub const EF_PARISC_LAZYSWAP: u32 = 0x0040_0000; -/// Architecture version. -pub const EF_PARISC_ARCH: u32 = 0x0000_ffff; - -// Values for `EF_PARISC_ARCH'. - -/// PA-RISC 1.0 big-endian. -pub const EFA_PARISC_1_0: u32 = 0x020b; -/// PA-RISC 1.1 big-endian. -pub const EFA_PARISC_1_1: u32 = 0x0210; -/// PA-RISC 2.0 big-endian. -pub const EFA_PARISC_2_0: u32 = 0x0214; - -// PA-RISC values for `Sym*::st_shndx`. - -/// Section for tentatively declared symbols in ANSI C. -pub const SHN_PARISC_ANSI_COMMON: u16 = 0xff00; -/// Common blocks in huge model. -pub const SHN_PARISC_HUGE_COMMON: u16 = 0xff01; - -// PA-RISC values for `SectionHeader32::sh_type`. - -/// Contains product specific ext. -pub const SHT_PARISC_EXT: u32 = 0x7000_0000; -/// Unwind information. -pub const SHT_PARISC_UNWIND: u32 = 0x7000_0001; -/// Debug info for optimized code. -pub const SHT_PARISC_DOC: u32 = 0x7000_0002; - -// PA-RISC values for `SectionHeader32::sh_flags`. - -/// Section with short addressing. -pub const SHF_PARISC_SHORT: u32 = 0x2000_0000; -/// Section far from gp. -pub const SHF_PARISC_HUGE: u32 = 0x4000_0000; -/// Static branch prediction code. -pub const SHF_PARISC_SBP: u32 = 0x8000_0000; - -// PA-RISC values for `st_type` component of `Sym32::st_info`. - -/// Millicode function entry point. -pub const STT_PARISC_MILLICODE: u8 = 13; - -pub const STT_HP_OPAQUE: u8 = STT_LOOS + 0x1; -pub const STT_HP_STUB: u8 = STT_LOOS + 0x2; - -// PA-RISC values for `Rel*::r_type`. - -/// No reloc. -pub const R_PARISC_NONE: u32 = 0; -/// Direct 32-bit reference. -pub const R_PARISC_DIR32: u32 = 1; -/// Left 21 bits of eff. address. -pub const R_PARISC_DIR21L: u32 = 2; -/// Right 17 bits of eff. address. -pub const R_PARISC_DIR17R: u32 = 3; -/// 17 bits of eff. address. -pub const R_PARISC_DIR17F: u32 = 4; -/// Right 14 bits of eff. address. -pub const R_PARISC_DIR14R: u32 = 6; -/// 32-bit rel. address. -pub const R_PARISC_PCREL32: u32 = 9; -/// Left 21 bits of rel. address. -pub const R_PARISC_PCREL21L: u32 = 10; -/// Right 17 bits of rel. address. -pub const R_PARISC_PCREL17R: u32 = 11; -/// 17 bits of rel. address. -pub const R_PARISC_PCREL17F: u32 = 12; -/// Right 14 bits of rel. address. -pub const R_PARISC_PCREL14R: u32 = 14; -/// Left 21 bits of rel. address. -pub const R_PARISC_DPREL21L: u32 = 18; -/// Right 14 bits of rel. address. -pub const R_PARISC_DPREL14R: u32 = 22; -/// GP-relative, left 21 bits. -pub const R_PARISC_GPREL21L: u32 = 26; -/// GP-relative, right 14 bits. -pub const R_PARISC_GPREL14R: u32 = 30; -/// LT-relative, left 21 bits. -pub const R_PARISC_LTOFF21L: u32 = 34; -/// LT-relative, right 14 bits. -pub const R_PARISC_LTOFF14R: u32 = 38; -/// 32 bits section rel. address. -pub const R_PARISC_SECREL32: u32 = 41; -/// No relocation, set segment base. -pub const R_PARISC_SEGBASE: u32 = 48; -/// 32 bits segment rel. address. -pub const R_PARISC_SEGREL32: u32 = 49; -/// PLT rel. address, left 21 bits. -pub const R_PARISC_PLTOFF21L: u32 = 50; -/// PLT rel. address, right 14 bits. -pub const R_PARISC_PLTOFF14R: u32 = 54; -/// 32 bits LT-rel. function pointer. -pub const R_PARISC_LTOFF_FPTR32: u32 = 57; -/// LT-rel. fct ptr, left 21 bits. -pub const R_PARISC_LTOFF_FPTR21L: u32 = 58; -/// LT-rel. fct ptr, right 14 bits. -pub const R_PARISC_LTOFF_FPTR14R: u32 = 62; -/// 64 bits function address. -pub const R_PARISC_FPTR64: u32 = 64; -/// 32 bits function address. -pub const R_PARISC_PLABEL32: u32 = 65; -/// Left 21 bits of fdesc address. -pub const R_PARISC_PLABEL21L: u32 = 66; -/// Right 14 bits of fdesc address. -pub const R_PARISC_PLABEL14R: u32 = 70; -/// 64 bits PC-rel. address. -pub const R_PARISC_PCREL64: u32 = 72; -/// 22 bits PC-rel. address. -pub const R_PARISC_PCREL22F: u32 = 74; -/// PC-rel. address, right 14 bits. -pub const R_PARISC_PCREL14WR: u32 = 75; -/// PC rel. address, right 14 bits. -pub const R_PARISC_PCREL14DR: u32 = 76; -/// 16 bits PC-rel. address. -pub const R_PARISC_PCREL16F: u32 = 77; -/// 16 bits PC-rel. address. -pub const R_PARISC_PCREL16WF: u32 = 78; -/// 16 bits PC-rel. address. -pub const R_PARISC_PCREL16DF: u32 = 79; -/// 64 bits of eff. address. -pub const R_PARISC_DIR64: u32 = 80; -/// 14 bits of eff. address. -pub const R_PARISC_DIR14WR: u32 = 83; -/// 14 bits of eff. address. -pub const R_PARISC_DIR14DR: u32 = 84; -/// 16 bits of eff. address. -pub const R_PARISC_DIR16F: u32 = 85; -/// 16 bits of eff. address. -pub const R_PARISC_DIR16WF: u32 = 86; -/// 16 bits of eff. address. -pub const R_PARISC_DIR16DF: u32 = 87; -/// 64 bits of GP-rel. address. -pub const R_PARISC_GPREL64: u32 = 88; -/// GP-rel. address, right 14 bits. -pub const R_PARISC_GPREL14WR: u32 = 91; -/// GP-rel. address, right 14 bits. -pub const R_PARISC_GPREL14DR: u32 = 92; -/// 16 bits GP-rel. address. -pub const R_PARISC_GPREL16F: u32 = 93; -/// 16 bits GP-rel. address. -pub const R_PARISC_GPREL16WF: u32 = 94; -/// 16 bits GP-rel. address. -pub const R_PARISC_GPREL16DF: u32 = 95; -/// 64 bits LT-rel. address. -pub const R_PARISC_LTOFF64: u32 = 96; -/// LT-rel. address, right 14 bits. -pub const R_PARISC_LTOFF14WR: u32 = 99; -/// LT-rel. address, right 14 bits. -pub const R_PARISC_LTOFF14DR: u32 = 100; -/// 16 bits LT-rel. address. -pub const R_PARISC_LTOFF16F: u32 = 101; -/// 16 bits LT-rel. address. -pub const R_PARISC_LTOFF16WF: u32 = 102; -/// 16 bits LT-rel. address. -pub const R_PARISC_LTOFF16DF: u32 = 103; -/// 64 bits section rel. address. -pub const R_PARISC_SECREL64: u32 = 104; -/// 64 bits segment rel. address. -pub const R_PARISC_SEGREL64: u32 = 112; -/// PLT-rel. address, right 14 bits. -pub const R_PARISC_PLTOFF14WR: u32 = 115; -/// PLT-rel. address, right 14 bits. -pub const R_PARISC_PLTOFF14DR: u32 = 116; -/// 16 bits LT-rel. address. -pub const R_PARISC_PLTOFF16F: u32 = 117; -/// 16 bits PLT-rel. address. -pub const R_PARISC_PLTOFF16WF: u32 = 118; -/// 16 bits PLT-rel. address. -pub const R_PARISC_PLTOFF16DF: u32 = 119; -/// 64 bits LT-rel. function ptr. -pub const R_PARISC_LTOFF_FPTR64: u32 = 120; -/// LT-rel. fct. ptr., right 14 bits. -pub const R_PARISC_LTOFF_FPTR14WR: u32 = 123; -/// LT-rel. fct. ptr., right 14 bits. -pub const R_PARISC_LTOFF_FPTR14DR: u32 = 124; -/// 16 bits LT-rel. function ptr. -pub const R_PARISC_LTOFF_FPTR16F: u32 = 125; -/// 16 bits LT-rel. function ptr. -pub const R_PARISC_LTOFF_FPTR16WF: u32 = 126; -/// 16 bits LT-rel. function ptr. -pub const R_PARISC_LTOFF_FPTR16DF: u32 = 127; -pub const R_PARISC_LORESERVE: u32 = 128; -/// Copy relocation. -pub const R_PARISC_COPY: u32 = 128; -/// Dynamic reloc, imported PLT -pub const R_PARISC_IPLT: u32 = 129; -/// Dynamic reloc, exported PLT -pub const R_PARISC_EPLT: u32 = 130; -/// 32 bits TP-rel. address. -pub const R_PARISC_TPREL32: u32 = 153; -/// TP-rel. address, left 21 bits. -pub const R_PARISC_TPREL21L: u32 = 154; -/// TP-rel. address, right 14 bits. -pub const R_PARISC_TPREL14R: u32 = 158; -/// LT-TP-rel. address, left 21 bits. -pub const R_PARISC_LTOFF_TP21L: u32 = 162; -/// LT-TP-rel. address, right 14 bits. -pub const R_PARISC_LTOFF_TP14R: u32 = 166; -/// 14 bits LT-TP-rel. address. -pub const R_PARISC_LTOFF_TP14F: u32 = 167; -/// 64 bits TP-rel. address. -pub const R_PARISC_TPREL64: u32 = 216; -/// TP-rel. address, right 14 bits. -pub const R_PARISC_TPREL14WR: u32 = 219; -/// TP-rel. address, right 14 bits. -pub const R_PARISC_TPREL14DR: u32 = 220; -/// 16 bits TP-rel. address. -pub const R_PARISC_TPREL16F: u32 = 221; -/// 16 bits TP-rel. address. -pub const R_PARISC_TPREL16WF: u32 = 222; -/// 16 bits TP-rel. address. -pub const R_PARISC_TPREL16DF: u32 = 223; -/// 64 bits LT-TP-rel. address. -pub const R_PARISC_LTOFF_TP64: u32 = 224; -/// LT-TP-rel. address, right 14 bits. -pub const R_PARISC_LTOFF_TP14WR: u32 = 227; -/// LT-TP-rel. address, right 14 bits. -pub const R_PARISC_LTOFF_TP14DR: u32 = 228; -/// 16 bits LT-TP-rel. address. -pub const R_PARISC_LTOFF_TP16F: u32 = 229; -/// 16 bits LT-TP-rel. address. -pub const R_PARISC_LTOFF_TP16WF: u32 = 230; -/// 16 bits LT-TP-rel. address. -pub const R_PARISC_LTOFF_TP16DF: u32 = 231; -pub const R_PARISC_GNU_VTENTRY: u32 = 232; -pub const R_PARISC_GNU_VTINHERIT: u32 = 233; -/// GD 21-bit left. -pub const R_PARISC_TLS_GD21L: u32 = 234; -/// GD 14-bit right. -pub const R_PARISC_TLS_GD14R: u32 = 235; -/// GD call to __t_g_a. -pub const R_PARISC_TLS_GDCALL: u32 = 236; -/// LD module 21-bit left. -pub const R_PARISC_TLS_LDM21L: u32 = 237; -/// LD module 14-bit right. -pub const R_PARISC_TLS_LDM14R: u32 = 238; -/// LD module call to __t_g_a. -pub const R_PARISC_TLS_LDMCALL: u32 = 239; -/// LD offset 21-bit left. -pub const R_PARISC_TLS_LDO21L: u32 = 240; -/// LD offset 14-bit right. -pub const R_PARISC_TLS_LDO14R: u32 = 241; -/// DTP module 32-bit. -pub const R_PARISC_TLS_DTPMOD32: u32 = 242; -/// DTP module 64-bit. -pub const R_PARISC_TLS_DTPMOD64: u32 = 243; -/// DTP offset 32-bit. -pub const R_PARISC_TLS_DTPOFF32: u32 = 244; -/// DTP offset 32-bit. -pub const R_PARISC_TLS_DTPOFF64: u32 = 245; -pub const R_PARISC_TLS_LE21L: u32 = R_PARISC_TPREL21L; -pub const R_PARISC_TLS_LE14R: u32 = R_PARISC_TPREL14R; -pub const R_PARISC_TLS_IE21L: u32 = R_PARISC_LTOFF_TP21L; -pub const R_PARISC_TLS_IE14R: u32 = R_PARISC_LTOFF_TP14R; -pub const R_PARISC_TLS_TPREL32: u32 = R_PARISC_TPREL32; -pub const R_PARISC_TLS_TPREL64: u32 = R_PARISC_TPREL64; -pub const R_PARISC_HIRESERVE: u32 = 255; - -// PA-RISC values for `ProgramHeader*::p_type`. - -pub const PT_HP_TLS: u32 = PT_LOOS + 0x0; -pub const PT_HP_CORE_NONE: u32 = PT_LOOS + 0x1; -pub const PT_HP_CORE_VERSION: u32 = PT_LOOS + 0x2; -pub const PT_HP_CORE_KERNEL: u32 = PT_LOOS + 0x3; -pub const PT_HP_CORE_COMM: u32 = PT_LOOS + 0x4; -pub const PT_HP_CORE_PROC: u32 = PT_LOOS + 0x5; -pub const PT_HP_CORE_LOADABLE: u32 = PT_LOOS + 0x6; -pub const PT_HP_CORE_STACK: u32 = PT_LOOS + 0x7; -pub const PT_HP_CORE_SHM: u32 = PT_LOOS + 0x8; -pub const PT_HP_CORE_MMF: u32 = PT_LOOS + 0x9; -pub const PT_HP_PARALLEL: u32 = PT_LOOS + 0x10; -pub const PT_HP_FASTBIND: u32 = PT_LOOS + 0x11; -pub const PT_HP_OPT_ANNOT: u32 = PT_LOOS + 0x12; -pub const PT_HP_HSL_ANNOT: u32 = PT_LOOS + 0x13; -pub const PT_HP_STACK: u32 = PT_LOOS + 0x14; - -pub const PT_PARISC_ARCHEXT: u32 = 0x7000_0000; -pub const PT_PARISC_UNWIND: u32 = 0x7000_0001; - -// PA-RISC values for `ProgramHeader*::p_flags`. - -pub const PF_PARISC_SBP: u32 = 0x0800_0000; - -pub const PF_HP_PAGE_SIZE: u32 = 0x0010_0000; -pub const PF_HP_FAR_SHARED: u32 = 0x0020_0000; -pub const PF_HP_NEAR_SHARED: u32 = 0x0040_0000; -pub const PF_HP_CODE: u32 = 0x0100_0000; -pub const PF_HP_MODIFY: u32 = 0x0200_0000; -pub const PF_HP_LAZYSWAP: u32 = 0x0400_0000; -pub const PF_HP_SBP: u32 = 0x0800_0000; - -// Alpha specific definitions. - -// Alpha values for `FileHeader64::e_flags`. - -/// All addresses must be < 2GB. -pub const EF_ALPHA_32BIT: u32 = 1; -/// Relocations for relaxing exist. -pub const EF_ALPHA_CANRELAX: u32 = 2; - -// Alpha values for `SectionHeader64::sh_type`. - -// These two are primerily concerned with ECOFF debugging info. -pub const SHT_ALPHA_DEBUG: u32 = 0x7000_0001; -pub const SHT_ALPHA_REGINFO: u32 = 0x7000_0002; - -// Alpha values for `SectionHeader64::sh_flags`. - -pub const SHF_ALPHA_GPREL: u32 = 0x1000_0000; - -// Alpha values for `Sym64::st_other`. -/// No PV required. -pub const STO_ALPHA_NOPV: u8 = 0x80; -/// PV only used for initial ldgp. -pub const STO_ALPHA_STD_GPLOAD: u8 = 0x88; - -// Alpha values for `Rel64::r_type`. - -/// No reloc -pub const R_ALPHA_NONE: u32 = 0; -/// Direct 32 bit -pub const R_ALPHA_REFLONG: u32 = 1; -/// Direct 64 bit -pub const R_ALPHA_REFQUAD: u32 = 2; -/// GP relative 32 bit -pub const R_ALPHA_GPREL32: u32 = 3; -/// GP relative 16 bit w/optimization -pub const R_ALPHA_LITERAL: u32 = 4; -/// Optimization hint for LITERAL -pub const R_ALPHA_LITUSE: u32 = 5; -/// Add displacement to GP -pub const R_ALPHA_GPDISP: u32 = 6; -/// PC+4 relative 23 bit shifted -pub const R_ALPHA_BRADDR: u32 = 7; -/// PC+4 relative 16 bit shifted -pub const R_ALPHA_HINT: u32 = 8; -/// PC relative 16 bit -pub const R_ALPHA_SREL16: u32 = 9; -/// PC relative 32 bit -pub const R_ALPHA_SREL32: u32 = 10; -/// PC relative 64 bit -pub const R_ALPHA_SREL64: u32 = 11; -/// GP relative 32 bit, high 16 bits -pub const R_ALPHA_GPRELHIGH: u32 = 17; -/// GP relative 32 bit, low 16 bits -pub const R_ALPHA_GPRELLOW: u32 = 18; -/// GP relative 16 bit -pub const R_ALPHA_GPREL16: u32 = 19; -/// Copy symbol at runtime -pub const R_ALPHA_COPY: u32 = 24; -/// Create GOT entry -pub const R_ALPHA_GLOB_DAT: u32 = 25; -/// Create PLT entry -pub const R_ALPHA_JMP_SLOT: u32 = 26; -/// Adjust by program base -pub const R_ALPHA_RELATIVE: u32 = 27; -pub const R_ALPHA_TLS_GD_HI: u32 = 28; -pub const R_ALPHA_TLSGD: u32 = 29; -pub const R_ALPHA_TLS_LDM: u32 = 30; -pub const R_ALPHA_DTPMOD64: u32 = 31; -pub const R_ALPHA_GOTDTPREL: u32 = 32; -pub const R_ALPHA_DTPREL64: u32 = 33; -pub const R_ALPHA_DTPRELHI: u32 = 34; -pub const R_ALPHA_DTPRELLO: u32 = 35; -pub const R_ALPHA_DTPREL16: u32 = 36; -pub const R_ALPHA_GOTTPREL: u32 = 37; -pub const R_ALPHA_TPREL64: u32 = 38; -pub const R_ALPHA_TPRELHI: u32 = 39; -pub const R_ALPHA_TPRELLO: u32 = 40; -pub const R_ALPHA_TPREL16: u32 = 41; - -// Magic values of the `R_ALPHA_LITUSE` relocation addend. -pub const LITUSE_ALPHA_ADDR: u32 = 0; -pub const LITUSE_ALPHA_BASE: u32 = 1; -pub const LITUSE_ALPHA_BYTOFF: u32 = 2; -pub const LITUSE_ALPHA_JSR: u32 = 3; -pub const LITUSE_ALPHA_TLS_GD: u32 = 4; -pub const LITUSE_ALPHA_TLS_LDM: u32 = 5; - -// Alpha values for `Dyn64::d_tag`. -pub const DT_ALPHA_PLTRO: u32 = DT_LOPROC + 0; - -// PowerPC specific declarations. - -// PowerPC values for `FileHeader*::e_flags`. -/// PowerPC embedded flag -pub const EF_PPC_EMB: u32 = 0x8000_0000; - -// Cygnus local bits below . -/// PowerPC -mrelocatable flag -pub const EF_PPC_RELOCATABLE: u32 = 0x0001_0000; -/// PowerPC -mrelocatable-lib flag -pub const EF_PPC_RELOCATABLE_LIB: u32 = 0x0000_8000; - -// PowerPC values for `Rel*::r_type` defined by the ABIs. -pub const R_PPC_NONE: u32 = 0; -/// 32bit absolute address -pub const R_PPC_ADDR32: u32 = 1; -/// 26bit address, 2 bits ignored. -pub const R_PPC_ADDR24: u32 = 2; -/// 16bit absolute address -pub const R_PPC_ADDR16: u32 = 3; -/// lower 16bit of absolute address -pub const R_PPC_ADDR16_LO: u32 = 4; -/// high 16bit of absolute address -pub const R_PPC_ADDR16_HI: u32 = 5; -/// adjusted high 16bit -pub const R_PPC_ADDR16_HA: u32 = 6; -/// 16bit address, 2 bits ignored -pub const R_PPC_ADDR14: u32 = 7; -pub const R_PPC_ADDR14_BRTAKEN: u32 = 8; -pub const R_PPC_ADDR14_BRNTAKEN: u32 = 9; -/// PC relative 26 bit -pub const R_PPC_REL24: u32 = 10; -/// PC relative 16 bit -pub const R_PPC_REL14: u32 = 11; -pub const R_PPC_REL14_BRTAKEN: u32 = 12; -pub const R_PPC_REL14_BRNTAKEN: u32 = 13; -pub const R_PPC_GOT16: u32 = 14; -pub const R_PPC_GOT16_LO: u32 = 15; -pub const R_PPC_GOT16_HI: u32 = 16; -pub const R_PPC_GOT16_HA: u32 = 17; -pub const R_PPC_PLTREL24: u32 = 18; -pub const R_PPC_COPY: u32 = 19; -pub const R_PPC_GLOB_DAT: u32 = 20; -pub const R_PPC_JMP_SLOT: u32 = 21; -pub const R_PPC_RELATIVE: u32 = 22; -pub const R_PPC_LOCAL24PC: u32 = 23; -pub const R_PPC_UADDR32: u32 = 24; -pub const R_PPC_UADDR16: u32 = 25; -pub const R_PPC_REL32: u32 = 26; -pub const R_PPC_PLT32: u32 = 27; -pub const R_PPC_PLTREL32: u32 = 28; -pub const R_PPC_PLT16_LO: u32 = 29; -pub const R_PPC_PLT16_HI: u32 = 30; -pub const R_PPC_PLT16_HA: u32 = 31; -pub const R_PPC_SDAREL16: u32 = 32; -pub const R_PPC_SECTOFF: u32 = 33; -pub const R_PPC_SECTOFF_LO: u32 = 34; -pub const R_PPC_SECTOFF_HI: u32 = 35; -pub const R_PPC_SECTOFF_HA: u32 = 36; - -// PowerPC values for `Rel*::r_type` defined for the TLS access ABI. -/// none    (sym+add)@tls -pub const R_PPC_TLS: u32 = 67; -/// word32  (sym+add)@dtpmod -pub const R_PPC_DTPMOD32: u32 = 68; -/// half16* (sym+add)@tprel -pub const R_PPC_TPREL16: u32 = 69; -/// half16  (sym+add)@tprel@l -pub const R_PPC_TPREL16_LO: u32 = 70; -/// half16  (sym+add)@tprel@h -pub const R_PPC_TPREL16_HI: u32 = 71; -/// half16  (sym+add)@tprel@ha -pub const R_PPC_TPREL16_HA: u32 = 72; -/// word32  (sym+add)@tprel -pub const R_PPC_TPREL32: u32 = 73; -/// half16*(sym+add)@dtprel -pub const R_PPC_DTPREL16: u32 = 74; -/// half16  (sym+add)@dtprel@l -pub const R_PPC_DTPREL16_LO: u32 = 75; -/// half16  (sym+add)@dtprel@h -pub const R_PPC_DTPREL16_HI: u32 = 76; -/// half16  (sym+add)@dtprel@ha -pub const R_PPC_DTPREL16_HA: u32 = 77; -/// word32  (sym+add)@dtprel -pub const R_PPC_DTPREL32: u32 = 78; -/// half16* (sym+add)@got@tlsgd -pub const R_PPC_GOT_TLSGD16: u32 = 79; -/// half16  (sym+add)@got@tlsgd@l -pub const R_PPC_GOT_TLSGD16_LO: u32 = 80; -/// half16  (sym+add)@got@tlsgd@h -pub const R_PPC_GOT_TLSGD16_HI: u32 = 81; -/// half16  (sym+add)@got@tlsgd@ha -pub const R_PPC_GOT_TLSGD16_HA: u32 = 82; -/// half16* (sym+add)@got@tlsld -pub const R_PPC_GOT_TLSLD16: u32 = 83; -/// half16  (sym+add)@got@tlsld@l -pub const R_PPC_GOT_TLSLD16_LO: u32 = 84; -/// half16  (sym+add)@got@tlsld@h -pub const R_PPC_GOT_TLSLD16_HI: u32 = 85; -/// half16  (sym+add)@got@tlsld@ha -pub const R_PPC_GOT_TLSLD16_HA: u32 = 86; -/// half16* (sym+add)@got@tprel -pub const R_PPC_GOT_TPREL16: u32 = 87; -/// half16  (sym+add)@got@tprel@l -pub const R_PPC_GOT_TPREL16_LO: u32 = 88; -/// half16  (sym+add)@got@tprel@h -pub const R_PPC_GOT_TPREL16_HI: u32 = 89; -/// half16  (sym+add)@got@tprel@ha -pub const R_PPC_GOT_TPREL16_HA: u32 = 90; -/// half16* (sym+add)@got@dtprel -pub const R_PPC_GOT_DTPREL16: u32 = 91; -/// half16* (sym+add)@got@dtprel@l -pub const R_PPC_GOT_DTPREL16_LO: u32 = 92; -/// half16* (sym+add)@got@dtprel@h -pub const R_PPC_GOT_DTPREL16_HI: u32 = 93; -/// half16* (sym+add)@got@dtprel@ha -pub const R_PPC_GOT_DTPREL16_HA: u32 = 94; -/// none    (sym+add)@tlsgd -pub const R_PPC_TLSGD: u32 = 95; -/// none    (sym+add)@tlsld -pub const R_PPC_TLSLD: u32 = 96; - -// PowerPC values for `Rel*::r_type` from the Embedded ELF ABI. -pub const R_PPC_EMB_NADDR32: u32 = 101; -pub const R_PPC_EMB_NADDR16: u32 = 102; -pub const R_PPC_EMB_NADDR16_LO: u32 = 103; -pub const R_PPC_EMB_NADDR16_HI: u32 = 104; -pub const R_PPC_EMB_NADDR16_HA: u32 = 105; -pub const R_PPC_EMB_SDAI16: u32 = 106; -pub const R_PPC_EMB_SDA2I16: u32 = 107; -pub const R_PPC_EMB_SDA2REL: u32 = 108; -/// 16 bit offset in SDA -pub const R_PPC_EMB_SDA21: u32 = 109; -pub const R_PPC_EMB_MRKREF: u32 = 110; -pub const R_PPC_EMB_RELSEC16: u32 = 111; -pub const R_PPC_EMB_RELST_LO: u32 = 112; -pub const R_PPC_EMB_RELST_HI: u32 = 113; -pub const R_PPC_EMB_RELST_HA: u32 = 114; -pub const R_PPC_EMB_BIT_FLD: u32 = 115; -/// 16 bit relative offset in SDA -pub const R_PPC_EMB_RELSDA: u32 = 116; - -// Diab tool values for `Rel*::r_type`. -/// like EMB_SDA21, but lower 16 bit -pub const R_PPC_DIAB_SDA21_LO: u32 = 180; -/// like EMB_SDA21, but high 16 bit -pub const R_PPC_DIAB_SDA21_HI: u32 = 181; -/// like EMB_SDA21, adjusted high 16 -pub const R_PPC_DIAB_SDA21_HA: u32 = 182; -/// like EMB_RELSDA, but lower 16 bit -pub const R_PPC_DIAB_RELSDA_LO: u32 = 183; -/// like EMB_RELSDA, but high 16 bit -pub const R_PPC_DIAB_RELSDA_HI: u32 = 184; -/// like EMB_RELSDA, adjusted high 16 -pub const R_PPC_DIAB_RELSDA_HA: u32 = 185; - -/// GNU extension to support local ifunc. -pub const R_PPC_IRELATIVE: u32 = 248; - -// GNU relocs used in PIC code sequences. -/// half16   (sym+add-.) -pub const R_PPC_REL16: u32 = 249; -/// half16   (sym+add-.)@l -pub const R_PPC_REL16_LO: u32 = 250; -/// half16   (sym+add-.)@h -pub const R_PPC_REL16_HI: u32 = 251; -/// half16   (sym+add-.)@ha -pub const R_PPC_REL16_HA: u32 = 252; - -/// This is a phony reloc to handle any old fashioned TOC16 references that may -/// still be in object files. -pub const R_PPC_TOC16: u32 = 255; - -// PowerPC specific values for `Dyn*::d_tag`. -pub const DT_PPC_GOT: u32 = DT_LOPROC + 0; -pub const DT_PPC_OPT: u32 = DT_LOPROC + 1; - -// PowerPC specific values for the `DT_PPC_OPT` entry. -pub const PPC_OPT_TLS: u32 = 1; - -// PowerPC64 values for `Rel*::r_type` defined by the ABIs. -pub const R_PPC64_NONE: u32 = R_PPC_NONE; -/// 32bit absolute address -pub const R_PPC64_ADDR32: u32 = R_PPC_ADDR32; -/// 26bit address, word aligned -pub const R_PPC64_ADDR24: u32 = R_PPC_ADDR24; -/// 16bit absolute address -pub const R_PPC64_ADDR16: u32 = R_PPC_ADDR16; -/// lower 16bits of address -pub const R_PPC64_ADDR16_LO: u32 = R_PPC_ADDR16_LO; -/// high 16bits of address. -pub const R_PPC64_ADDR16_HI: u32 = R_PPC_ADDR16_HI; -/// adjusted high 16bits. -pub const R_PPC64_ADDR16_HA: u32 = R_PPC_ADDR16_HA; -/// 16bit address, word aligned -pub const R_PPC64_ADDR14: u32 = R_PPC_ADDR14; -pub const R_PPC64_ADDR14_BRTAKEN: u32 = R_PPC_ADDR14_BRTAKEN; -pub const R_PPC64_ADDR14_BRNTAKEN: u32 = R_PPC_ADDR14_BRNTAKEN; -/// PC-rel. 26 bit, word aligned -pub const R_PPC64_REL24: u32 = R_PPC_REL24; -/// PC relative 16 bit -pub const R_PPC64_REL14: u32 = R_PPC_REL14; -pub const R_PPC64_REL14_BRTAKEN: u32 = R_PPC_REL14_BRTAKEN; -pub const R_PPC64_REL14_BRNTAKEN: u32 = R_PPC_REL14_BRNTAKEN; -pub const R_PPC64_GOT16: u32 = R_PPC_GOT16; -pub const R_PPC64_GOT16_LO: u32 = R_PPC_GOT16_LO; -pub const R_PPC64_GOT16_HI: u32 = R_PPC_GOT16_HI; -pub const R_PPC64_GOT16_HA: u32 = R_PPC_GOT16_HA; - -pub const R_PPC64_COPY: u32 = R_PPC_COPY; -pub const R_PPC64_GLOB_DAT: u32 = R_PPC_GLOB_DAT; -pub const R_PPC64_JMP_SLOT: u32 = R_PPC_JMP_SLOT; -pub const R_PPC64_RELATIVE: u32 = R_PPC_RELATIVE; - -pub const R_PPC64_UADDR32: u32 = R_PPC_UADDR32; -pub const R_PPC64_UADDR16: u32 = R_PPC_UADDR16; -pub const R_PPC64_REL32: u32 = R_PPC_REL32; -pub const R_PPC64_PLT32: u32 = R_PPC_PLT32; -pub const R_PPC64_PLTREL32: u32 = R_PPC_PLTREL32; -pub const R_PPC64_PLT16_LO: u32 = R_PPC_PLT16_LO; -pub const R_PPC64_PLT16_HI: u32 = R_PPC_PLT16_HI; -pub const R_PPC64_PLT16_HA: u32 = R_PPC_PLT16_HA; - -pub const R_PPC64_SECTOFF: u32 = R_PPC_SECTOFF; -pub const R_PPC64_SECTOFF_LO: u32 = R_PPC_SECTOFF_LO; -pub const R_PPC64_SECTOFF_HI: u32 = R_PPC_SECTOFF_HI; -pub const R_PPC64_SECTOFF_HA: u32 = R_PPC_SECTOFF_HA; -/// word30 (S + A - P) >> 2 -pub const R_PPC64_ADDR30: u32 = 37; -/// doubleword64 S + A -pub const R_PPC64_ADDR64: u32 = 38; -/// half16 #higher(S + A) -pub const R_PPC64_ADDR16_HIGHER: u32 = 39; -/// half16 #highera(S + A) -pub const R_PPC64_ADDR16_HIGHERA: u32 = 40; -/// half16 #highest(S + A) -pub const R_PPC64_ADDR16_HIGHEST: u32 = 41; -/// half16 #highesta(S + A) -pub const R_PPC64_ADDR16_HIGHESTA: u32 = 42; -/// doubleword64 S + A -pub const R_PPC64_UADDR64: u32 = 43; -/// doubleword64 S + A - P -pub const R_PPC64_REL64: u32 = 44; -/// doubleword64 L + A -pub const R_PPC64_PLT64: u32 = 45; -/// doubleword64 L + A - P -pub const R_PPC64_PLTREL64: u32 = 46; -/// half16* S + A - .TOC -pub const R_PPC64_TOC16: u32 = 47; -/// half16 #lo(S + A - .TOC.) -pub const R_PPC64_TOC16_LO: u32 = 48; -/// half16 #hi(S + A - .TOC.) -pub const R_PPC64_TOC16_HI: u32 = 49; -/// half16 #ha(S + A - .TOC.) -pub const R_PPC64_TOC16_HA: u32 = 50; -/// doubleword64 .TOC -pub const R_PPC64_TOC: u32 = 51; -/// half16* M + A -pub const R_PPC64_PLTGOT16: u32 = 52; -/// half16 #lo(M + A) -pub const R_PPC64_PLTGOT16_LO: u32 = 53; -/// half16 #hi(M + A) -pub const R_PPC64_PLTGOT16_HI: u32 = 54; -/// half16 #ha(M + A) -pub const R_PPC64_PLTGOT16_HA: u32 = 55; - -/// half16ds* (S + A) >> 2 -pub const R_PPC64_ADDR16_DS: u32 = 56; -/// half16ds  #lo(S + A) >> 2 -pub const R_PPC64_ADDR16_LO_DS: u32 = 57; -/// half16ds* (G + A) >> 2 -pub const R_PPC64_GOT16_DS: u32 = 58; -/// half16ds  #lo(G + A) >> 2 -pub const R_PPC64_GOT16_LO_DS: u32 = 59; -/// half16ds  #lo(L + A) >> 2 -pub const R_PPC64_PLT16_LO_DS: u32 = 60; -/// half16ds* (R + A) >> 2 -pub const R_PPC64_SECTOFF_DS: u32 = 61; -/// half16ds  #lo(R + A) >> 2 -pub const R_PPC64_SECTOFF_LO_DS: u32 = 62; -/// half16ds* (S + A - .TOC.) >> 2 -pub const R_PPC64_TOC16_DS: u32 = 63; -/// half16ds  #lo(S + A - .TOC.) >> 2 -pub const R_PPC64_TOC16_LO_DS: u32 = 64; -/// half16ds* (M + A) >> 2 -pub const R_PPC64_PLTGOT16_DS: u32 = 65; -/// half16ds  #lo(M + A) >> 2 -pub const R_PPC64_PLTGOT16_LO_DS: u32 = 66; - -// PowerPC64 values for `Rel*::r_type` defined for the TLS access ABI. -/// none    (sym+add)@tls -pub const R_PPC64_TLS: u32 = 67; -/// doubleword64 (sym+add)@dtpmod -pub const R_PPC64_DTPMOD64: u32 = 68; -/// half16* (sym+add)@tprel -pub const R_PPC64_TPREL16: u32 = 69; -/// half16  (sym+add)@tprel@l -pub const R_PPC64_TPREL16_LO: u32 = 70; -/// half16  (sym+add)@tprel@h -pub const R_PPC64_TPREL16_HI: u32 = 71; -/// half16  (sym+add)@tprel@ha -pub const R_PPC64_TPREL16_HA: u32 = 72; -/// doubleword64 (sym+add)@tprel -pub const R_PPC64_TPREL64: u32 = 73; -/// half16* (sym+add)@dtprel -pub const R_PPC64_DTPREL16: u32 = 74; -/// half16  (sym+add)@dtprel@l -pub const R_PPC64_DTPREL16_LO: u32 = 75; -/// half16  (sym+add)@dtprel@h -pub const R_PPC64_DTPREL16_HI: u32 = 76; -/// half16  (sym+add)@dtprel@ha -pub const R_PPC64_DTPREL16_HA: u32 = 77; -/// doubleword64 (sym+add)@dtprel -pub const R_PPC64_DTPREL64: u32 = 78; -/// half16* (sym+add)@got@tlsgd -pub const R_PPC64_GOT_TLSGD16: u32 = 79; -/// half16  (sym+add)@got@tlsgd@l -pub const R_PPC64_GOT_TLSGD16_LO: u32 = 80; -/// half16  (sym+add)@got@tlsgd@h -pub const R_PPC64_GOT_TLSGD16_HI: u32 = 81; -/// half16  (sym+add)@got@tlsgd@ha -pub const R_PPC64_GOT_TLSGD16_HA: u32 = 82; -/// half16* (sym+add)@got@tlsld -pub const R_PPC64_GOT_TLSLD16: u32 = 83; -/// half16  (sym+add)@got@tlsld@l -pub const R_PPC64_GOT_TLSLD16_LO: u32 = 84; -/// half16  (sym+add)@got@tlsld@h -pub const R_PPC64_GOT_TLSLD16_HI: u32 = 85; -/// half16  (sym+add)@got@tlsld@ha -pub const R_PPC64_GOT_TLSLD16_HA: u32 = 86; -/// half16ds* (sym+add)@got@tprel -pub const R_PPC64_GOT_TPREL16_DS: u32 = 87; -/// half16ds (sym+add)@got@tprel@l -pub const R_PPC64_GOT_TPREL16_LO_DS: u32 = 88; -/// half16  (sym+add)@got@tprel@h -pub const R_PPC64_GOT_TPREL16_HI: u32 = 89; -/// half16  (sym+add)@got@tprel@ha -pub const R_PPC64_GOT_TPREL16_HA: u32 = 90; -/// half16ds* (sym+add)@got@dtprel -pub const R_PPC64_GOT_DTPREL16_DS: u32 = 91; -/// half16ds (sym+add)@got@dtprel@l -pub const R_PPC64_GOT_DTPREL16_LO_DS: u32 = 92; -/// half16  (sym+add)@got@dtprel@h -pub const R_PPC64_GOT_DTPREL16_HI: u32 = 93; -/// half16  (sym+add)@got@dtprel@ha -pub const R_PPC64_GOT_DTPREL16_HA: u32 = 94; -/// half16ds* (sym+add)@tprel -pub const R_PPC64_TPREL16_DS: u32 = 95; -/// half16ds (sym+add)@tprel@l -pub const R_PPC64_TPREL16_LO_DS: u32 = 96; -/// half16  (sym+add)@tprel@higher -pub const R_PPC64_TPREL16_HIGHER: u32 = 97; -/// half16  (sym+add)@tprel@highera -pub const R_PPC64_TPREL16_HIGHERA: u32 = 98; -/// half16  (sym+add)@tprel@highest -pub const R_PPC64_TPREL16_HIGHEST: u32 = 99; -/// half16  (sym+add)@tprel@highesta -pub const R_PPC64_TPREL16_HIGHESTA: u32 = 100; -/// half16ds* (sym+add)@dtprel -pub const R_PPC64_DTPREL16_DS: u32 = 101; -/// half16ds (sym+add)@dtprel@l -pub const R_PPC64_DTPREL16_LO_DS: u32 = 102; -/// half16  (sym+add)@dtprel@higher -pub const R_PPC64_DTPREL16_HIGHER: u32 = 103; -/// half16  (sym+add)@dtprel@highera -pub const R_PPC64_DTPREL16_HIGHERA: u32 = 104; -/// half16  (sym+add)@dtprel@highest -pub const R_PPC64_DTPREL16_HIGHEST: u32 = 105; -/// half16  (sym+add)@dtprel@highesta -pub const R_PPC64_DTPREL16_HIGHESTA: u32 = 106; -/// none    (sym+add)@tlsgd -pub const R_PPC64_TLSGD: u32 = 107; -/// none    (sym+add)@tlsld -pub const R_PPC64_TLSLD: u32 = 108; -/// none -pub const R_PPC64_TOCSAVE: u32 = 109; - -// Added when HA and HI relocs were changed to report overflows. -pub const R_PPC64_ADDR16_HIGH: u32 = 110; -pub const R_PPC64_ADDR16_HIGHA: u32 = 111; -pub const R_PPC64_TPREL16_HIGH: u32 = 112; -pub const R_PPC64_TPREL16_HIGHA: u32 = 113; -pub const R_PPC64_DTPREL16_HIGH: u32 = 114; -pub const R_PPC64_DTPREL16_HIGHA: u32 = 115; - -/// GNU extension to support local ifunc. -pub const R_PPC64_JMP_IREL: u32 = 247; -/// GNU extension to support local ifunc. -pub const R_PPC64_IRELATIVE: u32 = 248; -/// half16   (sym+add-.) -pub const R_PPC64_REL16: u32 = 249; -/// half16   (sym+add-.)@l -pub const R_PPC64_REL16_LO: u32 = 250; -/// half16   (sym+add-.)@h -pub const R_PPC64_REL16_HI: u32 = 251; -/// half16   (sym+add-.)@ha -pub const R_PPC64_REL16_HA: u32 = 252; - -// PowerPC64 values for `FileHeader64::e_flags. -/// PowerPC64 bits specifying ABI. -/// -/// 1 for original function descriptor using ABI, -/// 2 for revised ABI without function descriptors, -/// 0 for unspecified or not using any features affected by the differences. -pub const EF_PPC64_ABI: u32 = 3; - -// PowerPC64 values for `Dyn64::d_tag. -pub const DT_PPC64_GLINK: u32 = DT_LOPROC + 0; -pub const DT_PPC64_OPD: u32 = DT_LOPROC + 1; -pub const DT_PPC64_OPDSZ: u32 = DT_LOPROC + 2; -pub const DT_PPC64_OPT: u32 = DT_LOPROC + 3; - -// PowerPC64 bits for `DT_PPC64_OPT` entry. -pub const PPC64_OPT_TLS: u32 = 1; -pub const PPC64_OPT_MULTI_TOC: u32 = 2; -pub const PPC64_OPT_LOCALENTRY: u32 = 4; - -// PowerPC64 values for `Sym64::st_other. -pub const STO_PPC64_LOCAL_BIT: u8 = 5; -pub const STO_PPC64_LOCAL_MASK: u8 = 7 << STO_PPC64_LOCAL_BIT; - -// ARM specific declarations. - -// ARM values for `FileHeader*::e_flags`. -pub const EF_ARM_RELEXEC: u32 = 0x01; -pub const EF_ARM_HASENTRY: u32 = 0x02; -pub const EF_ARM_INTERWORK: u32 = 0x04; -pub const EF_ARM_APCS_26: u32 = 0x08; -pub const EF_ARM_APCS_FLOAT: u32 = 0x10; -pub const EF_ARM_PIC: u32 = 0x20; -/// 8-bit structure alignment is in use -pub const EF_ARM_ALIGN8: u32 = 0x40; -pub const EF_ARM_NEW_ABI: u32 = 0x80; -pub const EF_ARM_OLD_ABI: u32 = 0x100; -pub const EF_ARM_SOFT_FLOAT: u32 = 0x200; -pub const EF_ARM_VFP_FLOAT: u32 = 0x400; -pub const EF_ARM_MAVERICK_FLOAT: u32 = 0x800; - -/// NB conflicts with EF_ARM_SOFT_FLOAT -pub const EF_ARM_ABI_FLOAT_SOFT: u32 = 0x200; -/// NB conflicts with EF_ARM_VFP_FLOAT -pub const EF_ARM_ABI_FLOAT_HARD: u32 = 0x400; - -// Other constants defined in the ARM ELF spec. version B-01. -// NB. These conflict with values defined above. -pub const EF_ARM_SYMSARESORTED: u32 = 0x04; -pub const EF_ARM_DYNSYMSUSESEGIDX: u32 = 0x08; -pub const EF_ARM_MAPSYMSFIRST: u32 = 0x10; - -// Constants defined in AAELF. -pub const EF_ARM_BE8: u32 = 0x0080_0000; -pub const EF_ARM_LE8: u32 = 0x0040_0000; - -pub const EF_ARM_EABIMASK: u32 = 0xff00_0000; -pub const EF_ARM_EABI_UNKNOWN: u32 = 0x0000_0000; -pub const EF_ARM_EABI_VER1: u32 = 0x0100_0000; -pub const EF_ARM_EABI_VER2: u32 = 0x0200_0000; -pub const EF_ARM_EABI_VER3: u32 = 0x0300_0000; -pub const EF_ARM_EABI_VER4: u32 = 0x0400_0000; -pub const EF_ARM_EABI_VER5: u32 = 0x0500_0000; - -// ARM Thumb values for `st_type` component of `Sym*::st_info`. -/// A Thumb function. -pub const STT_ARM_TFUNC: u8 = STT_LOPROC; -/// A Thumb label. -pub const STT_ARM_16BIT: u8 = STT_HIPROC; - -// ARM values for `SectionHeader*::sh_flags`. -/// Section contains an entry point -pub const SHF_ARM_ENTRYSECT: u32 = 0x1000_0000; -/// Section may be multiply defined in the input to a link step. -pub const SHF_ARM_COMDEF: u32 = 0x8000_0000; - -// ARM values for `ProgramHeader*::p_flags`. -/// Segment contains the location addressed by the static base. -pub const PF_ARM_SB: u32 = 0x1000_0000; -/// Position-independent segment. -pub const PF_ARM_PI: u32 = 0x2000_0000; -/// Absolute segment. -pub const PF_ARM_ABS: u32 = 0x4000_0000; - -// ARM values for `ProgramHeader*::p_type`. -/// ARM unwind segment. -pub const PT_ARM_EXIDX: u32 = PT_LOPROC + 1; - -// ARM values for `SectionHeader*::sh_type`. -/// ARM unwind section. -pub const SHT_ARM_EXIDX: u32 = SHT_LOPROC + 1; -/// Preemption details. -pub const SHT_ARM_PREEMPTMAP: u32 = SHT_LOPROC + 2; -/// ARM attributes section. -pub const SHT_ARM_ATTRIBUTES: u32 = SHT_LOPROC + 3; - -// AArch64 values for `Rel*::r_type`. - -/// No relocation. -pub const R_AARCH64_NONE: u32 = 0; - -// ILP32 AArch64 relocs. -/// Direct 32 bit. -pub const R_AARCH64_P32_ABS32: u32 = 1; -/// Copy symbol at runtime. -pub const R_AARCH64_P32_COPY: u32 = 180; -/// Create GOT entry. -pub const R_AARCH64_P32_GLOB_DAT: u32 = 181; -/// Create PLT entry. -pub const R_AARCH64_P32_JUMP_SLOT: u32 = 182; -/// Adjust by program base. -pub const R_AARCH64_P32_RELATIVE: u32 = 183; -/// Module number, 32 bit. -pub const R_AARCH64_P32_TLS_DTPMOD: u32 = 184; -/// Module-relative offset, 32 bit. -pub const R_AARCH64_P32_TLS_DTPREL: u32 = 185; -/// TP-relative offset, 32 bit. -pub const R_AARCH64_P32_TLS_TPREL: u32 = 186; -/// TLS Descriptor. -pub const R_AARCH64_P32_TLSDESC: u32 = 187; -/// STT_GNU_IFUNC relocation. -pub const R_AARCH64_P32_IRELATIVE: u32 = 188; - -// LP64 AArch64 relocs. -/// Direct 64 bit. -pub const R_AARCH64_ABS64: u32 = 257; -/// Direct 32 bit. -pub const R_AARCH64_ABS32: u32 = 258; -/// Direct 16-bit. -pub const R_AARCH64_ABS16: u32 = 259; -/// PC-relative 64-bit. -pub const R_AARCH64_PREL64: u32 = 260; -/// PC-relative 32-bit. -pub const R_AARCH64_PREL32: u32 = 261; -/// PC-relative 16-bit. -pub const R_AARCH64_PREL16: u32 = 262; -/// Dir. MOVZ imm. from bits 15:0. -pub const R_AARCH64_MOVW_UABS_G0: u32 = 263; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_UABS_G0_NC: u32 = 264; -/// Dir. MOVZ imm. from bits 31:16. -pub const R_AARCH64_MOVW_UABS_G1: u32 = 265; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_UABS_G1_NC: u32 = 266; -/// Dir. MOVZ imm. from bits 47:32. -pub const R_AARCH64_MOVW_UABS_G2: u32 = 267; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_UABS_G2_NC: u32 = 268; -/// Dir. MOV{K,Z} imm. from 63:48. -pub const R_AARCH64_MOVW_UABS_G3: u32 = 269; -/// Dir. MOV{N,Z} imm. from 15:0. -pub const R_AARCH64_MOVW_SABS_G0: u32 = 270; -/// Dir. MOV{N,Z} imm. from 31:16. -pub const R_AARCH64_MOVW_SABS_G1: u32 = 271; -/// Dir. MOV{N,Z} imm. from 47:32. -pub const R_AARCH64_MOVW_SABS_G2: u32 = 272; -/// PC-rel. LD imm. from bits 20:2. -pub const R_AARCH64_LD_PREL_LO19: u32 = 273; -/// PC-rel. ADR imm. from bits 20:0. -pub const R_AARCH64_ADR_PREL_LO21: u32 = 274; -/// Page-rel. ADRP imm. from 32:12. -pub const R_AARCH64_ADR_PREL_PG_HI21: u32 = 275; -/// Likewise; no overflow check. -pub const R_AARCH64_ADR_PREL_PG_HI21_NC: u32 = 276; -/// Dir. ADD imm. from bits 11:0. -pub const R_AARCH64_ADD_ABS_LO12_NC: u32 = 277; -/// Likewise for LD/ST; no check. -pub const R_AARCH64_LDST8_ABS_LO12_NC: u32 = 278; -/// PC-rel. TBZ/TBNZ imm. from 15:2. -pub const R_AARCH64_TSTBR14: u32 = 279; -/// PC-rel. cond. br. imm. from 20:2. -pub const R_AARCH64_CONDBR19: u32 = 280; -/// PC-rel. B imm. from bits 27:2. -pub const R_AARCH64_JUMP26: u32 = 282; -/// Likewise for CALL. -pub const R_AARCH64_CALL26: u32 = 283; -/// Dir. ADD imm. from bits 11:1. -pub const R_AARCH64_LDST16_ABS_LO12_NC: u32 = 284; -/// Likewise for bits 11:2. -pub const R_AARCH64_LDST32_ABS_LO12_NC: u32 = 285; -/// Likewise for bits 11:3. -pub const R_AARCH64_LDST64_ABS_LO12_NC: u32 = 286; -/// PC-rel. MOV{N,Z} imm. from 15:0. -pub const R_AARCH64_MOVW_PREL_G0: u32 = 287; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_PREL_G0_NC: u32 = 288; -/// PC-rel. MOV{N,Z} imm. from 31:16. -pub const R_AARCH64_MOVW_PREL_G1: u32 = 289; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_PREL_G1_NC: u32 = 290; -/// PC-rel. MOV{N,Z} imm. from 47:32. -pub const R_AARCH64_MOVW_PREL_G2: u32 = 291; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_PREL_G2_NC: u32 = 292; -/// PC-rel. MOV{N,Z} imm. from 63:48. -pub const R_AARCH64_MOVW_PREL_G3: u32 = 293; -/// Dir. ADD imm. from bits 11:4. -pub const R_AARCH64_LDST128_ABS_LO12_NC: u32 = 299; -/// GOT-rel. off. MOV{N,Z} imm. 15:0. -pub const R_AARCH64_MOVW_GOTOFF_G0: u32 = 300; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_GOTOFF_G0_NC: u32 = 301; -/// GOT-rel. o. MOV{N,Z} imm. 31:16. -pub const R_AARCH64_MOVW_GOTOFF_G1: u32 = 302; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_GOTOFF_G1_NC: u32 = 303; -/// GOT-rel. o. MOV{N,Z} imm. 47:32. -pub const R_AARCH64_MOVW_GOTOFF_G2: u32 = 304; -/// Likewise for MOVK; no check. -pub const R_AARCH64_MOVW_GOTOFF_G2_NC: u32 = 305; -/// GOT-rel. o. MOV{N,Z} imm. 63:48. -pub const R_AARCH64_MOVW_GOTOFF_G3: u32 = 306; -/// GOT-relative 64-bit. -pub const R_AARCH64_GOTREL64: u32 = 307; -/// GOT-relative 32-bit. -pub const R_AARCH64_GOTREL32: u32 = 308; -/// PC-rel. GOT off. load imm. 20:2. -pub const R_AARCH64_GOT_LD_PREL19: u32 = 309; -/// GOT-rel. off. LD/ST imm. 14:3. -pub const R_AARCH64_LD64_GOTOFF_LO15: u32 = 310; -/// P-page-rel. GOT off. ADRP 32:12. -pub const R_AARCH64_ADR_GOT_PAGE: u32 = 311; -/// Dir. GOT off. LD/ST imm. 11:3. -pub const R_AARCH64_LD64_GOT_LO12_NC: u32 = 312; -/// GOT-page-rel. GOT off. LD/ST 14:3 -pub const R_AARCH64_LD64_GOTPAGE_LO15: u32 = 313; -/// PC-relative ADR imm. 20:0. -pub const R_AARCH64_TLSGD_ADR_PREL21: u32 = 512; -/// page-rel. ADRP imm. 32:12. -pub const R_AARCH64_TLSGD_ADR_PAGE21: u32 = 513; -/// direct ADD imm. from 11:0. -pub const R_AARCH64_TLSGD_ADD_LO12_NC: u32 = 514; -/// GOT-rel. MOV{N,Z} 31:16. -pub const R_AARCH64_TLSGD_MOVW_G1: u32 = 515; -/// GOT-rel. MOVK imm. 15:0. -pub const R_AARCH64_TLSGD_MOVW_G0_NC: u32 = 516; -/// Like 512; local dynamic model. -pub const R_AARCH64_TLSLD_ADR_PREL21: u32 = 517; -/// Like 513; local dynamic model. -pub const R_AARCH64_TLSLD_ADR_PAGE21: u32 = 518; -/// Like 514; local dynamic model. -pub const R_AARCH64_TLSLD_ADD_LO12_NC: u32 = 519; -/// Like 515; local dynamic model. -pub const R_AARCH64_TLSLD_MOVW_G1: u32 = 520; -/// Like 516; local dynamic model. -pub const R_AARCH64_TLSLD_MOVW_G0_NC: u32 = 521; -/// TLS PC-rel. load imm. 20:2. -pub const R_AARCH64_TLSLD_LD_PREL19: u32 = 522; -/// TLS DTP-rel. MOV{N,Z} 47:32. -pub const R_AARCH64_TLSLD_MOVW_DTPREL_G2: u32 = 523; -/// TLS DTP-rel. MOV{N,Z} 31:16. -pub const R_AARCH64_TLSLD_MOVW_DTPREL_G1: u32 = 524; -/// Likewise; MOVK; no check. -pub const R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: u32 = 525; -/// TLS DTP-rel. MOV{N,Z} 15:0. -pub const R_AARCH64_TLSLD_MOVW_DTPREL_G0: u32 = 526; -/// Likewise; MOVK; no check. -pub const R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: u32 = 527; -/// DTP-rel. ADD imm. from 23:12. -pub const R_AARCH64_TLSLD_ADD_DTPREL_HI12: u32 = 528; -/// DTP-rel. ADD imm. from 11:0. -pub const R_AARCH64_TLSLD_ADD_DTPREL_LO12: u32 = 529; -/// Likewise; no ovfl. check. -pub const R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: u32 = 530; -/// DTP-rel. LD/ST imm. 11:0. -pub const R_AARCH64_TLSLD_LDST8_DTPREL_LO12: u32 = 531; -/// Likewise; no check. -pub const R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: u32 = 532; -/// DTP-rel. LD/ST imm. 11:1. -pub const R_AARCH64_TLSLD_LDST16_DTPREL_LO12: u32 = 533; -/// Likewise; no check. -pub const R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: u32 = 534; -/// DTP-rel. LD/ST imm. 11:2. -pub const R_AARCH64_TLSLD_LDST32_DTPREL_LO12: u32 = 535; -/// Likewise; no check. -pub const R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: u32 = 536; -/// DTP-rel. LD/ST imm. 11:3. -pub const R_AARCH64_TLSLD_LDST64_DTPREL_LO12: u32 = 537; -/// Likewise; no check. -pub const R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: u32 = 538; -/// GOT-rel. MOV{N,Z} 31:16. -pub const R_AARCH64_TLSIE_MOVW_GOTTPREL_G1: u32 = 539; -/// GOT-rel. MOVK 15:0. -pub const R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: u32 = 540; -/// Page-rel. ADRP 32:12. -pub const R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: u32 = 541; -/// Direct LD off. 11:3. -pub const R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: u32 = 542; -/// PC-rel. load imm. 20:2. -pub const R_AARCH64_TLSIE_LD_GOTTPREL_PREL19: u32 = 543; -/// TLS TP-rel. MOV{N,Z} 47:32. -pub const R_AARCH64_TLSLE_MOVW_TPREL_G2: u32 = 544; -/// TLS TP-rel. MOV{N,Z} 31:16. -pub const R_AARCH64_TLSLE_MOVW_TPREL_G1: u32 = 545; -/// Likewise; MOVK; no check. -pub const R_AARCH64_TLSLE_MOVW_TPREL_G1_NC: u32 = 546; -/// TLS TP-rel. MOV{N,Z} 15:0. -pub const R_AARCH64_TLSLE_MOVW_TPREL_G0: u32 = 547; -/// Likewise; MOVK; no check. -pub const R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: u32 = 548; -/// TP-rel. ADD imm. 23:12. -pub const R_AARCH64_TLSLE_ADD_TPREL_HI12: u32 = 549; -/// TP-rel. ADD imm. 11:0. -pub const R_AARCH64_TLSLE_ADD_TPREL_LO12: u32 = 550; -/// Likewise; no ovfl. check. -pub const R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: u32 = 551; -/// TP-rel. LD/ST off. 11:0. -pub const R_AARCH64_TLSLE_LDST8_TPREL_LO12: u32 = 552; -/// Likewise; no ovfl. check. -pub const R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: u32 = 553; -/// TP-rel. LD/ST off. 11:1. -pub const R_AARCH64_TLSLE_LDST16_TPREL_LO12: u32 = 554; -/// Likewise; no check. -pub const R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: u32 = 555; -/// TP-rel. LD/ST off. 11:2. -pub const R_AARCH64_TLSLE_LDST32_TPREL_LO12: u32 = 556; -/// Likewise; no check. -pub const R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: u32 = 557; -/// TP-rel. LD/ST off. 11:3. -pub const R_AARCH64_TLSLE_LDST64_TPREL_LO12: u32 = 558; -/// Likewise; no check. -pub const R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: u32 = 559; -/// PC-rel. load immediate 20:2. -pub const R_AARCH64_TLSDESC_LD_PREL19: u32 = 560; -/// PC-rel. ADR immediate 20:0. -pub const R_AARCH64_TLSDESC_ADR_PREL21: u32 = 561; -/// Page-rel. ADRP imm. 32:12. -pub const R_AARCH64_TLSDESC_ADR_PAGE21: u32 = 562; -/// Direct LD off. from 11:3. -pub const R_AARCH64_TLSDESC_LD64_LO12: u32 = 563; -/// Direct ADD imm. from 11:0. -pub const R_AARCH64_TLSDESC_ADD_LO12: u32 = 564; -/// GOT-rel. MOV{N,Z} imm. 31:16. -pub const R_AARCH64_TLSDESC_OFF_G1: u32 = 565; -/// GOT-rel. MOVK imm. 15:0; no ck. -pub const R_AARCH64_TLSDESC_OFF_G0_NC: u32 = 566; -/// Relax LDR. -pub const R_AARCH64_TLSDESC_LDR: u32 = 567; -/// Relax ADD. -pub const R_AARCH64_TLSDESC_ADD: u32 = 568; -/// Relax BLR. -pub const R_AARCH64_TLSDESC_CALL: u32 = 569; -/// TP-rel. LD/ST off. 11:4. -pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12: u32 = 570; -/// Likewise; no check. -pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: u32 = 571; -/// DTP-rel. LD/ST imm. 11:4. -pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12: u32 = 572; -/// Likewise; no check. -pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC: u32 = 573; -/// Copy symbol at runtime. -pub const R_AARCH64_COPY: u32 = 1024; -/// Create GOT entry. -pub const R_AARCH64_GLOB_DAT: u32 = 1025; -/// Create PLT entry. -pub const R_AARCH64_JUMP_SLOT: u32 = 1026; -/// Adjust by program base. -pub const R_AARCH64_RELATIVE: u32 = 1027; -/// Module number, 64 bit. -pub const R_AARCH64_TLS_DTPMOD: u32 = 1028; -/// Module-relative offset, 64 bit. -pub const R_AARCH64_TLS_DTPREL: u32 = 1029; -/// TP-relative offset, 64 bit. -pub const R_AARCH64_TLS_TPREL: u32 = 1030; -/// TLS Descriptor. -pub const R_AARCH64_TLSDESC: u32 = 1031; -/// STT_GNU_IFUNC relocation. -pub const R_AARCH64_IRELATIVE: u32 = 1032; - -// AVR values for `FileHeader*::e_flags`. - -/// Bitmask for `EF_AVR_ARCH_*`. -pub const EF_AVR_ARCH: u32 = 0x7F; - -/// If set, it is assumed that the elf file uses local symbols as reference -/// for the relocations so that linker relaxation is possible. -pub const EF_AVR_LINKRELAX_PREPARED: u32 = 0x80; - -pub const EF_AVR_ARCH_AVR1: u32 = 1; -pub const EF_AVR_ARCH_AVR2: u32 = 2; -pub const EF_AVR_ARCH_AVR25: u32 = 25; -pub const EF_AVR_ARCH_AVR3: u32 = 3; -pub const EF_AVR_ARCH_AVR31: u32 = 31; -pub const EF_AVR_ARCH_AVR35: u32 = 35; -pub const EF_AVR_ARCH_AVR4: u32 = 4; -pub const EF_AVR_ARCH_AVR5: u32 = 5; -pub const EF_AVR_ARCH_AVR51: u32 = 51; -pub const EF_AVR_ARCH_AVR6: u32 = 6; -pub const EF_AVR_ARCH_AVRTINY: u32 = 100; -pub const EF_AVR_ARCH_XMEGA1: u32 = 101; -pub const EF_AVR_ARCH_XMEGA2: u32 = 102; -pub const EF_AVR_ARCH_XMEGA3: u32 = 103; -pub const EF_AVR_ARCH_XMEGA4: u32 = 104; -pub const EF_AVR_ARCH_XMEGA5: u32 = 105; -pub const EF_AVR_ARCH_XMEGA6: u32 = 106; -pub const EF_AVR_ARCH_XMEGA7: u32 = 107; - -// AVR values for `Rel*::r_type`. - -pub const R_AVR_NONE: u32 = 0; -/// Direct 32 bit -pub const R_AVR_32: u32 = 1; -pub const R_AVR_7_PCREL: u32 = 2; -pub const R_AVR_13_PCREL: u32 = 3; -/// Direct 16 bit -pub const R_AVR_16: u32 = 4; -pub const R_AVR_16_PM: u32 = 5; -pub const R_AVR_LO8_LDI: u32 = 6; -pub const R_AVR_HI8_LDI: u32 = 7; -pub const R_AVR_HH8_LDI: u32 = 8; -pub const R_AVR_LO8_LDI_NEG: u32 = 9; -pub const R_AVR_HI8_LDI_NEG: u32 = 10; -pub const R_AVR_HH8_LDI_NEG: u32 = 11; -pub const R_AVR_LO8_LDI_PM: u32 = 12; -pub const R_AVR_HI8_LDI_PM: u32 = 13; -pub const R_AVR_HH8_LDI_PM: u32 = 14; -pub const R_AVR_LO8_LDI_PM_NEG: u32 = 15; -pub const R_AVR_HI8_LDI_PM_NEG: u32 = 16; -pub const R_AVR_HH8_LDI_PM_NEG: u32 = 17; -pub const R_AVR_CALL: u32 = 18; -pub const R_AVR_LDI: u32 = 19; -pub const R_AVR_6: u32 = 20; -pub const R_AVR_6_ADIW: u32 = 21; -pub const R_AVR_MS8_LDI: u32 = 22; -pub const R_AVR_MS8_LDI_NEG: u32 = 23; -pub const R_AVR_LO8_LDI_GS: u32 = 24; -pub const R_AVR_HI8_LDI_GS: u32 = 25; -pub const R_AVR_8: u32 = 26; -pub const R_AVR_8_LO8: u32 = 27; -pub const R_AVR_8_HI8: u32 = 28; -pub const R_AVR_8_HLO8: u32 = 29; -pub const R_AVR_DIFF8: u32 = 30; -pub const R_AVR_DIFF16: u32 = 31; -pub const R_AVR_DIFF32: u32 = 32; -pub const R_AVR_LDS_STS_16: u32 = 33; -pub const R_AVR_PORT6: u32 = 34; -pub const R_AVR_PORT5: u32 = 35; -pub const R_AVR_32_PCREL: u32 = 36; - -// MSP430 values for `Rel*::r_type`. - -/// Direct 32 bit -pub const R_MSP430_32: u32 = 1; -/// Direct 16 bit -pub const R_MSP430_16_BYTE: u32 = 5; - -// Hexagon values for `Rel*::r_type`. - -/// Direct 32 bit -pub const R_HEX_32: u32 = 6; - -// ARM values for `Rel*::r_type`. - -/// No reloc -pub const R_ARM_NONE: u32 = 0; -/// Deprecated PC relative 26 bit branch. -pub const R_ARM_PC24: u32 = 1; -/// Direct 32 bit -pub const R_ARM_ABS32: u32 = 2; -/// PC relative 32 bit -pub const R_ARM_REL32: u32 = 3; -pub const R_ARM_PC13: u32 = 4; -/// Direct 16 bit -pub const R_ARM_ABS16: u32 = 5; -/// Direct 12 bit -pub const R_ARM_ABS12: u32 = 6; -/// Direct & 0x7C (`LDR`, `STR`). -pub const R_ARM_THM_ABS5: u32 = 7; -/// Direct 8 bit -pub const R_ARM_ABS8: u32 = 8; -pub const R_ARM_SBREL32: u32 = 9; -/// PC relative 24 bit (Thumb32 `BL`). -pub const R_ARM_THM_PC22: u32 = 10; -/// PC relative & 0x3FC (Thumb16 `LDR`, `ADD`, `ADR`). -pub const R_ARM_THM_PC8: u32 = 11; -pub const R_ARM_AMP_VCALL9: u32 = 12; -/// Obsolete static relocation. -pub const R_ARM_SWI24: u32 = 13; -/// Dynamic relocation. -pub const R_ARM_TLS_DESC: u32 = 13; -/// Reserved. -pub const R_ARM_THM_SWI8: u32 = 14; -/// Reserved. -pub const R_ARM_XPC25: u32 = 15; -/// Reserved. -pub const R_ARM_THM_XPC22: u32 = 16; -/// ID of module containing symbol -pub const R_ARM_TLS_DTPMOD32: u32 = 17; -/// Offset in TLS block -pub const R_ARM_TLS_DTPOFF32: u32 = 18; -/// Offset in static TLS block -pub const R_ARM_TLS_TPOFF32: u32 = 19; -/// Copy symbol at runtime -pub const R_ARM_COPY: u32 = 20; -/// Create GOT entry -pub const R_ARM_GLOB_DAT: u32 = 21; -/// Create PLT entry -pub const R_ARM_JUMP_SLOT: u32 = 22; -/// Adjust by program base -pub const R_ARM_RELATIVE: u32 = 23; -/// 32 bit offset to GOT -pub const R_ARM_GOTOFF: u32 = 24; -/// 32 bit PC relative offset to GOT -pub const R_ARM_GOTPC: u32 = 25; -/// 32 bit GOT entry -pub const R_ARM_GOT32: u32 = 26; -/// Deprecated, 32 bit PLT address. -pub const R_ARM_PLT32: u32 = 27; -/// PC relative 24 bit (`BL`, `BLX`). -pub const R_ARM_CALL: u32 = 28; -/// PC relative 24 bit (`B`, `BL<cond>`). -pub const R_ARM_JUMP24: u32 = 29; -/// PC relative 24 bit (Thumb32 `B.W`). -pub const R_ARM_THM_JUMP24: u32 = 30; -/// Adjust by program base. -pub const R_ARM_BASE_ABS: u32 = 31; -/// Obsolete. -pub const R_ARM_ALU_PCREL_7_0: u32 = 32; -/// Obsolete. -pub const R_ARM_ALU_PCREL_15_8: u32 = 33; -/// Obsolete. -pub const R_ARM_ALU_PCREL_23_15: u32 = 34; -/// Deprecated, prog. base relative. -pub const R_ARM_LDR_SBREL_11_0: u32 = 35; -/// Deprecated, prog. base relative. -pub const R_ARM_ALU_SBREL_19_12: u32 = 36; -/// Deprecated, prog. base relative. -pub const R_ARM_ALU_SBREL_27_20: u32 = 37; -pub const R_ARM_TARGET1: u32 = 38; -/// Program base relative. -pub const R_ARM_SBREL31: u32 = 39; -pub const R_ARM_V4BX: u32 = 40; -pub const R_ARM_TARGET2: u32 = 41; -/// 32 bit PC relative. -pub const R_ARM_PREL31: u32 = 42; -/// Direct 16-bit (`MOVW`). -pub const R_ARM_MOVW_ABS_NC: u32 = 43; -/// Direct high 16-bit (`MOVT`). -pub const R_ARM_MOVT_ABS: u32 = 44; -/// PC relative 16-bit (`MOVW`). -pub const R_ARM_MOVW_PREL_NC: u32 = 45; -/// PC relative (MOVT). -pub const R_ARM_MOVT_PREL: u32 = 46; -/// Direct 16 bit (Thumb32 `MOVW`). -pub const R_ARM_THM_MOVW_ABS_NC: u32 = 47; -/// Direct high 16 bit (Thumb32 `MOVT`). -pub const R_ARM_THM_MOVT_ABS: u32 = 48; -/// PC relative 16 bit (Thumb32 `MOVW`). -pub const R_ARM_THM_MOVW_PREL_NC: u32 = 49; -/// PC relative high 16 bit (Thumb32 `MOVT`). -pub const R_ARM_THM_MOVT_PREL: u32 = 50; -/// PC relative 20 bit (Thumb32 `B<cond>.W`). -pub const R_ARM_THM_JUMP19: u32 = 51; -/// PC relative X & 0x7E (Thumb16 `CBZ`, `CBNZ`). -pub const R_ARM_THM_JUMP6: u32 = 52; -/// PC relative 12 bit (Thumb32 `ADR.W`). -pub const R_ARM_THM_ALU_PREL_11_0: u32 = 53; -/// PC relative 12 bit (Thumb32 `LDR{D,SB,H,SH}`). -pub const R_ARM_THM_PC12: u32 = 54; -/// Direct 32-bit. -pub const R_ARM_ABS32_NOI: u32 = 55; -/// PC relative 32-bit. -pub const R_ARM_REL32_NOI: u32 = 56; -/// PC relative (`ADD`, `SUB`). -pub const R_ARM_ALU_PC_G0_NC: u32 = 57; -/// PC relative (`ADD`, `SUB`). -pub const R_ARM_ALU_PC_G0: u32 = 58; -/// PC relative (`ADD`, `SUB`). -pub const R_ARM_ALU_PC_G1_NC: u32 = 59; -/// PC relative (`ADD`, `SUB`). -pub const R_ARM_ALU_PC_G1: u32 = 60; -/// PC relative (`ADD`, `SUB`). -pub const R_ARM_ALU_PC_G2: u32 = 61; -/// PC relative (`LDR`,`STR`,`LDRB`,`STRB`). -pub const R_ARM_LDR_PC_G1: u32 = 62; -/// PC relative (`LDR`,`STR`,`LDRB`,`STRB`). -pub const R_ARM_LDR_PC_G2: u32 = 63; -/// PC relative (`STR{D,H}`, `LDR{D,SB,H,SH}`). -pub const R_ARM_LDRS_PC_G0: u32 = 64; -/// PC relative (`STR{D,H}`, `LDR{D,SB,H,SH}`). -pub const R_ARM_LDRS_PC_G1: u32 = 65; -/// PC relative (`STR{D,H}`, `LDR{D,SB,H,SH}`). -pub const R_ARM_LDRS_PC_G2: u32 = 66; -/// PC relative (`LDC`, `STC`). -pub const R_ARM_LDC_PC_G0: u32 = 67; -/// PC relative (`LDC`, `STC`). -pub const R_ARM_LDC_PC_G1: u32 = 68; -/// PC relative (`LDC`, `STC`). -pub const R_ARM_LDC_PC_G2: u32 = 69; -/// Program base relative (`ADD`,`SUB`). -pub const R_ARM_ALU_SB_G0_NC: u32 = 70; -/// Program base relative (`ADD`,`SUB`). -pub const R_ARM_ALU_SB_G0: u32 = 71; -/// Program base relative (`ADD`,`SUB`). -pub const R_ARM_ALU_SB_G1_NC: u32 = 72; -/// Program base relative (`ADD`,`SUB`). -pub const R_ARM_ALU_SB_G1: u32 = 73; -/// Program base relative (`ADD`,`SUB`). -pub const R_ARM_ALU_SB_G2: u32 = 74; -/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`). -pub const R_ARM_LDR_SB_G0: u32 = 75; -/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`). -pub const R_ARM_LDR_SB_G1: u32 = 76; -/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`). -pub const R_ARM_LDR_SB_G2: u32 = 77; -/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`). -pub const R_ARM_LDRS_SB_G0: u32 = 78; -/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`). -pub const R_ARM_LDRS_SB_G1: u32 = 79; -/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`). -pub const R_ARM_LDRS_SB_G2: u32 = 80; -/// Program base relative (`LDC`,`STC`). -pub const R_ARM_LDC_SB_G0: u32 = 81; -/// Program base relative (`LDC`,`STC`). -pub const R_ARM_LDC_SB_G1: u32 = 82; -/// Program base relative (`LDC`,`STC`). -pub const R_ARM_LDC_SB_G2: u32 = 83; -/// Program base relative 16 bit (`MOVW`). -pub const R_ARM_MOVW_BREL_NC: u32 = 84; -/// Program base relative high 16 bit (`MOVT`). -pub const R_ARM_MOVT_BREL: u32 = 85; -/// Program base relative 16 bit (`MOVW`). -pub const R_ARM_MOVW_BREL: u32 = 86; -/// Program base relative 16 bit (Thumb32 `MOVW`). -pub const R_ARM_THM_MOVW_BREL_NC: u32 = 87; -/// Program base relative high 16 bit (Thumb32 `MOVT`). -pub const R_ARM_THM_MOVT_BREL: u32 = 88; -/// Program base relative 16 bit (Thumb32 `MOVW`). -pub const R_ARM_THM_MOVW_BREL: u32 = 89; -pub const R_ARM_TLS_GOTDESC: u32 = 90; -pub const R_ARM_TLS_CALL: u32 = 91; -/// TLS relaxation. -pub const R_ARM_TLS_DESCSEQ: u32 = 92; -pub const R_ARM_THM_TLS_CALL: u32 = 93; -pub const R_ARM_PLT32_ABS: u32 = 94; -/// GOT entry. -pub const R_ARM_GOT_ABS: u32 = 95; -/// PC relative GOT entry. -pub const R_ARM_GOT_PREL: u32 = 96; -/// GOT entry relative to GOT origin (`LDR`). -pub const R_ARM_GOT_BREL12: u32 = 97; -/// 12 bit, GOT entry relative to GOT origin (`LDR`, `STR`). -pub const R_ARM_GOTOFF12: u32 = 98; -pub const R_ARM_GOTRELAX: u32 = 99; -pub const R_ARM_GNU_VTENTRY: u32 = 100; -pub const R_ARM_GNU_VTINHERIT: u32 = 101; -/// PC relative & 0xFFE (Thumb16 `B`). -pub const R_ARM_THM_PC11: u32 = 102; -/// PC relative & 0x1FE (Thumb16 `B`/`B<cond>`). -pub const R_ARM_THM_PC9: u32 = 103; -/// PC-rel 32 bit for global dynamic thread local data -pub const R_ARM_TLS_GD32: u32 = 104; -/// PC-rel 32 bit for local dynamic thread local data -pub const R_ARM_TLS_LDM32: u32 = 105; -/// 32 bit offset relative to TLS block -pub const R_ARM_TLS_LDO32: u32 = 106; -/// PC-rel 32 bit for GOT entry of static TLS block offset -pub const R_ARM_TLS_IE32: u32 = 107; -/// 32 bit offset relative to static TLS block -pub const R_ARM_TLS_LE32: u32 = 108; -/// 12 bit relative to TLS block (`LDR`, `STR`). -pub const R_ARM_TLS_LDO12: u32 = 109; -/// 12 bit relative to static TLS block (`LDR`, `STR`). -pub const R_ARM_TLS_LE12: u32 = 110; -/// 12 bit GOT entry relative to GOT origin (`LDR`). -pub const R_ARM_TLS_IE12GP: u32 = 111; -/// Obsolete. -pub const R_ARM_ME_TOO: u32 = 128; -pub const R_ARM_THM_TLS_DESCSEQ: u32 = 129; -pub const R_ARM_THM_TLS_DESCSEQ16: u32 = 129; -pub const R_ARM_THM_TLS_DESCSEQ32: u32 = 130; -/// GOT entry relative to GOT origin, 12 bit (Thumb32 `LDR`). -pub const R_ARM_THM_GOT_BREL12: u32 = 131; -pub const R_ARM_IRELATIVE: u32 = 160; -pub const R_ARM_RXPC25: u32 = 249; -pub const R_ARM_RSBREL32: u32 = 250; -pub const R_ARM_THM_RPC22: u32 = 251; -pub const R_ARM_RREL32: u32 = 252; -pub const R_ARM_RABS22: u32 = 253; -pub const R_ARM_RPC24: u32 = 254; -pub const R_ARM_RBASE: u32 = 255; - -// C-SKY values for `Rel*::r_type`. -/// no reloc -pub const R_CKCORE_NONE: u32 = 0; -/// direct 32 bit (S + A) -pub const R_CKCORE_ADDR32: u32 = 1; -/// disp ((S + A - P) >> 2) & 0xff -pub const R_CKCORE_PCRELIMM8BY4: u32 = 2; -/// disp ((S + A - P) >> 1) & 0x7ff -pub const R_CKCORE_PCRELIMM11BY2: u32 = 3; -/// 32-bit rel (S + A - P) -pub const R_CKCORE_PCREL32: u32 = 5; -/// disp ((S + A - P) >>1) & 0x7ff -pub const R_CKCORE_PCRELJSR_IMM11BY2: u32 = 6; -/// 32 bit adjust program base(B + A) -pub const R_CKCORE_RELATIVE: u32 = 9; -/// 32 bit adjust by program base -pub const R_CKCORE_COPY: u32 = 10; -/// off between got and sym (S) -pub const R_CKCORE_GLOB_DAT: u32 = 11; -/// PLT entry (S) -pub const R_CKCORE_JUMP_SLOT: u32 = 12; -/// offset to GOT (S + A - GOT) -pub const R_CKCORE_GOTOFF: u32 = 13; -/// PC offset to GOT (GOT + A - P) -pub const R_CKCORE_GOTPC: u32 = 14; -/// 32 bit GOT entry (G) -pub const R_CKCORE_GOT32: u32 = 15; -/// 32 bit PLT entry (G) -pub const R_CKCORE_PLT32: u32 = 16; -/// GOT entry in GLOB_DAT (GOT + G) -pub const R_CKCORE_ADDRGOT: u32 = 17; -/// PLT entry in GLOB_DAT (GOT + G) -pub const R_CKCORE_ADDRPLT: u32 = 18; -/// ((S + A - P) >> 1) & 0x3ff_ffff -pub const R_CKCORE_PCREL_IMM26BY2: u32 = 19; -/// disp ((S + A - P) >> 1) & 0xffff -pub const R_CKCORE_PCREL_IMM16BY2: u32 = 20; -/// disp ((S + A - P) >> 2) & 0xffff -pub const R_CKCORE_PCREL_IMM16BY4: u32 = 21; -/// disp ((S + A - P) >> 1) & 0x3ff -pub const R_CKCORE_PCREL_IMM10BY2: u32 = 22; -/// disp ((S + A - P) >> 2) & 0x3ff -pub const R_CKCORE_PCREL_IMM10BY4: u32 = 23; -/// high & low 16 bit ADDR, ((S + A) >> 16) & 0xffff -pub const R_CKCORE_ADDR_HI16: u32 = 24; -/// (S + A) & 0xffff -pub const R_CKCORE_ADDR_LO16: u32 = 25; -/// high & low 16 bit GOTPC, ((GOT + A - P) >> 16) & 0xffff -pub const R_CKCORE_GOTPC_HI16: u32 = 26; -/// (GOT + A - P) & 0xffff -pub const R_CKCORE_GOTPC_LO16: u32 = 27; -/// high & low 16 bit GOTOFF, ((S + A - GOT) >> 16) & 0xffff -pub const R_CKCORE_GOTOFF_HI16: u32 = 28; -/// (S + A - GOT) & 0xffff -pub const R_CKCORE_GOTOFF_LO16: u32 = 29; -/// 12 bit disp GOT entry (G) -pub const R_CKCORE_GOT12: u32 = 30; -/// high & low 16 bit GOT, (G >> 16) & 0xffff -pub const R_CKCORE_GOT_HI16: u32 = 31; -/// (G & 0xffff) -pub const R_CKCORE_GOT_LO16: u32 = 32; -/// 12 bit disp PLT entry (G) -pub const R_CKCORE_PLT12: u32 = 33; -/// high & low 16 bit PLT, (G >> 16) & 0xffff -pub const R_CKCORE_PLT_HI16: u32 = 34; -/// G & 0xffff -pub const R_CKCORE_PLT_LO16: u32 = 35; -/// high & low 16 bit ADDRGOT, (GOT + G * 4) & 0xffff -pub const R_CKCORE_ADDRGOT_HI16: u32 = 36; -/// (GOT + G * 4) & 0xffff -pub const R_CKCORE_ADDRGOT_LO16: u32 = 37; -/// high & low 16 bit ADDRPLT, ((GOT + G * 4) >> 16) & 0xFFFF -pub const R_CKCORE_ADDRPLT_HI16: u32 = 38; -/// (GOT+G*4) & 0xffff -pub const R_CKCORE_ADDRPLT_LO16: u32 = 39; -/// disp ((S+A-P) >>1) & x3ff_ffff -pub const R_CKCORE_PCREL_JSR_IMM26BY2: u32 = 40; -/// (S+A-BTEXT) & 0xffff -pub const R_CKCORE_TOFFSET_LO16: u32 = 41; -/// (S+A-BTEXT) & 0xffff -pub const R_CKCORE_DOFFSET_LO16: u32 = 42; -/// disp ((S+A-P) >>1) & 0x3ffff -pub const R_CKCORE_PCREL_IMM18BY2: u32 = 43; -/// disp (S+A-BDATA) & 0x3ffff -pub const R_CKCORE_DOFFSET_IMM18: u32 = 44; -/// disp ((S+A-BDATA)>>1) & 0x3ffff -pub const R_CKCORE_DOFFSET_IMM18BY2: u32 = 45; -/// disp ((S+A-BDATA)>>2) & 0x3ffff -pub const R_CKCORE_DOFFSET_IMM18BY4: u32 = 46; -/// disp (G >> 2) -pub const R_CKCORE_GOT_IMM18BY4: u32 = 48; -/// disp (G >> 2) -pub const R_CKCORE_PLT_IMM18BY4: u32 = 49; -/// disp ((S+A-P) >>2) & 0x7f -pub const R_CKCORE_PCREL_IMM7BY4: u32 = 50; -/// 32 bit offset to TLS block -pub const R_CKCORE_TLS_LE32: u32 = 51; -pub const R_CKCORE_TLS_IE32: u32 = 52; -pub const R_CKCORE_TLS_GD32: u32 = 53; -pub const R_CKCORE_TLS_LDM32: u32 = 54; -pub const R_CKCORE_TLS_LDO32: u32 = 55; -pub const R_CKCORE_TLS_DTPMOD32: u32 = 56; -pub const R_CKCORE_TLS_DTPOFF32: u32 = 57; -pub const R_CKCORE_TLS_TPOFF32: u32 = 58; - -// C-SKY values for `FileHeader*::e_flags`. -pub const EF_CSKY_ABIMASK: u32 = 0xF000_0000; -pub const EF_CSKY_OTHER: u32 = 0x0FFF_0000; -pub const EF_CSKY_PROCESSOR: u32 = 0x0000_FFFF; - -pub const EF_CSKY_ABIV1: u32 = 0x1000_0000; -pub const EF_CSKY_ABIV2: u32 = 0x2000_0000; - -// C-SKY values for `SectionHeader*::sh_type`. -/// C-SKY attributes section. -pub const SHT_CSKY_ATTRIBUTES: u32 = SHT_LOPROC + 1; - -// IA-64 specific declarations. - -// IA-64 values for `FileHeader64::e_flags`. -/// os-specific flags -pub const EF_IA_64_MASKOS: u32 = 0x0000_000f; -/// 64-bit ABI -pub const EF_IA_64_ABI64: u32 = 0x0000_0010; -/// arch. version mask -pub const EF_IA_64_ARCH: u32 = 0xff00_0000; - -// IA-64 values for `ProgramHeader64::p_type`. -/// arch extension bits -pub const PT_IA_64_ARCHEXT: u32 = PT_LOPROC + 0; -/// ia64 unwind bits -pub const PT_IA_64_UNWIND: u32 = PT_LOPROC + 1; -pub const PT_IA_64_HP_OPT_ANOT: u32 = PT_LOOS + 0x12; -pub const PT_IA_64_HP_HSL_ANOT: u32 = PT_LOOS + 0x13; -pub const PT_IA_64_HP_STACK: u32 = PT_LOOS + 0x14; - -// IA-64 values for `ProgramHeader64::p_flags`. -/// spec insns w/o recovery -pub const PF_IA_64_NORECOV: u32 = 0x8000_0000; - -// IA-64 values for `SectionHeader64::sh_type`. -/// extension bits -pub const SHT_IA_64_EXT: u32 = SHT_LOPROC + 0; -/// unwind bits -pub const SHT_IA_64_UNWIND: u32 = SHT_LOPROC + 1; - -// IA-64 values for `SectionHeader64::sh_flags`. -/// section near gp -pub const SHF_IA_64_SHORT: u32 = 0x1000_0000; -/// spec insns w/o recovery -pub const SHF_IA_64_NORECOV: u32 = 0x2000_0000; - -// IA-64 values for `Dyn64::d_tag`. -pub const DT_IA_64_PLT_RESERVE: u32 = DT_LOPROC + 0; - -// IA-64 values for `Rel*::r_type`. -/// none -pub const R_IA64_NONE: u32 = 0x00; -/// symbol + addend, add imm14 -pub const R_IA64_IMM14: u32 = 0x21; -/// symbol + addend, add imm22 -pub const R_IA64_IMM22: u32 = 0x22; -/// symbol + addend, mov imm64 -pub const R_IA64_IMM64: u32 = 0x23; -/// symbol + addend, data4 MSB -pub const R_IA64_DIR32MSB: u32 = 0x24; -/// symbol + addend, data4 LSB -pub const R_IA64_DIR32LSB: u32 = 0x25; -/// symbol + addend, data8 MSB -pub const R_IA64_DIR64MSB: u32 = 0x26; -/// symbol + addend, data8 LSB -pub const R_IA64_DIR64LSB: u32 = 0x27; -/// @gprel(sym + add), add imm22 -pub const R_IA64_GPREL22: u32 = 0x2a; -/// @gprel(sym + add), mov imm64 -pub const R_IA64_GPREL64I: u32 = 0x2b; -/// @gprel(sym + add), data4 MSB -pub const R_IA64_GPREL32MSB: u32 = 0x2c; -/// @gprel(sym + add), data4 LSB -pub const R_IA64_GPREL32LSB: u32 = 0x2d; -/// @gprel(sym + add), data8 MSB -pub const R_IA64_GPREL64MSB: u32 = 0x2e; -/// @gprel(sym + add), data8 LSB -pub const R_IA64_GPREL64LSB: u32 = 0x2f; -/// @ltoff(sym + add), add imm22 -pub const R_IA64_LTOFF22: u32 = 0x32; -/// @ltoff(sym + add), mov imm64 -pub const R_IA64_LTOFF64I: u32 = 0x33; -/// @pltoff(sym + add), add imm22 -pub const R_IA64_PLTOFF22: u32 = 0x3a; -/// @pltoff(sym + add), mov imm64 -pub const R_IA64_PLTOFF64I: u32 = 0x3b; -/// @pltoff(sym + add), data8 MSB -pub const R_IA64_PLTOFF64MSB: u32 = 0x3e; -/// @pltoff(sym + add), data8 LSB -pub const R_IA64_PLTOFF64LSB: u32 = 0x3f; -/// @fptr(sym + add), mov imm64 -pub const R_IA64_FPTR64I: u32 = 0x43; -/// @fptr(sym + add), data4 MSB -pub const R_IA64_FPTR32MSB: u32 = 0x44; -/// @fptr(sym + add), data4 LSB -pub const R_IA64_FPTR32LSB: u32 = 0x45; -/// @fptr(sym + add), data8 MSB -pub const R_IA64_FPTR64MSB: u32 = 0x46; -/// @fptr(sym + add), data8 LSB -pub const R_IA64_FPTR64LSB: u32 = 0x47; -/// @pcrel(sym + add), brl -pub const R_IA64_PCREL60B: u32 = 0x48; -/// @pcrel(sym + add), ptb, call -pub const R_IA64_PCREL21B: u32 = 0x49; -/// @pcrel(sym + add), chk.s -pub const R_IA64_PCREL21M: u32 = 0x4a; -/// @pcrel(sym + add), fchkf -pub const R_IA64_PCREL21F: u32 = 0x4b; -/// @pcrel(sym + add), data4 MSB -pub const R_IA64_PCREL32MSB: u32 = 0x4c; -/// @pcrel(sym + add), data4 LSB -pub const R_IA64_PCREL32LSB: u32 = 0x4d; -/// @pcrel(sym + add), data8 MSB -pub const R_IA64_PCREL64MSB: u32 = 0x4e; -/// @pcrel(sym + add), data8 LSB -pub const R_IA64_PCREL64LSB: u32 = 0x4f; -/// @ltoff(@fptr(s+a)), imm22 -pub const R_IA64_LTOFF_FPTR22: u32 = 0x52; -/// @ltoff(@fptr(s+a)), imm64 -pub const R_IA64_LTOFF_FPTR64I: u32 = 0x53; -/// @ltoff(@fptr(s+a)), data4 MSB -pub const R_IA64_LTOFF_FPTR32MSB: u32 = 0x54; -/// @ltoff(@fptr(s+a)), data4 LSB -pub const R_IA64_LTOFF_FPTR32LSB: u32 = 0x55; -/// @ltoff(@fptr(s+a)), data8 MSB -pub const R_IA64_LTOFF_FPTR64MSB: u32 = 0x56; -/// @ltoff(@fptr(s+a)), data8 LSB -pub const R_IA64_LTOFF_FPTR64LSB: u32 = 0x57; -/// @segrel(sym + add), data4 MSB -pub const R_IA64_SEGREL32MSB: u32 = 0x5c; -/// @segrel(sym + add), data4 LSB -pub const R_IA64_SEGREL32LSB: u32 = 0x5d; -/// @segrel(sym + add), data8 MSB -pub const R_IA64_SEGREL64MSB: u32 = 0x5e; -/// @segrel(sym + add), data8 LSB -pub const R_IA64_SEGREL64LSB: u32 = 0x5f; -/// @secrel(sym + add), data4 MSB -pub const R_IA64_SECREL32MSB: u32 = 0x64; -/// @secrel(sym + add), data4 LSB -pub const R_IA64_SECREL32LSB: u32 = 0x65; -/// @secrel(sym + add), data8 MSB -pub const R_IA64_SECREL64MSB: u32 = 0x66; -/// @secrel(sym + add), data8 LSB -pub const R_IA64_SECREL64LSB: u32 = 0x67; -/// data 4 + REL -pub const R_IA64_REL32MSB: u32 = 0x6c; -/// data 4 + REL -pub const R_IA64_REL32LSB: u32 = 0x6d; -/// data 8 + REL -pub const R_IA64_REL64MSB: u32 = 0x6e; -/// data 8 + REL -pub const R_IA64_REL64LSB: u32 = 0x6f; -/// symbol + addend, data4 MSB -pub const R_IA64_LTV32MSB: u32 = 0x74; -/// symbol + addend, data4 LSB -pub const R_IA64_LTV32LSB: u32 = 0x75; -/// symbol + addend, data8 MSB -pub const R_IA64_LTV64MSB: u32 = 0x76; -/// symbol + addend, data8 LSB -pub const R_IA64_LTV64LSB: u32 = 0x77; -/// @pcrel(sym + add), 21bit inst -pub const R_IA64_PCREL21BI: u32 = 0x79; -/// @pcrel(sym + add), 22bit inst -pub const R_IA64_PCREL22: u32 = 0x7a; -/// @pcrel(sym + add), 64bit inst -pub const R_IA64_PCREL64I: u32 = 0x7b; -/// dynamic reloc, imported PLT, MSB -pub const R_IA64_IPLTMSB: u32 = 0x80; -/// dynamic reloc, imported PLT, LSB -pub const R_IA64_IPLTLSB: u32 = 0x81; -/// copy relocation -pub const R_IA64_COPY: u32 = 0x84; -/// Addend and symbol difference -pub const R_IA64_SUB: u32 = 0x85; -/// LTOFF22, relaxable. -pub const R_IA64_LTOFF22X: u32 = 0x86; -/// Use of LTOFF22X. -pub const R_IA64_LDXMOV: u32 = 0x87; -/// @tprel(sym + add), imm14 -pub const R_IA64_TPREL14: u32 = 0x91; -/// @tprel(sym + add), imm22 -pub const R_IA64_TPREL22: u32 = 0x92; -/// @tprel(sym + add), imm64 -pub const R_IA64_TPREL64I: u32 = 0x93; -/// @tprel(sym + add), data8 MSB -pub const R_IA64_TPREL64MSB: u32 = 0x96; -/// @tprel(sym + add), data8 LSB -pub const R_IA64_TPREL64LSB: u32 = 0x97; -/// @ltoff(@tprel(s+a)), imm2 -pub const R_IA64_LTOFF_TPREL22: u32 = 0x9a; -/// @dtpmod(sym + add), data8 MSB -pub const R_IA64_DTPMOD64MSB: u32 = 0xa6; -/// @dtpmod(sym + add), data8 LSB -pub const R_IA64_DTPMOD64LSB: u32 = 0xa7; -/// @ltoff(@dtpmod(sym + add)), imm22 -pub const R_IA64_LTOFF_DTPMOD22: u32 = 0xaa; -/// @dtprel(sym + add), imm14 -pub const R_IA64_DTPREL14: u32 = 0xb1; -/// @dtprel(sym + add), imm22 -pub const R_IA64_DTPREL22: u32 = 0xb2; -/// @dtprel(sym + add), imm64 -pub const R_IA64_DTPREL64I: u32 = 0xb3; -/// @dtprel(sym + add), data4 MSB -pub const R_IA64_DTPREL32MSB: u32 = 0xb4; -/// @dtprel(sym + add), data4 LSB -pub const R_IA64_DTPREL32LSB: u32 = 0xb5; -/// @dtprel(sym + add), data8 MSB -pub const R_IA64_DTPREL64MSB: u32 = 0xb6; -/// @dtprel(sym + add), data8 LSB -pub const R_IA64_DTPREL64LSB: u32 = 0xb7; -/// @ltoff(@dtprel(s+a)), imm22 -pub const R_IA64_LTOFF_DTPREL22: u32 = 0xba; - -// SH specific declarations. - -// SH values `FileHeader*::e_flags`. -pub const EF_SH_MACH_MASK: u32 = 0x1f; -pub const EF_SH_UNKNOWN: u32 = 0x0; -pub const EF_SH1: u32 = 0x1; -pub const EF_SH2: u32 = 0x2; -pub const EF_SH3: u32 = 0x3; -pub const EF_SH_DSP: u32 = 0x4; -pub const EF_SH3_DSP: u32 = 0x5; -pub const EF_SH4AL_DSP: u32 = 0x6; -pub const EF_SH3E: u32 = 0x8; -pub const EF_SH4: u32 = 0x9; -pub const EF_SH2E: u32 = 0xb; -pub const EF_SH4A: u32 = 0xc; -pub const EF_SH2A: u32 = 0xd; -pub const EF_SH4_NOFPU: u32 = 0x10; -pub const EF_SH4A_NOFPU: u32 = 0x11; -pub const EF_SH4_NOMMU_NOFPU: u32 = 0x12; -pub const EF_SH2A_NOFPU: u32 = 0x13; -pub const EF_SH3_NOMMU: u32 = 0x14; -pub const EF_SH2A_SH4_NOFPU: u32 = 0x15; -pub const EF_SH2A_SH3_NOFPU: u32 = 0x16; -pub const EF_SH2A_SH4: u32 = 0x17; -pub const EF_SH2A_SH3E: u32 = 0x18; - -// SH values `Rel*::r_type`. -pub const R_SH_NONE: u32 = 0; -pub const R_SH_DIR32: u32 = 1; -pub const R_SH_REL32: u32 = 2; -pub const R_SH_DIR8WPN: u32 = 3; -pub const R_SH_IND12W: u32 = 4; -pub const R_SH_DIR8WPL: u32 = 5; -pub const R_SH_DIR8WPZ: u32 = 6; -pub const R_SH_DIR8BP: u32 = 7; -pub const R_SH_DIR8W: u32 = 8; -pub const R_SH_DIR8L: u32 = 9; -pub const R_SH_SWITCH16: u32 = 25; -pub const R_SH_SWITCH32: u32 = 26; -pub const R_SH_USES: u32 = 27; -pub const R_SH_COUNT: u32 = 28; -pub const R_SH_ALIGN: u32 = 29; -pub const R_SH_CODE: u32 = 30; -pub const R_SH_DATA: u32 = 31; -pub const R_SH_LABEL: u32 = 32; -pub const R_SH_SWITCH8: u32 = 33; -pub const R_SH_GNU_VTINHERIT: u32 = 34; -pub const R_SH_GNU_VTENTRY: u32 = 35; -pub const R_SH_TLS_GD_32: u32 = 144; -pub const R_SH_TLS_LD_32: u32 = 145; -pub const R_SH_TLS_LDO_32: u32 = 146; -pub const R_SH_TLS_IE_32: u32 = 147; -pub const R_SH_TLS_LE_32: u32 = 148; -pub const R_SH_TLS_DTPMOD32: u32 = 149; -pub const R_SH_TLS_DTPOFF32: u32 = 150; -pub const R_SH_TLS_TPOFF32: u32 = 151; -pub const R_SH_GOT32: u32 = 160; -pub const R_SH_PLT32: u32 = 161; -pub const R_SH_COPY: u32 = 162; -pub const R_SH_GLOB_DAT: u32 = 163; -pub const R_SH_JMP_SLOT: u32 = 164; -pub const R_SH_RELATIVE: u32 = 165; -pub const R_SH_GOTOFF: u32 = 166; -pub const R_SH_GOTPC: u32 = 167; - -// S/390 specific definitions. - -// S/390 values `FileHeader*::e_flags`. - -/// High GPRs kernel facility needed. -pub const EF_S390_HIGH_GPRS: u32 = 0x0000_0001; - -// S/390 values `Rel*::r_type`. - -/// No reloc. -pub const R_390_NONE: u32 = 0; -/// Direct 8 bit. -pub const R_390_8: u32 = 1; -/// Direct 12 bit. -pub const R_390_12: u32 = 2; -/// Direct 16 bit. -pub const R_390_16: u32 = 3; -/// Direct 32 bit. -pub const R_390_32: u32 = 4; -/// PC relative 32 bit. -pub const R_390_PC32: u32 = 5; -/// 12 bit GOT offset. -pub const R_390_GOT12: u32 = 6; -/// 32 bit GOT offset. -pub const R_390_GOT32: u32 = 7; -/// 32 bit PC relative PLT address. -pub const R_390_PLT32: u32 = 8; -/// Copy symbol at runtime. -pub const R_390_COPY: u32 = 9; -/// Create GOT entry. -pub const R_390_GLOB_DAT: u32 = 10; -/// Create PLT entry. -pub const R_390_JMP_SLOT: u32 = 11; -/// Adjust by program base. -pub const R_390_RELATIVE: u32 = 12; -/// 32 bit offset to GOT. -pub const R_390_GOTOFF32: u32 = 13; -/// 32 bit PC relative offset to GOT. -pub const R_390_GOTPC: u32 = 14; -/// 16 bit GOT offset. -pub const R_390_GOT16: u32 = 15; -/// PC relative 16 bit. -pub const R_390_PC16: u32 = 16; -/// PC relative 16 bit shifted by 1. -pub const R_390_PC16DBL: u32 = 17; -/// 16 bit PC rel. PLT shifted by 1. -pub const R_390_PLT16DBL: u32 = 18; -/// PC relative 32 bit shifted by 1. -pub const R_390_PC32DBL: u32 = 19; -/// 32 bit PC rel. PLT shifted by 1. -pub const R_390_PLT32DBL: u32 = 20; -/// 32 bit PC rel. GOT shifted by 1. -pub const R_390_GOTPCDBL: u32 = 21; -/// Direct 64 bit. -pub const R_390_64: u32 = 22; -/// PC relative 64 bit. -pub const R_390_PC64: u32 = 23; -/// 64 bit GOT offset. -pub const R_390_GOT64: u32 = 24; -/// 64 bit PC relative PLT address. -pub const R_390_PLT64: u32 = 25; -/// 32 bit PC rel. to GOT entry >> 1. -pub const R_390_GOTENT: u32 = 26; -/// 16 bit offset to GOT. -pub const R_390_GOTOFF16: u32 = 27; -/// 64 bit offset to GOT. -pub const R_390_GOTOFF64: u32 = 28; -/// 12 bit offset to jump slot. -pub const R_390_GOTPLT12: u32 = 29; -/// 16 bit offset to jump slot. -pub const R_390_GOTPLT16: u32 = 30; -/// 32 bit offset to jump slot. -pub const R_390_GOTPLT32: u32 = 31; -/// 64 bit offset to jump slot. -pub const R_390_GOTPLT64: u32 = 32; -/// 32 bit rel. offset to jump slot. -pub const R_390_GOTPLTENT: u32 = 33; -/// 16 bit offset from GOT to PLT. -pub const R_390_PLTOFF16: u32 = 34; -/// 32 bit offset from GOT to PLT. -pub const R_390_PLTOFF32: u32 = 35; -/// 16 bit offset from GOT to PLT. -pub const R_390_PLTOFF64: u32 = 36; -/// Tag for load insn in TLS code. -pub const R_390_TLS_LOAD: u32 = 37; -/// Tag for function call in general dynamic TLS code. -pub const R_390_TLS_GDCALL: u32 = 38; -/// Tag for function call in local dynamic TLS code. -pub const R_390_TLS_LDCALL: u32 = 39; -/// Direct 32 bit for general dynamic thread local data. -pub const R_390_TLS_GD32: u32 = 40; -/// Direct 64 bit for general dynamic thread local data. -pub const R_390_TLS_GD64: u32 = 41; -/// 12 bit GOT offset for static TLS block offset. -pub const R_390_TLS_GOTIE12: u32 = 42; -/// 32 bit GOT offset for static TLS block offset. -pub const R_390_TLS_GOTIE32: u32 = 43; -/// 64 bit GOT offset for static TLS block offset. -pub const R_390_TLS_GOTIE64: u32 = 44; -/// Direct 32 bit for local dynamic thread local data in LE code. -pub const R_390_TLS_LDM32: u32 = 45; -/// Direct 64 bit for local dynamic thread local data in LE code. -pub const R_390_TLS_LDM64: u32 = 46; -/// 32 bit address of GOT entry for negated static TLS block offset. -pub const R_390_TLS_IE32: u32 = 47; -/// 64 bit address of GOT entry for negated static TLS block offset. -pub const R_390_TLS_IE64: u32 = 48; -/// 32 bit rel. offset to GOT entry for negated static TLS block offset. -pub const R_390_TLS_IEENT: u32 = 49; -/// 32 bit negated offset relative to static TLS block. -pub const R_390_TLS_LE32: u32 = 50; -/// 64 bit negated offset relative to static TLS block. -pub const R_390_TLS_LE64: u32 = 51; -/// 32 bit offset relative to TLS block. -pub const R_390_TLS_LDO32: u32 = 52; -/// 64 bit offset relative to TLS block. -pub const R_390_TLS_LDO64: u32 = 53; -/// ID of module containing symbol. -pub const R_390_TLS_DTPMOD: u32 = 54; -/// Offset in TLS block. -pub const R_390_TLS_DTPOFF: u32 = 55; -/// Negated offset in static TLS block. -pub const R_390_TLS_TPOFF: u32 = 56; -/// Direct 20 bit. -pub const R_390_20: u32 = 57; -/// 20 bit GOT offset. -pub const R_390_GOT20: u32 = 58; -/// 20 bit offset to jump slot. -pub const R_390_GOTPLT20: u32 = 59; -/// 20 bit GOT offset for static TLS block offset. -pub const R_390_TLS_GOTIE20: u32 = 60; -/// STT_GNU_IFUNC relocation. -pub const R_390_IRELATIVE: u32 = 61; - -// CRIS values `Rel*::r_type`. -pub const R_CRIS_NONE: u32 = 0; -pub const R_CRIS_8: u32 = 1; -pub const R_CRIS_16: u32 = 2; -pub const R_CRIS_32: u32 = 3; -pub const R_CRIS_8_PCREL: u32 = 4; -pub const R_CRIS_16_PCREL: u32 = 5; -pub const R_CRIS_32_PCREL: u32 = 6; -pub const R_CRIS_GNU_VTINHERIT: u32 = 7; -pub const R_CRIS_GNU_VTENTRY: u32 = 8; -pub const R_CRIS_COPY: u32 = 9; -pub const R_CRIS_GLOB_DAT: u32 = 10; -pub const R_CRIS_JUMP_SLOT: u32 = 11; -pub const R_CRIS_RELATIVE: u32 = 12; -pub const R_CRIS_16_GOT: u32 = 13; -pub const R_CRIS_32_GOT: u32 = 14; -pub const R_CRIS_16_GOTPLT: u32 = 15; -pub const R_CRIS_32_GOTPLT: u32 = 16; -pub const R_CRIS_32_GOTREL: u32 = 17; -pub const R_CRIS_32_PLT_GOTREL: u32 = 18; -pub const R_CRIS_32_PLT_PCREL: u32 = 19; - -// AMD x86-64 values `Rel*::r_type`. -/// No reloc -pub const R_X86_64_NONE: u32 = 0; -/// Direct 64 bit -pub const R_X86_64_64: u32 = 1; -/// PC relative 32 bit signed -pub const R_X86_64_PC32: u32 = 2; -/// 32 bit GOT entry -pub const R_X86_64_GOT32: u32 = 3; -/// 32 bit PLT address -pub const R_X86_64_PLT32: u32 = 4; -/// Copy symbol at runtime -pub const R_X86_64_COPY: u32 = 5; -/// Create GOT entry -pub const R_X86_64_GLOB_DAT: u32 = 6; -/// Create PLT entry -pub const R_X86_64_JUMP_SLOT: u32 = 7; -/// Adjust by program base -pub const R_X86_64_RELATIVE: u32 = 8; -/// 32 bit signed PC relative offset to GOT -pub const R_X86_64_GOTPCREL: u32 = 9; -/// Direct 32 bit zero extended -pub const R_X86_64_32: u32 = 10; -/// Direct 32 bit sign extended -pub const R_X86_64_32S: u32 = 11; -/// Direct 16 bit zero extended -pub const R_X86_64_16: u32 = 12; -/// 16 bit sign extended pc relative -pub const R_X86_64_PC16: u32 = 13; -/// Direct 8 bit sign extended -pub const R_X86_64_8: u32 = 14; -/// 8 bit sign extended pc relative -pub const R_X86_64_PC8: u32 = 15; -/// ID of module containing symbol -pub const R_X86_64_DTPMOD64: u32 = 16; -/// Offset in module's TLS block -pub const R_X86_64_DTPOFF64: u32 = 17; -/// Offset in initial TLS block -pub const R_X86_64_TPOFF64: u32 = 18; -/// 32 bit signed PC relative offset to two GOT entries for GD symbol -pub const R_X86_64_TLSGD: u32 = 19; -/// 32 bit signed PC relative offset to two GOT entries for LD symbol -pub const R_X86_64_TLSLD: u32 = 20; -/// Offset in TLS block -pub const R_X86_64_DTPOFF32: u32 = 21; -/// 32 bit signed PC relative offset to GOT entry for IE symbol -pub const R_X86_64_GOTTPOFF: u32 = 22; -/// Offset in initial TLS block -pub const R_X86_64_TPOFF32: u32 = 23; -/// PC relative 64 bit -pub const R_X86_64_PC64: u32 = 24; -/// 64 bit offset to GOT -pub const R_X86_64_GOTOFF64: u32 = 25; -/// 32 bit signed pc relative offset to GOT -pub const R_X86_64_GOTPC32: u32 = 26; -/// 64-bit GOT entry offset -pub const R_X86_64_GOT64: u32 = 27; -/// 64-bit PC relative offset to GOT entry -pub const R_X86_64_GOTPCREL64: u32 = 28; -/// 64-bit PC relative offset to GOT -pub const R_X86_64_GOTPC64: u32 = 29; -/// like GOT64, says PLT entry needed -pub const R_X86_64_GOTPLT64: u32 = 30; -/// 64-bit GOT relative offset to PLT entry -pub const R_X86_64_PLTOFF64: u32 = 31; -/// Size of symbol plus 32-bit addend -pub const R_X86_64_SIZE32: u32 = 32; -/// Size of symbol plus 64-bit addend -pub const R_X86_64_SIZE64: u32 = 33; -/// GOT offset for TLS descriptor. -pub const R_X86_64_GOTPC32_TLSDESC: u32 = 34; -/// Marker for call through TLS descriptor. -pub const R_X86_64_TLSDESC_CALL: u32 = 35; -/// TLS descriptor. -pub const R_X86_64_TLSDESC: u32 = 36; -/// Adjust indirectly by program base -pub const R_X86_64_IRELATIVE: u32 = 37; -/// 64-bit adjust by program base -pub const R_X86_64_RELATIVE64: u32 = 38; -// 39 Reserved was R_X86_64_PC32_BND -// 40 Reserved was R_X86_64_PLT32_BND -/// Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable. -pub const R_X86_64_GOTPCRELX: u32 = 41; -/// Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable. -pub const R_X86_64_REX_GOTPCRELX: u32 = 42; - -// AMD x86-64 values `SectionHeader*::sh_type`. -/// Unwind information. -pub const SHT_X86_64_UNWIND: u32 = 0x7000_0001; - -// AM33 values `Rel*::r_type`. -/// No reloc. -pub const R_MN10300_NONE: u32 = 0; -/// Direct 32 bit. -pub const R_MN10300_32: u32 = 1; -/// Direct 16 bit. -pub const R_MN10300_16: u32 = 2; -/// Direct 8 bit. -pub const R_MN10300_8: u32 = 3; -/// PC-relative 32-bit. -pub const R_MN10300_PCREL32: u32 = 4; -/// PC-relative 16-bit signed. -pub const R_MN10300_PCREL16: u32 = 5; -/// PC-relative 8-bit signed. -pub const R_MN10300_PCREL8: u32 = 6; -/// Ancient C++ vtable garbage... -pub const R_MN10300_GNU_VTINHERIT: u32 = 7; -/// ... collection annotation. -pub const R_MN10300_GNU_VTENTRY: u32 = 8; -/// Direct 24 bit. -pub const R_MN10300_24: u32 = 9; -/// 32-bit PCrel offset to GOT. -pub const R_MN10300_GOTPC32: u32 = 10; -/// 16-bit PCrel offset to GOT. -pub const R_MN10300_GOTPC16: u32 = 11; -/// 32-bit offset from GOT. -pub const R_MN10300_GOTOFF32: u32 = 12; -/// 24-bit offset from GOT. -pub const R_MN10300_GOTOFF24: u32 = 13; -/// 16-bit offset from GOT. -pub const R_MN10300_GOTOFF16: u32 = 14; -/// 32-bit PCrel to PLT entry. -pub const R_MN10300_PLT32: u32 = 15; -/// 16-bit PCrel to PLT entry. -pub const R_MN10300_PLT16: u32 = 16; -/// 32-bit offset to GOT entry. -pub const R_MN10300_GOT32: u32 = 17; -/// 24-bit offset to GOT entry. -pub const R_MN10300_GOT24: u32 = 18; -/// 16-bit offset to GOT entry. -pub const R_MN10300_GOT16: u32 = 19; -/// Copy symbol at runtime. -pub const R_MN10300_COPY: u32 = 20; -/// Create GOT entry. -pub const R_MN10300_GLOB_DAT: u32 = 21; -/// Create PLT entry. -pub const R_MN10300_JMP_SLOT: u32 = 22; -/// Adjust by program base. -pub const R_MN10300_RELATIVE: u32 = 23; -/// 32-bit offset for global dynamic. -pub const R_MN10300_TLS_GD: u32 = 24; -/// 32-bit offset for local dynamic. -pub const R_MN10300_TLS_LD: u32 = 25; -/// Module-relative offset. -pub const R_MN10300_TLS_LDO: u32 = 26; -/// GOT offset for static TLS block offset. -pub const R_MN10300_TLS_GOTIE: u32 = 27; -/// GOT address for static TLS block offset. -pub const R_MN10300_TLS_IE: u32 = 28; -/// Offset relative to static TLS block. -pub const R_MN10300_TLS_LE: u32 = 29; -/// ID of module containing symbol. -pub const R_MN10300_TLS_DTPMOD: u32 = 30; -/// Offset in module TLS block. -pub const R_MN10300_TLS_DTPOFF: u32 = 31; -/// Offset in static TLS block. -pub const R_MN10300_TLS_TPOFF: u32 = 32; -/// Adjustment for next reloc as needed by linker relaxation. -pub const R_MN10300_SYM_DIFF: u32 = 33; -/// Alignment requirement for linker relaxation. -pub const R_MN10300_ALIGN: u32 = 34; - -// M32R values `Rel32::r_type`. -/// No reloc. -pub const R_M32R_NONE: u32 = 0; -/// Direct 16 bit. -pub const R_M32R_16: u32 = 1; -/// Direct 32 bit. -pub const R_M32R_32: u32 = 2; -/// Direct 24 bit. -pub const R_M32R_24: u32 = 3; -/// PC relative 10 bit shifted. -pub const R_M32R_10_PCREL: u32 = 4; -/// PC relative 18 bit shifted. -pub const R_M32R_18_PCREL: u32 = 5; -/// PC relative 26 bit shifted. -pub const R_M32R_26_PCREL: u32 = 6; -/// High 16 bit with unsigned low. -pub const R_M32R_HI16_ULO: u32 = 7; -/// High 16 bit with signed low. -pub const R_M32R_HI16_SLO: u32 = 8; -/// Low 16 bit. -pub const R_M32R_LO16: u32 = 9; -/// 16 bit offset in SDA. -pub const R_M32R_SDA16: u32 = 10; -pub const R_M32R_GNU_VTINHERIT: u32 = 11; -pub const R_M32R_GNU_VTENTRY: u32 = 12; -// M32R values `Rela32::r_type`. -/// Direct 16 bit. -pub const R_M32R_16_RELA: u32 = 33; -/// Direct 32 bit. -pub const R_M32R_32_RELA: u32 = 34; -/// Direct 24 bit. -pub const R_M32R_24_RELA: u32 = 35; -/// PC relative 10 bit shifted. -pub const R_M32R_10_PCREL_RELA: u32 = 36; -/// PC relative 18 bit shifted. -pub const R_M32R_18_PCREL_RELA: u32 = 37; -/// PC relative 26 bit shifted. -pub const R_M32R_26_PCREL_RELA: u32 = 38; -/// High 16 bit with unsigned low -pub const R_M32R_HI16_ULO_RELA: u32 = 39; -/// High 16 bit with signed low -pub const R_M32R_HI16_SLO_RELA: u32 = 40; -/// Low 16 bit -pub const R_M32R_LO16_RELA: u32 = 41; -/// 16 bit offset in SDA -pub const R_M32R_SDA16_RELA: u32 = 42; -pub const R_M32R_RELA_GNU_VTINHERIT: u32 = 43; -pub const R_M32R_RELA_GNU_VTENTRY: u32 = 44; -/// PC relative 32 bit. -pub const R_M32R_REL32: u32 = 45; - -/// 24 bit GOT entry -pub const R_M32R_GOT24: u32 = 48; -/// 26 bit PC relative to PLT shifted -pub const R_M32R_26_PLTREL: u32 = 49; -/// Copy symbol at runtime -pub const R_M32R_COPY: u32 = 50; -/// Create GOT entry -pub const R_M32R_GLOB_DAT: u32 = 51; -/// Create PLT entry -pub const R_M32R_JMP_SLOT: u32 = 52; -/// Adjust by program base -pub const R_M32R_RELATIVE: u32 = 53; -/// 24 bit offset to GOT -pub const R_M32R_GOTOFF: u32 = 54; -/// 24 bit PC relative offset to GOT -pub const R_M32R_GOTPC24: u32 = 55; -/// High 16 bit GOT entry with unsigned low -pub const R_M32R_GOT16_HI_ULO: u32 = 56; -/// High 16 bit GOT entry with signed low -pub const R_M32R_GOT16_HI_SLO: u32 = 57; -/// Low 16 bit GOT entry -pub const R_M32R_GOT16_LO: u32 = 58; -/// High 16 bit PC relative offset to GOT with unsigned low -pub const R_M32R_GOTPC_HI_ULO: u32 = 59; -/// High 16 bit PC relative offset to GOT with signed low -pub const R_M32R_GOTPC_HI_SLO: u32 = 60; -/// Low 16 bit PC relative offset to GOT -pub const R_M32R_GOTPC_LO: u32 = 61; -/// High 16 bit offset to GOT with unsigned low -pub const R_M32R_GOTOFF_HI_ULO: u32 = 62; -/// High 16 bit offset to GOT with signed low -pub const R_M32R_GOTOFF_HI_SLO: u32 = 63; -/// Low 16 bit offset to GOT -pub const R_M32R_GOTOFF_LO: u32 = 64; -/// Keep this the last entry. -pub const R_M32R_NUM: u32 = 256; - -// MicroBlaze values `Rel*::r_type`. -/// No reloc. -pub const R_MICROBLAZE_NONE: u32 = 0; -/// Direct 32 bit. -pub const R_MICROBLAZE_32: u32 = 1; -/// PC relative 32 bit. -pub const R_MICROBLAZE_32_PCREL: u32 = 2; -/// PC relative 64 bit. -pub const R_MICROBLAZE_64_PCREL: u32 = 3; -/// Low 16 bits of PCREL32. -pub const R_MICROBLAZE_32_PCREL_LO: u32 = 4; -/// Direct 64 bit. -pub const R_MICROBLAZE_64: u32 = 5; -/// Low 16 bit. -pub const R_MICROBLAZE_32_LO: u32 = 6; -/// Read-only small data area. -pub const R_MICROBLAZE_SRO32: u32 = 7; -/// Read-write small data area. -pub const R_MICROBLAZE_SRW32: u32 = 8; -/// No reloc. -pub const R_MICROBLAZE_64_NONE: u32 = 9; -/// Symbol Op Symbol relocation. -pub const R_MICROBLAZE_32_SYM_OP_SYM: u32 = 10; -/// GNU C++ vtable hierarchy. -pub const R_MICROBLAZE_GNU_VTINHERIT: u32 = 11; -/// GNU C++ vtable member usage. -pub const R_MICROBLAZE_GNU_VTENTRY: u32 = 12; -/// PC-relative GOT offset. -pub const R_MICROBLAZE_GOTPC_64: u32 = 13; -/// GOT entry offset. -pub const R_MICROBLAZE_GOT_64: u32 = 14; -/// PLT offset (PC-relative). -pub const R_MICROBLAZE_PLT_64: u32 = 15; -/// Adjust by program base. -pub const R_MICROBLAZE_REL: u32 = 16; -/// Create PLT entry. -pub const R_MICROBLAZE_JUMP_SLOT: u32 = 17; -/// Create GOT entry. -pub const R_MICROBLAZE_GLOB_DAT: u32 = 18; -/// 64 bit offset to GOT. -pub const R_MICROBLAZE_GOTOFF_64: u32 = 19; -/// 32 bit offset to GOT. -pub const R_MICROBLAZE_GOTOFF_32: u32 = 20; -/// Runtime copy. -pub const R_MICROBLAZE_COPY: u32 = 21; -/// TLS Reloc. -pub const R_MICROBLAZE_TLS: u32 = 22; -/// TLS General Dynamic. -pub const R_MICROBLAZE_TLSGD: u32 = 23; -/// TLS Local Dynamic. -pub const R_MICROBLAZE_TLSLD: u32 = 24; -/// TLS Module ID. -pub const R_MICROBLAZE_TLSDTPMOD32: u32 = 25; -/// TLS Offset Within TLS Block. -pub const R_MICROBLAZE_TLSDTPREL32: u32 = 26; -/// TLS Offset Within TLS Block. -pub const R_MICROBLAZE_TLSDTPREL64: u32 = 27; -/// TLS Offset From Thread Pointer. -pub const R_MICROBLAZE_TLSGOTTPREL32: u32 = 28; -/// TLS Offset From Thread Pointer. -pub const R_MICROBLAZE_TLSTPREL32: u32 = 29; - -// Nios II values `Dyn::d_tag`. -/// Address of _gp. -pub const DT_NIOS2_GP: u32 = 0x7000_0002; - -// Nios II values `Rel*::r_type`. -/// No reloc. -pub const R_NIOS2_NONE: u32 = 0; -/// Direct signed 16 bit. -pub const R_NIOS2_S16: u32 = 1; -/// Direct unsigned 16 bit. -pub const R_NIOS2_U16: u32 = 2; -/// PC relative 16 bit. -pub const R_NIOS2_PCREL16: u32 = 3; -/// Direct call. -pub const R_NIOS2_CALL26: u32 = 4; -/// 5 bit constant expression. -pub const R_NIOS2_IMM5: u32 = 5; -/// 5 bit expression, shift 22. -pub const R_NIOS2_CACHE_OPX: u32 = 6; -/// 6 bit constant expression. -pub const R_NIOS2_IMM6: u32 = 7; -/// 8 bit constant expression. -pub const R_NIOS2_IMM8: u32 = 8; -/// High 16 bit. -pub const R_NIOS2_HI16: u32 = 9; -/// Low 16 bit. -pub const R_NIOS2_LO16: u32 = 10; -/// High 16 bit, adjusted. -pub const R_NIOS2_HIADJ16: u32 = 11; -/// 32 bit symbol value + addend. -pub const R_NIOS2_BFD_RELOC_32: u32 = 12; -/// 16 bit symbol value + addend. -pub const R_NIOS2_BFD_RELOC_16: u32 = 13; -/// 8 bit symbol value + addend. -pub const R_NIOS2_BFD_RELOC_8: u32 = 14; -/// 16 bit GP pointer offset. -pub const R_NIOS2_GPREL: u32 = 15; -/// GNU C++ vtable hierarchy. -pub const R_NIOS2_GNU_VTINHERIT: u32 = 16; -/// GNU C++ vtable member usage. -pub const R_NIOS2_GNU_VTENTRY: u32 = 17; -/// Unconditional branch. -pub const R_NIOS2_UJMP: u32 = 18; -/// Conditional branch. -pub const R_NIOS2_CJMP: u32 = 19; -/// Indirect call through register. -pub const R_NIOS2_CALLR: u32 = 20; -/// Alignment requirement for linker relaxation. -pub const R_NIOS2_ALIGN: u32 = 21; -/// 16 bit GOT entry. -pub const R_NIOS2_GOT16: u32 = 22; -/// 16 bit GOT entry for function. -pub const R_NIOS2_CALL16: u32 = 23; -/// %lo of offset to GOT pointer. -pub const R_NIOS2_GOTOFF_LO: u32 = 24; -/// %hiadj of offset to GOT pointer. -pub const R_NIOS2_GOTOFF_HA: u32 = 25; -/// %lo of PC relative offset. -pub const R_NIOS2_PCREL_LO: u32 = 26; -/// %hiadj of PC relative offset. -pub const R_NIOS2_PCREL_HA: u32 = 27; -/// 16 bit GOT offset for TLS GD. -pub const R_NIOS2_TLS_GD16: u32 = 28; -/// 16 bit GOT offset for TLS LDM. -pub const R_NIOS2_TLS_LDM16: u32 = 29; -/// 16 bit module relative offset. -pub const R_NIOS2_TLS_LDO16: u32 = 30; -/// 16 bit GOT offset for TLS IE. -pub const R_NIOS2_TLS_IE16: u32 = 31; -/// 16 bit LE TP-relative offset. -pub const R_NIOS2_TLS_LE16: u32 = 32; -/// Module number. -pub const R_NIOS2_TLS_DTPMOD: u32 = 33; -/// Module-relative offset. -pub const R_NIOS2_TLS_DTPREL: u32 = 34; -/// TP-relative offset. -pub const R_NIOS2_TLS_TPREL: u32 = 35; -/// Copy symbol at runtime. -pub const R_NIOS2_COPY: u32 = 36; -/// Create GOT entry. -pub const R_NIOS2_GLOB_DAT: u32 = 37; -/// Create PLT entry. -pub const R_NIOS2_JUMP_SLOT: u32 = 38; -/// Adjust by program base. -pub const R_NIOS2_RELATIVE: u32 = 39; -/// 16 bit offset to GOT pointer. -pub const R_NIOS2_GOTOFF: u32 = 40; -/// Direct call in .noat section. -pub const R_NIOS2_CALL26_NOAT: u32 = 41; -/// %lo() of GOT entry. -pub const R_NIOS2_GOT_LO: u32 = 42; -/// %hiadj() of GOT entry. -pub const R_NIOS2_GOT_HA: u32 = 43; -/// %lo() of function GOT entry. -pub const R_NIOS2_CALL_LO: u32 = 44; -/// %hiadj() of function GOT entry. -pub const R_NIOS2_CALL_HA: u32 = 45; - -// TILEPro values `Rel*::r_type`. -/// No reloc -pub const R_TILEPRO_NONE: u32 = 0; -/// Direct 32 bit -pub const R_TILEPRO_32: u32 = 1; -/// Direct 16 bit -pub const R_TILEPRO_16: u32 = 2; -/// Direct 8 bit -pub const R_TILEPRO_8: u32 = 3; -/// PC relative 32 bit -pub const R_TILEPRO_32_PCREL: u32 = 4; -/// PC relative 16 bit -pub const R_TILEPRO_16_PCREL: u32 = 5; -/// PC relative 8 bit -pub const R_TILEPRO_8_PCREL: u32 = 6; -/// Low 16 bit -pub const R_TILEPRO_LO16: u32 = 7; -/// High 16 bit -pub const R_TILEPRO_HI16: u32 = 8; -/// High 16 bit, adjusted -pub const R_TILEPRO_HA16: u32 = 9; -/// Copy relocation -pub const R_TILEPRO_COPY: u32 = 10; -/// Create GOT entry -pub const R_TILEPRO_GLOB_DAT: u32 = 11; -/// Create PLT entry -pub const R_TILEPRO_JMP_SLOT: u32 = 12; -/// Adjust by program base -pub const R_TILEPRO_RELATIVE: u32 = 13; -/// X1 pipe branch offset -pub const R_TILEPRO_BROFF_X1: u32 = 14; -/// X1 pipe jump offset -pub const R_TILEPRO_JOFFLONG_X1: u32 = 15; -/// X1 pipe jump offset to PLT -pub const R_TILEPRO_JOFFLONG_X1_PLT: u32 = 16; -/// X0 pipe 8-bit -pub const R_TILEPRO_IMM8_X0: u32 = 17; -/// Y0 pipe 8-bit -pub const R_TILEPRO_IMM8_Y0: u32 = 18; -/// X1 pipe 8-bit -pub const R_TILEPRO_IMM8_X1: u32 = 19; -/// Y1 pipe 8-bit -pub const R_TILEPRO_IMM8_Y1: u32 = 20; -/// X1 pipe mtspr -pub const R_TILEPRO_MT_IMM15_X1: u32 = 21; -/// X1 pipe mfspr -pub const R_TILEPRO_MF_IMM15_X1: u32 = 22; -/// X0 pipe 16-bit -pub const R_TILEPRO_IMM16_X0: u32 = 23; -/// X1 pipe 16-bit -pub const R_TILEPRO_IMM16_X1: u32 = 24; -/// X0 pipe low 16-bit -pub const R_TILEPRO_IMM16_X0_LO: u32 = 25; -/// X1 pipe low 16-bit -pub const R_TILEPRO_IMM16_X1_LO: u32 = 26; -/// X0 pipe high 16-bit -pub const R_TILEPRO_IMM16_X0_HI: u32 = 27; -/// X1 pipe high 16-bit -pub const R_TILEPRO_IMM16_X1_HI: u32 = 28; -/// X0 pipe high 16-bit, adjusted -pub const R_TILEPRO_IMM16_X0_HA: u32 = 29; -/// X1 pipe high 16-bit, adjusted -pub const R_TILEPRO_IMM16_X1_HA: u32 = 30; -/// X0 pipe PC relative 16 bit -pub const R_TILEPRO_IMM16_X0_PCREL: u32 = 31; -/// X1 pipe PC relative 16 bit -pub const R_TILEPRO_IMM16_X1_PCREL: u32 = 32; -/// X0 pipe PC relative low 16 bit -pub const R_TILEPRO_IMM16_X0_LO_PCREL: u32 = 33; -/// X1 pipe PC relative low 16 bit -pub const R_TILEPRO_IMM16_X1_LO_PCREL: u32 = 34; -/// X0 pipe PC relative high 16 bit -pub const R_TILEPRO_IMM16_X0_HI_PCREL: u32 = 35; -/// X1 pipe PC relative high 16 bit -pub const R_TILEPRO_IMM16_X1_HI_PCREL: u32 = 36; -/// X0 pipe PC relative ha() 16 bit -pub const R_TILEPRO_IMM16_X0_HA_PCREL: u32 = 37; -/// X1 pipe PC relative ha() 16 bit -pub const R_TILEPRO_IMM16_X1_HA_PCREL: u32 = 38; -/// X0 pipe 16-bit GOT offset -pub const R_TILEPRO_IMM16_X0_GOT: u32 = 39; -/// X1 pipe 16-bit GOT offset -pub const R_TILEPRO_IMM16_X1_GOT: u32 = 40; -/// X0 pipe low 16-bit GOT offset -pub const R_TILEPRO_IMM16_X0_GOT_LO: u32 = 41; -/// X1 pipe low 16-bit GOT offset -pub const R_TILEPRO_IMM16_X1_GOT_LO: u32 = 42; -/// X0 pipe high 16-bit GOT offset -pub const R_TILEPRO_IMM16_X0_GOT_HI: u32 = 43; -/// X1 pipe high 16-bit GOT offset -pub const R_TILEPRO_IMM16_X1_GOT_HI: u32 = 44; -/// X0 pipe ha() 16-bit GOT offset -pub const R_TILEPRO_IMM16_X0_GOT_HA: u32 = 45; -/// X1 pipe ha() 16-bit GOT offset -pub const R_TILEPRO_IMM16_X1_GOT_HA: u32 = 46; -/// X0 pipe mm "start" -pub const R_TILEPRO_MMSTART_X0: u32 = 47; -/// X0 pipe mm "end" -pub const R_TILEPRO_MMEND_X0: u32 = 48; -/// X1 pipe mm "start" -pub const R_TILEPRO_MMSTART_X1: u32 = 49; -/// X1 pipe mm "end" -pub const R_TILEPRO_MMEND_X1: u32 = 50; -/// X0 pipe shift amount -pub const R_TILEPRO_SHAMT_X0: u32 = 51; -/// X1 pipe shift amount -pub const R_TILEPRO_SHAMT_X1: u32 = 52; -/// Y0 pipe shift amount -pub const R_TILEPRO_SHAMT_Y0: u32 = 53; -/// Y1 pipe shift amount -pub const R_TILEPRO_SHAMT_Y1: u32 = 54; -/// X1 pipe destination 8-bit -pub const R_TILEPRO_DEST_IMM8_X1: u32 = 55; -// Relocs 56-59 are currently not defined. -/// "jal" for TLS GD -pub const R_TILEPRO_TLS_GD_CALL: u32 = 60; -/// X0 pipe "addi" for TLS GD -pub const R_TILEPRO_IMM8_X0_TLS_GD_ADD: u32 = 61; -/// X1 pipe "addi" for TLS GD -pub const R_TILEPRO_IMM8_X1_TLS_GD_ADD: u32 = 62; -/// Y0 pipe "addi" for TLS GD -pub const R_TILEPRO_IMM8_Y0_TLS_GD_ADD: u32 = 63; -/// Y1 pipe "addi" for TLS GD -pub const R_TILEPRO_IMM8_Y1_TLS_GD_ADD: u32 = 64; -/// "lw_tls" for TLS IE -pub const R_TILEPRO_TLS_IE_LOAD: u32 = 65; -/// X0 pipe 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X0_TLS_GD: u32 = 66; -/// X1 pipe 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X1_TLS_GD: u32 = 67; -/// X0 pipe low 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X0_TLS_GD_LO: u32 = 68; -/// X1 pipe low 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X1_TLS_GD_LO: u32 = 69; -/// X0 pipe high 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X0_TLS_GD_HI: u32 = 70; -/// X1 pipe high 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X1_TLS_GD_HI: u32 = 71; -/// X0 pipe ha() 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X0_TLS_GD_HA: u32 = 72; -/// X1 pipe ha() 16-bit TLS GD offset -pub const R_TILEPRO_IMM16_X1_TLS_GD_HA: u32 = 73; -/// X0 pipe 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X0_TLS_IE: u32 = 74; -/// X1 pipe 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X1_TLS_IE: u32 = 75; -/// X0 pipe low 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X0_TLS_IE_LO: u32 = 76; -/// X1 pipe low 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X1_TLS_IE_LO: u32 = 77; -/// X0 pipe high 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X0_TLS_IE_HI: u32 = 78; -/// X1 pipe high 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X1_TLS_IE_HI: u32 = 79; -/// X0 pipe ha() 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X0_TLS_IE_HA: u32 = 80; -/// X1 pipe ha() 16-bit TLS IE offset -pub const R_TILEPRO_IMM16_X1_TLS_IE_HA: u32 = 81; -/// ID of module containing symbol -pub const R_TILEPRO_TLS_DTPMOD32: u32 = 82; -/// Offset in TLS block -pub const R_TILEPRO_TLS_DTPOFF32: u32 = 83; -/// Offset in static TLS block -pub const R_TILEPRO_TLS_TPOFF32: u32 = 84; -/// X0 pipe 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X0_TLS_LE: u32 = 85; -/// X1 pipe 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X1_TLS_LE: u32 = 86; -/// X0 pipe low 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X0_TLS_LE_LO: u32 = 87; -/// X1 pipe low 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X1_TLS_LE_LO: u32 = 88; -/// X0 pipe high 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X0_TLS_LE_HI: u32 = 89; -/// X1 pipe high 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X1_TLS_LE_HI: u32 = 90; -/// X0 pipe ha() 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X0_TLS_LE_HA: u32 = 91; -/// X1 pipe ha() 16-bit TLS LE offset -pub const R_TILEPRO_IMM16_X1_TLS_LE_HA: u32 = 92; - -/// GNU C++ vtable hierarchy -pub const R_TILEPRO_GNU_VTINHERIT: u32 = 128; -/// GNU C++ vtable member usage -pub const R_TILEPRO_GNU_VTENTRY: u32 = 129; - -// TILE-Gx values `Rel*::r_type`. -/// No reloc -pub const R_TILEGX_NONE: u32 = 0; -/// Direct 64 bit -pub const R_TILEGX_64: u32 = 1; -/// Direct 32 bit -pub const R_TILEGX_32: u32 = 2; -/// Direct 16 bit -pub const R_TILEGX_16: u32 = 3; -/// Direct 8 bit -pub const R_TILEGX_8: u32 = 4; -/// PC relative 64 bit -pub const R_TILEGX_64_PCREL: u32 = 5; -/// PC relative 32 bit -pub const R_TILEGX_32_PCREL: u32 = 6; -/// PC relative 16 bit -pub const R_TILEGX_16_PCREL: u32 = 7; -/// PC relative 8 bit -pub const R_TILEGX_8_PCREL: u32 = 8; -/// hword 0 16-bit -pub const R_TILEGX_HW0: u32 = 9; -/// hword 1 16-bit -pub const R_TILEGX_HW1: u32 = 10; -/// hword 2 16-bit -pub const R_TILEGX_HW2: u32 = 11; -/// hword 3 16-bit -pub const R_TILEGX_HW3: u32 = 12; -/// last hword 0 16-bit -pub const R_TILEGX_HW0_LAST: u32 = 13; -/// last hword 1 16-bit -pub const R_TILEGX_HW1_LAST: u32 = 14; -/// last hword 2 16-bit -pub const R_TILEGX_HW2_LAST: u32 = 15; -/// Copy relocation -pub const R_TILEGX_COPY: u32 = 16; -/// Create GOT entry -pub const R_TILEGX_GLOB_DAT: u32 = 17; -/// Create PLT entry -pub const R_TILEGX_JMP_SLOT: u32 = 18; -/// Adjust by program base -pub const R_TILEGX_RELATIVE: u32 = 19; -/// X1 pipe branch offset -pub const R_TILEGX_BROFF_X1: u32 = 20; -/// X1 pipe jump offset -pub const R_TILEGX_JUMPOFF_X1: u32 = 21; -/// X1 pipe jump offset to PLT -pub const R_TILEGX_JUMPOFF_X1_PLT: u32 = 22; -/// X0 pipe 8-bit -pub const R_TILEGX_IMM8_X0: u32 = 23; -/// Y0 pipe 8-bit -pub const R_TILEGX_IMM8_Y0: u32 = 24; -/// X1 pipe 8-bit -pub const R_TILEGX_IMM8_X1: u32 = 25; -/// Y1 pipe 8-bit -pub const R_TILEGX_IMM8_Y1: u32 = 26; -/// X1 pipe destination 8-bit -pub const R_TILEGX_DEST_IMM8_X1: u32 = 27; -/// X1 pipe mtspr -pub const R_TILEGX_MT_IMM14_X1: u32 = 28; -/// X1 pipe mfspr -pub const R_TILEGX_MF_IMM14_X1: u32 = 29; -/// X0 pipe mm "start" -pub const R_TILEGX_MMSTART_X0: u32 = 30; -/// X0 pipe mm "end" -pub const R_TILEGX_MMEND_X0: u32 = 31; -/// X0 pipe shift amount -pub const R_TILEGX_SHAMT_X0: u32 = 32; -/// X1 pipe shift amount -pub const R_TILEGX_SHAMT_X1: u32 = 33; -/// Y0 pipe shift amount -pub const R_TILEGX_SHAMT_Y0: u32 = 34; -/// Y1 pipe shift amount -pub const R_TILEGX_SHAMT_Y1: u32 = 35; -/// X0 pipe hword 0 -pub const R_TILEGX_IMM16_X0_HW0: u32 = 36; -/// X1 pipe hword 0 -pub const R_TILEGX_IMM16_X1_HW0: u32 = 37; -/// X0 pipe hword 1 -pub const R_TILEGX_IMM16_X0_HW1: u32 = 38; -/// X1 pipe hword 1 -pub const R_TILEGX_IMM16_X1_HW1: u32 = 39; -/// X0 pipe hword 2 -pub const R_TILEGX_IMM16_X0_HW2: u32 = 40; -/// X1 pipe hword 2 -pub const R_TILEGX_IMM16_X1_HW2: u32 = 41; -/// X0 pipe hword 3 -pub const R_TILEGX_IMM16_X0_HW3: u32 = 42; -/// X1 pipe hword 3 -pub const R_TILEGX_IMM16_X1_HW3: u32 = 43; -/// X0 pipe last hword 0 -pub const R_TILEGX_IMM16_X0_HW0_LAST: u32 = 44; -/// X1 pipe last hword 0 -pub const R_TILEGX_IMM16_X1_HW0_LAST: u32 = 45; -/// X0 pipe last hword 1 -pub const R_TILEGX_IMM16_X0_HW1_LAST: u32 = 46; -/// X1 pipe last hword 1 -pub const R_TILEGX_IMM16_X1_HW1_LAST: u32 = 47; -/// X0 pipe last hword 2 -pub const R_TILEGX_IMM16_X0_HW2_LAST: u32 = 48; -/// X1 pipe last hword 2 -pub const R_TILEGX_IMM16_X1_HW2_LAST: u32 = 49; -/// X0 pipe PC relative hword 0 -pub const R_TILEGX_IMM16_X0_HW0_PCREL: u32 = 50; -/// X1 pipe PC relative hword 0 -pub const R_TILEGX_IMM16_X1_HW0_PCREL: u32 = 51; -/// X0 pipe PC relative hword 1 -pub const R_TILEGX_IMM16_X0_HW1_PCREL: u32 = 52; -/// X1 pipe PC relative hword 1 -pub const R_TILEGX_IMM16_X1_HW1_PCREL: u32 = 53; -/// X0 pipe PC relative hword 2 -pub const R_TILEGX_IMM16_X0_HW2_PCREL: u32 = 54; -/// X1 pipe PC relative hword 2 -pub const R_TILEGX_IMM16_X1_HW2_PCREL: u32 = 55; -/// X0 pipe PC relative hword 3 -pub const R_TILEGX_IMM16_X0_HW3_PCREL: u32 = 56; -/// X1 pipe PC relative hword 3 -pub const R_TILEGX_IMM16_X1_HW3_PCREL: u32 = 57; -/// X0 pipe PC-rel last hword 0 -pub const R_TILEGX_IMM16_X0_HW0_LAST_PCREL: u32 = 58; -/// X1 pipe PC-rel last hword 0 -pub const R_TILEGX_IMM16_X1_HW0_LAST_PCREL: u32 = 59; -/// X0 pipe PC-rel last hword 1 -pub const R_TILEGX_IMM16_X0_HW1_LAST_PCREL: u32 = 60; -/// X1 pipe PC-rel last hword 1 -pub const R_TILEGX_IMM16_X1_HW1_LAST_PCREL: u32 = 61; -/// X0 pipe PC-rel last hword 2 -pub const R_TILEGX_IMM16_X0_HW2_LAST_PCREL: u32 = 62; -/// X1 pipe PC-rel last hword 2 -pub const R_TILEGX_IMM16_X1_HW2_LAST_PCREL: u32 = 63; -/// X0 pipe hword 0 GOT offset -pub const R_TILEGX_IMM16_X0_HW0_GOT: u32 = 64; -/// X1 pipe hword 0 GOT offset -pub const R_TILEGX_IMM16_X1_HW0_GOT: u32 = 65; -/// X0 pipe PC-rel PLT hword 0 -pub const R_TILEGX_IMM16_X0_HW0_PLT_PCREL: u32 = 66; -/// X1 pipe PC-rel PLT hword 0 -pub const R_TILEGX_IMM16_X1_HW0_PLT_PCREL: u32 = 67; -/// X0 pipe PC-rel PLT hword 1 -pub const R_TILEGX_IMM16_X0_HW1_PLT_PCREL: u32 = 68; -/// X1 pipe PC-rel PLT hword 1 -pub const R_TILEGX_IMM16_X1_HW1_PLT_PCREL: u32 = 69; -/// X0 pipe PC-rel PLT hword 2 -pub const R_TILEGX_IMM16_X0_HW2_PLT_PCREL: u32 = 70; -/// X1 pipe PC-rel PLT hword 2 -pub const R_TILEGX_IMM16_X1_HW2_PLT_PCREL: u32 = 71; -/// X0 pipe last hword 0 GOT offset -pub const R_TILEGX_IMM16_X0_HW0_LAST_GOT: u32 = 72; -/// X1 pipe last hword 0 GOT offset -pub const R_TILEGX_IMM16_X1_HW0_LAST_GOT: u32 = 73; -/// X0 pipe last hword 1 GOT offset -pub const R_TILEGX_IMM16_X0_HW1_LAST_GOT: u32 = 74; -/// X1 pipe last hword 1 GOT offset -pub const R_TILEGX_IMM16_X1_HW1_LAST_GOT: u32 = 75; -/// X0 pipe PC-rel PLT hword 3 -pub const R_TILEGX_IMM16_X0_HW3_PLT_PCREL: u32 = 76; -/// X1 pipe PC-rel PLT hword 3 -pub const R_TILEGX_IMM16_X1_HW3_PLT_PCREL: u32 = 77; -/// X0 pipe hword 0 TLS GD offset -pub const R_TILEGX_IMM16_X0_HW0_TLS_GD: u32 = 78; -/// X1 pipe hword 0 TLS GD offset -pub const R_TILEGX_IMM16_X1_HW0_TLS_GD: u32 = 79; -/// X0 pipe hword 0 TLS LE offset -pub const R_TILEGX_IMM16_X0_HW0_TLS_LE: u32 = 80; -/// X1 pipe hword 0 TLS LE offset -pub const R_TILEGX_IMM16_X1_HW0_TLS_LE: u32 = 81; -/// X0 pipe last hword 0 LE off -pub const R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: u32 = 82; -/// X1 pipe last hword 0 LE off -pub const R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: u32 = 83; -/// X0 pipe last hword 1 LE off -pub const R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: u32 = 84; -/// X1 pipe last hword 1 LE off -pub const R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: u32 = 85; -/// X0 pipe last hword 0 GD off -pub const R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: u32 = 86; -/// X1 pipe last hword 0 GD off -pub const R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: u32 = 87; -/// X0 pipe last hword 1 GD off -pub const R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: u32 = 88; -/// X1 pipe last hword 1 GD off -pub const R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: u32 = 89; -// Relocs 90-91 are currently not defined. -/// X0 pipe hword 0 TLS IE offset -pub const R_TILEGX_IMM16_X0_HW0_TLS_IE: u32 = 92; -/// X1 pipe hword 0 TLS IE offset -pub const R_TILEGX_IMM16_X1_HW0_TLS_IE: u32 = 93; -/// X0 pipe PC-rel PLT last hword 0 -pub const R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: u32 = 94; -/// X1 pipe PC-rel PLT last hword 0 -pub const R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: u32 = 95; -/// X0 pipe PC-rel PLT last hword 1 -pub const R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: u32 = 96; -/// X1 pipe PC-rel PLT last hword 1 -pub const R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: u32 = 97; -/// X0 pipe PC-rel PLT last hword 2 -pub const R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: u32 = 98; -/// X1 pipe PC-rel PLT last hword 2 -pub const R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: u32 = 99; -/// X0 pipe last hword 0 IE off -pub const R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: u32 = 100; -/// X1 pipe last hword 0 IE off -pub const R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: u32 = 101; -/// X0 pipe last hword 1 IE off -pub const R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: u32 = 102; -/// X1 pipe last hword 1 IE off -pub const R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: u32 = 103; -// Relocs 104-105 are currently not defined. -/// 64-bit ID of symbol's module -pub const R_TILEGX_TLS_DTPMOD64: u32 = 106; -/// 64-bit offset in TLS block -pub const R_TILEGX_TLS_DTPOFF64: u32 = 107; -/// 64-bit offset in static TLS block -pub const R_TILEGX_TLS_TPOFF64: u32 = 108; -/// 32-bit ID of symbol's module -pub const R_TILEGX_TLS_DTPMOD32: u32 = 109; -/// 32-bit offset in TLS block -pub const R_TILEGX_TLS_DTPOFF32: u32 = 110; -/// 32-bit offset in static TLS block -pub const R_TILEGX_TLS_TPOFF32: u32 = 111; -/// "jal" for TLS GD -pub const R_TILEGX_TLS_GD_CALL: u32 = 112; -/// X0 pipe "addi" for TLS GD -pub const R_TILEGX_IMM8_X0_TLS_GD_ADD: u32 = 113; -/// X1 pipe "addi" for TLS GD -pub const R_TILEGX_IMM8_X1_TLS_GD_ADD: u32 = 114; -/// Y0 pipe "addi" for TLS GD -pub const R_TILEGX_IMM8_Y0_TLS_GD_ADD: u32 = 115; -/// Y1 pipe "addi" for TLS GD -pub const R_TILEGX_IMM8_Y1_TLS_GD_ADD: u32 = 116; -/// "ld_tls" for TLS IE -pub const R_TILEGX_TLS_IE_LOAD: u32 = 117; -/// X0 pipe "addi" for TLS GD/IE -pub const R_TILEGX_IMM8_X0_TLS_ADD: u32 = 118; -/// X1 pipe "addi" for TLS GD/IE -pub const R_TILEGX_IMM8_X1_TLS_ADD: u32 = 119; -/// Y0 pipe "addi" for TLS GD/IE -pub const R_TILEGX_IMM8_Y0_TLS_ADD: u32 = 120; -/// Y1 pipe "addi" for TLS GD/IE -pub const R_TILEGX_IMM8_Y1_TLS_ADD: u32 = 121; - -/// GNU C++ vtable hierarchy -pub const R_TILEGX_GNU_VTINHERIT: u32 = 128; -/// GNU C++ vtable member usage -pub const R_TILEGX_GNU_VTENTRY: u32 = 129; - -// RISC-V values `FileHeader*::e_flags`. -pub const EF_RISCV_RVC: u32 = 0x0001; -pub const EF_RISCV_FLOAT_ABI: u32 = 0x0006; -pub const EF_RISCV_FLOAT_ABI_SOFT: u32 = 0x0000; -pub const EF_RISCV_FLOAT_ABI_SINGLE: u32 = 0x0002; -pub const EF_RISCV_FLOAT_ABI_DOUBLE: u32 = 0x0004; -pub const EF_RISCV_FLOAT_ABI_QUAD: u32 = 0x0006; -pub const EF_RISCV_RVE: u32 = 0x0008; -pub const EF_RISCV_TSO: u32 = 0x0010; - -// RISC-V values `Rel*::r_type`. -pub const R_RISCV_NONE: u32 = 0; -pub const R_RISCV_32: u32 = 1; -pub const R_RISCV_64: u32 = 2; -pub const R_RISCV_RELATIVE: u32 = 3; -pub const R_RISCV_COPY: u32 = 4; -pub const R_RISCV_JUMP_SLOT: u32 = 5; -pub const R_RISCV_TLS_DTPMOD32: u32 = 6; -pub const R_RISCV_TLS_DTPMOD64: u32 = 7; -pub const R_RISCV_TLS_DTPREL32: u32 = 8; -pub const R_RISCV_TLS_DTPREL64: u32 = 9; -pub const R_RISCV_TLS_TPREL32: u32 = 10; -pub const R_RISCV_TLS_TPREL64: u32 = 11; -pub const R_RISCV_BRANCH: u32 = 16; -pub const R_RISCV_JAL: u32 = 17; -pub const R_RISCV_CALL: u32 = 18; -pub const R_RISCV_CALL_PLT: u32 = 19; -pub const R_RISCV_GOT_HI20: u32 = 20; -pub const R_RISCV_TLS_GOT_HI20: u32 = 21; -pub const R_RISCV_TLS_GD_HI20: u32 = 22; -pub const R_RISCV_PCREL_HI20: u32 = 23; -pub const R_RISCV_PCREL_LO12_I: u32 = 24; -pub const R_RISCV_PCREL_LO12_S: u32 = 25; -pub const R_RISCV_HI20: u32 = 26; -pub const R_RISCV_LO12_I: u32 = 27; -pub const R_RISCV_LO12_S: u32 = 28; -pub const R_RISCV_TPREL_HI20: u32 = 29; -pub const R_RISCV_TPREL_LO12_I: u32 = 30; -pub const R_RISCV_TPREL_LO12_S: u32 = 31; -pub const R_RISCV_TPREL_ADD: u32 = 32; -pub const R_RISCV_ADD8: u32 = 33; -pub const R_RISCV_ADD16: u32 = 34; -pub const R_RISCV_ADD32: u32 = 35; -pub const R_RISCV_ADD64: u32 = 36; -pub const R_RISCV_SUB8: u32 = 37; -pub const R_RISCV_SUB16: u32 = 38; -pub const R_RISCV_SUB32: u32 = 39; -pub const R_RISCV_SUB64: u32 = 40; -pub const R_RISCV_GNU_VTINHERIT: u32 = 41; -pub const R_RISCV_GNU_VTENTRY: u32 = 42; -pub const R_RISCV_ALIGN: u32 = 43; -pub const R_RISCV_RVC_BRANCH: u32 = 44; -pub const R_RISCV_RVC_JUMP: u32 = 45; -pub const R_RISCV_RVC_LUI: u32 = 46; -pub const R_RISCV_GPREL_I: u32 = 47; -pub const R_RISCV_GPREL_S: u32 = 48; -pub const R_RISCV_TPREL_I: u32 = 49; -pub const R_RISCV_TPREL_S: u32 = 50; -pub const R_RISCV_RELAX: u32 = 51; -pub const R_RISCV_SUB6: u32 = 52; -pub const R_RISCV_SET6: u32 = 53; -pub const R_RISCV_SET8: u32 = 54; -pub const R_RISCV_SET16: u32 = 55; -pub const R_RISCV_SET32: u32 = 56; -pub const R_RISCV_32_PCREL: u32 = 57; - -// BPF values `Rel*::r_type`. -/// No reloc -pub const R_BPF_NONE: u32 = 0; -pub const R_BPF_64_64: u32 = 1; -pub const R_BPF_64_32: u32 = 10; - -// SBF values `Rel*::r_type`. -/// No reloc -pub const R_SBF_NONE: u32 = 0; -pub const R_SBF_64_64: u32 = 1; -pub const R_SBF_64_32: u32 = 10; - -// Imagination Meta values `Rel*::r_type`. - -pub const R_METAG_HIADDR16: u32 = 0; -pub const R_METAG_LOADDR16: u32 = 1; -/// 32bit absolute address -pub const R_METAG_ADDR32: u32 = 2; -/// No reloc -pub const R_METAG_NONE: u32 = 3; -pub const R_METAG_RELBRANCH: u32 = 4; -pub const R_METAG_GETSETOFF: u32 = 5; - -// Backward compatibility -pub const R_METAG_REG32OP1: u32 = 6; -pub const R_METAG_REG32OP2: u32 = 7; -pub const R_METAG_REG32OP3: u32 = 8; -pub const R_METAG_REG16OP1: u32 = 9; -pub const R_METAG_REG16OP2: u32 = 10; -pub const R_METAG_REG16OP3: u32 = 11; -pub const R_METAG_REG32OP4: u32 = 12; - -pub const R_METAG_HIOG: u32 = 13; -pub const R_METAG_LOOG: u32 = 14; - -pub const R_METAG_REL8: u32 = 15; -pub const R_METAG_REL16: u32 = 16; - -pub const R_METAG_GNU_VTINHERIT: u32 = 30; -pub const R_METAG_GNU_VTENTRY: u32 = 31; - -// PIC relocations -pub const R_METAG_HI16_GOTOFF: u32 = 32; -pub const R_METAG_LO16_GOTOFF: u32 = 33; -pub const R_METAG_GETSET_GOTOFF: u32 = 34; -pub const R_METAG_GETSET_GOT: u32 = 35; -pub const R_METAG_HI16_GOTPC: u32 = 36; -pub const R_METAG_LO16_GOTPC: u32 = 37; -pub const R_METAG_HI16_PLT: u32 = 38; -pub const R_METAG_LO16_PLT: u32 = 39; -pub const R_METAG_RELBRANCH_PLT: u32 = 40; -pub const R_METAG_GOTOFF: u32 = 41; -pub const R_METAG_PLT: u32 = 42; -pub const R_METAG_COPY: u32 = 43; -pub const R_METAG_JMP_SLOT: u32 = 44; -pub const R_METAG_RELATIVE: u32 = 45; -pub const R_METAG_GLOB_DAT: u32 = 46; - -// TLS relocations -pub const R_METAG_TLS_GD: u32 = 47; -pub const R_METAG_TLS_LDM: u32 = 48; -pub const R_METAG_TLS_LDO_HI16: u32 = 49; -pub const R_METAG_TLS_LDO_LO16: u32 = 50; -pub const R_METAG_TLS_LDO: u32 = 51; -pub const R_METAG_TLS_IE: u32 = 52; -pub const R_METAG_TLS_IENONPIC: u32 = 53; -pub const R_METAG_TLS_IENONPIC_HI16: u32 = 54; -pub const R_METAG_TLS_IENONPIC_LO16: u32 = 55; -pub const R_METAG_TLS_TPOFF: u32 = 56; -pub const R_METAG_TLS_DTPMOD: u32 = 57; -pub const R_METAG_TLS_DTPOFF: u32 = 58; -pub const R_METAG_TLS_LE: u32 = 59; -pub const R_METAG_TLS_LE_HI16: u32 = 60; -pub const R_METAG_TLS_LE_LO16: u32 = 61; - -// NDS32 values `Rel*::r_type`. -pub const R_NDS32_NONE: u32 = 0; -pub const R_NDS32_32_RELA: u32 = 20; -pub const R_NDS32_COPY: u32 = 39; -pub const R_NDS32_GLOB_DAT: u32 = 40; -pub const R_NDS32_JMP_SLOT: u32 = 41; -pub const R_NDS32_RELATIVE: u32 = 42; -pub const R_NDS32_TLS_TPOFF: u32 = 102; -pub const R_NDS32_TLS_DESC: u32 = 119; - -// LoongArch values `FileHeader*::e_flags`. -/// Additional properties of the base ABI type, including the FP calling -/// convention. -pub const EF_LARCH_ABI_MODIFIER_MASK: u32 = 0x7; -/// Uses GPRs and the stack for parameter passing -pub const EF_LARCH_ABI_SOFT_FLOAT: u32 = 0x1; -/// Uses GPRs, 32-bit FPRs and the stack for parameter passing -pub const EF_LARCH_ABI_SINGLE_FLOAT: u32 = 0x2; -/// Uses GPRs, 64-bit FPRs and the stack for parameter passing -pub const EF_LARCH_ABI_DOUBLE_FLOAT: u32 = 0x3; -/// Uses relocation types directly writing to immediate slots -pub const EF_LARCH_OBJABI_V1: u32 = 0x40; - -// LoongArch values `Rel*::r_type`. -/// No reloc -pub const R_LARCH_NONE: u32 = 0; -/// Runtime address resolving -pub const R_LARCH_32: u32 = 1; -/// Runtime address resolving -pub const R_LARCH_64: u32 = 2; -/// Runtime fixup for load-address -pub const R_LARCH_RELATIVE: u32 = 3; -/// Runtime memory copy in executable -pub const R_LARCH_COPY: u32 = 4; -/// Runtime PLT supporting -pub const R_LARCH_JUMP_SLOT: u32 = 5; -/// Runtime relocation for TLS-GD -pub const R_LARCH_TLS_DTPMOD32: u32 = 6; -/// Runtime relocation for TLS-GD -pub const R_LARCH_TLS_DTPMOD64: u32 = 7; -/// Runtime relocation for TLS-GD -pub const R_LARCH_TLS_DTPREL32: u32 = 8; -/// Runtime relocation for TLS-GD -pub const R_LARCH_TLS_DTPREL64: u32 = 9; -/// Runtime relocation for TLE-IE -pub const R_LARCH_TLS_TPREL32: u32 = 10; -/// Runtime relocation for TLE-IE -pub const R_LARCH_TLS_TPREL64: u32 = 11; -/// Runtime local indirect function resolving -pub const R_LARCH_IRELATIVE: u32 = 12; -/// Mark la.abs: load absolute address for static link. -pub const R_LARCH_MARK_LA: u32 = 20; -/// Mark external label branch: access PC relative address for static link. -pub const R_LARCH_MARK_PCREL: u32 = 21; -/// Push PC-relative offset -pub const R_LARCH_SOP_PUSH_PCREL: u32 = 22; -/// Push constant or absolute address -pub const R_LARCH_SOP_PUSH_ABSOLUTE: u32 = 23; -/// Duplicate stack top -pub const R_LARCH_SOP_PUSH_DUP: u32 = 24; -/// Push for access GOT entry -pub const R_LARCH_SOP_PUSH_GPREL: u32 = 25; -/// Push for TLS-LE -pub const R_LARCH_SOP_PUSH_TLS_TPREL: u32 = 26; -/// Push for TLS-IE -pub const R_LARCH_SOP_PUSH_TLS_GOT: u32 = 27; -/// Push for TLS-GD -pub const R_LARCH_SOP_PUSH_TLS_GD: u32 = 28; -/// Push for external function calling -pub const R_LARCH_SOP_PUSH_PLT_PCREL: u32 = 29; -/// Assert stack top -pub const R_LARCH_SOP_ASSERT: u32 = 30; -/// Stack top logical not (unary) -pub const R_LARCH_SOP_NOT: u32 = 31; -/// Stack top subtraction (binary) -pub const R_LARCH_SOP_SUB: u32 = 32; -/// Stack top left shift (binary) -pub const R_LARCH_SOP_SL: u32 = 33; -/// Stack top right shift (binary) -pub const R_LARCH_SOP_SR: u32 = 34; -/// Stack top addition (binary) -pub const R_LARCH_SOP_ADD: u32 = 35; -/// Stack top bitwise and (binary) -pub const R_LARCH_SOP_AND: u32 = 36; -/// Stack top selection (tertiary) -pub const R_LARCH_SOP_IF_ELSE: u32 = 37; -/// Pop stack top to fill 5-bit signed immediate operand -pub const R_LARCH_SOP_POP_32_S_10_5: u32 = 38; -/// Pop stack top to fill 12-bit unsigned immediate operand -pub const R_LARCH_SOP_POP_32_U_10_12: u32 = 39; -/// Pop stack top to fill 12-bit signed immediate operand -pub const R_LARCH_SOP_POP_32_S_10_12: u32 = 40; -/// Pop stack top to fill 16-bit signed immediate operand -pub const R_LARCH_SOP_POP_32_S_10_16: u32 = 41; -/// Pop stack top to fill 18-bit signed immediate operand with two trailing -/// zeros implied -pub const R_LARCH_SOP_POP_32_S_10_16_S2: u32 = 42; -/// Pop stack top to fill 20-bit signed immediate operand -pub const R_LARCH_SOP_POP_32_S_5_20: u32 = 43; -/// Pop stack top to fill 23-bit signed immediate operand with two trailing -/// zeros implied -pub const R_LARCH_SOP_POP_32_S_0_5_10_16_S2: u32 = 44; -/// Pop stack top to fill 28-bit signed immediate operand with two trailing -/// zeros implied -pub const R_LARCH_SOP_POP_32_S_0_10_10_16_S2: u32 = 45; -/// Pop stack top to fill an instruction -pub const R_LARCH_SOP_POP_32_U: u32 = 46; -/// 8-bit in-place addition -pub const R_LARCH_ADD8: u32 = 47; -/// 16-bit in-place addition -pub const R_LARCH_ADD16: u32 = 48; -/// 24-bit in-place addition -pub const R_LARCH_ADD24: u32 = 49; -/// 32-bit in-place addition -pub const R_LARCH_ADD32: u32 = 50; -/// 64-bit in-place addition -pub const R_LARCH_ADD64: u32 = 51; -/// 8-bit in-place subtraction -pub const R_LARCH_SUB8: u32 = 52; -/// 16-bit in-place subtraction -pub const R_LARCH_SUB16: u32 = 53; -/// 24-bit in-place subtraction -pub const R_LARCH_SUB24: u32 = 54; -/// 32-bit in-place subtraction -pub const R_LARCH_SUB32: u32 = 55; -/// 64-bit in-place subtraction -pub const R_LARCH_SUB64: u32 = 56; -/// GNU C++ vtable hierarchy -pub const R_LARCH_GNU_VTINHERIT: u32 = 57; -/// GNU C++ vtable member usage -pub const R_LARCH_GNU_VTENTRY: u32 = 58; -/// 18-bit PC-relative jump offset with two trailing zeros -pub const R_LARCH_B16: u32 = 64; -/// 23-bit PC-relative jump offset with two trailing zeros -pub const R_LARCH_B21: u32 = 65; -/// 28-bit PC-relative jump offset with two trailing zeros -pub const R_LARCH_B26: u32 = 66; -/// 12..=31 bits of 32/64-bit absolute address -pub const R_LARCH_ABS_HI20: u32 = 67; -/// 0..=11 bits of 32/64-bit absolute address -pub const R_LARCH_ABS_LO12: u32 = 68; -/// 32..=51 bits of 64-bit absolute address -pub const R_LARCH_ABS64_LO20: u32 = 69; -/// 52..=63 bits of 64-bit absolute address -pub const R_LARCH_ABS64_HI12: u32 = 70; -/// The signed 32-bit offset `offs` from `PC & 0xfffff000` to -/// `(S + A + 0x800) & 0xfffff000`, with 12 trailing zeros removed. -/// -/// We define the *PC relative anchor* for `S + A` as `PC + offs` (`offs` -/// is sign-extended to VA bits). -pub const R_LARCH_PCALA_HI20: u32 = 71; -/// Same as R_LARCH_ABS_LO12.  0..=11 bits of the 32/64-bit offset from the -/// [PC relative anchor][R_LARCH_PCALA_HI20]. -pub const R_LARCH_PCALA_LO12: u32 = 72; -/// 32..=51 bits of the 64-bit offset from the -/// [PC relative anchor][R_LARCH_PCALA_HI20]. -pub const R_LARCH_PCALA64_LO20: u32 = 73; -/// 52..=63 bits of the 64-bit offset from the -/// [PC relative anchor][R_LARCH_PCALA_HI20]. -pub const R_LARCH_PCALA64_HI12: u32 = 74; -/// The signed 32-bit offset `offs` from `PC & 0xfffff000` to -/// `(GP + G + 0x800) & 0xfffff000`, with 12 trailing zeros removed. -/// -/// We define the *PC relative anchor* for the GOT entry at `GP + G` as -/// `PC + offs` (`offs` is sign-extended to VA bits). -pub const R_LARCH_GOT_PC_HI20: u32 = 75; -/// 0..=11 bits of the 32/64-bit offset from the -/// [PC relative anchor][R_LARCH_GOT_PC_HI20] to the GOT entry. -pub const R_LARCH_GOT_PC_LO12: u32 = 76; -/// 32..=51 bits of the 64-bit offset from the -/// [PC relative anchor][R_LARCH_GOT_PC_HI20] to the GOT entry. -pub const R_LARCH_GOT64_PC_LO20: u32 = 77; -/// 52..=63 bits of the 64-bit offset from the -/// [PC relative anchor][R_LARCH_GOT_PC_HI20] to the GOT entry. -pub const R_LARCH_GOT64_PC_HI12: u32 = 78; -/// 12..=31 bits of 32/64-bit GOT entry absolute address -pub const R_LARCH_GOT_HI20: u32 = 79; -/// 0..=11 bits of 32/64-bit GOT entry absolute address -pub const R_LARCH_GOT_LO12: u32 = 80; -/// 32..=51 bits of 64-bit GOT entry absolute address -pub const R_LARCH_GOT64_LO20: u32 = 81; -/// 52..=63 bits of 64-bit GOT entry absolute address -pub const R_LARCH_GOT64_HI12: u32 = 82; -/// 12..=31 bits of TLS LE 32/64-bit offset from thread pointer -pub const R_LARCH_TLS_LE_HI20: u32 = 83; -/// 0..=11 bits of TLS LE 32/64-bit offset from thread pointer -pub const R_LARCH_TLS_LE_LO12: u32 = 84; -/// 32..=51 bits of TLS LE 64-bit offset from thread pointer -pub const R_LARCH_TLS_LE64_LO20: u32 = 85; -/// 52..=63 bits of TLS LE 64-bit offset from thread pointer -pub const R_LARCH_TLS_LE64_HI12: u32 = 86; -/// The signed 32-bit offset `offs` from `PC & 0xfffff000` to -/// `(GP + IE + 0x800) & 0xfffff000`, with 12 trailing zeros removed. -/// -/// We define the *PC relative anchor* for the TLS IE GOT entry at -/// `GP + IE` as `PC + offs` (`offs` is sign-extended to VA bits). -pub const R_LARCH_TLS_IE_PC_HI20: u32 = 87; -/// 0..=12 bits of the 32/64-bit offset from the -/// [PC-relative anchor][R_LARCH_TLS_IE_PC_HI20] to the TLS IE GOT entry. -pub const R_LARCH_TLS_IE_PC_LO12: u32 = 88; -/// 32..=51 bits of the 64-bit offset from the -/// [PC-relative anchor][R_LARCH_TLS_IE_PC_HI20] to the TLS IE GOT entry. -pub const R_LARCH_TLS_IE64_PC_LO20: u32 = 89; -/// 52..=63 bits of the 64-bit offset from the -/// [PC-relative anchor][R_LARCH_TLS_IE_PC_HI20] to the TLS IE GOT entry. -pub const R_LARCH_TLS_IE64_PC_HI12: u32 = 90; -/// 12..=31 bits of TLS IE GOT entry 32/64-bit absolute address -pub const R_LARCH_TLS_IE_HI20: u32 = 91; -/// 0..=11 bits of TLS IE GOT entry 32/64-bit absolute address -pub const R_LARCH_TLS_IE_LO12: u32 = 92; -/// 32..=51 bits of TLS IE GOT entry 64-bit absolute address -pub const R_LARCH_TLS_IE64_LO20: u32 = 93; -/// 51..=63 bits of TLS IE GOT entry 64-bit absolute address -pub const R_LARCH_TLS_IE64_HI12: u32 = 94; -/// 12..=31 bits of the offset from `PC` to `GP + GD + 0x800`, where -/// `GP + GD` is a TLS LD GOT entry -pub const R_LARCH_TLS_LD_PC_HI20: u32 = 95; -/// 12..=31 bits of TLS LD GOT entry 32/64-bit absolute address -pub const R_LARCH_TLS_LD_HI20: u32 = 96; -/// 12..=31 bits of the 32/64-bit PC-relative offset to the PC-relative -/// anchor for the TLE GD GOT entry. -pub const R_LARCH_TLS_GD_PC_HI20: u32 = 97; -/// 12..=31 bits of TLS GD GOT entry 32/64-bit absolute address -pub const R_LARCH_TLS_GD_HI20: u32 = 98; -/// 32-bit PC relative -pub const R_LARCH_32_PCREL: u32 = 99; -/// Paired with a normal relocation at the same address to indicate the -/// instruction can be relaxed -pub const R_LARCH_RELAX: u32 = 100; -/// Reserved -pub const R_LARCH_DELETE: u32 = 101; -/// Delete some bytes to ensure the instruction at PC + A aligned to -/// `A.next_power_of_two()`-byte boundary -pub const R_LARCH_ALIGN: u32 = 102; -/// 22-bit PC-relative offset with two trailing zeros -pub const R_LARCH_PCREL20_S2: u32 = 103; -/// Reserved -pub const R_LARCH_CFA: u32 = 104; -/// 6-bit in-place addition -pub const R_LARCH_ADD6: u32 = 105; -/// 6-bit in-place subtraction -pub const R_LARCH_SUB6: u32 = 106; -/// LEB128 in-place addition -pub const R_LARCH_ADD_ULEB128: u32 = 107; -/// LEB128 in-place subtraction -pub const R_LARCH_SUB_ULEB128: u32 = 108; -/// 64-bit PC relative -pub const R_LARCH_64_PCREL: u32 = 109; -/// 18..=37 bits of `S + A - PC` into the `pcaddu18i` instruction at `PC`, -/// and 2..=17 bits of `S + A - PC` into the `jirl` instruction at `PC + 4` -pub const R_LARCH_CALL36: u32 = 110; - -// Xtensa values Rel*::r_type`. -pub const R_XTENSA_NONE: u32 = 0; -pub const R_XTENSA_32: u32 = 1; -pub const R_XTENSA_RTLD: u32 = 2; -pub const R_XTENSA_GLOB_DAT: u32 = 3; -pub const R_XTENSA_JMP_SLOT: u32 = 4; -pub const R_XTENSA_RELATIVE: u32 = 5; -pub const R_XTENSA_PLT: u32 = 6; -pub const R_XTENSA_OP0: u32 = 8; -pub const R_XTENSA_OP1: u32 = 9; -pub const R_XTENSA_OP2: u32 = 10; -pub const R_XTENSA_ASM_EXPAND: u32 = 11; -pub const R_XTENSA_ASM_SIMPLIFY: u32 = 12; -pub const R_XTENSA_32_PCREL: u32 = 14; -pub const R_XTENSA_GNU_VTINHERIT: u32 = 15; -pub const R_XTENSA_GNU_VTENTRY: u32 = 16; -pub const R_XTENSA_DIFF8: u32 = 17; -pub const R_XTENSA_DIFF16: u32 = 18; -pub const R_XTENSA_DIFF32: u32 = 19; -pub const R_XTENSA_SLOT0_OP: u32 = 20; -pub const R_XTENSA_SLOT1_OP: u32 = 21; -pub const R_XTENSA_SLOT2_OP: u32 = 22; -pub const R_XTENSA_SLOT3_OP: u32 = 23; -pub const R_XTENSA_SLOT4_OP: u32 = 24; -pub const R_XTENSA_SLOT5_OP: u32 = 25; -pub const R_XTENSA_SLOT6_OP: u32 = 26; -pub const R_XTENSA_SLOT7_OP: u32 = 27; -pub const R_XTENSA_SLOT8_OP: u32 = 28; -pub const R_XTENSA_SLOT9_OP: u32 = 29; -pub const R_XTENSA_SLOT10_OP: u32 = 30; -pub const R_XTENSA_SLOT11_OP: u32 = 31; -pub const R_XTENSA_SLOT12_OP: u32 = 32; -pub const R_XTENSA_SLOT13_OP: u32 = 33; -pub const R_XTENSA_SLOT14_OP: u32 = 34; -pub const R_XTENSA_SLOT0_ALT: u32 = 35; -pub const R_XTENSA_SLOT1_ALT: u32 = 36; -pub const R_XTENSA_SLOT2_ALT: u32 = 37; -pub const R_XTENSA_SLOT3_ALT: u32 = 38; -pub const R_XTENSA_SLOT4_ALT: u32 = 39; -pub const R_XTENSA_SLOT5_ALT: u32 = 40; -pub const R_XTENSA_SLOT6_ALT: u32 = 41; -pub const R_XTENSA_SLOT7_ALT: u32 = 42; -pub const R_XTENSA_SLOT8_ALT: u32 = 43; -pub const R_XTENSA_SLOT9_ALT: u32 = 44; -pub const R_XTENSA_SLOT10_ALT: u32 = 45; -pub const R_XTENSA_SLOT11_ALT: u32 = 46; -pub const R_XTENSA_SLOT12_ALT: u32 = 47; -pub const R_XTENSA_SLOT13_ALT: u32 = 48; -pub const R_XTENSA_SLOT14_ALT: u32 = 49; -pub const R_XTENSA_TLSDESC_FN: u32 = 50; -pub const R_XTENSA_TLSDESC_ARG: u32 = 51; -pub const R_XTENSA_TLS_DTPOFF: u32 = 52; -pub const R_XTENSA_TLS_TPOFF: u32 = 53; -pub const R_XTENSA_TLS_FUNC: u32 = 54; -pub const R_XTENSA_TLS_ARG: u32 = 55; -pub const R_XTENSA_TLS_CALL: u32 = 56; -pub const R_XTENSA_PDIFF8: u32 = 57; -pub const R_XTENSA_PDIFF16: u32 = 58; -pub const R_XTENSA_PDIFF32: u32 = 59; -pub const R_XTENSA_NDIFF8: u32 = 60; -pub const R_XTENSA_NDIFF16: u32 = 61; -pub const R_XTENSA_NDIFF32: u32 = 62; - -#[allow(non_upper_case_globals)] -pub const Tag_File: u8 = 1; -#[allow(non_upper_case_globals)] -pub const Tag_Section: u8 = 2; -#[allow(non_upper_case_globals)] -pub const Tag_Symbol: u8 = 3; - -unsafe_impl_endian_pod!( -    FileHeader32, -    FileHeader64, -    SectionHeader32, -    SectionHeader64, -    CompressionHeader32, -    CompressionHeader64, -    Sym32, -    Sym64, -    Syminfo32, -    Syminfo64, -    Rel32, -    Rel64, -    Rela32, -    Rela64, -    ProgramHeader32, -    ProgramHeader64, -    Dyn32, -    Dyn64, -    Versym, -    Verdef, -    Verdaux, -    Verneed, -    Vernaux, -    NoteHeader32, -    NoteHeader64, -    HashHeader, -    GnuHashHeader, -); diff --git a/vendor/object/src/endian.rs b/vendor/object/src/endian.rs deleted file mode 100644 index e4a36ba..0000000 --- a/vendor/object/src/endian.rs +++ /dev/null @@ -1,831 +0,0 @@ -//! Types for compile-time and run-time endianness. - -use crate::pod::Pod; -use core::fmt::{self, Debug}; -use core::marker::PhantomData; - -/// A trait for using an endianness specification. -/// -/// Provides methods for converting between the specified endianness and -/// the native endianness of the target machine. -/// -/// This trait does not require that the endianness is known at compile time. -pub trait Endian: Debug + Default + Clone + Copy + PartialEq + Eq + 'static { -    /// Construct a specification for the endianness of some values. -    /// -    /// Returns `None` if the type does not support specifying the given endianness. -    fn from_big_endian(big_endian: bool) -> Option<Self>; - -    /// Construct a specification for the endianness of some values. -    /// -    /// Returns `None` if the type does not support specifying the given endianness. -    fn from_little_endian(little_endian: bool) -> Option<Self> { -        Self::from_big_endian(!little_endian) -    } - -    /// Return true for big endian byte order. -    fn is_big_endian(self) -> bool; - -    /// Return true for little endian byte order. -    #[inline] -    fn is_little_endian(self) -> bool { -        !self.is_big_endian() -    } - -    /// Converts an unsigned 16 bit integer to native endian. -    #[inline] -    fn read_u16(self, n: u16) -> u16 { -        if self.is_big_endian() { -            u16::from_be(n) -        } else { -            u16::from_le(n) -        } -    } - -    /// Converts an unsigned 32 bit integer to native endian. -    #[inline] -    fn read_u32(self, n: u32) -> u32 { -        if self.is_big_endian() { -            u32::from_be(n) -        } else { -            u32::from_le(n) -        } -    } - -    /// Converts an unsigned 64 bit integer to native endian. -    #[inline] -    fn read_u64(self, n: u64) -> u64 { -        if self.is_big_endian() { -            u64::from_be(n) -        } else { -            u64::from_le(n) -        } -    } - -    /// Converts a signed 16 bit integer to native endian. -    #[inline] -    fn read_i16(self, n: i16) -> i16 { -        if self.is_big_endian() { -            i16::from_be(n) -        } else { -            i16::from_le(n) -        } -    } - -    /// Converts a signed 32 bit integer to native endian. -    #[inline] -    fn read_i32(self, n: i32) -> i32 { -        if self.is_big_endian() { -            i32::from_be(n) -        } else { -            i32::from_le(n) -        } -    } - -    /// Converts a signed 64 bit integer to native endian. -    #[inline] -    fn read_i64(self, n: i64) -> i64 { -        if self.is_big_endian() { -            i64::from_be(n) -        } else { -            i64::from_le(n) -        } -    } - -    /// Converts an unaligned unsigned 16 bit integer to native endian. -    #[inline] -    fn read_u16_bytes(self, n: [u8; 2]) -> u16 { -        if self.is_big_endian() { -            u16::from_be_bytes(n) -        } else { -            u16::from_le_bytes(n) -        } -    } - -    /// Converts an unaligned unsigned 32 bit integer to native endian. -    #[inline] -    fn read_u32_bytes(self, n: [u8; 4]) -> u32 { -        if self.is_big_endian() { -            u32::from_be_bytes(n) -        } else { -            u32::from_le_bytes(n) -        } -    } - -    /// Converts an unaligned unsigned 64 bit integer to native endian. -    #[inline] -    fn read_u64_bytes(self, n: [u8; 8]) -> u64 { -        if self.is_big_endian() { -            u64::from_be_bytes(n) -        } else { -            u64::from_le_bytes(n) -        } -    } - -    /// Converts an unaligned signed 16 bit integer to native endian. -    #[inline] -    fn read_i16_bytes(self, n: [u8; 2]) -> i16 { -        if self.is_big_endian() { -            i16::from_be_bytes(n) -        } else { -            i16::from_le_bytes(n) -        } -    } - -    /// Converts an unaligned signed 32 bit integer to native endian. -    #[inline] -    fn read_i32_bytes(self, n: [u8; 4]) -> i32 { -        if self.is_big_endian() { -            i32::from_be_bytes(n) -        } else { -            i32::from_le_bytes(n) -        } -    } - -    /// Converts an unaligned signed 64 bit integer to native endian. -    #[inline] -    fn read_i64_bytes(self, n: [u8; 8]) -> i64 { -        if self.is_big_endian() { -            i64::from_be_bytes(n) -        } else { -            i64::from_le_bytes(n) -        } -    } - -    /// Converts an unsigned 16 bit integer from native endian. -    #[inline] -    fn write_u16(self, n: u16) -> u16 { -        if self.is_big_endian() { -            u16::to_be(n) -        } else { -            u16::to_le(n) -        } -    } - -    /// Converts an unsigned 32 bit integer from native endian. -    #[inline] -    fn write_u32(self, n: u32) -> u32 { -        if self.is_big_endian() { -            u32::to_be(n) -        } else { -            u32::to_le(n) -        } -    } - -    /// Converts an unsigned 64 bit integer from native endian. -    #[inline] -    fn write_u64(self, n: u64) -> u64 { -        if self.is_big_endian() { -            u64::to_be(n) -        } else { -            u64::to_le(n) -        } -    } - -    /// Converts a signed 16 bit integer from native endian. -    #[inline] -    fn write_i16(self, n: i16) -> i16 { -        if self.is_big_endian() { -            i16::to_be(n) -        } else { -            i16::to_le(n) -        } -    } - -    /// Converts a signed 32 bit integer from native endian. -    #[inline] -    fn write_i32(self, n: i32) -> i32 { -        if self.is_big_endian() { -            i32::to_be(n) -        } else { -            i32::to_le(n) -        } -    } - -    /// Converts a signed 64 bit integer from native endian. -    #[inline] -    fn write_i64(self, n: i64) -> i64 { -        if self.is_big_endian() { -            i64::to_be(n) -        } else { -            i64::to_le(n) -        } -    } - -    /// Converts an unaligned unsigned 16 bit integer from native endian. -    #[inline] -    fn write_u16_bytes(self, n: u16) -> [u8; 2] { -        if self.is_big_endian() { -            u16::to_be_bytes(n) -        } else { -            u16::to_le_bytes(n) -        } -    } - -    /// Converts an unaligned unsigned 32 bit integer from native endian. -    #[inline] -    fn write_u32_bytes(self, n: u32) -> [u8; 4] { -        if self.is_big_endian() { -            u32::to_be_bytes(n) -        } else { -            u32::to_le_bytes(n) -        } -    } - -    /// Converts an unaligned unsigned 64 bit integer from native endian. -    #[inline] -    fn write_u64_bytes(self, n: u64) -> [u8; 8] { -        if self.is_big_endian() { -            u64::to_be_bytes(n) -        } else { -            u64::to_le_bytes(n) -        } -    } - -    /// Converts an unaligned signed 16 bit integer from native endian. -    #[inline] -    fn write_i16_bytes(self, n: i16) -> [u8; 2] { -        if self.is_big_endian() { -            i16::to_be_bytes(n) -        } else { -            i16::to_le_bytes(n) -        } -    } - -    /// Converts an unaligned signed 32 bit integer from native endian. -    #[inline] -    fn write_i32_bytes(self, n: i32) -> [u8; 4] { -        if self.is_big_endian() { -            i32::to_be_bytes(n) -        } else { -            i32::to_le_bytes(n) -        } -    } - -    /// Converts an unaligned signed 64 bit integer from native endian. -    #[inline] -    fn write_i64_bytes(self, n: i64) -> [u8; 8] { -        if self.is_big_endian() { -            i64::to_be_bytes(n) -        } else { -            i64::to_le_bytes(n) -        } -    } -} - -/// An endianness that is selectable at run-time. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum Endianness { -    /// Little endian byte order. -    Little, -    /// Big endian byte order. -    Big, -} - -impl Default for Endianness { -    #[cfg(target_endian = "little")] -    #[inline] -    fn default() -> Endianness { -        Endianness::Little -    } - -    #[cfg(target_endian = "big")] -    #[inline] -    fn default() -> Endianness { -        Endianness::Big -    } -} - -impl Endian for Endianness { -    #[inline] -    fn from_big_endian(big_endian: bool) -> Option<Self> { -        Some(if big_endian { -            Endianness::Big -        } else { -            Endianness::Little -        }) -    } - -    #[inline] -    fn is_big_endian(self) -> bool { -        self != Endianness::Little -    } -} - -/// Compile-time little endian byte order. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct LittleEndian; - -impl Default for LittleEndian { -    #[inline] -    fn default() -> LittleEndian { -        LittleEndian -    } -} - -impl Endian for LittleEndian { -    #[inline] -    fn from_big_endian(big_endian: bool) -> Option<Self> { -        if big_endian { -            None -        } else { -            Some(LittleEndian) -        } -    } - -    #[inline] -    fn is_big_endian(self) -> bool { -        false -    } -} - -/// Compile-time big endian byte order. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct BigEndian; - -impl Default for BigEndian { -    #[inline] -    fn default() -> BigEndian { -        BigEndian -    } -} - -impl Endian for BigEndian { -    #[inline] -    fn from_big_endian(big_endian: bool) -> Option<Self> { -        if big_endian { -            Some(BigEndian) -        } else { -            None -        } -    } - -    #[inline] -    fn is_big_endian(self) -> bool { -        true -    } -} - -/// The native endianness for the target platform. -#[cfg(target_endian = "little")] -pub type NativeEndian = LittleEndian; - -#[cfg(target_endian = "little")] -#[allow(non_upper_case_globals)] -#[doc(hidden)] -pub const NativeEndian: LittleEndian = LittleEndian; - -/// The native endianness for the target platform. -#[cfg(target_endian = "big")] -pub type NativeEndian = BigEndian; - -#[cfg(target_endian = "big")] -#[allow(non_upper_case_globals)] -#[doc(hidden)] -pub const NativeEndian: BigEndian = BigEndian; - -macro_rules! unsafe_impl_endian_pod { -    ($($struct_name:ident),+ $(,)?) => { -        $( -            unsafe impl<E: Endian> Pod for $struct_name<E> { } -        )+ -    } -} - -#[cfg(not(feature = "unaligned"))] -mod aligned { -    use super::{fmt, Endian, PhantomData, Pod}; - -    /// A `u16` value with an externally specified endianness of type `E`. -    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -    #[repr(transparent)] -    pub struct U16<E: Endian>(u16, PhantomData<E>); - -    impl<E: Endian> U16<E> { -        /// Construct a new value given bytes that already have the required endianness. -        pub fn from_bytes(n: [u8; 2]) -> Self { -            Self(u16::from_ne_bytes(n), PhantomData) -        } - -        /// Construct a new value given a native endian value. -        pub fn new(e: E, n: u16) -> Self { -            Self(e.write_u16(n), PhantomData) -        } - -        /// Return the value as a native endian value. -        pub fn get(self, e: E) -> u16 { -            e.read_u16(self.0) -        } - -        /// Set the value given a native endian value. -        pub fn set(&mut self, e: E, n: u16) { -            self.0 = e.write_u16(n); -        } -    } - -    /// A `u32` value with an externally specified endianness of type `E`. -    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -    #[repr(transparent)] -    pub struct U32<E: Endian>(u32, PhantomData<E>); - -    impl<E: Endian> U32<E> { -        /// Construct a new value given bytes that already have the required endianness. -        pub fn from_bytes(n: [u8; 4]) -> Self { -            Self(u32::from_ne_bytes(n), PhantomData) -        } - -        /// Construct a new value given a native endian value. -        pub fn new(e: E, n: u32) -> Self { -            Self(e.write_u32(n), PhantomData) -        } -        /// Return the value as a native endian value. -        pub fn get(self, e: E) -> u32 { -            e.read_u32(self.0) -        } -        /// Set the value given a native endian value. -        pub fn set(&mut self, e: E, n: u32) { -            self.0 = e.write_u32(n); -        } -    } - -    /// A `u64` value with an externally specified endianness of type `E`. -    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -    #[repr(transparent)] -    pub struct U64<E: Endian>(u64, PhantomData<E>); - -    impl<E: Endian> U64<E> { -        /// Construct a new value given bytes that already have the required endianness. -        pub fn from_bytes(n: [u8; 8]) -> Self { -            Self(u64::from_ne_bytes(n), PhantomData) -        } - -        /// Construct a new value given a native endian value. -        pub fn new(e: E, n: u64) -> Self { -            Self(e.write_u64(n), PhantomData) -        } -        /// Return the value as a native endian value. -        pub fn get(self, e: E) -> u64 { -            e.read_u64(self.0) -        } -        /// Set the value given a native endian value. -        pub fn set(&mut self, e: E, n: u64) { -            self.0 = e.write_u64(n); -        } -    } - -    /// An `i16` value with an externally specified endianness of type `E`. -    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -    #[repr(transparent)] -    pub struct I16<E: Endian>(i16, PhantomData<E>); - -    impl<E: Endian> I16<E> { -        /// Construct a new value given bytes that already have the required endianness. -        pub fn from_bytes(n: [u8; 2]) -> Self { -            Self(i16::from_ne_bytes(n), PhantomData) -        } - -        /// Construct a new value given a native endian value. -        pub fn new(e: E, n: i16) -> Self { -            Self(e.write_i16(n), PhantomData) -        } -        /// Return the value as a native endian value. -        pub fn get(self, e: E) -> i16 { -            e.read_i16(self.0) -        } -        /// Set the value given a native endian value. -        pub fn set(&mut self, e: E, n: i16) { -            self.0 = e.write_i16(n); -        } -    } - -    /// An `i32` value with an externally specified endianness of type `E`. -    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -    #[repr(transparent)] -    pub struct I32<E: Endian>(i32, PhantomData<E>); - -    impl<E: Endian> I32<E> { -        /// Construct a new value given bytes that already have the required endianness. -        pub fn from_bytes(n: [u8; 4]) -> Self { -            Self(i32::from_ne_bytes(n), PhantomData) -        } - -        /// Construct a new value given a native endian value. -        pub fn new(e: E, n: i32) -> Self { -            Self(e.write_i32(n), PhantomData) -        } -        /// Return the value as a native endian value. -        pub fn get(self, e: E) -> i32 { -            e.read_i32(self.0) -        } -        /// Set the value given a native endian value. -        pub fn set(&mut self, e: E, n: i32) { -            self.0 = e.write_i32(n); -        } -    } - -    /// An `i64` value with an externally specified endianness of type `E`. -    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -    #[repr(transparent)] -    pub struct I64<E: Endian>(i64, PhantomData<E>); - -    impl<E: Endian> I64<E> { -        /// Construct a new value given bytes that already have the required endianness. -        pub fn from_bytes(n: [u8; 8]) -> Self { -            Self(i64::from_ne_bytes(n), PhantomData) -        } - -        /// Construct a new value given a native endian value. -        pub fn new(e: E, n: i64) -> Self { -            Self(e.write_i64(n), PhantomData) -        } -        /// Return the value as a native endian value. -        pub fn get(self, e: E) -> i64 { -            e.read_i64(self.0) -        } -        /// Set the value given a native endian value. -        pub fn set(&mut self, e: E, n: i64) { -            self.0 = e.write_i64(n); -        } -    } - -    impl<E: Endian> fmt::Debug for U16<E> { -        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -            write!(f, "U16({:x})", self.0) -        } -    } - -    impl<E: Endian> fmt::Debug for U32<E> { -        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -            write!(f, "U32({:x})", self.0) -        } -    } - -    impl<E: Endian> fmt::Debug for U64<E> { -        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -            write!(f, "U64({:x})", self.0) -        } -    } - -    impl<E: Endian> fmt::Debug for I16<E> { -        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -            write!(f, "I16({:x})", self.0) -        } -    } - -    impl<E: Endian> fmt::Debug for I32<E> { -        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -            write!(f, "I32({:x})", self.0) -        } -    } - -    impl<E: Endian> fmt::Debug for I64<E> { -        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -            write!(f, "I64({:x})", self.0) -        } -    } - -    unsafe_impl_endian_pod!(U16, U32, U64, I16, I32, I64); -} - -#[cfg(not(feature = "unaligned"))] -pub use aligned::*; - -/// A `u16` value with an externally specified endianness of type `E`. -#[cfg(feature = "unaligned")] -pub type U16<E> = U16Bytes<E>; - -/// A `u32` value with an externally specified endianness of type `E`. -#[cfg(feature = "unaligned")] -pub type U32<E> = U32Bytes<E>; - -/// A `u64` value with an externally specified endianness of type `E`. -#[cfg(feature = "unaligned")] -pub type U64<E> = U64Bytes<E>; - -/// An `i16` value with an externally specified endianness of type `E`. -#[cfg(feature = "unaligned")] -pub type I16<E> = I16Bytes<E>; - -/// An `i32` value with an externally specified endianness of type `E`. -#[cfg(feature = "unaligned")] -pub type I32<E> = I32Bytes<E>; - -/// An `i64` value with an externally specified endianness of type `E`. -#[cfg(feature = "unaligned")] -pub type I64<E> = I64Bytes<E>; - -/// An unaligned `u16` value with an externally specified endianness of type `E`. -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -pub struct U16Bytes<E: Endian>([u8; 2], PhantomData<E>); - -impl<E: Endian> U16Bytes<E> { -    /// Construct a new value given bytes that already have the required endianness. -    pub fn from_bytes(n: [u8; 2]) -> Self { -        Self(n, PhantomData) -    } - -    /// Construct a new value given a native endian value. -    pub fn new(e: E, n: u16) -> Self { -        Self(e.write_u16_bytes(n), PhantomData) -    } - -    /// Return the value as a native endian value. -    pub fn get(self, e: E) -> u16 { -        e.read_u16_bytes(self.0) -    } - -    /// Set the value given a native endian value. -    pub fn set(&mut self, e: E, n: u16) { -        self.0 = e.write_u16_bytes(n); -    } -} - -/// An unaligned `u32` value with an externally specified endianness of type `E`. -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -pub struct U32Bytes<E: Endian>([u8; 4], PhantomData<E>); - -impl<E: Endian> U32Bytes<E> { -    /// Construct a new value given bytes that already have the required endianness. -    pub fn from_bytes(n: [u8; 4]) -> Self { -        Self(n, PhantomData) -    } - -    /// Construct a new value given a native endian value. -    pub fn new(e: E, n: u32) -> Self { -        Self(e.write_u32_bytes(n), PhantomData) -    } - -    /// Return the value as a native endian value. -    pub fn get(self, e: E) -> u32 { -        e.read_u32_bytes(self.0) -    } - -    /// Set the value given a native endian value. -    pub fn set(&mut self, e: E, n: u32) { -        self.0 = e.write_u32_bytes(n); -    } -} - -/// An unaligned `u64` value with an externally specified endianness of type `E`. -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -pub struct U64Bytes<E: Endian>([u8; 8], PhantomData<E>); - -impl<E: Endian> U64Bytes<E> { -    /// Construct a new value given bytes that already have the required endianness. -    pub fn from_bytes(n: [u8; 8]) -> Self { -        Self(n, PhantomData) -    } - -    /// Construct a new value given a native endian value. -    pub fn new(e: E, n: u64) -> Self { -        Self(e.write_u64_bytes(n), PhantomData) -    } - -    /// Return the value as a native endian value. -    pub fn get(self, e: E) -> u64 { -        e.read_u64_bytes(self.0) -    } - -    /// Set the value given a native endian value. -    pub fn set(&mut self, e: E, n: u64) { -        self.0 = e.write_u64_bytes(n); -    } -} - -/// An unaligned `i16` value with an externally specified endianness of type `E`. -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -pub struct I16Bytes<E: Endian>([u8; 2], PhantomData<E>); - -impl<E: Endian> I16Bytes<E> { -    /// Construct a new value given bytes that already have the required endianness. -    pub fn from_bytes(n: [u8; 2]) -> Self { -        Self(n, PhantomData) -    } - -    /// Construct a new value given a native endian value. -    pub fn new(e: E, n: i16) -> Self { -        Self(e.write_i16_bytes(n), PhantomData) -    } - -    /// Return the value as a native endian value. -    pub fn get(self, e: E) -> i16 { -        e.read_i16_bytes(self.0) -    } - -    /// Set the value given a native endian value. -    pub fn set(&mut self, e: E, n: i16) { -        self.0 = e.write_i16_bytes(n); -    } -} - -/// An unaligned `i32` value with an externally specified endianness of type `E`. -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -pub struct I32Bytes<E: Endian>([u8; 4], PhantomData<E>); - -impl<E: Endian> I32Bytes<E> { -    /// Construct a new value given bytes that already have the required endianness. -    pub fn from_bytes(n: [u8; 4]) -> Self { -        Self(n, PhantomData) -    } - -    /// Construct a new value given a native endian value. -    pub fn new(e: E, n: i32) -> Self { -        Self(e.write_i32_bytes(n), PhantomData) -    } - -    /// Return the value as a native endian value. -    pub fn get(self, e: E) -> i32 { -        e.read_i32_bytes(self.0) -    } - -    /// Set the value given a native endian value. -    pub fn set(&mut self, e: E, n: i32) { -        self.0 = e.write_i32_bytes(n); -    } -} - -/// An unaligned `i64` value with an externally specified endianness of type `E`. -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -pub struct I64Bytes<E: Endian>([u8; 8], PhantomData<E>); - -impl<E: Endian> I64Bytes<E> { -    /// Construct a new value given bytes that already have the required endianness. -    pub fn from_bytes(n: [u8; 8]) -> Self { -        Self(n, PhantomData) -    } - -    /// Construct a new value given a native endian value. -    pub fn new(e: E, n: i64) -> Self { -        Self(e.write_i64_bytes(n), PhantomData) -    } - -    /// Return the value as a native endian value. -    pub fn get(self, e: E) -> i64 { -        e.read_i64_bytes(self.0) -    } - -    /// Set the value given a native endian value. -    pub fn set(&mut self, e: E, n: i64) { -        self.0 = e.write_i64_bytes(n); -    } -} - -impl<E: Endian> fmt::Debug for U16Bytes<E> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!(f, "U16({:x}, {:x})", self.0[0], self.0[1],) -    } -} - -impl<E: Endian> fmt::Debug for U32Bytes<E> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!( -            f, -            "U32({:x}, {:x}, {:x}, {:x})", -            self.0[0], self.0[1], self.0[2], self.0[3], -        ) -    } -} - -impl<E: Endian> fmt::Debug for U64Bytes<E> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!( -            f, -            "U64({:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x})", -            self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], -        ) -    } -} - -impl<E: Endian> fmt::Debug for I16Bytes<E> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!(f, "I16({:x}, {:x})", self.0[0], self.0[1],) -    } -} - -impl<E: Endian> fmt::Debug for I32Bytes<E> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!( -            f, -            "I32({:x}, {:x}, {:x}, {:x})", -            self.0[0], self.0[1], self.0[2], self.0[3], -        ) -    } -} - -impl<E: Endian> fmt::Debug for I64Bytes<E> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!( -            f, -            "I64({:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x})", -            self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], -        ) -    } -} - -unsafe_impl_endian_pod!(U16Bytes, U32Bytes, U64Bytes, I16Bytes, I32Bytes, I64Bytes); diff --git a/vendor/object/src/lib.rs b/vendor/object/src/lib.rs deleted file mode 100644 index 5956e06..0000000 --- a/vendor/object/src/lib.rs +++ /dev/null @@ -1,99 +0,0 @@ -//! # `object` -//! -//! The `object` crate provides a unified interface to working with object files -//! across platforms. It supports reading relocatable object files and executable files, -//! and writing relocatable object files and some executable files. -//! -//! ## Raw struct definitions -//! -//! Raw structs are defined for: [ELF](elf), [Mach-O](macho), [PE/COFF](pe), -//! [XCOFF](xcoff), [archive]. -//! Types and traits for zerocopy support are defined in the [`pod`] and [`endian`] modules. -//! -//! ## Unified read API -//! -//! The [`read`] module provides a unified read API using the [`read::Object`] trait. -//! There is an implementation of this trait for [`read::File`], which allows reading any -//! file format, as well as implementations for each file format. -//! -//! ## Low level read API -//! -//! The [`read#modules`] submodules define helpers that operate on the raw structs. -//! These can be used instead of the unified API, or in conjunction with it to access -//! details that are not available via the unified API. -//! -//! ## Unified write API -//! -//! The [`mod@write`] module provides a unified write API for relocatable object files -//! using [`write::Object`]. This does not support writing executable files. -//! -//! ## Low level write API -//! -//! The [`mod@write#modules`] submodules define helpers for writing the raw structs. -//! -//! ## Shared definitions -//! -//! The crate provides a number of definitions that are used by both the read and write -//! APIs. These are defined at the top level module, but none of these are the main entry -//! points of the crate. - -#![deny(missing_docs)] -#![deny(missing_debug_implementations)] -#![no_std] -#![warn(rust_2018_idioms)] -// Style. -#![allow(clippy::collapsible_if)] -#![allow(clippy::comparison_chain)] -#![allow(clippy::manual_flatten)] -#![allow(clippy::match_like_matches_macro)] -#![allow(clippy::single_match)] -#![allow(clippy::type_complexity)] -// Occurs due to fallible iteration. -#![allow(clippy::should_implement_trait)] -// Unit errors are converted to other types by callers. -#![allow(clippy::result_unit_err)] -// Worse readability sometimes. -#![allow(clippy::collapsible_else_if)] - -#[cfg(feature = "cargo-all")] -compile_error!("'--all-features' is not supported; use '--features all' instead"); - -#[cfg(any(feature = "read_core", feature = "write_core"))] -#[allow(unused_imports)] -#[macro_use] -extern crate alloc; - -#[cfg(feature = "std")] -#[allow(unused_imports)] -#[macro_use] -extern crate std; - -mod common; -pub use common::*; - -#[macro_use] -pub mod endian; -pub use endian::*; - -#[macro_use] -pub mod pod; -pub use pod::*; - -#[cfg(feature = "read_core")] -pub mod read; -#[cfg(feature = "read_core")] -pub use read::*; - -#[cfg(feature = "write_core")] -pub mod write; - -#[cfg(feature = "archive")] -pub mod archive; -#[cfg(feature = "elf")] -pub mod elf; -#[cfg(feature = "macho")] -pub mod macho; -#[cfg(any(feature = "coff", feature = "pe"))] -pub mod pe; -#[cfg(feature = "xcoff")] -pub mod xcoff; diff --git a/vendor/object/src/macho.rs b/vendor/object/src/macho.rs deleted file mode 100644 index 3cd38e0..0000000 --- a/vendor/object/src/macho.rs +++ /dev/null @@ -1,3307 +0,0 @@ -//! Mach-O definitions. -//! -//! These definitions are independent of read/write support, although we do implement -//! some traits useful for those. -//! -//! This module is based heavily on header files from MacOSX11.1.sdk. - -#![allow(missing_docs)] - -use crate::endian::{BigEndian, Endian, U64Bytes, U16, U32, U64}; -use crate::pod::Pod; - -// Definitions from "/usr/include/mach/machine.h". - -/* - * Capability bits used in the definition of cpu_type. - */ - -/// mask for architecture bits -pub const CPU_ARCH_MASK: u32 = 0xff00_0000; -/// 64 bit ABI -pub const CPU_ARCH_ABI64: u32 = 0x0100_0000; -/// ABI for 64-bit hardware with 32-bit types; LP32 -pub const CPU_ARCH_ABI64_32: u32 = 0x0200_0000; - -/* - *	Machine types known by all. - */ - -pub const CPU_TYPE_ANY: u32 = !0; - -pub const CPU_TYPE_VAX: u32 = 1; -pub const CPU_TYPE_MC680X0: u32 = 6; -pub const CPU_TYPE_X86: u32 = 7; -pub const CPU_TYPE_X86_64: u32 = CPU_TYPE_X86 | CPU_ARCH_ABI64; -pub const CPU_TYPE_MIPS: u32 = 8; -pub const CPU_TYPE_MC98000: u32 = 10; -pub const CPU_TYPE_HPPA: u32 = 11; -pub const CPU_TYPE_ARM: u32 = 12; -pub const CPU_TYPE_ARM64: u32 = CPU_TYPE_ARM | CPU_ARCH_ABI64; -pub const CPU_TYPE_ARM64_32: u32 = CPU_TYPE_ARM | CPU_ARCH_ABI64_32; -pub const CPU_TYPE_MC88000: u32 = 13; -pub const CPU_TYPE_SPARC: u32 = 14; -pub const CPU_TYPE_I860: u32 = 15; -pub const CPU_TYPE_ALPHA: u32 = 16; -pub const CPU_TYPE_POWERPC: u32 = 18; -pub const CPU_TYPE_POWERPC64: u32 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64; - -/* - * Capability bits used in the definition of cpu_subtype. - */ -/// mask for feature flags -pub const CPU_SUBTYPE_MASK: u32 = 0xff00_0000; -/// 64 bit libraries -pub const CPU_SUBTYPE_LIB64: u32 = 0x8000_0000; -/// pointer authentication with versioned ABI -pub const CPU_SUBTYPE_PTRAUTH_ABI: u32 = 0x8000_0000; - -/// When selecting a slice, ANY will pick the slice with the best -/// grading for the selected cpu_type_t, unlike the "ALL" subtypes, -/// which are the slices that can run on any hardware for that cpu type. -pub const CPU_SUBTYPE_ANY: u32 = !0; - -/* - *	Object files that are hand-crafted to run on any - *	implementation of an architecture are tagged with - *	CPU_SUBTYPE_MULTIPLE.  This functions essentially the same as - *	the "ALL" subtype of an architecture except that it allows us - *	to easily find object files that may need to be modified - *	whenever a new implementation of an architecture comes out. - * - *	It is the responsibility of the implementor to make sure the - *	software handles unsupported implementations elegantly. - */ -pub const CPU_SUBTYPE_MULTIPLE: u32 = !0; -pub const CPU_SUBTYPE_LITTLE_ENDIAN: u32 = 0; -pub const CPU_SUBTYPE_BIG_ENDIAN: u32 = 1; - -/* - *	VAX subtypes (these do *not* necessary conform to the actual cpu - *	ID assigned by DEC available via the SID register). - */ - -pub const CPU_SUBTYPE_VAX_ALL: u32 = 0; -pub const CPU_SUBTYPE_VAX780: u32 = 1; -pub const CPU_SUBTYPE_VAX785: u32 = 2; -pub const CPU_SUBTYPE_VAX750: u32 = 3; -pub const CPU_SUBTYPE_VAX730: u32 = 4; -pub const CPU_SUBTYPE_UVAXI: u32 = 5; -pub const CPU_SUBTYPE_UVAXII: u32 = 6; -pub const CPU_SUBTYPE_VAX8200: u32 = 7; -pub const CPU_SUBTYPE_VAX8500: u32 = 8; -pub const CPU_SUBTYPE_VAX8600: u32 = 9; -pub const CPU_SUBTYPE_VAX8650: u32 = 10; -pub const CPU_SUBTYPE_VAX8800: u32 = 11; -pub const CPU_SUBTYPE_UVAXIII: u32 = 12; - -/* - *      680x0 subtypes - * - * The subtype definitions here are unusual for historical reasons. - * NeXT used to consider 68030 code as generic 68000 code.  For - * backwards compatibility: - * - *	CPU_SUBTYPE_MC68030 symbol has been preserved for source code - *	compatibility. - * - *	CPU_SUBTYPE_MC680x0_ALL has been defined to be the same - *	subtype as CPU_SUBTYPE_MC68030 for binary comatability. - * - *	CPU_SUBTYPE_MC68030_ONLY has been added to allow new object - *	files to be tagged as containing 68030-specific instructions. - */ - -pub const CPU_SUBTYPE_MC680X0_ALL: u32 = 1; -// compat -pub const CPU_SUBTYPE_MC68030: u32 = 1; -pub const CPU_SUBTYPE_MC68040: u32 = 2; -pub const CPU_SUBTYPE_MC68030_ONLY: u32 = 3; - -/* - *	I386 subtypes - */ - -#[inline] -pub const fn cpu_subtype_intel(f: u32, m: u32) -> u32 { -    f + (m << 4) -} - -pub const CPU_SUBTYPE_I386_ALL: u32 = cpu_subtype_intel(3, 0); -pub const CPU_SUBTYPE_386: u32 = cpu_subtype_intel(3, 0); -pub const CPU_SUBTYPE_486: u32 = cpu_subtype_intel(4, 0); -pub const CPU_SUBTYPE_486SX: u32 = cpu_subtype_intel(4, 8); -pub const CPU_SUBTYPE_586: u32 = cpu_subtype_intel(5, 0); -pub const CPU_SUBTYPE_PENT: u32 = cpu_subtype_intel(5, 0); -pub const CPU_SUBTYPE_PENTPRO: u32 = cpu_subtype_intel(6, 1); -pub const CPU_SUBTYPE_PENTII_M3: u32 = cpu_subtype_intel(6, 3); -pub const CPU_SUBTYPE_PENTII_M5: u32 = cpu_subtype_intel(6, 5); -pub const CPU_SUBTYPE_CELERON: u32 = cpu_subtype_intel(7, 6); -pub const CPU_SUBTYPE_CELERON_MOBILE: u32 = cpu_subtype_intel(7, 7); -pub const CPU_SUBTYPE_PENTIUM_3: u32 = cpu_subtype_intel(8, 0); -pub const CPU_SUBTYPE_PENTIUM_3_M: u32 = cpu_subtype_intel(8, 1); -pub const CPU_SUBTYPE_PENTIUM_3_XEON: u32 = cpu_subtype_intel(8, 2); -pub const CPU_SUBTYPE_PENTIUM_M: u32 = cpu_subtype_intel(9, 0); -pub const CPU_SUBTYPE_PENTIUM_4: u32 = cpu_subtype_intel(10, 0); -pub const CPU_SUBTYPE_PENTIUM_4_M: u32 = cpu_subtype_intel(10, 1); -pub const CPU_SUBTYPE_ITANIUM: u32 = cpu_subtype_intel(11, 0); -pub const CPU_SUBTYPE_ITANIUM_2: u32 = cpu_subtype_intel(11, 1); -pub const CPU_SUBTYPE_XEON: u32 = cpu_subtype_intel(12, 0); -pub const CPU_SUBTYPE_XEON_MP: u32 = cpu_subtype_intel(12, 1); - -#[inline] -pub const fn cpu_subtype_intel_family(x: u32) -> u32 { -    x & 15 -} -pub const CPU_SUBTYPE_INTEL_FAMILY_MAX: u32 = 15; - -#[inline] -pub const fn cpu_subtype_intel_model(x: u32) -> u32 { -    x >> 4 -} -pub const CPU_SUBTYPE_INTEL_MODEL_ALL: u32 = 0; - -/* - *	X86 subtypes. - */ - -pub const CPU_SUBTYPE_X86_ALL: u32 = 3; -pub const CPU_SUBTYPE_X86_64_ALL: u32 = 3; -pub const CPU_SUBTYPE_X86_ARCH1: u32 = 4; -/// Haswell feature subset -pub const CPU_SUBTYPE_X86_64_H: u32 = 8; - -/* - *	Mips subtypes. - */ - -pub const CPU_SUBTYPE_MIPS_ALL: u32 = 0; -pub const CPU_SUBTYPE_MIPS_R2300: u32 = 1; -pub const CPU_SUBTYPE_MIPS_R2600: u32 = 2; -pub const CPU_SUBTYPE_MIPS_R2800: u32 = 3; -/// pmax -pub const CPU_SUBTYPE_MIPS_R2000A: u32 = 4; -pub const CPU_SUBTYPE_MIPS_R2000: u32 = 5; -/// 3max -pub const CPU_SUBTYPE_MIPS_R3000A: u32 = 6; -pub const CPU_SUBTYPE_MIPS_R3000: u32 = 7; - -/* - *	MC98000 (PowerPC) subtypes - */ -pub const CPU_SUBTYPE_MC98000_ALL: u32 = 0; -pub const CPU_SUBTYPE_MC98601: u32 = 1; - -/* - *	HPPA subtypes for Hewlett-Packard HP-PA family of - *	risc processors. Port by NeXT to 700 series. - */ - -pub const CPU_SUBTYPE_HPPA_ALL: u32 = 0; -pub const CPU_SUBTYPE_HPPA_7100LC: u32 = 1; - -/* - *	MC88000 subtypes. - */ -pub const CPU_SUBTYPE_MC88000_ALL: u32 = 0; -pub const CPU_SUBTYPE_MC88100: u32 = 1; -pub const CPU_SUBTYPE_MC88110: u32 = 2; - -/* - *	SPARC subtypes - */ -pub const CPU_SUBTYPE_SPARC_ALL: u32 = 0; - -/* - *	I860 subtypes - */ -pub const CPU_SUBTYPE_I860_ALL: u32 = 0; -pub const CPU_SUBTYPE_I860_860: u32 = 1; - -/* - *	PowerPC subtypes - */ -pub const CPU_SUBTYPE_POWERPC_ALL: u32 = 0; -pub const CPU_SUBTYPE_POWERPC_601: u32 = 1; -pub const CPU_SUBTYPE_POWERPC_602: u32 = 2; -pub const CPU_SUBTYPE_POWERPC_603: u32 = 3; -pub const CPU_SUBTYPE_POWERPC_603E: u32 = 4; -pub const CPU_SUBTYPE_POWERPC_603EV: u32 = 5; -pub const CPU_SUBTYPE_POWERPC_604: u32 = 6; -pub const CPU_SUBTYPE_POWERPC_604E: u32 = 7; -pub const CPU_SUBTYPE_POWERPC_620: u32 = 8; -pub const CPU_SUBTYPE_POWERPC_750: u32 = 9; -pub const CPU_SUBTYPE_POWERPC_7400: u32 = 10; -pub const CPU_SUBTYPE_POWERPC_7450: u32 = 11; -pub const CPU_SUBTYPE_POWERPC_970: u32 = 100; - -/* - *	ARM subtypes - */ -pub const CPU_SUBTYPE_ARM_ALL: u32 = 0; -pub const CPU_SUBTYPE_ARM_V4T: u32 = 5; -pub const CPU_SUBTYPE_ARM_V6: u32 = 6; -pub const CPU_SUBTYPE_ARM_V5TEJ: u32 = 7; -pub const CPU_SUBTYPE_ARM_XSCALE: u32 = 8; -/// ARMv7-A and ARMv7-R -pub const CPU_SUBTYPE_ARM_V7: u32 = 9; -/// Cortex A9 -pub const CPU_SUBTYPE_ARM_V7F: u32 = 10; -/// Swift -pub const CPU_SUBTYPE_ARM_V7S: u32 = 11; -pub const CPU_SUBTYPE_ARM_V7K: u32 = 12; -pub const CPU_SUBTYPE_ARM_V8: u32 = 13; -/// Not meant to be run under xnu -pub const CPU_SUBTYPE_ARM_V6M: u32 = 14; -/// Not meant to be run under xnu -pub const CPU_SUBTYPE_ARM_V7M: u32 = 15; -/// Not meant to be run under xnu -pub const CPU_SUBTYPE_ARM_V7EM: u32 = 16; -/// Not meant to be run under xnu -pub const CPU_SUBTYPE_ARM_V8M: u32 = 17; - -/* - *  ARM64 subtypes - */ -pub const CPU_SUBTYPE_ARM64_ALL: u32 = 0; -pub const CPU_SUBTYPE_ARM64_V8: u32 = 1; -pub const CPU_SUBTYPE_ARM64E: u32 = 2; - -/* - *  ARM64_32 subtypes - */ -pub const CPU_SUBTYPE_ARM64_32_ALL: u32 = 0; -pub const CPU_SUBTYPE_ARM64_32_V8: u32 = 1; - -// Definitions from "/usr/include/mach/vm_prot.h". - -/// read permission -pub const VM_PROT_READ: u32 = 0x01; -/// write permission -pub const VM_PROT_WRITE: u32 = 0x02; -/// execute permission -pub const VM_PROT_EXECUTE: u32 = 0x04; - -// Definitions from https://opensource.apple.com/source/dyld/dyld-210.2.3/launch-cache/dyld_cache_format.h.auto.html - -/// The dyld cache header. -/// Corresponds to struct dyld_cache_header from dyld_cache_format.h. -/// This header has grown over time. Only the fields up to and including dyld_base_address -/// are guaranteed to be present. For all other fields, check the header size before -/// accessing the field. The header size is stored in mapping_offset; the mappings start -/// right after the theader. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DyldCacheHeader<E: Endian> { -    /// e.g. "dyld_v0    i386" -    pub magic: [u8; 16], -    /// file offset to first dyld_cache_mapping_info -    pub mapping_offset: U32<E>, // offset: 0x10 -    /// number of dyld_cache_mapping_info entries -    pub mapping_count: U32<E>, // offset: 0x14 -    /// file offset to first dyld_cache_image_info -    pub images_offset: U32<E>, // offset: 0x18 -    /// number of dyld_cache_image_info entries -    pub images_count: U32<E>, // offset: 0x1c -    /// base address of dyld when cache was built -    pub dyld_base_address: U64<E>, // offset: 0x20 -    /// -    reserved1: [u8; 32], // offset: 0x28 -    /// file offset of where local symbols are stored -    pub local_symbols_offset: U64<E>, // offset: 0x48 -    /// size of local symbols information -    pub local_symbols_size: U64<E>, // offset: 0x50 -    /// unique value for each shared cache file -    pub uuid: [u8; 16], // offset: 0x58 -    /// -    reserved2: [u8; 32], // offset: 0x68 -    /// -    reserved3: [u8; 32], // offset: 0x88 -    /// -    reserved4: [u8; 32], // offset: 0xa8 -    /// -    reserved5: [u8; 32], // offset: 0xc8 -    /// -    reserved6: [u8; 32], // offset: 0xe8 -    /// -    reserved7: [u8; 32], // offset: 0x108 -    /// -    reserved8: [u8; 32], // offset: 0x128 -    /// -    reserved9: [u8; 32], // offset: 0x148 -    /// -    reserved10: [u8; 32], // offset: 0x168 -    /// file offset to first dyld_subcache_info -    pub subcaches_offset: U32<E>, // offset: 0x188 -    /// number of dyld_subcache_info entries -    pub subcaches_count: U32<E>, // offset: 0x18c -    /// the UUID of the .symbols subcache -    pub symbols_subcache_uuid: [u8; 16], // offset: 0x190 -    /// -    reserved11: [u8; 32], // offset: 0x1a0 -    /// file offset to first dyld_cache_image_info -    /// Use this  instead of images_offset if mapping_offset is at least 0x1c4. -    pub images_across_all_subcaches_offset: U32<E>, // offset: 0x1c0 -    /// number of dyld_cache_image_info entries -    /// Use this  instead of images_count if mapping_offset is at least 0x1c4. -    pub images_across_all_subcaches_count: U32<E>, // offset: 0x1c4 -} - -/// Corresponds to struct dyld_cache_mapping_info from dyld_cache_format.h. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DyldCacheMappingInfo<E: Endian> { -    /// -    pub address: U64<E>, -    /// -    pub size: U64<E>, -    /// -    pub file_offset: U64<E>, -    /// -    pub max_prot: U32<E>, -    /// -    pub init_prot: U32<E>, -} - -/// Corresponds to struct dyld_cache_image_info from dyld_cache_format.h. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DyldCacheImageInfo<E: Endian> { -    /// -    pub address: U64<E>, -    /// -    pub mod_time: U64<E>, -    /// -    pub inode: U64<E>, -    /// -    pub path_file_offset: U32<E>, -    /// -    pub pad: U32<E>, -} - -/// Corresponds to a struct whose source code has not been published as of Nov 2021. -/// Added in the dyld cache version which shipped with macOS 12 / iOS 15. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DyldSubCacheInfo<E: Endian> { -    /// The UUID of this subcache. -    pub uuid: [u8; 16], -    /// The size of this subcache plus all previous subcaches. -    pub cumulative_size: U64<E>, -} - -// Definitions from "/usr/include/mach-o/loader.h". - -/* - * This header file describes the structures of the file format for "fat" - * architecture specific file (wrapper design).  At the beginning of the file - * there is one `FatHeader` structure followed by a number of `FatArch*` - * structures.  For each architecture in the file, specified by a pair of - * cputype and cpusubtype, the `FatHeader` describes the file offset, file - * size and alignment in the file of the architecture specific member. - * The padded bytes in the file to place each member on it's specific alignment - * are defined to be read as zeros and can be left as "holes" if the file system - * can support them as long as they read as zeros. - * - * All structures defined here are always written and read to/from disk - * in big-endian order. - */ - -pub const FAT_MAGIC: u32 = 0xcafe_babe; -/// NXSwapLong(FAT_MAGIC) -pub const FAT_CIGAM: u32 = 0xbeba_feca; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FatHeader { -    /// FAT_MAGIC or FAT_MAGIC_64 -    pub magic: U32<BigEndian>, -    /// number of structs that follow -    pub nfat_arch: U32<BigEndian>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FatArch32 { -    /// cpu specifier (int) -    pub cputype: U32<BigEndian>, -    /// machine specifier (int) -    pub cpusubtype: U32<BigEndian>, -    /// file offset to this object file -    pub offset: U32<BigEndian>, -    /// size of this object file -    pub size: U32<BigEndian>, -    /// alignment as a power of 2 -    pub align: U32<BigEndian>, -} - -/* - * The support for the 64-bit fat file format described here is a work in - * progress and not yet fully supported in all the Apple Developer Tools. - * - * When a slice is greater than 4mb or an offset to a slice is greater than 4mb - * then the 64-bit fat file format is used. - */ -pub const FAT_MAGIC_64: u32 = 0xcafe_babf; -/// NXSwapLong(FAT_MAGIC_64) -pub const FAT_CIGAM_64: u32 = 0xbfba_feca; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FatArch64 { -    /// cpu specifier (int) -    pub cputype: U32<BigEndian>, -    /// machine specifier (int) -    pub cpusubtype: U32<BigEndian>, -    /// file offset to this object file -    pub offset: U64<BigEndian>, -    /// size of this object file -    pub size: U64<BigEndian>, -    /// alignment as a power of 2 -    pub align: U32<BigEndian>, -    /// reserved -    pub reserved: U32<BigEndian>, -} - -// Definitions from "/usr/include/mach-o/loader.h". - -/// The 32-bit mach header. -/// -/// Appears at the very beginning of the object file for 32-bit architectures. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct MachHeader32<E: Endian> { -    /// mach magic number identifier -    pub magic: U32<BigEndian>, -    /// cpu specifier -    pub cputype: U32<E>, -    /// machine specifier -    pub cpusubtype: U32<E>, -    /// type of file -    pub filetype: U32<E>, -    /// number of load commands -    pub ncmds: U32<E>, -    /// the size of all the load commands -    pub sizeofcmds: U32<E>, -    /// flags -    pub flags: U32<E>, -} - -// Values for `MachHeader32::magic`. -/// the mach magic number -pub const MH_MAGIC: u32 = 0xfeed_face; -/// NXSwapInt(MH_MAGIC) -pub const MH_CIGAM: u32 = 0xcefa_edfe; - -/// The 64-bit mach header. -/// -/// Appears at the very beginning of object files for 64-bit architectures. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct MachHeader64<E: Endian> { -    /// mach magic number identifier -    pub magic: U32<BigEndian>, -    /// cpu specifier -    pub cputype: U32<E>, -    /// machine specifier -    pub cpusubtype: U32<E>, -    /// type of file -    pub filetype: U32<E>, -    /// number of load commands -    pub ncmds: U32<E>, -    /// the size of all the load commands -    pub sizeofcmds: U32<E>, -    /// flags -    pub flags: U32<E>, -    /// reserved -    pub reserved: U32<E>, -} - -// Values for `MachHeader64::magic`. -/// the 64-bit mach magic number -pub const MH_MAGIC_64: u32 = 0xfeed_facf; -/// NXSwapInt(MH_MAGIC_64) -pub const MH_CIGAM_64: u32 = 0xcffa_edfe; - -/* - * The layout of the file depends on the filetype.  For all but the MH_OBJECT - * file type the segments are padded out and aligned on a segment alignment - * boundary for efficient demand pageing.  The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, - * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part - * of their first segment. - * - * The file type MH_OBJECT is a compact format intended as output of the - * assembler and input (and possibly output) of the link editor (the .o - * format).  All sections are in one unnamed segment with no segment padding. - * This format is used as an executable format when the file is so small the - * segment padding greatly increases its size. - * - * The file type MH_PRELOAD is an executable format intended for things that - * are not executed under the kernel (proms, stand alones, kernels, etc).  The - * format can be executed under the kernel but may demand paged it and not - * preload it before execution. - * - * A core file is in MH_CORE format and can be any in an arbritray legal - * Mach-O file. - */ - -// Values for `MachHeader*::filetype`. -/// relocatable object file -pub const MH_OBJECT: u32 = 0x1; -/// demand paged executable file -pub const MH_EXECUTE: u32 = 0x2; -/// fixed VM shared library file -pub const MH_FVMLIB: u32 = 0x3; -/// core file -pub const MH_CORE: u32 = 0x4; -/// preloaded executable file -pub const MH_PRELOAD: u32 = 0x5; -/// dynamically bound shared library -pub const MH_DYLIB: u32 = 0x6; -/// dynamic link editor -pub const MH_DYLINKER: u32 = 0x7; -/// dynamically bound bundle file -pub const MH_BUNDLE: u32 = 0x8; -/// shared library stub for static linking only, no section contents -pub const MH_DYLIB_STUB: u32 = 0x9; -/// companion file with only debug sections -pub const MH_DSYM: u32 = 0xa; -/// x86_64 kexts -pub const MH_KEXT_BUNDLE: u32 = 0xb; -/// set of mach-o's -pub const MH_FILESET: u32 = 0xc; - -// Values for `MachHeader*::flags`. -/// the object file has no undefined references -pub const MH_NOUNDEFS: u32 = 0x1; -/// the object file is the output of an incremental link against a base file and can't be link edited again -pub const MH_INCRLINK: u32 = 0x2; -/// the object file is input for the dynamic linker and can't be statically link edited again -pub const MH_DYLDLINK: u32 = 0x4; -/// the object file's undefined references are bound by the dynamic linker when loaded. -pub const MH_BINDATLOAD: u32 = 0x8; -/// the file has its dynamic undefined references prebound. -pub const MH_PREBOUND: u32 = 0x10; -/// the file has its read-only and read-write segments split -pub const MH_SPLIT_SEGS: u32 = 0x20; -/// the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete) -pub const MH_LAZY_INIT: u32 = 0x40; -/// the image is using two-level name space bindings -pub const MH_TWOLEVEL: u32 = 0x80; -/// the executable is forcing all images to use flat name space bindings -pub const MH_FORCE_FLAT: u32 = 0x100; -/// this umbrella guarantees no multiple definitions of symbols in its sub-images so the two-level namespace hints can always be used. -pub const MH_NOMULTIDEFS: u32 = 0x200; -/// do not have dyld notify the prebinding agent about this executable -pub const MH_NOFIXPREBINDING: u32 = 0x400; -/// the binary is not prebound but can have its prebinding redone. only used when MH_PREBOUND is not set. -pub const MH_PREBINDABLE: u32 = 0x800; -/// indicates that this binary binds to all two-level namespace modules of its dependent libraries. only used when MH_PREBINDABLE and MH_TWOLEVEL are both set. -pub const MH_ALLMODSBOUND: u32 = 0x1000; -/// safe to divide up the sections into sub-sections via symbols for dead code stripping -pub const MH_SUBSECTIONS_VIA_SYMBOLS: u32 = 0x2000; -/// the binary has been canonicalized via the unprebind operation -pub const MH_CANONICAL: u32 = 0x4000; -/// the final linked image contains external weak symbols -pub const MH_WEAK_DEFINES: u32 = 0x8000; -/// the final linked image uses weak symbols -pub const MH_BINDS_TO_WEAK: u32 = 0x10000; -/// When this bit is set, all stacks in the task will be given stack execution privilege.  Only used in MH_EXECUTE filetypes. -pub const MH_ALLOW_STACK_EXECUTION: u32 = 0x20000; -/// When this bit is set, the binary declares it is safe for use in processes with uid zero -pub const MH_ROOT_SAFE: u32 = 0x40000; -/// When this bit is set, the binary declares it is safe for use in processes when issetugid() is true -pub const MH_SETUID_SAFE: u32 = 0x80000; -/// When this bit is set on a dylib, the static linker does not need to examine dependent dylibs to see if any are re-exported -pub const MH_NO_REEXPORTED_DYLIBS: u32 = 0x10_0000; -/// When this bit is set, the OS will load the main executable at a random address.  Only used in MH_EXECUTE filetypes. -pub const MH_PIE: u32 = 0x20_0000; -/// Only for use on dylibs.  When linking against a dylib that has this bit set, the static linker will automatically not create a LC_LOAD_DYLIB load command to the dylib if no symbols are being referenced from the dylib. -pub const MH_DEAD_STRIPPABLE_DYLIB: u32 = 0x40_0000; -/// Contains a section of type S_THREAD_LOCAL_VARIABLES -pub const MH_HAS_TLV_DESCRIPTORS: u32 = 0x80_0000; -/// When this bit is set, the OS will run the main executable with a non-executable heap even on platforms (e.g. i386) that don't require it. Only used in MH_EXECUTE filetypes. -pub const MH_NO_HEAP_EXECUTION: u32 = 0x100_0000; -/// The code was linked for use in an application extension. -pub const MH_APP_EXTENSION_SAFE: u32 = 0x0200_0000; -/// The external symbols listed in the nlist symbol table do not include all the symbols listed in the dyld info. -pub const MH_NLIST_OUTOFSYNC_WITH_DYLDINFO: u32 = 0x0400_0000; -/// Allow LC_MIN_VERSION_MACOS and LC_BUILD_VERSION load commands with -/// the platforms macOS, iOSMac, iOSSimulator, tvOSSimulator and watchOSSimulator. -pub const MH_SIM_SUPPORT: u32 = 0x0800_0000; -/// Only for use on dylibs. When this bit is set, the dylib is part of the dyld -/// shared cache, rather than loose in the filesystem. -pub const MH_DYLIB_IN_CACHE: u32 = 0x8000_0000; - -/// Common fields at the start of every load command. -/// -/// The load commands directly follow the mach_header.  The total size of all -/// of the commands is given by the sizeofcmds field in the mach_header.  All -/// load commands must have as their first two fields `cmd` and `cmdsize`.  The `cmd` -/// field is filled in with a constant for that command type.  Each command type -/// has a structure specifically for it.  The `cmdsize` field is the size in bytes -/// of the particular load command structure plus anything that follows it that -/// is a part of the load command (i.e. section structures, strings, etc.).  To -/// advance to the next load command the `cmdsize` can be added to the offset or -/// pointer of the current load command.  The `cmdsize` for 32-bit architectures -/// MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple -/// of 8 bytes (these are forever the maximum alignment of any load commands). -/// The padded bytes must be zero.  All tables in the object file must also -/// follow these rules so the file can be memory mapped.  Otherwise the pointers -/// to these tables will not work well or at all on some machines.  With all -/// padding zeroed like objects will compare byte for byte. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct LoadCommand<E: Endian> { -    /// Type of load command. -    /// -    /// One of the `LC_*` constants. -    pub cmd: U32<E>, -    /// Total size of command in bytes. -    pub cmdsize: U32<E>, -} - -/* - * After MacOS X 10.1 when a new load command is added that is required to be - * understood by the dynamic linker for the image to execute properly the - * LC_REQ_DYLD bit will be or'ed into the load command constant.  If the dynamic - * linker sees such a load command it it does not understand will issue a - * "unknown load command required for execution" error and refuse to use the - * image.  Other load commands without this bit that are not understood will - * simply be ignored. - */ -pub const LC_REQ_DYLD: u32 = 0x8000_0000; - -/* Constants for the cmd field of all load commands, the type */ -/// segment of this file to be mapped -pub const LC_SEGMENT: u32 = 0x1; -/// link-edit stab symbol table info -pub const LC_SYMTAB: u32 = 0x2; -/// link-edit gdb symbol table info (obsolete) -pub const LC_SYMSEG: u32 = 0x3; -/// thread -pub const LC_THREAD: u32 = 0x4; -/// unix thread (includes a stack) -pub const LC_UNIXTHREAD: u32 = 0x5; -/// load a specified fixed VM shared library -pub const LC_LOADFVMLIB: u32 = 0x6; -/// fixed VM shared library identification -pub const LC_IDFVMLIB: u32 = 0x7; -/// object identification info (obsolete) -pub const LC_IDENT: u32 = 0x8; -/// fixed VM file inclusion (internal use) -pub const LC_FVMFILE: u32 = 0x9; -/// prepage command (internal use) -pub const LC_PREPAGE: u32 = 0xa; -/// dynamic link-edit symbol table info -pub const LC_DYSYMTAB: u32 = 0xb; -/// load a dynamically linked shared library -pub const LC_LOAD_DYLIB: u32 = 0xc; -/// dynamically linked shared lib ident -pub const LC_ID_DYLIB: u32 = 0xd; -/// load a dynamic linker -pub const LC_LOAD_DYLINKER: u32 = 0xe; -/// dynamic linker identification -pub const LC_ID_DYLINKER: u32 = 0xf; -/// modules prebound for a dynamically linked shared library -pub const LC_PREBOUND_DYLIB: u32 = 0x10; -/// image routines -pub const LC_ROUTINES: u32 = 0x11; -/// sub framework -pub const LC_SUB_FRAMEWORK: u32 = 0x12; -/// sub umbrella -pub const LC_SUB_UMBRELLA: u32 = 0x13; -/// sub client -pub const LC_SUB_CLIENT: u32 = 0x14; -/// sub library -pub const LC_SUB_LIBRARY: u32 = 0x15; -/// two-level namespace lookup hints -pub const LC_TWOLEVEL_HINTS: u32 = 0x16; -/// prebind checksum -pub const LC_PREBIND_CKSUM: u32 = 0x17; -/// load a dynamically linked shared library that is allowed to be missing -/// (all symbols are weak imported). -pub const LC_LOAD_WEAK_DYLIB: u32 = 0x18 | LC_REQ_DYLD; -/// 64-bit segment of this file to be mapped -pub const LC_SEGMENT_64: u32 = 0x19; -/// 64-bit image routines -pub const LC_ROUTINES_64: u32 = 0x1a; -/// the uuid -pub const LC_UUID: u32 = 0x1b; -/// runpath additions -pub const LC_RPATH: u32 = 0x1c | LC_REQ_DYLD; -/// local of code signature -pub const LC_CODE_SIGNATURE: u32 = 0x1d; -/// local of info to split segments -pub const LC_SEGMENT_SPLIT_INFO: u32 = 0x1e; -/// load and re-export dylib -pub const LC_REEXPORT_DYLIB: u32 = 0x1f | LC_REQ_DYLD; -/// delay load of dylib until first use -pub const LC_LAZY_LOAD_DYLIB: u32 = 0x20; -/// encrypted segment information -pub const LC_ENCRYPTION_INFO: u32 = 0x21; -/// compressed dyld information -pub const LC_DYLD_INFO: u32 = 0x22; -/// compressed dyld information only -pub const LC_DYLD_INFO_ONLY: u32 = 0x22 | LC_REQ_DYLD; -/// load upward dylib -pub const LC_LOAD_UPWARD_DYLIB: u32 = 0x23 | LC_REQ_DYLD; -/// build for MacOSX min OS version -pub const LC_VERSION_MIN_MACOSX: u32 = 0x24; -/// build for iPhoneOS min OS version -pub const LC_VERSION_MIN_IPHONEOS: u32 = 0x25; -/// compressed table of function start addresses -pub const LC_FUNCTION_STARTS: u32 = 0x26; -/// string for dyld to treat like environment variable -pub const LC_DYLD_ENVIRONMENT: u32 = 0x27; -/// replacement for LC_UNIXTHREAD -pub const LC_MAIN: u32 = 0x28 | LC_REQ_DYLD; -/// table of non-instructions in __text -pub const LC_DATA_IN_CODE: u32 = 0x29; -/// source version used to build binary -pub const LC_SOURCE_VERSION: u32 = 0x2A; -/// Code signing DRs copied from linked dylibs -pub const LC_DYLIB_CODE_SIGN_DRS: u32 = 0x2B; -/// 64-bit encrypted segment information -pub const LC_ENCRYPTION_INFO_64: u32 = 0x2C; -/// linker options in MH_OBJECT files -pub const LC_LINKER_OPTION: u32 = 0x2D; -/// optimization hints in MH_OBJECT files -pub const LC_LINKER_OPTIMIZATION_HINT: u32 = 0x2E; -/// build for AppleTV min OS version -pub const LC_VERSION_MIN_TVOS: u32 = 0x2F; -/// build for Watch min OS version -pub const LC_VERSION_MIN_WATCHOS: u32 = 0x30; -/// arbitrary data included within a Mach-O file -pub const LC_NOTE: u32 = 0x31; -/// build for platform min OS version -pub const LC_BUILD_VERSION: u32 = 0x32; -/// used with `LinkeditDataCommand`, payload is trie -pub const LC_DYLD_EXPORTS_TRIE: u32 = 0x33 | LC_REQ_DYLD; -/// used with `LinkeditDataCommand` -pub const LC_DYLD_CHAINED_FIXUPS: u32 = 0x34 | LC_REQ_DYLD; -/// used with `FilesetEntryCommand` -pub const LC_FILESET_ENTRY: u32 = 0x35 | LC_REQ_DYLD; - -/// A variable length string in a load command. -/// -/// The strings are stored just after the load command structure and -/// the offset is from the start of the load command structure.  The size -/// of the string is reflected in the `cmdsize` field of the load command. -/// Once again any padded bytes to bring the `cmdsize` field to a multiple -/// of 4 bytes must be zero. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct LcStr<E: Endian> { -    /// offset to the string -    pub offset: U32<E>, -} - -/// 32-bit segment load command. -/// -/// The segment load command indicates that a part of this file is to be -/// mapped into the task's address space.  The size of this segment in memory, -/// vmsize, maybe equal to or larger than the amount to map from this file, -/// filesize.  The file is mapped starting at fileoff to the beginning of -/// the segment in memory, vmaddr.  The rest of the memory of the segment, -/// if any, is allocated zero fill on demand.  The segment's maximum virtual -/// memory protection and initial virtual memory protection are specified -/// by the maxprot and initprot fields.  If the segment has sections then the -/// `Section32` structures directly follow the segment command and their size is -/// reflected in `cmdsize`. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SegmentCommand32<E: Endian> { -    /// LC_SEGMENT -    pub cmd: U32<E>, -    /// includes sizeof section structs -    pub cmdsize: U32<E>, -    /// segment name -    pub segname: [u8; 16], -    /// memory address of this segment -    pub vmaddr: U32<E>, -    /// memory size of this segment -    pub vmsize: U32<E>, -    /// file offset of this segment -    pub fileoff: U32<E>, -    /// amount to map from the file -    pub filesize: U32<E>, -    /// maximum VM protection -    pub maxprot: U32<E>, -    /// initial VM protection -    pub initprot: U32<E>, -    /// number of sections in segment -    pub nsects: U32<E>, -    /// flags -    pub flags: U32<E>, -} - -/// 64-bit segment load command. -/// -/// The 64-bit segment load command indicates that a part of this file is to be -/// mapped into a 64-bit task's address space.  If the 64-bit segment has -/// sections then `Section64` structures directly follow the 64-bit segment -/// command and their size is reflected in `cmdsize`. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SegmentCommand64<E: Endian> { -    /// LC_SEGMENT_64 -    pub cmd: U32<E>, -    /// includes sizeof section_64 structs -    pub cmdsize: U32<E>, -    /// segment name -    pub segname: [u8; 16], -    /// memory address of this segment -    pub vmaddr: U64<E>, -    /// memory size of this segment -    pub vmsize: U64<E>, -    /// file offset of this segment -    pub fileoff: U64<E>, -    /// amount to map from the file -    pub filesize: U64<E>, -    /// maximum VM protection -    pub maxprot: U32<E>, -    /// initial VM protection -    pub initprot: U32<E>, -    /// number of sections in segment -    pub nsects: U32<E>, -    /// flags -    pub flags: U32<E>, -} - -// Values for `SegmentCommand*::flags`. -/// the file contents for this segment is for the high part of the VM space, the low part is zero filled (for stacks in core files) -pub const SG_HIGHVM: u32 = 0x1; -/// this segment is the VM that is allocated by a fixed VM library, for overlap checking in the link editor -pub const SG_FVMLIB: u32 = 0x2; -/// this segment has nothing that was relocated in it and nothing relocated to it, that is it maybe safely replaced without relocation -pub const SG_NORELOC: u32 = 0x4; -/// This segment is protected.  If the segment starts at file offset 0, the first page of the segment is not protected.  All other pages of the segment are protected. -pub const SG_PROTECTED_VERSION_1: u32 = 0x8; -/// This segment is made read-only after fixups -pub const SG_READ_ONLY: u32 = 0x10; - -/* - * A segment is made up of zero or more sections.  Non-MH_OBJECT files have - * all of their segments with the proper sections in each, and padded to the - * specified segment alignment when produced by the link editor.  The first - * segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header - * and load commands of the object file before its first section.  The zero - * fill sections are always last in their segment (in all formats).  This - * allows the zeroed segment padding to be mapped into memory where zero fill - * sections might be. The gigabyte zero fill sections, those with the section - * type S_GB_ZEROFILL, can only be in a segment with sections of this type. - * These segments are then placed after all other segments. - * - * The MH_OBJECT format has all of its sections in one segment for - * compactness.  There is no padding to a specified segment boundary and the - * mach_header and load commands are not part of the segment. - * - * Sections with the same section name, sectname, going into the same segment, - * segname, are combined by the link editor.  The resulting section is aligned - * to the maximum alignment of the combined sections and is the new section's - * alignment.  The combined sections are aligned to their original alignment in - * the combined section.  Any padded bytes to get the specified alignment are - * zeroed. - * - * The format of the relocation entries referenced by the reloff and nreloc - * fields of the section structure for mach object files is described in the - * header file <reloc.h>. - */ -/// 32-bit section. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Section32<E: Endian> { -    /// name of this section -    pub sectname: [u8; 16], -    /// segment this section goes in -    pub segname: [u8; 16], -    /// memory address of this section -    pub addr: U32<E>, -    /// size in bytes of this section -    pub size: U32<E>, -    /// file offset of this section -    pub offset: U32<E>, -    /// section alignment (power of 2) -    pub align: U32<E>, -    /// file offset of relocation entries -    pub reloff: U32<E>, -    /// number of relocation entries -    pub nreloc: U32<E>, -    /// flags (section type and attributes) -    pub flags: U32<E>, -    /// reserved (for offset or index) -    pub reserved1: U32<E>, -    /// reserved (for count or sizeof) -    pub reserved2: U32<E>, -} - -/// 64-bit section. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Section64<E: Endian> { -    /// name of this section -    pub sectname: [u8; 16], -    /// segment this section goes in -    pub segname: [u8; 16], -    /// memory address of this section -    pub addr: U64<E>, -    /// size in bytes of this section -    pub size: U64<E>, -    /// file offset of this section -    pub offset: U32<E>, -    /// section alignment (power of 2) -    pub align: U32<E>, -    /// file offset of relocation entries -    pub reloff: U32<E>, -    /// number of relocation entries -    pub nreloc: U32<E>, -    /// flags (section type and attributes) -    pub flags: U32<E>, -    /// reserved (for offset or index) -    pub reserved1: U32<E>, -    /// reserved (for count or sizeof) -    pub reserved2: U32<E>, -    /// reserved -    pub reserved3: U32<E>, -} - -/* - * The flags field of a section structure is separated into two parts a section - * type and section attributes.  The section types are mutually exclusive (it - * can only have one type) but the section attributes are not (it may have more - * than one attribute). - */ -/// 256 section types -pub const SECTION_TYPE: u32 = 0x0000_00ff; -/// 24 section attributes -pub const SECTION_ATTRIBUTES: u32 = 0xffff_ff00; - -/* Constants for the type of a section */ -/// regular section -pub const S_REGULAR: u32 = 0x0; -/// zero fill on demand section -pub const S_ZEROFILL: u32 = 0x1; -/// section with only literal C strings -pub const S_CSTRING_LITERALS: u32 = 0x2; -/// section with only 4 byte literals -pub const S_4BYTE_LITERALS: u32 = 0x3; -/// section with only 8 byte literals -pub const S_8BYTE_LITERALS: u32 = 0x4; -/// section with only pointers to literals -pub const S_LITERAL_POINTERS: u32 = 0x5; -/* - * For the two types of symbol pointers sections and the symbol stubs section - * they have indirect symbol table entries.  For each of the entries in the - * section the indirect symbol table entries, in corresponding order in the - * indirect symbol table, start at the index stored in the reserved1 field - * of the section structure.  Since the indirect symbol table entries - * correspond to the entries in the section the number of indirect symbol table - * entries is inferred from the size of the section divided by the size of the - * entries in the section.  For symbol pointers sections the size of the entries - * in the section is 4 bytes and for symbol stubs sections the byte size of the - * stubs is stored in the reserved2 field of the section structure. - */ -/// section with only non-lazy symbol pointers -pub const S_NON_LAZY_SYMBOL_POINTERS: u32 = 0x6; -/// section with only lazy symbol pointers -pub const S_LAZY_SYMBOL_POINTERS: u32 = 0x7; -/// section with only symbol stubs, byte size of stub in the reserved2 field -pub const S_SYMBOL_STUBS: u32 = 0x8; -/// section with only function pointers for initialization -pub const S_MOD_INIT_FUNC_POINTERS: u32 = 0x9; -/// section with only function pointers for termination -pub const S_MOD_TERM_FUNC_POINTERS: u32 = 0xa; -/// section contains symbols that are to be coalesced -pub const S_COALESCED: u32 = 0xb; -/// zero fill on demand section (that can be larger than 4 gigabytes) -pub const S_GB_ZEROFILL: u32 = 0xc; -/// section with only pairs of function pointers for interposing -pub const S_INTERPOSING: u32 = 0xd; -/// section with only 16 byte literals -pub const S_16BYTE_LITERALS: u32 = 0xe; -/// section contains DTrace Object Format -pub const S_DTRACE_DOF: u32 = 0xf; -/// section with only lazy symbol pointers to lazy loaded dylibs -pub const S_LAZY_DYLIB_SYMBOL_POINTERS: u32 = 0x10; -/* - * Section types to support thread local variables - */ -/// template of initial values for TLVs -pub const S_THREAD_LOCAL_REGULAR: u32 = 0x11; -/// template of initial values for TLVs -pub const S_THREAD_LOCAL_ZEROFILL: u32 = 0x12; -/// TLV descriptors -pub const S_THREAD_LOCAL_VARIABLES: u32 = 0x13; -/// pointers to TLV descriptors -pub const S_THREAD_LOCAL_VARIABLE_POINTERS: u32 = 0x14; -/// functions to call to initialize TLV values -pub const S_THREAD_LOCAL_INIT_FUNCTION_POINTERS: u32 = 0x15; -/// 32-bit offsets to initializers -pub const S_INIT_FUNC_OFFSETS: u32 = 0x16; - -/* - * Constants for the section attributes part of the flags field of a section - * structure. - */ -/// User setable attributes -pub const SECTION_ATTRIBUTES_USR: u32 = 0xff00_0000; -/// section contains only true machine instructions -pub const S_ATTR_PURE_INSTRUCTIONS: u32 = 0x8000_0000; -/// section contains coalesced symbols that are not to be in a ranlib table of contents -pub const S_ATTR_NO_TOC: u32 = 0x4000_0000; -/// ok to strip static symbols in this section in files with the MH_DYLDLINK flag -pub const S_ATTR_STRIP_STATIC_SYMS: u32 = 0x2000_0000; -/// no dead stripping -pub const S_ATTR_NO_DEAD_STRIP: u32 = 0x1000_0000; -/// blocks are live if they reference live blocks -pub const S_ATTR_LIVE_SUPPORT: u32 = 0x0800_0000; -/// Used with i386 code stubs written on by dyld -pub const S_ATTR_SELF_MODIFYING_CODE: u32 = 0x0400_0000; -/* - * If a segment contains any sections marked with S_ATTR_DEBUG then all - * sections in that segment must have this attribute.  No section other than - * a section marked with this attribute may reference the contents of this - * section.  A section with this attribute may contain no symbols and must have - * a section type S_REGULAR.  The static linker will not copy section contents - * from sections with this attribute into its output file.  These sections - * generally contain DWARF debugging info. - */ -/// a debug section -pub const S_ATTR_DEBUG: u32 = 0x0200_0000; -/// system setable attributes -pub const SECTION_ATTRIBUTES_SYS: u32 = 0x00ff_ff00; -/// section contains some machine instructions -pub const S_ATTR_SOME_INSTRUCTIONS: u32 = 0x0000_0400; -/// section has external relocation entries -pub const S_ATTR_EXT_RELOC: u32 = 0x0000_0200; -/// section has local relocation entries -pub const S_ATTR_LOC_RELOC: u32 = 0x0000_0100; - -/* - * The names of segments and sections in them are mostly meaningless to the - * link-editor.  But there are few things to support traditional UNIX - * executables that require the link-editor and assembler to use some names - * agreed upon by convention. - * - * The initial protection of the "__TEXT" segment has write protection turned - * off (not writeable). - * - * The link-editor will allocate common symbols at the end of the "__common" - * section in the "__DATA" segment.  It will create the section and segment - * if needed. - */ - -/* The currently known segment names and the section names in those segments */ - -/// the pagezero segment which has no protections and catches NULL references for MH_EXECUTE files -pub const SEG_PAGEZERO: &str = "__PAGEZERO"; - -/// the tradition UNIX text segment -pub const SEG_TEXT: &str = "__TEXT"; -/// the real text part of the text section no headers, and no padding -pub const SECT_TEXT: &str = "__text"; -/// the fvmlib initialization section -pub const SECT_FVMLIB_INIT0: &str = "__fvmlib_init0"; -/// the section following the fvmlib initialization section -pub const SECT_FVMLIB_INIT1: &str = "__fvmlib_init1"; - -/// the tradition UNIX data segment -pub const SEG_DATA: &str = "__DATA"; -/// the real initialized data section no padding, no bss overlap -pub const SECT_DATA: &str = "__data"; -/// the real uninitialized data section no padding -pub const SECT_BSS: &str = "__bss"; -/// the section common symbols are allocated in by the link editor -pub const SECT_COMMON: &str = "__common"; - -/// objective-C runtime segment -pub const SEG_OBJC: &str = "__OBJC"; -/// symbol table -pub const SECT_OBJC_SYMBOLS: &str = "__symbol_table"; -/// module information -pub const SECT_OBJC_MODULES: &str = "__module_info"; -/// string table -pub const SECT_OBJC_STRINGS: &str = "__selector_strs"; -/// string table -pub const SECT_OBJC_REFS: &str = "__selector_refs"; - -/// the icon segment -pub const SEG_ICON: &str = "__ICON"; -/// the icon headers -pub const SECT_ICON_HEADER: &str = "__header"; -/// the icons in tiff format -pub const SECT_ICON_TIFF: &str = "__tiff"; - -/// the segment containing all structs created and maintained by the link editor.  Created with -seglinkedit option to ld(1) for MH_EXECUTE and FVMLIB file types only -pub const SEG_LINKEDIT: &str = "__LINKEDIT"; - -/// the segment overlapping with linkedit containing linking information -pub const SEG_LINKINFO: &str = "__LINKINFO"; - -/// the unix stack segment -pub const SEG_UNIXSTACK: &str = "__UNIXSTACK"; - -/// the segment for the self (dyld) modifying code stubs that has read, write and execute permissions -pub const SEG_IMPORT: &str = "__IMPORT"; - -/* - * Fixed virtual memory shared libraries are identified by two things.  The - * target pathname (the name of the library as found for execution), and the - * minor version number.  The address of where the headers are loaded is in - * header_addr. (THIS IS OBSOLETE and no longer supported). - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Fvmlib<E: Endian> { -    /// library's target pathname -    pub name: LcStr<E>, -    /// library's minor version number -    pub minor_version: U32<E>, -    /// library's header address -    pub header_addr: U32<E>, -} - -/* - * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header) - * contains a `FvmlibCommand` (cmd == LC_IDFVMLIB) to identify the library. - * An object that uses a fixed virtual shared library also contains a - * `FvmlibCommand` (cmd == LC_LOADFVMLIB) for each library it uses. - * (THIS IS OBSOLETE and no longer supported). - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FvmlibCommand<E: Endian> { -    /// LC_IDFVMLIB or LC_LOADFVMLIB -    pub cmd: U32<E>, -    /// includes pathname string -    pub cmdsize: U32<E>, -    /// the library identification -    pub fvmlib: Fvmlib<E>, -} - -/* - * Dynamically linked shared libraries are identified by two things.  The - * pathname (the name of the library as found for execution), and the - * compatibility version number.  The pathname must match and the compatibility - * number in the user of the library must be greater than or equal to the - * library being used.  The time stamp is used to record the time a library was - * built and copied into user so it can be use to determined if the library used - * at runtime is exactly the same as used to built the program. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Dylib<E: Endian> { -    /// library's path name -    pub name: LcStr<E>, -    /// library's build time stamp -    pub timestamp: U32<E>, -    /// library's current version number -    pub current_version: U32<E>, -    /// library's compatibility vers number -    pub compatibility_version: U32<E>, -} - -/* - * A dynamically linked shared library (filetype == MH_DYLIB in the mach header) - * contains a `DylibCommand` (cmd == LC_ID_DYLIB) to identify the library. - * An object that uses a dynamically linked shared library also contains a - * `DylibCommand` (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or - * LC_REEXPORT_DYLIB) for each library it uses. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DylibCommand<E: Endian> { -    /// LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, LC_REEXPORT_DYLIB -    pub cmd: U32<E>, -    /// includes pathname string -    pub cmdsize: U32<E>, -    /// the library identification -    pub dylib: Dylib<E>, -} - -/* - * A dynamically linked shared library may be a subframework of an umbrella - * framework.  If so it will be linked with "-umbrella umbrella_name" where - * Where "umbrella_name" is the name of the umbrella framework. A subframework - * can only be linked against by its umbrella framework or other subframeworks - * that are part of the same umbrella framework.  Otherwise the static link - * editor produces an error and states to link against the umbrella framework. - * The name of the umbrella framework for subframeworks is recorded in the - * following structure. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SubFrameworkCommand<E: Endian> { -    /// LC_SUB_FRAMEWORK -    pub cmd: U32<E>, -    /// includes umbrella string -    pub cmdsize: U32<E>, -    /// the umbrella framework name -    pub umbrella: LcStr<E>, -} - -/* - * For dynamically linked shared libraries that are subframework of an umbrella - * framework they can allow clients other than the umbrella framework or other - * subframeworks in the same umbrella framework.  To do this the subframework - * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load - * command is created for each -allowable_client flag.  The client_name is - * usually a framework name.  It can also be a name used for bundles clients - * where the bundle is built with "-client_name client_name". - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SubClientCommand<E: Endian> { -    /// LC_SUB_CLIENT -    pub cmd: U32<E>, -    /// includes client string -    pub cmdsize: U32<E>, -    /// the client name -    pub client: LcStr<E>, -} - -/* - * A dynamically linked shared library may be a sub_umbrella of an umbrella - * framework.  If so it will be linked with "-sub_umbrella umbrella_name" where - * Where "umbrella_name" is the name of the sub_umbrella framework.  When - * statically linking when -twolevel_namespace is in effect a twolevel namespace - * umbrella framework will only cause its subframeworks and those frameworks - * listed as sub_umbrella frameworks to be implicited linked in.  Any other - * dependent dynamic libraries will not be linked it when -twolevel_namespace - * is in effect.  The primary library recorded by the static linker when - * resolving a symbol in these libraries will be the umbrella framework. - * Zero or more sub_umbrella frameworks may be use by an umbrella framework. - * The name of a sub_umbrella framework is recorded in the following structure. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SubUmbrellaCommand<E: Endian> { -    /// LC_SUB_UMBRELLA -    pub cmd: U32<E>, -    /// includes sub_umbrella string -    pub cmdsize: U32<E>, -    /// the sub_umbrella framework name -    pub sub_umbrella: LcStr<E>, -} - -/* - * A dynamically linked shared library may be a sub_library of another shared - * library.  If so it will be linked with "-sub_library library_name" where - * Where "library_name" is the name of the sub_library shared library.  When - * statically linking when -twolevel_namespace is in effect a twolevel namespace - * shared library will only cause its subframeworks and those frameworks - * listed as sub_umbrella frameworks and libraries listed as sub_libraries to - * be implicited linked in.  Any other dependent dynamic libraries will not be - * linked it when -twolevel_namespace is in effect.  The primary library - * recorded by the static linker when resolving a symbol in these libraries - * will be the umbrella framework (or dynamic library). Zero or more sub_library - * shared libraries may be use by an umbrella framework or (or dynamic library). - * The name of a sub_library framework is recorded in the following structure. - * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc". - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SubLibraryCommand<E: Endian> { -    /// LC_SUB_LIBRARY -    pub cmd: U32<E>, -    /// includes sub_library string -    pub cmdsize: U32<E>, -    /// the sub_library name -    pub sub_library: LcStr<E>, -} - -/* - * A program (filetype == MH_EXECUTE) that is - * prebound to its dynamic libraries has one of these for each library that - * the static linker used in prebinding.  It contains a bit vector for the - * modules in the library.  The bits indicate which modules are bound (1) and - * which are not (0) from the library.  The bit for module 0 is the low bit - * of the first byte.  So the bit for the Nth module is: - * (linked_modules[N/8] >> N%8) & 1 - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct PreboundDylibCommand<E: Endian> { -    /// LC_PREBOUND_DYLIB -    pub cmd: U32<E>, -    /// includes strings -    pub cmdsize: U32<E>, -    /// library's path name -    pub name: LcStr<E>, -    /// number of modules in library -    pub nmodules: U32<E>, -    /// bit vector of linked modules -    pub linked_modules: LcStr<E>, -} - -/* - * A program that uses a dynamic linker contains a `DylinkerCommand` to identify - * the name of the dynamic linker (LC_LOAD_DYLINKER).  And a dynamic linker - * contains a `DylinkerCommand` to identify the dynamic linker (LC_ID_DYLINKER). - * A file can have at most one of these. - * This struct is also used for the LC_DYLD_ENVIRONMENT load command and - * contains string for dyld to treat like environment variable. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DylinkerCommand<E: Endian> { -    /// LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT -    pub cmd: U32<E>, -    /// includes pathname string -    pub cmdsize: U32<E>, -    /// dynamic linker's path name -    pub name: LcStr<E>, -} - -/* - * Thread commands contain machine-specific data structures suitable for - * use in the thread state primitives.  The machine specific data structures - * follow the struct `ThreadCommand` as follows. - * Each flavor of machine specific data structure is preceded by an uint32_t - * constant for the flavor of that data structure, an uint32_t that is the - * count of uint32_t's of the size of the state data structure and then - * the state data structure follows.  This triple may be repeated for many - * flavors.  The constants for the flavors, counts and state data structure - * definitions are expected to be in the header file <machine/thread_status.h>. - * These machine specific data structures sizes must be multiples of - * 4 bytes.  The `cmdsize` reflects the total size of the `ThreadCommand` - * and all of the sizes of the constants for the flavors, counts and state - * data structures. - * - * For executable objects that are unix processes there will be one - * `ThreadCommand` (cmd == LC_UNIXTHREAD) created for it by the link-editor. - * This is the same as a LC_THREAD, except that a stack is automatically - * created (based on the shell's limit for the stack size).  Command arguments - * and environment variables are copied onto that stack. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ThreadCommand<E: Endian> { -    /// LC_THREAD or  LC_UNIXTHREAD -    pub cmd: U32<E>, -    /// total size of this command -    pub cmdsize: U32<E>, -    /* uint32_t flavor		   flavor of thread state */ -    /* uint32_t count		   count of uint32_t's in thread state */ -    /* struct XXX_thread_state state   thread state for this flavor */ -    /* ... */ -} - -/* - * The routines command contains the address of the dynamic shared library - * initialization routine and an index into the module table for the module - * that defines the routine.  Before any modules are used from the library the - * dynamic linker fully binds the module that defines the initialization routine - * and then calls it.  This gets called before any module initialization - * routines (used for C++ static constructors) in the library. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct RoutinesCommand32<E: Endian> { -    /* for 32-bit architectures */ -    /// LC_ROUTINES -    pub cmd: U32<E>, -    /// total size of this command -    pub cmdsize: U32<E>, -    /// address of initialization routine -    pub init_address: U32<E>, -    /// index into the module table that the init routine is defined in -    pub init_module: U32<E>, -    pub reserved1: U32<E>, -    pub reserved2: U32<E>, -    pub reserved3: U32<E>, -    pub reserved4: U32<E>, -    pub reserved5: U32<E>, -    pub reserved6: U32<E>, -} - -/* - * The 64-bit routines command.  Same use as above. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct RoutinesCommand64<E: Endian> { -    /* for 64-bit architectures */ -    /// LC_ROUTINES_64 -    pub cmd: U32<E>, -    /// total size of this command -    pub cmdsize: U32<E>, -    /// address of initialization routine -    pub init_address: U64<E>, -    /// index into the module table that the init routine is defined in -    pub init_module: U64<E>, -    pub reserved1: U64<E>, -    pub reserved2: U64<E>, -    pub reserved3: U64<E>, -    pub reserved4: U64<E>, -    pub reserved5: U64<E>, -    pub reserved6: U64<E>, -} - -/* - * The `SymtabCommand` contains the offsets and sizes of the link-edit 4.3BSD - * "stab" style symbol table information as described in the header files - * <nlist.h> and <stab.h>. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SymtabCommand<E: Endian> { -    /// LC_SYMTAB -    pub cmd: U32<E>, -    /// sizeof(struct SymtabCommand) -    pub cmdsize: U32<E>, -    /// symbol table offset -    pub symoff: U32<E>, -    /// number of symbol table entries -    pub nsyms: U32<E>, -    /// string table offset -    pub stroff: U32<E>, -    /// string table size in bytes -    pub strsize: U32<E>, -} - -/* - * This is the second set of the symbolic information which is used to support - * the data structures for the dynamically link editor. - * - * The original set of symbolic information in the `SymtabCommand` which contains - * the symbol and string tables must also be present when this load command is - * present.  When this load command is present the symbol table is organized - * into three groups of symbols: - *	local symbols (static and debugging symbols) - grouped by module - *	defined external symbols - grouped by module (sorted by name if not lib) - *	undefined external symbols (sorted by name if MH_BINDATLOAD is not set, - *	     			    and in order the were seen by the static - *				    linker if MH_BINDATLOAD is set) - * In this load command there are offsets and counts to each of the three groups - * of symbols. - * - * This load command contains a the offsets and sizes of the following new - * symbolic information tables: - *	table of contents - *	module table - *	reference symbol table - *	indirect symbol table - * The first three tables above (the table of contents, module table and - * reference symbol table) are only present if the file is a dynamically linked - * shared library.  For executable and object modules, which are files - * containing only one module, the information that would be in these three - * tables is determined as follows: - * 	table of contents - the defined external symbols are sorted by name - *	module table - the file contains only one module so everything in the - *		       file is part of the module. - *	reference symbol table - is the defined and undefined external symbols - * - * For dynamically linked shared library files this load command also contains - * offsets and sizes to the pool of relocation entries for all sections - * separated into two groups: - *	external relocation entries - *	local relocation entries - * For executable and object modules the relocation entries continue to hang - * off the section structures. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DysymtabCommand<E: Endian> { -    /// LC_DYSYMTAB -    pub cmd: U32<E>, -    /// sizeof(struct DysymtabCommand) -    pub cmdsize: U32<E>, - -    /* -     * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command -     * are grouped into the following three groups: -     *    local symbols (further grouped by the module they are from) -     *    defined external symbols (further grouped by the module they are from) -     *    undefined symbols -     * -     * The local symbols are used only for debugging.  The dynamic binding -     * process may have to use them to indicate to the debugger the local -     * symbols for a module that is being bound. -     * -     * The last two groups are used by the dynamic binding process to do the -     * binding (indirectly through the module table and the reference symbol -     * table when this is a dynamically linked shared library file). -     */ -    /// index to local symbols -    pub ilocalsym: U32<E>, -    /// number of local symbols -    pub nlocalsym: U32<E>, - -    /// index to externally defined symbols -    pub iextdefsym: U32<E>, -    /// number of externally defined symbols -    pub nextdefsym: U32<E>, - -    /// index to undefined symbols -    pub iundefsym: U32<E>, -    /// number of undefined symbols -    pub nundefsym: U32<E>, - -    /* -     * For the for the dynamic binding process to find which module a symbol -     * is defined in the table of contents is used (analogous to the ranlib -     * structure in an archive) which maps defined external symbols to modules -     * they are defined in.  This exists only in a dynamically linked shared -     * library file.  For executable and object modules the defined external -     * symbols are sorted by name and is use as the table of contents. -     */ -    /// file offset to table of contents -    pub tocoff: U32<E>, -    /// number of entries in table of contents -    pub ntoc: U32<E>, - -    /* -     * To support dynamic binding of "modules" (whole object files) the symbol -     * table must reflect the modules that the file was created from.  This is -     * done by having a module table that has indexes and counts into the merged -     * tables for each module.  The module structure that these two entries -     * refer to is described below.  This exists only in a dynamically linked -     * shared library file.  For executable and object modules the file only -     * contains one module so everything in the file belongs to the module. -     */ -    /// file offset to module table -    pub modtaboff: U32<E>, -    /// number of module table entries -    pub nmodtab: U32<E>, - -    /* -     * To support dynamic module binding the module structure for each module -     * indicates the external references (defined and undefined) each module -     * makes.  For each module there is an offset and a count into the -     * reference symbol table for the symbols that the module references. -     * This exists only in a dynamically linked shared library file.  For -     * executable and object modules the defined external symbols and the -     * undefined external symbols indicates the external references. -     */ -    /// offset to referenced symbol table -    pub extrefsymoff: U32<E>, -    /// number of referenced symbol table entries -    pub nextrefsyms: U32<E>, - -    /* -     * The sections that contain "symbol pointers" and "routine stubs" have -     * indexes and (implied counts based on the size of the section and fixed -     * size of the entry) into the "indirect symbol" table for each pointer -     * and stub.  For every section of these two types the index into the -     * indirect symbol table is stored in the section header in the field -     * reserved1.  An indirect symbol table entry is simply a 32bit index into -     * the symbol table to the symbol that the pointer or stub is referring to. -     * The indirect symbol table is ordered to match the entries in the section. -     */ -    /// file offset to the indirect symbol table -    pub indirectsymoff: U32<E>, -    /// number of indirect symbol table entries -    pub nindirectsyms: U32<E>, - -    /* -     * To support relocating an individual module in a library file quickly the -     * external relocation entries for each module in the library need to be -     * accessed efficiently.  Since the relocation entries can't be accessed -     * through the section headers for a library file they are separated into -     * groups of local and external entries further grouped by module.  In this -     * case the presents of this load command who's extreloff, nextrel, -     * locreloff and nlocrel fields are non-zero indicates that the relocation -     * entries of non-merged sections are not referenced through the section -     * structures (and the reloff and nreloc fields in the section headers are -     * set to zero). -     * -     * Since the relocation entries are not accessed through the section headers -     * this requires the r_address field to be something other than a section -     * offset to identify the item to be relocated.  In this case r_address is -     * set to the offset from the vmaddr of the first LC_SEGMENT command. -     * For MH_SPLIT_SEGS images r_address is set to the the offset from the -     * vmaddr of the first read-write LC_SEGMENT command. -     * -     * The relocation entries are grouped by module and the module table -     * entries have indexes and counts into them for the group of external -     * relocation entries for that the module. -     * -     * For sections that are merged across modules there must not be any -     * remaining external relocation entries for them (for merged sections -     * remaining relocation entries must be local). -     */ -    /// offset to external relocation entries -    pub extreloff: U32<E>, -    /// number of external relocation entries -    pub nextrel: U32<E>, - -    /* -     * All the local relocation entries are grouped together (they are not -     * grouped by their module since they are only used if the object is moved -     * from it statically link edited address). -     */ -    /// offset to local relocation entries -    pub locreloff: U32<E>, -    /// number of local relocation entries -    pub nlocrel: U32<E>, -} - -/* - * An indirect symbol table entry is simply a 32bit index into the symbol table - * to the symbol that the pointer or stub is referring to.  Unless it is for a - * non-lazy symbol pointer section for a defined symbol which strip(1) as - * removed.  In which case it has the value INDIRECT_SYMBOL_LOCAL.  If the - * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. - */ -pub const INDIRECT_SYMBOL_LOCAL: u32 = 0x8000_0000; -pub const INDIRECT_SYMBOL_ABS: u32 = 0x4000_0000; - -/* a table of contents entry */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DylibTableOfContents<E: Endian> { -    /// the defined external symbol (index into the symbol table) -    pub symbol_index: U32<E>, -    /// index into the module table this symbol is defined in -    pub module_index: U32<E>, -} - -/* a module table entry */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DylibModule32<E: Endian> { -    /// the module name (index into string table) -    pub module_name: U32<E>, - -    /// index into externally defined symbols -    pub iextdefsym: U32<E>, -    /// number of externally defined symbols -    pub nextdefsym: U32<E>, -    /// index into reference symbol table -    pub irefsym: U32<E>, -    /// number of reference symbol table entries -    pub nrefsym: U32<E>, -    /// index into symbols for local symbols -    pub ilocalsym: U32<E>, -    /// number of local symbols -    pub nlocalsym: U32<E>, - -    /// index into external relocation entries -    pub iextrel: U32<E>, -    /// number of external relocation entries -    pub nextrel: U32<E>, - -    /// low 16 bits are the index into the init section, high 16 bits are the index into the term section -    pub iinit_iterm: U32<E>, -    /// low 16 bits are the number of init section entries, high 16 bits are the number of term section entries -    pub ninit_nterm: U32<E>, - -    /// for this module address of the start of the (__OBJC,__module_info) section -    pub objc_module_info_addr: U32<E>, -    /// for this module size of the (__OBJC,__module_info) section -    pub objc_module_info_size: U32<E>, -} - -/* a 64-bit module table entry */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DylibModule64<E: Endian> { -    /// the module name (index into string table) -    pub module_name: U32<E>, - -    /// index into externally defined symbols -    pub iextdefsym: U32<E>, -    /// number of externally defined symbols -    pub nextdefsym: U32<E>, -    /// index into reference symbol table -    pub irefsym: U32<E>, -    /// number of reference symbol table entries -    pub nrefsym: U32<E>, -    /// index into symbols for local symbols -    pub ilocalsym: U32<E>, -    /// number of local symbols -    pub nlocalsym: U32<E>, - -    /// index into external relocation entries -    pub iextrel: U32<E>, -    /// number of external relocation entries -    pub nextrel: U32<E>, - -    /// low 16 bits are the index into the init section, high 16 bits are the index into the term section -    pub iinit_iterm: U32<E>, -    /// low 16 bits are the number of init section entries, high 16 bits are the number of term section entries -    pub ninit_nterm: U32<E>, - -    /// for this module size of the (__OBJC,__module_info) section -    pub objc_module_info_size: U32<E>, -    /// for this module address of the start of the (__OBJC,__module_info) section -    pub objc_module_info_addr: U64<E>, -} - -/* - * The entries in the reference symbol table are used when loading the module - * (both by the static and dynamic link editors) and if the module is unloaded - * or replaced.  Therefore all external symbols (defined and undefined) are - * listed in the module's reference table.  The flags describe the type of - * reference that is being made.  The constants for the flags are defined in - * <mach-o/nlist.h> as they are also used for symbol table entries. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DylibReference<E: Endian> { -    /* TODO: -    uint32_t isym:24,		/* index into the symbol table */ -              flags:8;	/* flags to indicate the type of reference */ -    */ -    pub bitfield: U32<E>, -} - -/* - * The TwolevelHintsCommand contains the offset and number of hints in the - * two-level namespace lookup hints table. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct TwolevelHintsCommand<E: Endian> { -    /// LC_TWOLEVEL_HINTS -    pub cmd: U32<E>, -    /// sizeof(struct TwolevelHintsCommand) -    pub cmdsize: U32<E>, -    /// offset to the hint table -    pub offset: U32<E>, -    /// number of hints in the hint table -    pub nhints: U32<E>, -} - -/* - * The entries in the two-level namespace lookup hints table are TwolevelHint - * structs.  These provide hints to the dynamic link editor where to start - * looking for an undefined symbol in a two-level namespace image.  The - * isub_image field is an index into the sub-images (sub-frameworks and - * sub-umbrellas list) that made up the two-level image that the undefined - * symbol was found in when it was built by the static link editor.  If - * isub-image is 0 the the symbol is expected to be defined in library and not - * in the sub-images.  If isub-image is non-zero it is an index into the array - * of sub-images for the umbrella with the first index in the sub-images being - * 1. The array of sub-images is the ordered list of sub-images of the umbrella - * that would be searched for a symbol that has the umbrella recorded as its - * primary library.  The table of contents index is an index into the - * library's table of contents.  This is used as the starting point of the - * binary search or a directed linear search. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct TwolevelHint<E: Endian> { -    /* TODO: -    uint32_t -    isub_image:8,	/* index into the sub images */ -    itoc:24;	/* index into the table of contents */ -    */ -    pub bitfield: U32<E>, -} - -/* - * The PrebindCksumCommand contains the value of the original check sum for - * prebound files or zero.  When a prebound file is first created or modified - * for other than updating its prebinding information the value of the check sum - * is set to zero.  When the file has it prebinding re-done and if the value of - * the check sum is zero the original check sum is calculated and stored in - * cksum field of this load command in the output file.  If when the prebinding - * is re-done and the cksum field is non-zero it is left unchanged from the - * input file. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct PrebindCksumCommand<E: Endian> { -    /// LC_PREBIND_CKSUM -    pub cmd: U32<E>, -    /// sizeof(struct PrebindCksumCommand) -    pub cmdsize: U32<E>, -    /// the check sum or zero -    pub cksum: U32<E>, -} - -/* - * The uuid load command contains a single 128-bit unique random number that - * identifies an object produced by the static link editor. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct UuidCommand<E: Endian> { -    /// LC_UUID -    pub cmd: U32<E>, -    /// sizeof(struct UuidCommand) -    pub cmdsize: U32<E>, -    /// the 128-bit uuid -    pub uuid: [u8; 16], -} - -/* - * The RpathCommand contains a path which at runtime should be added to - * the current run path used to find @rpath prefixed dylibs. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct RpathCommand<E: Endian> { -    /// LC_RPATH -    pub cmd: U32<E>, -    /// includes string -    pub cmdsize: U32<E>, -    /// path to add to run path -    pub path: LcStr<E>, -} - -/* - * The LinkeditDataCommand contains the offsets and sizes of a blob - * of data in the __LINKEDIT segment. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct LinkeditDataCommand<E: Endian> { -    /// `LC_CODE_SIGNATURE`, `LC_SEGMENT_SPLIT_INFO`, `LC_FUNCTION_STARTS`, -    /// `LC_DATA_IN_CODE`, `LC_DYLIB_CODE_SIGN_DRS`, `LC_LINKER_OPTIMIZATION_HINT`, -    /// `LC_DYLD_EXPORTS_TRIE`, or `LC_DYLD_CHAINED_FIXUPS`. -    pub cmd: U32<E>, -    /// sizeof(struct LinkeditDataCommand) -    pub cmdsize: U32<E>, -    /// file offset of data in __LINKEDIT segment -    pub dataoff: U32<E>, -    /// file size of data in __LINKEDIT segment -    pub datasize: U32<E>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FilesetEntryCommand<E: Endian> { -    // LC_FILESET_ENTRY -    pub cmd: U32<E>, -    /// includes id string -    pub cmdsize: U32<E>, -    /// memory address of the dylib -    pub vmaddr: U64<E>, -    /// file offset of the dylib -    pub fileoff: U64<E>, -    /// contained entry id -    pub entry_id: LcStr<E>, -    /// entry_id is 32-bits long, so this is the reserved padding -    pub reserved: U32<E>, -} - -/* - * The EncryptionInfoCommand32 contains the file offset and size of an - * of an encrypted segment. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct EncryptionInfoCommand32<E: Endian> { -    /// LC_ENCRYPTION_INFO -    pub cmd: U32<E>, -    /// sizeof(struct EncryptionInfoCommand32) -    pub cmdsize: U32<E>, -    /// file offset of encrypted range -    pub cryptoff: U32<E>, -    /// file size of encrypted range -    pub cryptsize: U32<E>, -    /// which enryption system, 0 means not-encrypted yet -    pub cryptid: U32<E>, -} - -/* - * The EncryptionInfoCommand64 contains the file offset and size of an - * of an encrypted segment (for use in x86_64 targets). - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct EncryptionInfoCommand64<E: Endian> { -    /// LC_ENCRYPTION_INFO_64 -    pub cmd: U32<E>, -    /// sizeof(struct EncryptionInfoCommand64) -    pub cmdsize: U32<E>, -    /// file offset of encrypted range -    pub cryptoff: U32<E>, -    /// file size of encrypted range -    pub cryptsize: U32<E>, -    /// which enryption system, 0 means not-encrypted yet -    pub cryptid: U32<E>, -    /// padding to make this struct's size a multiple of 8 bytes -    pub pad: U32<E>, -} - -/* - * The VersionMinCommand contains the min OS version on which this - * binary was built to run. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct VersionMinCommand<E: Endian> { -    /// LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS or LC_VERSION_MIN_WATCHOS or LC_VERSION_MIN_TVOS -    pub cmd: U32<E>, -    /// sizeof(struct VersionMinCommand) -    pub cmdsize: U32<E>, -    /// X.Y.Z is encoded in nibbles xxxx.yy.zz -    pub version: U32<E>, -    /// X.Y.Z is encoded in nibbles xxxx.yy.zz -    pub sdk: U32<E>, -} - -/* - * The BuildVersionCommand contains the min OS version on which this - * binary was built to run for its platform.  The list of known platforms and - * tool values following it. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct BuildVersionCommand<E: Endian> { -    /// LC_BUILD_VERSION -    pub cmd: U32<E>, -    /// sizeof(struct BuildVersionCommand) plus ntools * sizeof(struct BuildToolVersion) -    pub cmdsize: U32<E>, -    /// platform -    pub platform: U32<E>, -    /// X.Y.Z is encoded in nibbles xxxx.yy.zz -    pub minos: U32<E>, -    /// X.Y.Z is encoded in nibbles xxxx.yy.zz -    pub sdk: U32<E>, -    /// number of tool entries following this -    pub ntools: U32<E>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct BuildToolVersion<E: Endian> { -    /// enum for the tool -    pub tool: U32<E>, -    /// version number of the tool -    pub version: U32<E>, -} - -/* Known values for the platform field above. */ -pub const PLATFORM_MACOS: u32 = 1; -pub const PLATFORM_IOS: u32 = 2; -pub const PLATFORM_TVOS: u32 = 3; -pub const PLATFORM_WATCHOS: u32 = 4; -pub const PLATFORM_BRIDGEOS: u32 = 5; -pub const PLATFORM_MACCATALYST: u32 = 6; -pub const PLATFORM_IOSSIMULATOR: u32 = 7; -pub const PLATFORM_TVOSSIMULATOR: u32 = 8; -pub const PLATFORM_WATCHOSSIMULATOR: u32 = 9; -pub const PLATFORM_DRIVERKIT: u32 = 10; - -/* Known values for the tool field above. */ -pub const TOOL_CLANG: u32 = 1; -pub const TOOL_SWIFT: u32 = 2; -pub const TOOL_LD: u32 = 3; - -/* - * The DyldInfoCommand contains the file offsets and sizes of - * the new compressed form of the information dyld needs to - * load the image.  This information is used by dyld on Mac OS X - * 10.6 and later.  All information pointed to by this command - * is encoded using byte streams, so no endian swapping is needed - * to interpret it. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DyldInfoCommand<E: Endian> { -    /// LC_DYLD_INFO or LC_DYLD_INFO_ONLY -    pub cmd: U32<E>, -    /// sizeof(struct DyldInfoCommand) -    pub cmdsize: U32<E>, - -    /* -     * Dyld rebases an image whenever dyld loads it at an address different -     * from its preferred address.  The rebase information is a stream -     * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_. -     * Conceptually the rebase information is a table of tuples: -     *    <seg-index, seg-offset, type> -     * The opcodes are a compressed way to encode the table by only -     * encoding when a column changes.  In addition simple patterns -     * like "every n'th offset for m times" can be encoded in a few -     * bytes. -     */ -    /// file offset to rebase info -    pub rebase_off: U32<E>, -    /// size of rebase info -    pub rebase_size: U32<E>, - -    /* -     * Dyld binds an image during the loading process, if the image -     * requires any pointers to be initialized to symbols in other images. -     * The bind information is a stream of byte sized -     * opcodes whose symbolic names start with BIND_OPCODE_. -     * Conceptually the bind information is a table of tuples: -     *    <seg-index, seg-offset, type, symbol-library-ordinal, symbol-name, addend> -     * The opcodes are a compressed way to encode the table by only -     * encoding when a column changes.  In addition simple patterns -     * like for runs of pointers initialized to the same value can be -     * encoded in a few bytes. -     */ -    /// file offset to binding info -    pub bind_off: U32<E>, -    /// size of binding info -    pub bind_size: U32<E>, - -    /* -     * Some C++ programs require dyld to unique symbols so that all -     * images in the process use the same copy of some code/data. -     * This step is done after binding. The content of the weak_bind -     * info is an opcode stream like the bind_info.  But it is sorted -     * alphabetically by symbol name.  This enable dyld to walk -     * all images with weak binding information in order and look -     * for collisions.  If there are no collisions, dyld does -     * no updating.  That means that some fixups are also encoded -     * in the bind_info.  For instance, all calls to "operator new" -     * are first bound to libstdc++.dylib using the information -     * in bind_info.  Then if some image overrides operator new -     * that is detected when the weak_bind information is processed -     * and the call to operator new is then rebound. -     */ -    /// file offset to weak binding info -    pub weak_bind_off: U32<E>, -    /// size of weak binding info -    pub weak_bind_size: U32<E>, - -    /* -     * Some uses of external symbols do not need to be bound immediately. -     * Instead they can be lazily bound on first use.  The lazy_bind -     * are contains a stream of BIND opcodes to bind all lazy symbols. -     * Normal use is that dyld ignores the lazy_bind section when -     * loading an image.  Instead the static linker arranged for the -     * lazy pointer to initially point to a helper function which -     * pushes the offset into the lazy_bind area for the symbol -     * needing to be bound, then jumps to dyld which simply adds -     * the offset to lazy_bind_off to get the information on what -     * to bind. -     */ -    /// file offset to lazy binding info -    pub lazy_bind_off: U32<E>, -    /// size of lazy binding infs -    pub lazy_bind_size: U32<E>, - -    /* -     * The symbols exported by a dylib are encoded in a trie.  This -     * is a compact representation that factors out common prefixes. -     * It also reduces LINKEDIT pages in RAM because it encodes all -     * information (name, address, flags) in one small, contiguous range. -     * The export area is a stream of nodes.  The first node sequentially -     * is the start node for the trie. -     * -     * Nodes for a symbol start with a uleb128 that is the length of -     * the exported symbol information for the string so far. -     * If there is no exported symbol, the node starts with a zero byte. -     * If there is exported info, it follows the length. -     * -     * First is a uleb128 containing flags. Normally, it is followed by -     * a uleb128 encoded offset which is location of the content named -     * by the symbol from the mach_header for the image.  If the flags -     * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is -     * a uleb128 encoded library ordinal, then a zero terminated -     * UTF8 string.  If the string is zero length, then the symbol -     * is re-export from the specified dylib with the same name. -     * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following -     * the flags is two uleb128s: the stub offset and the resolver offset. -     * The stub is used by non-lazy pointers.  The resolver is used -     * by lazy pointers and must be called to get the actual address to use. -     * -     * After the optional exported symbol information is a byte of -     * how many edges (0-255) that this node has leaving it, -     * followed by each edge. -     * Each edge is a zero terminated UTF8 of the addition chars -     * in the symbol, followed by a uleb128 offset for the node that -     * edge points to. -     * -     */ -    /// file offset to lazy binding info -    pub export_off: U32<E>, -    /// size of lazy binding infs -    pub export_size: U32<E>, -} - -/* - * The following are used to encode rebasing information - */ -pub const REBASE_TYPE_POINTER: u8 = 1; -pub const REBASE_TYPE_TEXT_ABSOLUTE32: u8 = 2; -pub const REBASE_TYPE_TEXT_PCREL32: u8 = 3; - -pub const REBASE_OPCODE_MASK: u8 = 0xF0; -pub const REBASE_IMMEDIATE_MASK: u8 = 0x0F; -pub const REBASE_OPCODE_DONE: u8 = 0x00; -pub const REBASE_OPCODE_SET_TYPE_IMM: u8 = 0x10; -pub const REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: u8 = 0x20; -pub const REBASE_OPCODE_ADD_ADDR_ULEB: u8 = 0x30; -pub const REBASE_OPCODE_ADD_ADDR_IMM_SCALED: u8 = 0x40; -pub const REBASE_OPCODE_DO_REBASE_IMM_TIMES: u8 = 0x50; -pub const REBASE_OPCODE_DO_REBASE_ULEB_TIMES: u8 = 0x60; -pub const REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: u8 = 0x70; -pub const REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: u8 = 0x80; - -/* - * The following are used to encode binding information - */ -pub const BIND_TYPE_POINTER: u8 = 1; -pub const BIND_TYPE_TEXT_ABSOLUTE32: u8 = 2; -pub const BIND_TYPE_TEXT_PCREL32: u8 = 3; - -pub const BIND_SPECIAL_DYLIB_SELF: i8 = 0; -pub const BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE: i8 = -1; -pub const BIND_SPECIAL_DYLIB_FLAT_LOOKUP: i8 = -2; -pub const BIND_SPECIAL_DYLIB_WEAK_LOOKUP: i8 = -3; - -pub const BIND_SYMBOL_FLAGS_WEAK_IMPORT: u8 = 0x1; -pub const BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION: u8 = 0x8; - -pub const BIND_OPCODE_MASK: u8 = 0xF0; -pub const BIND_IMMEDIATE_MASK: u8 = 0x0F; -pub const BIND_OPCODE_DONE: u8 = 0x00; -pub const BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: u8 = 0x10; -pub const BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: u8 = 0x20; -pub const BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: u8 = 0x30; -pub const BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: u8 = 0x40; -pub const BIND_OPCODE_SET_TYPE_IMM: u8 = 0x50; -pub const BIND_OPCODE_SET_ADDEND_SLEB: u8 = 0x60; -pub const BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: u8 = 0x70; -pub const BIND_OPCODE_ADD_ADDR_ULEB: u8 = 0x80; -pub const BIND_OPCODE_DO_BIND: u8 = 0x90; -pub const BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: u8 = 0xA0; -pub const BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: u8 = 0xB0; -pub const BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: u8 = 0xC0; -pub const BIND_OPCODE_THREADED: u8 = 0xD0; -pub const BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB: u8 = 0x00; -pub const BIND_SUBOPCODE_THREADED_APPLY: u8 = 0x01; - -/* - * The following are used on the flags byte of a terminal node - * in the export information. - */ -pub const EXPORT_SYMBOL_FLAGS_KIND_MASK: u32 = 0x03; -pub const EXPORT_SYMBOL_FLAGS_KIND_REGULAR: u32 = 0x00; -pub const EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: u32 = 0x01; -pub const EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: u32 = 0x02; -pub const EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION: u32 = 0x04; -pub const EXPORT_SYMBOL_FLAGS_REEXPORT: u32 = 0x08; -pub const EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER: u32 = 0x10; - -/* - * The LinkerOptionCommand contains linker options embedded in object files. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct LinkerOptionCommand<E: Endian> { -    /// LC_LINKER_OPTION only used in MH_OBJECT filetypes -    pub cmd: U32<E>, -    pub cmdsize: U32<E>, -    /// number of strings -    pub count: U32<E>, -    /* concatenation of zero terminated UTF8 strings. -    Zero filled at end to align */ -} - -/* - * The SymsegCommand contains the offset and size of the GNU style - * symbol table information as described in the header file <symseg.h>. - * The symbol roots of the symbol segments must also be aligned properly - * in the file.  So the requirement of keeping the offsets aligned to a - * multiple of a 4 bytes translates to the length field of the symbol - * roots also being a multiple of a long.  Also the padding must again be - * zeroed. (THIS IS OBSOLETE and no longer supported). - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SymsegCommand<E: Endian> { -    /// LC_SYMSEG -    pub cmd: U32<E>, -    /// sizeof(struct SymsegCommand) -    pub cmdsize: U32<E>, -    /// symbol segment offset -    pub offset: U32<E>, -    /// symbol segment size in bytes -    pub size: U32<E>, -} - -/* - * The IdentCommand contains a free format string table following the - * IdentCommand structure.  The strings are null terminated and the size of - * the command is padded out with zero bytes to a multiple of 4 bytes/ - * (THIS IS OBSOLETE and no longer supported). - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct IdentCommand<E: Endian> { -    /// LC_IDENT -    pub cmd: U32<E>, -    /// strings that follow this command -    pub cmdsize: U32<E>, -} - -/* - * The FvmfileCommand contains a reference to a file to be loaded at the - * specified virtual address.  (Presently, this command is reserved for - * internal use.  The kernel ignores this command when loading a program into - * memory). - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FvmfileCommand<E: Endian> { -    /// LC_FVMFILE -    pub cmd: U32<E>, -    /// includes pathname string -    pub cmdsize: U32<E>, -    /// files pathname -    pub name: LcStr<E>, -    /// files virtual address -    pub header_addr: U32<E>, -} - -/* - * The EntryPointCommand is a replacement for thread_command. - * It is used for main executables to specify the location (file offset) - * of main().  If -stack_size was used at link time, the stacksize - * field will contain the stack size need for the main thread. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct EntryPointCommand<E: Endian> { -    /// LC_MAIN only used in MH_EXECUTE filetypes -    pub cmd: U32<E>, -    /// 24 -    pub cmdsize: U32<E>, -    /// file (__TEXT) offset of main() -    pub entryoff: U64<E>, -    /// if not zero, initial stack size -    pub stacksize: U64<E>, -} - -/* - * The SourceVersionCommand is an optional load command containing - * the version of the sources used to build the binary. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SourceVersionCommand<E: Endian> { -    /// LC_SOURCE_VERSION -    pub cmd: U32<E>, -    /// 16 -    pub cmdsize: U32<E>, -    /// A.B.C.D.E packed as a24.b10.c10.d10.e10 -    pub version: U64<E>, -} - -/* - * The LC_DATA_IN_CODE load commands uses a LinkeditDataCommand - * to point to an array of DataInCodeEntry entries. Each entry - * describes a range of data in a code section. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DataInCodeEntry<E: Endian> { -    /// from mach_header to start of data range -    pub offset: U32<E>, -    /// number of bytes in data range -    pub length: U16<E>, -    /// a DICE_KIND_* value -    pub kind: U16<E>, -} -pub const DICE_KIND_DATA: u32 = 0x0001; -pub const DICE_KIND_JUMP_TABLE8: u32 = 0x0002; -pub const DICE_KIND_JUMP_TABLE16: u32 = 0x0003; -pub const DICE_KIND_JUMP_TABLE32: u32 = 0x0004; -pub const DICE_KIND_ABS_JUMP_TABLE32: u32 = 0x0005; - -/* - * Sections of type S_THREAD_LOCAL_VARIABLES contain an array - * of TlvDescriptor structures. - */ -/* TODO: -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct TlvDescriptor<E: Endian> -{ -    void*		(*thunk)(struct TlvDescriptor*); -    unsigned long	key; -    unsigned long	offset; -} -*/ - -/* - * LC_NOTE commands describe a region of arbitrary data included in a Mach-O - * file.  Its initial use is to record extra data in MH_CORE files. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct NoteCommand<E: Endian> { -    /// LC_NOTE -    pub cmd: U32<E>, -    /// sizeof(struct NoteCommand) -    pub cmdsize: U32<E>, -    /// owner name for this LC_NOTE -    pub data_owner: [u8; 16], -    /// file offset of this data -    pub offset: U64<E>, -    /// length of data region -    pub size: U64<E>, -} - -// Definitions from "/usr/include/mach-o/nlist.h". - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Nlist32<E: Endian> { -    /// index into the string table -    pub n_strx: U32<E>, -    /// type flag, see below -    pub n_type: u8, -    /// section number or NO_SECT -    pub n_sect: u8, -    /// see <mach-o/stab.h> -    pub n_desc: U16<E>, -    /// value of this symbol (or stab offset) -    pub n_value: U32<E>, -} - -/* - * This is the symbol table entry structure for 64-bit architectures. - */ -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Nlist64<E: Endian> { -    /// index into the string table -    pub n_strx: U32<E>, -    /// type flag, see below -    pub n_type: u8, -    /// section number or NO_SECT -    pub n_sect: u8, -    /// see <mach-o/stab.h> -    pub n_desc: U16<E>, -    /// value of this symbol (or stab offset) -    // Note: 4 byte alignment has been observed in practice. -    pub n_value: U64Bytes<E>, -} - -/* - * Symbols with a index into the string table of zero (n_un.n_strx == 0) are - * defined to have a null, "", name.  Therefore all string indexes to non null - * names must not have a zero string index.  This is bit historical information - * that has never been well documented. - */ - -/* - * The n_type field really contains four fields: - *	unsigned char N_STAB:3, - *		      N_PEXT:1, - *		      N_TYPE:3, - *		      N_EXT:1; - * which are used via the following masks. - */ -/// if any of these bits set, a symbolic debugging entry -pub const N_STAB: u8 = 0xe0; -/// private external symbol bit -pub const N_PEXT: u8 = 0x10; -/// mask for the type bits -pub const N_TYPE: u8 = 0x0e; -/// external symbol bit, set for external symbols -pub const N_EXT: u8 = 0x01; - -/* - * Only symbolic debugging entries have some of the N_STAB bits set and if any - * of these bits are set then it is a symbolic debugging entry (a stab).  In - * which case then the values of the n_type field (the entire field) are given - * in <mach-o/stab.h> - */ - -/* - * Values for N_TYPE bits of the n_type field. - */ -/// undefined, n_sect == NO_SECT -pub const N_UNDF: u8 = 0x0; -/// absolute, n_sect == NO_SECT -pub const N_ABS: u8 = 0x2; -/// defined in section number n_sect -pub const N_SECT: u8 = 0xe; -/// prebound undefined (defined in a dylib) -pub const N_PBUD: u8 = 0xc; -/// indirect -pub const N_INDR: u8 = 0xa; - -/* - * If the type is N_INDR then the symbol is defined to be the same as another - * symbol.  In this case the n_value field is an index into the string table - * of the other symbol's name.  When the other symbol is defined then they both - * take on the defined type and value. - */ - -/* - * If the type is N_SECT then the n_sect field contains an ordinal of the - * section the symbol is defined in.  The sections are numbered from 1 and - * refer to sections in order they appear in the load commands for the file - * they are in.  This means the same ordinal may very well refer to different - * sections in different files. - * - * The n_value field for all symbol table entries (including N_STAB's) gets - * updated by the link editor based on the value of it's n_sect field and where - * the section n_sect references gets relocated.  If the value of the n_sect - * field is NO_SECT then it's n_value field is not changed by the link editor. - */ -/// symbol is not in any section -pub const NO_SECT: u8 = 0; -/// 1 thru 255 inclusive -pub const MAX_SECT: u8 = 255; - -/* - * Common symbols are represented by undefined (N_UNDF) external (N_EXT) types - * who's values (n_value) are non-zero.  In which case the value of the n_value - * field is the size (in bytes) of the common symbol.  The n_sect field is set - * to NO_SECT.  The alignment of a common symbol may be set as a power of 2 - * between 2^1 and 2^15 as part of the n_desc field using the macros below. If - * the alignment is not set (a value of zero) then natural alignment based on - * the size is used. - */ -/* TODO: -#define GET_COMM_ALIGN(n_desc) (((n_desc) >> 8) & 0x0f) -#define SET_COMM_ALIGN(n_desc,align) \ -    (n_desc) = (((n_desc) & 0xf0ff) | (((align) & 0x0f) << 8)) - */ - -/* - * To support the lazy binding of undefined symbols in the dynamic link-editor, - * the undefined symbols in the symbol table (the nlist structures) are marked - * with the indication if the undefined reference is a lazy reference or - * non-lazy reference.  If both a non-lazy reference and a lazy reference is - * made to the same symbol the non-lazy reference takes precedence.  A reference - * is lazy only when all references to that symbol are made through a symbol - * pointer in a lazy symbol pointer section. - * - * The implementation of marking nlist structures in the symbol table for - * undefined symbols will be to use some of the bits of the n_desc field as a - * reference type.  The mask REFERENCE_TYPE will be applied to the n_desc field - * of an nlist structure for an undefined symbol to determine the type of - * undefined reference (lazy or non-lazy). - * - * The constants for the REFERENCE FLAGS are propagated to the reference table - * in a shared library file.  In that case the constant for a defined symbol, - * REFERENCE_FLAG_DEFINED, is also used. - */ -/* Reference type bits of the n_desc field of undefined symbols */ -pub const REFERENCE_TYPE: u16 = 0x7; -/* types of references */ -pub const REFERENCE_FLAG_UNDEFINED_NON_LAZY: u16 = 0; -pub const REFERENCE_FLAG_UNDEFINED_LAZY: u16 = 1; -pub const REFERENCE_FLAG_DEFINED: u16 = 2; -pub const REFERENCE_FLAG_PRIVATE_DEFINED: u16 = 3; -pub const REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY: u16 = 4; -pub const REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY: u16 = 5; - -/* - * To simplify stripping of objects that use are used with the dynamic link - * editor, the static link editor marks the symbols defined an object that are - * referenced by a dynamically bound object (dynamic shared libraries, bundles). - * With this marking strip knows not to strip these symbols. - */ -pub const REFERENCED_DYNAMICALLY: u16 = 0x0010; - -/* - * For images created by the static link editor with the -twolevel_namespace - * option in effect the flags field of the mach header is marked with - * MH_TWOLEVEL.  And the binding of the undefined references of the image are - * determined by the static link editor.  Which library an undefined symbol is - * bound to is recorded by the static linker in the high 8 bits of the n_desc - * field using the SET_LIBRARY_ORDINAL macro below.  The ordinal recorded - * references the libraries listed in the Mach-O's LC_LOAD_DYLIB, - * LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and - * LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the - * headers.   The library ordinals start from 1. - * For a dynamic library that is built as a two-level namespace image the - * undefined references from module defined in another use the same nlist struct - * an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal.  For - * defined symbols in all images they also must have the library ordinal set to - * SELF_LIBRARY_ORDINAL.  The EXECUTABLE_ORDINAL refers to the executable - * image for references from plugins that refer to the executable that loads - * them. - * - * The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace - * image that are looked up by the dynamic linker with flat namespace semantics. - * This ordinal was added as a feature in Mac OS X 10.3 by reducing the - * value of MAX_LIBRARY_ORDINAL by one.  So it is legal for existing binaries - * or binaries built with older tools to have 0xfe (254) dynamic libraries.  In - * this case the ordinal value 0xfe (254) must be treated as a library ordinal - * for compatibility. - */ -/* TODO: -#define GET_LIBRARY_ORDINAL(n_desc) (((n_desc) >> 8) & 0xff) -#define SET_LIBRARY_ORDINAL(n_desc,ordinal) \ -    (n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8)) - */ -pub const SELF_LIBRARY_ORDINAL: u8 = 0x0; -pub const MAX_LIBRARY_ORDINAL: u8 = 0xfd; -pub const DYNAMIC_LOOKUP_ORDINAL: u8 = 0xfe; -pub const EXECUTABLE_ORDINAL: u8 = 0xff; - -/* - * The bit 0x0020 of the n_desc field is used for two non-overlapping purposes - * and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED. - */ - -/* - * The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a - * relocatable .o file (MH_OBJECT filetype). And is used to indicate to the - * static link editor it is never to dead strip the symbol. - */ -/// symbol is not to be dead stripped -pub const N_NO_DEAD_STRIP: u16 = 0x0020; - -/* - * The N_DESC_DISCARDED bit of the n_desc field never appears in linked image. - * But is used in very rare cases by the dynamic link editor to mark an in - * memory symbol as discared and longer used for linking. - */ -/// symbol is discarded -pub const N_DESC_DISCARDED: u16 = 0x0020; - -/* - * The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that - * the undefined symbol is allowed to be missing and is to have the address of - * zero when missing. - */ -/// symbol is weak referenced -pub const N_WEAK_REF: u16 = 0x0040; - -/* - * The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic - * linkers that the symbol definition is weak, allowing a non-weak symbol to - * also be used which causes the weak definition to be discared.  Currently this - * is only supported for symbols in coalesced sections. - */ -/// coalesced symbol is a weak definition -pub const N_WEAK_DEF: u16 = 0x0080; - -/* - * The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker - * that the undefined symbol should be resolved using flat namespace searching. - */ -/// reference to a weak symbol -pub const N_REF_TO_WEAK: u16 = 0x0080; - -/* - * The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is - * a definition of a Thumb function. - */ -/// symbol is a Thumb function (ARM) -pub const N_ARM_THUMB_DEF: u16 = 0x0008; - -/* - * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the - * that the function is actually a resolver function and should - * be called to get the address of the real function to use. - * This bit is only available in .o files (MH_OBJECT filetype) - */ -pub const N_SYMBOL_RESOLVER: u16 = 0x0100; - -/* - * The N_ALT_ENTRY bit of the n_desc field indicates that the - * symbol is pinned to the previous content. - */ -pub const N_ALT_ENTRY: u16 = 0x0200; - -// Definitions from "/usr/include/mach-o/stab.h". - -/* - * This file gives definitions supplementing <nlist.h> for permanent symbol - * table entries of Mach-O files.  Modified from the BSD definitions.  The - * modifications from the original definitions were changing what the values of - * what was the n_other field (an unused field) which is now the n_sect field. - * These modifications are required to support symbols in an arbitrary number of - * sections not just the three sections (text, data and bss) in a BSD file. - * The values of the defined constants have NOT been changed. - * - * These must have one of the N_STAB bits on.  The n_value fields are subject - * to relocation according to the value of their n_sect field.  So for types - * that refer to things in sections the n_sect field must be filled in with the - * proper section ordinal.  For types that are not to have their n_value field - * relocatated the n_sect field must be NO_SECT. - */ - -/* - * Symbolic debugger symbols.  The comments give the conventional use for - * - * 	.stabs "n_name", n_type, n_sect, n_desc, n_value - * - * where n_type is the defined constant and not listed in the comment.  Other - * fields not listed are zero. n_sect is the section ordinal the entry is - * referring to. - */ -/// global symbol: name,,NO_SECT,type,0 -pub const N_GSYM: u8 = 0x20; -/// procedure name (f77 kludge): name,,NO_SECT,0,0 -pub const N_FNAME: u8 = 0x22; -/// procedure: name,,n_sect,linenumber,address -pub const N_FUN: u8 = 0x24; -/// static symbol: name,,n_sect,type,address -pub const N_STSYM: u8 = 0x26; -/// .lcomm symbol: name,,n_sect,type,address -pub const N_LCSYM: u8 = 0x28; -/// begin nsect sym: 0,,n_sect,0,address -pub const N_BNSYM: u8 = 0x2e; -/// AST file path: name,,NO_SECT,0,0 -pub const N_AST: u8 = 0x32; -/// emitted with gcc2_compiled and in gcc source -pub const N_OPT: u8 = 0x3c; -/// register sym: name,,NO_SECT,type,register -pub const N_RSYM: u8 = 0x40; -/// src line: 0,,n_sect,linenumber,address -pub const N_SLINE: u8 = 0x44; -/// end nsect sym: 0,,n_sect,0,address -pub const N_ENSYM: u8 = 0x4e; -/// structure elt: name,,NO_SECT,type,struct_offset -pub const N_SSYM: u8 = 0x60; -/// source file name: name,,n_sect,0,address -pub const N_SO: u8 = 0x64; -/// object file name: name,,0,0,st_mtime -pub const N_OSO: u8 = 0x66; -/// local sym: name,,NO_SECT,type,offset -pub const N_LSYM: u8 = 0x80; -/// include file beginning: name,,NO_SECT,0,sum -pub const N_BINCL: u8 = 0x82; -/// #included file name: name,,n_sect,0,address -pub const N_SOL: u8 = 0x84; -/// compiler parameters: name,,NO_SECT,0,0 -pub const N_PARAMS: u8 = 0x86; -/// compiler version: name,,NO_SECT,0,0 -pub const N_VERSION: u8 = 0x88; -/// compiler -O level: name,,NO_SECT,0,0 -pub const N_OLEVEL: u8 = 0x8A; -/// parameter: name,,NO_SECT,type,offset -pub const N_PSYM: u8 = 0xa0; -/// include file end: name,,NO_SECT,0,0 -pub const N_EINCL: u8 = 0xa2; -/// alternate entry: name,,n_sect,linenumber,address -pub const N_ENTRY: u8 = 0xa4; -/// left bracket: 0,,NO_SECT,nesting level,address -pub const N_LBRAC: u8 = 0xc0; -/// deleted include file: name,,NO_SECT,0,sum -pub const N_EXCL: u8 = 0xc2; -/// right bracket: 0,,NO_SECT,nesting level,address -pub const N_RBRAC: u8 = 0xe0; -/// begin common: name,,NO_SECT,0,0 -pub const N_BCOMM: u8 = 0xe2; -/// end common: name,,n_sect,0,0 -pub const N_ECOMM: u8 = 0xe4; -/// end common (local name): 0,,n_sect,0,address -pub const N_ECOML: u8 = 0xe8; -/// second stab entry with length information -pub const N_LENG: u8 = 0xfe; - -/* - * for the berkeley pascal compiler, pc(1): - */ -/// global pascal symbol: name,,NO_SECT,subtype,line -pub const N_PC: u8 = 0x30; - -// Definitions from "/usr/include/mach-o/reloc.h". - -/// A relocation entry. -/// -/// Mach-O relocations have plain and scattered variants, with the -/// meaning of the fields depending on the variant. -/// -/// This type provides functions for determining whether the relocation -/// is scattered, and for accessing the fields of each variant. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Relocation<E: Endian> { -    pub r_word0: U32<E>, -    pub r_word1: U32<E>, -} - -impl<E: Endian> Relocation<E> { -    /// Determine whether this is a scattered relocation. -    #[inline] -    pub fn r_scattered(self, endian: E, cputype: u32) -> bool { -        if cputype == CPU_TYPE_X86_64 { -            false -        } else { -            self.r_word0.get(endian) & R_SCATTERED != 0 -        } -    } - -    /// Return the fields of a plain relocation. -    pub fn info(self, endian: E) -> RelocationInfo { -        let r_address = self.r_word0.get(endian); -        let r_word1 = self.r_word1.get(endian); -        if endian.is_little_endian() { -            RelocationInfo { -                r_address, -                r_symbolnum: r_word1 & 0x00ff_ffff, -                r_pcrel: ((r_word1 >> 24) & 0x1) != 0, -                r_length: ((r_word1 >> 25) & 0x3) as u8, -                r_extern: ((r_word1 >> 27) & 0x1) != 0, -                r_type: (r_word1 >> 28) as u8, -            } -        } else { -            RelocationInfo { -                r_address, -                r_symbolnum: r_word1 >> 8, -                r_pcrel: ((r_word1 >> 7) & 0x1) != 0, -                r_length: ((r_word1 >> 5) & 0x3) as u8, -                r_extern: ((r_word1 >> 4) & 0x1) != 0, -                r_type: (r_word1 & 0xf) as u8, -            } -        } -    } - -    /// Return the fields of a scattered relocation. -    pub fn scattered_info(self, endian: E) -> ScatteredRelocationInfo { -        let r_word0 = self.r_word0.get(endian); -        let r_value = self.r_word1.get(endian); -        ScatteredRelocationInfo { -            r_address: r_word0 & 0x00ff_ffff, -            r_type: ((r_word0 >> 24) & 0xf) as u8, -            r_length: ((r_word0 >> 28) & 0x3) as u8, -            r_pcrel: ((r_word0 >> 30) & 0x1) != 0, -            r_value, -        } -    } -} - -/* - * Format of a relocation entry of a Mach-O file.  Modified from the 4.3BSD - * format.  The modifications from the original format were changing the value - * of the r_symbolnum field for "local" (r_extern == 0) relocation entries. - * This modification is required to support symbols in an arbitrary number of - * sections not just the three sections (text, data and bss) in a 4.3BSD file. - * Also the last 4 bits have had the r_type tag added to them. - */ - -#[derive(Debug, Clone, Copy)] -pub struct RelocationInfo { -    /// offset in the section to what is being relocated -    pub r_address: u32, -    /// symbol index if r_extern == 1 or section ordinal if r_extern == 0 -    pub r_symbolnum: u32, -    /// was relocated pc relative already -    pub r_pcrel: bool, -    /// 0=byte, 1=word, 2=long, 3=quad -    pub r_length: u8, -    /// does not include value of sym referenced -    pub r_extern: bool, -    /// if not 0, machine specific relocation type -    pub r_type: u8, -} - -impl RelocationInfo { -    /// Combine the fields into a `Relocation`. -    pub fn relocation<E: Endian>(self, endian: E) -> Relocation<E> { -        let r_word0 = U32::new(endian, self.r_address); -        let r_word1 = U32::new( -            endian, -            if endian.is_little_endian() { -                self.r_symbolnum & 0x00ff_ffff -                    | u32::from(self.r_pcrel) << 24 -                    | u32::from(self.r_length & 0x3) << 25 -                    | u32::from(self.r_extern) << 27 -                    | u32::from(self.r_type) << 28 -            } else { -                self.r_symbolnum >> 8 -                    | u32::from(self.r_pcrel) << 7 -                    | u32::from(self.r_length & 0x3) << 5 -                    | u32::from(self.r_extern) << 4 -                    | u32::from(self.r_type) & 0xf -            }, -        ); -        Relocation { r_word0, r_word1 } -    } -} - -/// absolute relocation type for Mach-O files -pub const R_ABS: u8 = 0; - -/* - * The r_address is not really the address as it's name indicates but an offset. - * In 4.3BSD a.out objects this offset is from the start of the "segment" for - * which relocation entry is for (text or data).  For Mach-O object files it is - * also an offset but from the start of the "section" for which the relocation - * entry is for.  See comments in <mach-o/loader.h> about the r_address feild - * in images for used with the dynamic linker. - * - * In 4.3BSD a.out objects if r_extern is zero then r_symbolnum is an ordinal - * for the segment the symbol being relocated is in.  These ordinals are the - * symbol types N_TEXT, N_DATA, N_BSS or N_ABS.  In Mach-O object files these - * ordinals refer to the sections in the object file in the order their section - * structures appear in the headers of the object file they are in.  The first - * section has the ordinal 1, the second 2, and so on.  This means that the - * same ordinal in two different object files could refer to two different - * sections.  And further could have still different ordinals when combined - * by the link-editor.  The value R_ABS is used for relocation entries for - * absolute symbols which need no further relocation. - */ - -/* - * For RISC machines some of the references are split across two instructions - * and the instruction does not contain the complete value of the reference. - * In these cases a second, or paired relocation entry, follows each of these - * relocation entries, using a PAIR r_type, which contains the other part of the - * reference not contained in the instruction.  This other part is stored in the - * pair's r_address field.  The exact number of bits of the other part of the - * reference store in the r_address field is dependent on the particular - * relocation type for the particular architecture. - */ - -/* - * To make scattered loading by the link editor work correctly "local" - * relocation entries can't be used when the item to be relocated is the value - * of a symbol plus an offset (where the resulting expression is outside the - * block the link editor is moving, a blocks are divided at symbol addresses). - * In this case. where the item is a symbol value plus offset, the link editor - * needs to know more than just the section the symbol was defined.  What is - * needed is the actual value of the symbol without the offset so it can do the - * relocation correctly based on where the value of the symbol got relocated to - * not the value of the expression (with the offset added to the symbol value). - * So for the NeXT 2.0 release no "local" relocation entries are ever used when - * there is a non-zero offset added to a symbol.  The "external" and "local" - * relocation entries remain unchanged. - * - * The implementation is quite messy given the compatibility with the existing - * relocation entry format.  The ASSUMPTION is that a section will never be - * bigger than 2**24 - 1 (0x00ffffff or 16,777,215) bytes.  This assumption - * allows the r_address (which is really an offset) to fit in 24 bits and high - * bit of the r_address field in the relocation_info structure to indicate - * it is really a scattered_relocation_info structure.  Since these are only - * used in places where "local" relocation entries are used and not where - * "external" relocation entries are used the r_extern field has been removed. - * - * For scattered loading to work on a RISC machine where some of the references - * are split across two instructions the link editor needs to be assured that - * each reference has a unique 32 bit reference (that more than one reference is - * NOT sharing the same high 16 bits for example) so it move each referenced - * item independent of each other.  Some compilers guarantees this but the - * compilers don't so scattered loading can be done on those that do guarantee - * this. - */ - -/// Bit set in `Relocation::r_word0` for scattered relocations. -pub const R_SCATTERED: u32 = 0x8000_0000; - -#[derive(Debug, Clone, Copy)] -pub struct ScatteredRelocationInfo { -    /// offset in the section to what is being relocated -    pub r_address: u32, -    /// if not 0, machine specific relocation type -    pub r_type: u8, -    /// 0=byte, 1=word, 2=long, 3=quad -    pub r_length: u8, -    /// was relocated pc relative already -    pub r_pcrel: bool, -    /// the value the item to be relocated is referring to (without any offset added) -    pub r_value: u32, -} - -impl ScatteredRelocationInfo { -    /// Combine the fields into a `Relocation`. -    pub fn relocation<E: Endian>(self, endian: E) -> Relocation<E> { -        let r_word0 = U32::new( -            endian, -            self.r_address & 0x00ff_ffff -                | u32::from(self.r_type & 0xf) << 24 -                | u32::from(self.r_length & 0x3) << 28 -                | u32::from(self.r_pcrel) << 30 -                | R_SCATTERED, -        ); -        let r_word1 = U32::new(endian, self.r_value); -        Relocation { r_word0, r_word1 } -    } -} - -/* - * Relocation types used in a generic implementation.  Relocation entries for - * normal things use the generic relocation as described above and their r_type - * is GENERIC_RELOC_VANILLA (a value of zero). - * - * Another type of generic relocation, GENERIC_RELOC_SECTDIFF, is to support - * the difference of two symbols defined in different sections.  That is the - * expression "symbol1 - symbol2 + constant" is a relocatable expression when - * both symbols are defined in some section.  For this type of relocation the - * both relocations entries are scattered relocation entries.  The value of - * symbol1 is stored in the first relocation entry's r_value field and the - * value of symbol2 is stored in the pair's r_value field. - * - * A special case for a prebound lazy pointer is needed to beable to set the - * value of the lazy pointer back to its non-prebound state.  This is done - * using the GENERIC_RELOC_PB_LA_PTR r_type.  This is a scattered relocation - * entry where the r_value feild is the value of the lazy pointer not prebound. - */ -/// generic relocation as described above -pub const GENERIC_RELOC_VANILLA: u8 = 0; -/// Only follows a GENERIC_RELOC_SECTDIFF -pub const GENERIC_RELOC_PAIR: u8 = 1; -pub const GENERIC_RELOC_SECTDIFF: u8 = 2; -/// prebound lazy pointer -pub const GENERIC_RELOC_PB_LA_PTR: u8 = 3; -pub const GENERIC_RELOC_LOCAL_SECTDIFF: u8 = 4; -/// thread local variables -pub const GENERIC_RELOC_TLV: u8 = 5; - -// Definitions from "/usr/include/mach-o/arm/reloc.h". - -/* - * Relocation types used in the arm implementation.  Relocation entries for - * things other than instructions use the same generic relocation as described - * in <mach-o/reloc.h> and their r_type is ARM_RELOC_VANILLA, one of the - * *_SECTDIFF or the *_PB_LA_PTR types.  The rest of the relocation types are - * for instructions.  Since they are for instructions the r_address field - * indicates the 32 bit instruction that the relocation is to be performed on. - */ -/// generic relocation as described above -pub const ARM_RELOC_VANILLA: u8 = 0; -/// the second relocation entry of a pair -pub const ARM_RELOC_PAIR: u8 = 1; -/// a PAIR follows with subtract symbol value -pub const ARM_RELOC_SECTDIFF: u8 = 2; -/// like ARM_RELOC_SECTDIFF, but the symbol referenced was local. -pub const ARM_RELOC_LOCAL_SECTDIFF: u8 = 3; -/// prebound lazy pointer -pub const ARM_RELOC_PB_LA_PTR: u8 = 4; -/// 24 bit branch displacement (to a word address) -pub const ARM_RELOC_BR24: u8 = 5; -/// 22 bit branch displacement (to a half-word address) -pub const ARM_THUMB_RELOC_BR22: u8 = 6; -/// obsolete - a thumb 32-bit branch instruction possibly needing page-spanning branch workaround -pub const ARM_THUMB_32BIT_BRANCH: u8 = 7; - -/* - * For these two r_type relocations they always have a pair following them - * and the r_length bits are used differently.  The encoding of the - * r_length is as follows: - * low bit of r_length: - *  0 - :lower16: for movw instructions - *  1 - :upper16: for movt instructions - * high bit of r_length: - *  0 - arm instructions - *  1 - thumb instructions - * the other half of the relocated expression is in the following pair - * relocation entry in the the low 16 bits of r_address field. - */ -pub const ARM_RELOC_HALF: u8 = 8; -pub const ARM_RELOC_HALF_SECTDIFF: u8 = 9; - -// Definitions from "/usr/include/mach-o/arm64/reloc.h". - -/* - * Relocation types used in the arm64 implementation. - */ -/// for pointers -pub const ARM64_RELOC_UNSIGNED: u8 = 0; -/// must be followed by a ARM64_RELOC_UNSIGNED -pub const ARM64_RELOC_SUBTRACTOR: u8 = 1; -/// a B/BL instruction with 26-bit displacement -pub const ARM64_RELOC_BRANCH26: u8 = 2; -/// pc-rel distance to page of target -pub const ARM64_RELOC_PAGE21: u8 = 3; -/// offset within page, scaled by r_length -pub const ARM64_RELOC_PAGEOFF12: u8 = 4; -/// pc-rel distance to page of GOT slot -pub const ARM64_RELOC_GOT_LOAD_PAGE21: u8 = 5; -/// offset within page of GOT slot, scaled by r_length -pub const ARM64_RELOC_GOT_LOAD_PAGEOFF12: u8 = 6; -/// for pointers to GOT slots -pub const ARM64_RELOC_POINTER_TO_GOT: u8 = 7; -/// pc-rel distance to page of TLVP slot -pub const ARM64_RELOC_TLVP_LOAD_PAGE21: u8 = 8; -/// offset within page of TLVP slot, scaled by r_length -pub const ARM64_RELOC_TLVP_LOAD_PAGEOFF12: u8 = 9; -/// must be followed by PAGE21 or PAGEOFF12 -pub const ARM64_RELOC_ADDEND: u8 = 10; - -// An arm64e authenticated pointer. -// -// Represents a pointer to a symbol (like ARM64_RELOC_UNSIGNED). -// Additionally, the resulting pointer is signed.  The signature is -// specified in the target location: the addend is restricted to the lower -// 32 bits (instead of the full 64 bits for ARM64_RELOC_UNSIGNED): -// -//   |63|62|61-51|50-49|  48  |47     -     32|31  -  0| -//   | 1| 0|  0  | key | addr | discriminator | addend | -// -// The key is one of: -//   IA: 00 IB: 01 -//   DA: 10 DB: 11 -// -// The discriminator field is used as extra signature diversification. -// -// The addr field indicates whether the target address should be blended -// into the discriminator. -// -pub const ARM64_RELOC_AUTHENTICATED_POINTER: u8 = 11; - -// Definitions from "/usr/include/mach-o/ppc/reloc.h". - -/* - * Relocation types used in the ppc implementation.  Relocation entries for - * things other than instructions use the same generic relocation as described - * above and their r_type is RELOC_VANILLA.  The rest of the relocation types - * are for instructions.  Since they are for instructions the r_address field - * indicates the 32 bit instruction that the relocation is to be performed on. - * The fields r_pcrel and r_length are ignored for non-RELOC_VANILLA r_types - * except for PPC_RELOC_BR14. - * - * For PPC_RELOC_BR14 if the r_length is the unused value 3, then the branch was - * statically predicted setting or clearing the Y-bit based on the sign of the - * displacement or the opcode.  If this is the case the static linker must flip - * the value of the Y-bit if the sign of the displacement changes for non-branch - * always conditions. - */ -/// generic relocation as described above -pub const PPC_RELOC_VANILLA: u8 = 0; -/// the second relocation entry of a pair -pub const PPC_RELOC_PAIR: u8 = 1; -/// 14 bit branch displacement (to a word address) -pub const PPC_RELOC_BR14: u8 = 2; -/// 24 bit branch displacement (to a word address) -pub const PPC_RELOC_BR24: u8 = 3; -/// a PAIR follows with the low half -pub const PPC_RELOC_HI16: u8 = 4; -/// a PAIR follows with the high half -pub const PPC_RELOC_LO16: u8 = 5; -/// Same as the RELOC_HI16 except the low 16 bits and the high 16 bits are added together -/// with the low 16 bits sign extended first.  This means if bit 15 of the low 16 bits is -/// set the high 16 bits stored in the instruction will be adjusted. -pub const PPC_RELOC_HA16: u8 = 6; -/// Same as the LO16 except that the low 2 bits are not stored in the instruction and are -/// always zero.  This is used in double word load/store instructions. -pub const PPC_RELOC_LO14: u8 = 7; -/// a PAIR follows with subtract symbol value -pub const PPC_RELOC_SECTDIFF: u8 = 8; -/// prebound lazy pointer -pub const PPC_RELOC_PB_LA_PTR: u8 = 9; -/// section difference forms of above.  a PAIR -pub const PPC_RELOC_HI16_SECTDIFF: u8 = 10; -/// follows these with subtract symbol value -pub const PPC_RELOC_LO16_SECTDIFF: u8 = 11; -pub const PPC_RELOC_HA16_SECTDIFF: u8 = 12; -pub const PPC_RELOC_JBSR: u8 = 13; -pub const PPC_RELOC_LO14_SECTDIFF: u8 = 14; -/// like PPC_RELOC_SECTDIFF, but the symbol referenced was local. -pub const PPC_RELOC_LOCAL_SECTDIFF: u8 = 15; - -// Definitions from "/usr/include/mach-o/x86_64/reloc.h". - -/* - * Relocations for x86_64 are a bit different than for other architectures in - * Mach-O: Scattered relocations are not used.  Almost all relocations produced - * by the compiler are external relocations.  An external relocation has the - * r_extern bit set to 1 and the r_symbolnum field contains the symbol table - * index of the target label. - * - * When the assembler is generating relocations, if the target label is a local - * label (begins with 'L'), then the previous non-local label in the same - * section is used as the target of the external relocation.  An addend is used - * with the distance from that non-local label to the target label.  Only when - * there is no previous non-local label in the section is an internal - * relocation used. - * - * The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does - * not have RELA relocations).  For PC-relative relocations, the addend is - * stored directly in the instruction.  This is different from other Mach-O - * architectures, which encode the addend minus the current section offset. - * - * The relocation types are: - * - * 	X86_64_RELOC_UNSIGNED	// for absolute addresses - * 	X86_64_RELOC_SIGNED		// for signed 32-bit displacement - * 	X86_64_RELOC_BRANCH		// a CALL/JMP instruction with 32-bit displacement - * 	X86_64_RELOC_GOT_LOAD	// a MOVQ load of a GOT entry - * 	X86_64_RELOC_GOT		// other GOT references - * 	X86_64_RELOC_SUBTRACTOR	// must be followed by a X86_64_RELOC_UNSIGNED - * - * The following are sample assembly instructions, followed by the relocation - * and section content they generate in an object file: - * - * 	call _foo - * 		r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		E8 00 00 00 00 - * - * 	call _foo+4 - * 		r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		E8 04 00 00 00 - * - * 	movq _foo@GOTPCREL(%rip), %rax - * 		r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		48 8B 05 00 00 00 00 - * - * 	pushq _foo@GOTPCREL(%rip) - * 		r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		FF 35 00 00 00 00 - * - * 	movl _foo(%rip), %eax - * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		8B 05 00 00 00 00 - * - * 	movl _foo+4(%rip), %eax - * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		8B 05 04 00 00 00 - * - * 	movb  $0x12, _foo(%rip) - * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		C6 05 FF FF FF FF 12 - * - * 	movl  $0x12345678, _foo(%rip) - * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo - * 		C7 05 FC FF FF FF 78 56 34 12 - * - * 	.quad _foo - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo - * 		00 00 00 00 00 00 00 00 - * - * 	.quad _foo+4 - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo - * 		04 00 00 00 00 00 00 00 - * - * 	.quad _foo - _bar - * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo - * 		00 00 00 00 00 00 00 00 - * - * 	.quad _foo - _bar + 4 - * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo - * 		04 00 00 00 00 00 00 00 - * - * 	.long _foo - _bar - * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo - * 		00 00 00 00 - * - * 	lea L1(%rip), %rax - * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev - * 		48 8d 05 12 00 00 00 - * 		// assumes _prev is the first non-local label 0x12 bytes before L1 - * - * 	lea L0(%rip), %rax - * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3 - * 		48 8d 05 56 00 00 00 - *		// assumes L0 is in third section and there is no previous non-local label. - *		// The rip-relative-offset of 0x00000056 is L0-address_of_next_instruction. - *		// address_of_next_instruction is the address of the relocation + 4. - * - *     add     $6,L0(%rip) - *             r_type=X86_64_RELOC_SIGNED_1, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3 - *		83 05 18 00 00 00 06 - *		// assumes L0 is in third section and there is no previous non-local label. - *		// The rip-relative-offset of 0x00000018 is L0-address_of_next_instruction. - *		// address_of_next_instruction is the address of the relocation + 4 + 1. - *		// The +1 comes from SIGNED_1.  This is used because the relocation is not - *		// at the end of the instruction. - * - * 	.quad L1 - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev - * 		12 00 00 00 00 00 00 00 - * 		// assumes _prev is the first non-local label 0x12 bytes before L1 - * - * 	.quad L0 - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3 - * 		56 00 00 00 00 00 00 00 - * 		// assumes L0 is in third section, has an address of 0x00000056 in .o - * 		// file, and there is no previous non-local label - * - * 	.quad _foo - . - * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo - * 		EE FF FF FF FF FF FF FF - * 		// assumes _prev is the first non-local label 0x12 bytes before this - * 		// .quad - * - * 	.quad _foo - L1 - * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev - * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo - * 		EE FF FF FF FF FF FF FF - * 		// assumes _prev is the first non-local label 0x12 bytes before L1 - * - * 	.quad L1 - _prev - * 		// No relocations.  This is an assembly time constant. - * 		12 00 00 00 00 00 00 00 - * 		// assumes _prev is the first non-local label 0x12 bytes before L1 - * - * - * - * In final linked images, there are only two valid relocation kinds: - * - *     r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index - *	This tells dyld to add the address of a symbol to a pointer sized (8-byte) - *  piece of data (i.e on disk the 8-byte piece of data contains the addend). The - *  r_symbolnum contains the index into the symbol table of the target symbol. - * - *     r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0 - * This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount - * the containing image was loaded from its base address (e.g. slide). - * - */ -/// for absolute addresses -pub const X86_64_RELOC_UNSIGNED: u8 = 0; -/// for signed 32-bit displacement -pub const X86_64_RELOC_SIGNED: u8 = 1; -/// a CALL/JMP instruction with 32-bit displacement -pub const X86_64_RELOC_BRANCH: u8 = 2; -/// a MOVQ load of a GOT entry -pub const X86_64_RELOC_GOT_LOAD: u8 = 3; -/// other GOT references -pub const X86_64_RELOC_GOT: u8 = 4; -/// must be followed by a X86_64_RELOC_UNSIGNED -pub const X86_64_RELOC_SUBTRACTOR: u8 = 5; -/// for signed 32-bit displacement with a -1 addend -pub const X86_64_RELOC_SIGNED_1: u8 = 6; -/// for signed 32-bit displacement with a -2 addend -pub const X86_64_RELOC_SIGNED_2: u8 = 7; -/// for signed 32-bit displacement with a -4 addend -pub const X86_64_RELOC_SIGNED_4: u8 = 8; -/// for thread local variables -pub const X86_64_RELOC_TLV: u8 = 9; - -unsafe_impl_pod!(FatHeader, FatArch32, FatArch64,); -unsafe_impl_endian_pod!( -    DyldCacheHeader, -    DyldCacheMappingInfo, -    DyldCacheImageInfo, -    DyldSubCacheInfo, -    MachHeader32, -    MachHeader64, -    LoadCommand, -    LcStr, -    SegmentCommand32, -    SegmentCommand64, -    Section32, -    Section64, -    Fvmlib, -    FvmlibCommand, -    Dylib, -    DylibCommand, -    SubFrameworkCommand, -    SubClientCommand, -    SubUmbrellaCommand, -    SubLibraryCommand, -    PreboundDylibCommand, -    DylinkerCommand, -    ThreadCommand, -    RoutinesCommand32, -    RoutinesCommand64, -    SymtabCommand, -    DysymtabCommand, -    DylibTableOfContents, -    DylibModule32, -    DylibModule64, -    DylibReference, -    TwolevelHintsCommand, -    TwolevelHint, -    PrebindCksumCommand, -    UuidCommand, -    RpathCommand, -    LinkeditDataCommand, -    FilesetEntryCommand, -    EncryptionInfoCommand32, -    EncryptionInfoCommand64, -    VersionMinCommand, -    BuildVersionCommand, -    BuildToolVersion, -    DyldInfoCommand, -    LinkerOptionCommand, -    SymsegCommand, -    IdentCommand, -    FvmfileCommand, -    EntryPointCommand, -    SourceVersionCommand, -    DataInCodeEntry, -    //TlvDescriptor, -    NoteCommand, -    Nlist32, -    Nlist64, -    Relocation, -); diff --git a/vendor/object/src/pe.rs b/vendor/object/src/pe.rs deleted file mode 100644 index 64ccf06..0000000 --- a/vendor/object/src/pe.rs +++ /dev/null @@ -1,3056 +0,0 @@ -//! PE/COFF definitions. -//! -//! These definitions are independent of read/write support, although we do implement -//! some traits useful for those. -//! -//! This module is based heavily on "winnt.h" (10.0.17763.0). - -#![allow(missing_docs)] - -use core::convert::TryInto; - -use crate::endian::{I32Bytes, LittleEndian as LE, U16Bytes, U32Bytes, I32, U16, U32, U64}; -use crate::pod::Pod; - -/// MZ -pub const IMAGE_DOS_SIGNATURE: u16 = 0x5A4D; -/// NE -pub const IMAGE_OS2_SIGNATURE: u16 = 0x454E; -/// LE -pub const IMAGE_OS2_SIGNATURE_LE: u16 = 0x454C; -/// LE -pub const IMAGE_VXD_SIGNATURE: u16 = 0x454C; -/// PE00 -pub const IMAGE_NT_SIGNATURE: u32 = 0x0000_4550; - -/// DOS .EXE header -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDosHeader { -    /// Magic number -    pub e_magic: U16<LE>, -    /// Bytes on last page of file -    pub e_cblp: U16<LE>, -    /// Pages in file -    pub e_cp: U16<LE>, -    /// Relocations -    pub e_crlc: U16<LE>, -    /// Size of header in paragraphs -    pub e_cparhdr: U16<LE>, -    /// Minimum extra paragraphs needed -    pub e_minalloc: U16<LE>, -    /// Maximum extra paragraphs needed -    pub e_maxalloc: U16<LE>, -    /// Initial (relative) SS value -    pub e_ss: U16<LE>, -    /// Initial SP value -    pub e_sp: U16<LE>, -    /// Checksum -    pub e_csum: U16<LE>, -    /// Initial IP value -    pub e_ip: U16<LE>, -    /// Initial (relative) CS value -    pub e_cs: U16<LE>, -    /// File address of relocation table -    pub e_lfarlc: U16<LE>, -    /// Overlay number -    pub e_ovno: U16<LE>, -    /// Reserved words -    pub e_res: [U16<LE>; 4], -    /// OEM identifier (for e_oeminfo) -    pub e_oemid: U16<LE>, -    /// OEM information; e_oemid specific -    pub e_oeminfo: U16<LE>, -    /// Reserved words -    pub e_res2: [U16<LE>; 10], -    /// File address of new exe header -    pub e_lfanew: U32<LE>, -} - -/// OS/2 .EXE header -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageOs2Header { -    /// Magic number -    pub ne_magic: U16<LE>, -    /// Version number -    pub ne_ver: i8, -    /// Revision number -    pub ne_rev: i8, -    /// Offset of Entry Table -    pub ne_enttab: U16<LE>, -    /// Number of bytes in Entry Table -    pub ne_cbenttab: U16<LE>, -    /// Checksum of whole file -    pub ne_crc: I32<LE>, -    /// Flag word -    pub ne_flags: U16<LE>, -    /// Automatic data segment number -    pub ne_autodata: U16<LE>, -    /// Initial heap allocation -    pub ne_heap: U16<LE>, -    /// Initial stack allocation -    pub ne_stack: U16<LE>, -    /// Initial CS:IP setting -    pub ne_csip: I32<LE>, -    /// Initial SS:SP setting -    pub ne_sssp: I32<LE>, -    /// Count of file segments -    pub ne_cseg: U16<LE>, -    /// Entries in Module Reference Table -    pub ne_cmod: U16<LE>, -    /// Size of non-resident name table -    pub ne_cbnrestab: U16<LE>, -    /// Offset of Segment Table -    pub ne_segtab: U16<LE>, -    /// Offset of Resource Table -    pub ne_rsrctab: U16<LE>, -    /// Offset of resident name table -    pub ne_restab: U16<LE>, -    /// Offset of Module Reference Table -    pub ne_modtab: U16<LE>, -    /// Offset of Imported Names Table -    pub ne_imptab: U16<LE>, -    /// Offset of Non-resident Names Table -    pub ne_nrestab: I32<LE>, -    /// Count of movable entries -    pub ne_cmovent: U16<LE>, -    /// Segment alignment shift count -    pub ne_align: U16<LE>, -    /// Count of resource segments -    pub ne_cres: U16<LE>, -    /// Target Operating system -    pub ne_exetyp: u8, -    /// Other .EXE flags -    pub ne_flagsothers: u8, -    /// offset to return thunks -    pub ne_pretthunks: U16<LE>, -    /// offset to segment ref. bytes -    pub ne_psegrefbytes: U16<LE>, -    /// Minimum code swap area size -    pub ne_swaparea: U16<LE>, -    /// Expected Windows version number -    pub ne_expver: U16<LE>, -} - -/// Windows VXD header -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageVxdHeader { -    /// Magic number -    pub e32_magic: U16<LE>, -    /// The byte ordering for the VXD -    pub e32_border: u8, -    /// The word ordering for the VXD -    pub e32_worder: u8, -    /// The EXE format level for now = 0 -    pub e32_level: U32<LE>, -    /// The CPU type -    pub e32_cpu: U16<LE>, -    /// The OS type -    pub e32_os: U16<LE>, -    /// Module version -    pub e32_ver: U32<LE>, -    /// Module flags -    pub e32_mflags: U32<LE>, -    /// Module # pages -    pub e32_mpages: U32<LE>, -    /// Object # for instruction pointer -    pub e32_startobj: U32<LE>, -    /// Extended instruction pointer -    pub e32_eip: U32<LE>, -    /// Object # for stack pointer -    pub e32_stackobj: U32<LE>, -    /// Extended stack pointer -    pub e32_esp: U32<LE>, -    /// VXD page size -    pub e32_pagesize: U32<LE>, -    /// Last page size in VXD -    pub e32_lastpagesize: U32<LE>, -    /// Fixup section size -    pub e32_fixupsize: U32<LE>, -    /// Fixup section checksum -    pub e32_fixupsum: U32<LE>, -    /// Loader section size -    pub e32_ldrsize: U32<LE>, -    /// Loader section checksum -    pub e32_ldrsum: U32<LE>, -    /// Object table offset -    pub e32_objtab: U32<LE>, -    /// Number of objects in module -    pub e32_objcnt: U32<LE>, -    /// Object page map offset -    pub e32_objmap: U32<LE>, -    /// Object iterated data map offset -    pub e32_itermap: U32<LE>, -    /// Offset of Resource Table -    pub e32_rsrctab: U32<LE>, -    /// Number of resource entries -    pub e32_rsrccnt: U32<LE>, -    /// Offset of resident name table -    pub e32_restab: U32<LE>, -    /// Offset of Entry Table -    pub e32_enttab: U32<LE>, -    /// Offset of Module Directive Table -    pub e32_dirtab: U32<LE>, -    /// Number of module directives -    pub e32_dircnt: U32<LE>, -    /// Offset of Fixup Page Table -    pub e32_fpagetab: U32<LE>, -    /// Offset of Fixup Record Table -    pub e32_frectab: U32<LE>, -    /// Offset of Import Module Name Table -    pub e32_impmod: U32<LE>, -    /// Number of entries in Import Module Name Table -    pub e32_impmodcnt: U32<LE>, -    /// Offset of Import Procedure Name Table -    pub e32_impproc: U32<LE>, -    /// Offset of Per-Page Checksum Table -    pub e32_pagesum: U32<LE>, -    /// Offset of Enumerated Data Pages -    pub e32_datapage: U32<LE>, -    /// Number of preload pages -    pub e32_preload: U32<LE>, -    /// Offset of Non-resident Names Table -    pub e32_nrestab: U32<LE>, -    /// Size of Non-resident Name Table -    pub e32_cbnrestab: U32<LE>, -    /// Non-resident Name Table Checksum -    pub e32_nressum: U32<LE>, -    /// Object # for automatic data object -    pub e32_autodata: U32<LE>, -    /// Offset of the debugging information -    pub e32_debuginfo: U32<LE>, -    /// The length of the debugging info. in bytes -    pub e32_debuglen: U32<LE>, -    /// Number of instance pages in preload section of VXD file -    pub e32_instpreload: U32<LE>, -    /// Number of instance pages in demand load section of VXD file -    pub e32_instdemand: U32<LE>, -    /// Size of heap - for 16-bit apps -    pub e32_heapsize: U32<LE>, -    /// Reserved words -    pub e32_res3: [u8; 12], -    pub e32_winresoff: U32<LE>, -    pub e32_winreslen: U32<LE>, -    /// Device ID for VxD -    pub e32_devid: U16<LE>, -    /// DDK version for VxD -    pub e32_ddkver: U16<LE>, -} - -/// A PE rich header entry. -/// -/// Rich headers have no official documentation, but have been heavily -/// reversed-engineered and documented in the wild, e.g.: -/// * `http://www.ntcore.com/files/richsign.htm` -/// * `https://www.researchgate.net/figure/Structure-of-the-Rich-Header_fig1_318145388` -/// -/// This data is "masked", i.e. XORed with a checksum derived from the file data. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct MaskedRichHeaderEntry { -    pub masked_comp_id: U32<LE>, -    pub masked_count: U32<LE>, -} - -// -// File header format. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageFileHeader { -    pub machine: U16<LE>, -    pub number_of_sections: U16<LE>, -    pub time_date_stamp: U32<LE>, -    pub pointer_to_symbol_table: U32<LE>, -    pub number_of_symbols: U32<LE>, -    pub size_of_optional_header: U16<LE>, -    pub characteristics: U16<LE>, -} - -pub const IMAGE_SIZEOF_FILE_HEADER: usize = 20; - -/// Relocation info stripped from file. -pub const IMAGE_FILE_RELOCS_STRIPPED: u16 = 0x0001; -/// File is executable  (i.e. no unresolved external references). -pub const IMAGE_FILE_EXECUTABLE_IMAGE: u16 = 0x0002; -/// Line numbers stripped from file. -pub const IMAGE_FILE_LINE_NUMS_STRIPPED: u16 = 0x0004; -/// Local symbols stripped from file. -pub const IMAGE_FILE_LOCAL_SYMS_STRIPPED: u16 = 0x0008; -/// Aggressively trim working set -pub const IMAGE_FILE_AGGRESIVE_WS_TRIM: u16 = 0x0010; -/// App can handle >2gb addresses -pub const IMAGE_FILE_LARGE_ADDRESS_AWARE: u16 = 0x0020; -/// Bytes of machine word are reversed. -pub const IMAGE_FILE_BYTES_REVERSED_LO: u16 = 0x0080; -/// 32 bit word machine. -pub const IMAGE_FILE_32BIT_MACHINE: u16 = 0x0100; -/// Debugging info stripped from file in .DBG file -pub const IMAGE_FILE_DEBUG_STRIPPED: u16 = 0x0200; -/// If Image is on removable media, copy and run from the swap file. -pub const IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP: u16 = 0x0400; -/// If Image is on Net, copy and run from the swap file. -pub const IMAGE_FILE_NET_RUN_FROM_SWAP: u16 = 0x0800; -/// System File. -pub const IMAGE_FILE_SYSTEM: u16 = 0x1000; -/// File is a DLL. -pub const IMAGE_FILE_DLL: u16 = 0x2000; -/// File should only be run on a UP machine -pub const IMAGE_FILE_UP_SYSTEM_ONLY: u16 = 0x4000; -/// Bytes of machine word are reversed. -pub const IMAGE_FILE_BYTES_REVERSED_HI: u16 = 0x8000; - -pub const IMAGE_FILE_MACHINE_UNKNOWN: u16 = 0; -/// Useful for indicating we want to interact with the host and not a WoW guest. -pub const IMAGE_FILE_MACHINE_TARGET_HOST: u16 = 0x0001; -/// Intel 386. -pub const IMAGE_FILE_MACHINE_I386: u16 = 0x014c; -/// MIPS little-endian, 0x160 big-endian -pub const IMAGE_FILE_MACHINE_R3000: u16 = 0x0162; -/// MIPS little-endian -pub const IMAGE_FILE_MACHINE_R4000: u16 = 0x0166; -/// MIPS little-endian -pub const IMAGE_FILE_MACHINE_R10000: u16 = 0x0168; -/// MIPS little-endian WCE v2 -pub const IMAGE_FILE_MACHINE_WCEMIPSV2: u16 = 0x0169; -/// Alpha_AXP -pub const IMAGE_FILE_MACHINE_ALPHA: u16 = 0x0184; -/// SH3 little-endian -pub const IMAGE_FILE_MACHINE_SH3: u16 = 0x01a2; -pub const IMAGE_FILE_MACHINE_SH3DSP: u16 = 0x01a3; -/// SH3E little-endian -pub const IMAGE_FILE_MACHINE_SH3E: u16 = 0x01a4; -/// SH4 little-endian -pub const IMAGE_FILE_MACHINE_SH4: u16 = 0x01a6; -/// SH5 -pub const IMAGE_FILE_MACHINE_SH5: u16 = 0x01a8; -/// ARM Little-Endian -pub const IMAGE_FILE_MACHINE_ARM: u16 = 0x01c0; -/// ARM Thumb/Thumb-2 Little-Endian -pub const IMAGE_FILE_MACHINE_THUMB: u16 = 0x01c2; -/// ARM Thumb-2 Little-Endian -pub const IMAGE_FILE_MACHINE_ARMNT: u16 = 0x01c4; -pub const IMAGE_FILE_MACHINE_AM33: u16 = 0x01d3; -/// IBM PowerPC Little-Endian -pub const IMAGE_FILE_MACHINE_POWERPC: u16 = 0x01F0; -pub const IMAGE_FILE_MACHINE_POWERPCFP: u16 = 0x01f1; -/// Intel 64 -pub const IMAGE_FILE_MACHINE_IA64: u16 = 0x0200; -/// MIPS -pub const IMAGE_FILE_MACHINE_MIPS16: u16 = 0x0266; -/// ALPHA64 -pub const IMAGE_FILE_MACHINE_ALPHA64: u16 = 0x0284; -/// MIPS -pub const IMAGE_FILE_MACHINE_MIPSFPU: u16 = 0x0366; -/// MIPS -pub const IMAGE_FILE_MACHINE_MIPSFPU16: u16 = 0x0466; -pub const IMAGE_FILE_MACHINE_AXP64: u16 = IMAGE_FILE_MACHINE_ALPHA64; -/// Infineon -pub const IMAGE_FILE_MACHINE_TRICORE: u16 = 0x0520; -pub const IMAGE_FILE_MACHINE_CEF: u16 = 0x0CEF; -/// EFI Byte Code -pub const IMAGE_FILE_MACHINE_EBC: u16 = 0x0EBC; -/// AMD64 (K8) -pub const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664; -/// M32R little-endian -pub const IMAGE_FILE_MACHINE_M32R: u16 = 0x9041; -/// ARM64 Little-Endian -pub const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64; -/// ARM64EC ("Emulation Compatible") -pub const IMAGE_FILE_MACHINE_ARM64EC: u16 = 0xA641; -pub const IMAGE_FILE_MACHINE_CEE: u16 = 0xC0EE; -/// RISCV32 -pub const IMAGE_FILE_MACHINE_RISCV32: u16 = 0x5032; -/// RISCV64 -pub const IMAGE_FILE_MACHINE_RISCV64: u16 = 0x5064; -/// RISCV128 -pub const IMAGE_FILE_MACHINE_RISCV128: u16 = 0x5128; - -// -// Directory format. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDataDirectory { -    pub virtual_address: U32<LE>, -    pub size: U32<LE>, -} - -pub const IMAGE_NUMBEROF_DIRECTORY_ENTRIES: usize = 16; - -// -// Optional header format. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageOptionalHeader32 { -    // Standard fields. -    pub magic: U16<LE>, -    pub major_linker_version: u8, -    pub minor_linker_version: u8, -    pub size_of_code: U32<LE>, -    pub size_of_initialized_data: U32<LE>, -    pub size_of_uninitialized_data: U32<LE>, -    pub address_of_entry_point: U32<LE>, -    pub base_of_code: U32<LE>, -    pub base_of_data: U32<LE>, - -    // NT additional fields. -    pub image_base: U32<LE>, -    pub section_alignment: U32<LE>, -    pub file_alignment: U32<LE>, -    pub major_operating_system_version: U16<LE>, -    pub minor_operating_system_version: U16<LE>, -    pub major_image_version: U16<LE>, -    pub minor_image_version: U16<LE>, -    pub major_subsystem_version: U16<LE>, -    pub minor_subsystem_version: U16<LE>, -    pub win32_version_value: U32<LE>, -    pub size_of_image: U32<LE>, -    pub size_of_headers: U32<LE>, -    pub check_sum: U32<LE>, -    pub subsystem: U16<LE>, -    pub dll_characteristics: U16<LE>, -    pub size_of_stack_reserve: U32<LE>, -    pub size_of_stack_commit: U32<LE>, -    pub size_of_heap_reserve: U32<LE>, -    pub size_of_heap_commit: U32<LE>, -    pub loader_flags: U32<LE>, -    pub number_of_rva_and_sizes: U32<LE>, -    //pub data_directory: [ImageDataDirectory; IMAGE_NUMBEROF_DIRECTORY_ENTRIES], -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageRomOptionalHeader { -    pub magic: U16<LE>, -    pub major_linker_version: u8, -    pub minor_linker_version: u8, -    pub size_of_code: U32<LE>, -    pub size_of_initialized_data: U32<LE>, -    pub size_of_uninitialized_data: U32<LE>, -    pub address_of_entry_point: U32<LE>, -    pub base_of_code: U32<LE>, -    pub base_of_data: U32<LE>, -    pub base_of_bss: U32<LE>, -    pub gpr_mask: U32<LE>, -    pub cpr_mask: [U32<LE>; 4], -    pub gp_value: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageOptionalHeader64 { -    pub magic: U16<LE>, -    pub major_linker_version: u8, -    pub minor_linker_version: u8, -    pub size_of_code: U32<LE>, -    pub size_of_initialized_data: U32<LE>, -    pub size_of_uninitialized_data: U32<LE>, -    pub address_of_entry_point: U32<LE>, -    pub base_of_code: U32<LE>, -    pub image_base: U64<LE>, -    pub section_alignment: U32<LE>, -    pub file_alignment: U32<LE>, -    pub major_operating_system_version: U16<LE>, -    pub minor_operating_system_version: U16<LE>, -    pub major_image_version: U16<LE>, -    pub minor_image_version: U16<LE>, -    pub major_subsystem_version: U16<LE>, -    pub minor_subsystem_version: U16<LE>, -    pub win32_version_value: U32<LE>, -    pub size_of_image: U32<LE>, -    pub size_of_headers: U32<LE>, -    pub check_sum: U32<LE>, -    pub subsystem: U16<LE>, -    pub dll_characteristics: U16<LE>, -    pub size_of_stack_reserve: U64<LE>, -    pub size_of_stack_commit: U64<LE>, -    pub size_of_heap_reserve: U64<LE>, -    pub size_of_heap_commit: U64<LE>, -    pub loader_flags: U32<LE>, -    pub number_of_rva_and_sizes: U32<LE>, -    //pub data_directory: [ImageDataDirectory; IMAGE_NUMBEROF_DIRECTORY_ENTRIES], -} - -pub const IMAGE_NT_OPTIONAL_HDR32_MAGIC: u16 = 0x10b; -pub const IMAGE_NT_OPTIONAL_HDR64_MAGIC: u16 = 0x20b; -pub const IMAGE_ROM_OPTIONAL_HDR_MAGIC: u16 = 0x107; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageNtHeaders64 { -    pub signature: U32<LE>, -    pub file_header: ImageFileHeader, -    pub optional_header: ImageOptionalHeader64, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageNtHeaders32 { -    pub signature: U32<LE>, -    pub file_header: ImageFileHeader, -    pub optional_header: ImageOptionalHeader32, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageRomHeaders { -    pub file_header: ImageFileHeader, -    pub optional_header: ImageRomOptionalHeader, -} - -// Values for `ImageOptionalHeader*::subsystem`. - -/// Unknown subsystem. -pub const IMAGE_SUBSYSTEM_UNKNOWN: u16 = 0; -/// Image doesn't require a subsystem. -pub const IMAGE_SUBSYSTEM_NATIVE: u16 = 1; -/// Image runs in the Windows GUI subsystem. -pub const IMAGE_SUBSYSTEM_WINDOWS_GUI: u16 = 2; -/// Image runs in the Windows character subsystem. -pub const IMAGE_SUBSYSTEM_WINDOWS_CUI: u16 = 3; -/// image runs in the OS/2 character subsystem. -pub const IMAGE_SUBSYSTEM_OS2_CUI: u16 = 5; -/// image runs in the Posix character subsystem. -pub const IMAGE_SUBSYSTEM_POSIX_CUI: u16 = 7; -/// image is a native Win9x driver. -pub const IMAGE_SUBSYSTEM_NATIVE_WINDOWS: u16 = 8; -/// Image runs in the Windows CE subsystem. -pub const IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: u16 = 9; -pub const IMAGE_SUBSYSTEM_EFI_APPLICATION: u16 = 10; -pub const IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: u16 = 11; -pub const IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: u16 = 12; -pub const IMAGE_SUBSYSTEM_EFI_ROM: u16 = 13; -pub const IMAGE_SUBSYSTEM_XBOX: u16 = 14; -pub const IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION: u16 = 16; -pub const IMAGE_SUBSYSTEM_XBOX_CODE_CATALOG: u16 = 17; - -// Values for `ImageOptionalHeader*::dll_characteristics`. - -//      IMAGE_LIBRARY_PROCESS_INIT            0x0001     // Reserved. -//      IMAGE_LIBRARY_PROCESS_TERM            0x0002     // Reserved. -//      IMAGE_LIBRARY_THREAD_INIT             0x0004     // Reserved. -//      IMAGE_LIBRARY_THREAD_TERM             0x0008     // Reserved. -/// Image can handle a high entropy 64-bit virtual address space. -pub const IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA: u16 = 0x0020; -/// DLL can move. -pub const IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE: u16 = 0x0040; -/// Code Integrity Image -pub const IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY: u16 = 0x0080; -/// Image is NX compatible -pub const IMAGE_DLLCHARACTERISTICS_NX_COMPAT: u16 = 0x0100; -/// Image understands isolation and doesn't want it -pub const IMAGE_DLLCHARACTERISTICS_NO_ISOLATION: u16 = 0x0200; -/// Image does not use SEH.  No SE handler may reside in this image -pub const IMAGE_DLLCHARACTERISTICS_NO_SEH: u16 = 0x0400; -/// Do not bind this image. -pub const IMAGE_DLLCHARACTERISTICS_NO_BIND: u16 = 0x0800; -/// Image should execute in an AppContainer -pub const IMAGE_DLLCHARACTERISTICS_APPCONTAINER: u16 = 0x1000; -/// Driver uses WDM model -pub const IMAGE_DLLCHARACTERISTICS_WDM_DRIVER: u16 = 0x2000; -/// Image supports Control Flow Guard. -pub const IMAGE_DLLCHARACTERISTICS_GUARD_CF: u16 = 0x4000; -pub const IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE: u16 = 0x8000; - -// Indices for `ImageOptionalHeader*::data_directory`. - -/// Export Directory -pub const IMAGE_DIRECTORY_ENTRY_EXPORT: usize = 0; -/// Import Directory -pub const IMAGE_DIRECTORY_ENTRY_IMPORT: usize = 1; -/// Resource Directory -pub const IMAGE_DIRECTORY_ENTRY_RESOURCE: usize = 2; -/// Exception Directory -pub const IMAGE_DIRECTORY_ENTRY_EXCEPTION: usize = 3; -/// Security Directory -pub const IMAGE_DIRECTORY_ENTRY_SECURITY: usize = 4; -/// Base Relocation Table -pub const IMAGE_DIRECTORY_ENTRY_BASERELOC: usize = 5; -/// Debug Directory -pub const IMAGE_DIRECTORY_ENTRY_DEBUG: usize = 6; -//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage) -/// Architecture Specific Data -pub const IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: usize = 7; -/// RVA of GP -pub const IMAGE_DIRECTORY_ENTRY_GLOBALPTR: usize = 8; -/// TLS Directory -pub const IMAGE_DIRECTORY_ENTRY_TLS: usize = 9; -/// Load Configuration Directory -pub const IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: usize = 10; -/// Bound Import Directory in headers -pub const IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: usize = 11; -/// Import Address Table -pub const IMAGE_DIRECTORY_ENTRY_IAT: usize = 12; -/// Delay Load Import Descriptors -pub const IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: usize = 13; -/// COM Runtime descriptor -pub const IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: usize = 14; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(C)] -pub struct Guid(pub [u8; 16]); - -impl Guid { -    #[inline] -    pub fn data1(self) -> U32<LE> { -        U32::from_bytes(self.0[0..4].try_into().unwrap()) -    } - -    #[inline] -    pub fn data2(self) -> U16<LE> { -        U16::from_bytes(self.0[4..6].try_into().unwrap()) -    } - -    #[inline] -    pub fn data3(self) -> U16<LE> { -        U16::from_bytes(self.0[6..8].try_into().unwrap()) -    } - -    #[inline] -    pub fn data4(self) -> [u8; 8] { -        self.0[8..16].try_into().unwrap() -    } -} - -pub use Guid as ClsId; - -/// Non-COFF Object file header -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AnonObjectHeader { -    /// Must be IMAGE_FILE_MACHINE_UNKNOWN -    pub sig1: U16<LE>, -    /// Must be 0xffff -    pub sig2: U16<LE>, -    /// >= 1 (implies the ClsId field is present) -    pub version: U16<LE>, -    pub machine: U16<LE>, -    pub time_date_stamp: U32<LE>, -    /// Used to invoke CoCreateInstance -    pub class_id: ClsId, -    /// Size of data that follows the header -    pub size_of_data: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AnonObjectHeaderV2 { -    /// Must be IMAGE_FILE_MACHINE_UNKNOWN -    pub sig1: U16<LE>, -    /// Must be 0xffff -    pub sig2: U16<LE>, -    /// >= 2 (implies the Flags field is present - otherwise V1) -    pub version: U16<LE>, -    pub machine: U16<LE>, -    pub time_date_stamp: U32<LE>, -    /// Used to invoke CoCreateInstance -    pub class_id: ClsId, -    /// Size of data that follows the header -    pub size_of_data: U32<LE>, -    /// 0x1 -> contains metadata -    pub flags: U32<LE>, -    /// Size of CLR metadata -    pub meta_data_size: U32<LE>, -    /// Offset of CLR metadata -    pub meta_data_offset: U32<LE>, -} - -/// The required value of `AnonObjectHeaderBigobj::class_id`. -pub const ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID: ClsId = ClsId([ -    0xC7, 0xA1, 0xBA, 0xD1, 0xEE, 0xBA, 0xA9, 0x4B, 0xAF, 0x20, 0xFA, 0xF6, 0x6A, 0xA4, 0xDC, 0xB8, -]); - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AnonObjectHeaderBigobj { -    /* same as ANON_OBJECT_HEADER_V2 */ -    /// Must be IMAGE_FILE_MACHINE_UNKNOWN -    pub sig1: U16<LE>, -    /// Must be 0xffff -    pub sig2: U16<LE>, -    /// >= 2 (implies the Flags field is present) -    pub version: U16<LE>, -    /// Actual machine - IMAGE_FILE_MACHINE_xxx -    pub machine: U16<LE>, -    pub time_date_stamp: U32<LE>, -    /// Must be `ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID`. -    pub class_id: ClsId, -    /// Size of data that follows the header -    pub size_of_data: U32<LE>, -    /// 0x1 -> contains metadata -    pub flags: U32<LE>, -    /// Size of CLR metadata -    pub meta_data_size: U32<LE>, -    /// Offset of CLR metadata -    pub meta_data_offset: U32<LE>, - -    /* bigobj specifics */ -    /// extended from WORD -    pub number_of_sections: U32<LE>, -    pub pointer_to_symbol_table: U32<LE>, -    pub number_of_symbols: U32<LE>, -} - -pub const IMAGE_SIZEOF_SHORT_NAME: usize = 8; - -// -// Section header format. -// - -#[derive(Debug, Default, Clone, Copy)] -#[repr(C)] -pub struct ImageSectionHeader { -    pub name: [u8; IMAGE_SIZEOF_SHORT_NAME], -    pub virtual_size: U32<LE>, -    pub virtual_address: U32<LE>, -    pub size_of_raw_data: U32<LE>, -    pub pointer_to_raw_data: U32<LE>, -    pub pointer_to_relocations: U32<LE>, -    pub pointer_to_linenumbers: U32<LE>, -    pub number_of_relocations: U16<LE>, -    pub number_of_linenumbers: U16<LE>, -    pub characteristics: U32<LE>, -} - -pub const IMAGE_SIZEOF_SECTION_HEADER: usize = 40; - -// Values for `ImageSectionHeader::characteristics`. - -//      IMAGE_SCN_TYPE_REG                   0x00000000  // Reserved. -//      IMAGE_SCN_TYPE_DSECT                 0x00000001  // Reserved. -//      IMAGE_SCN_TYPE_NOLOAD                0x00000002  // Reserved. -//      IMAGE_SCN_TYPE_GROUP                 0x00000004  // Reserved. -/// Reserved. -pub const IMAGE_SCN_TYPE_NO_PAD: u32 = 0x0000_0008; -//      IMAGE_SCN_TYPE_COPY                  0x00000010  // Reserved. - -/// Section contains code. -pub const IMAGE_SCN_CNT_CODE: u32 = 0x0000_0020; -/// Section contains initialized data. -pub const IMAGE_SCN_CNT_INITIALIZED_DATA: u32 = 0x0000_0040; -/// Section contains uninitialized data. -pub const IMAGE_SCN_CNT_UNINITIALIZED_DATA: u32 = 0x0000_0080; - -/// Reserved. -pub const IMAGE_SCN_LNK_OTHER: u32 = 0x0000_0100; -/// Section contains comments or some other type of information. -pub const IMAGE_SCN_LNK_INFO: u32 = 0x0000_0200; -//      IMAGE_SCN_TYPE_OVER                  0x00000400  // Reserved. -/// Section contents will not become part of image. -pub const IMAGE_SCN_LNK_REMOVE: u32 = 0x0000_0800; -/// Section contents comdat. -pub const IMAGE_SCN_LNK_COMDAT: u32 = 0x0000_1000; -//                                           0x00002000  // Reserved. -//      IMAGE_SCN_MEM_PROTECTED - Obsolete   0x00004000 -/// Reset speculative exceptions handling bits in the TLB entries for this section. -pub const IMAGE_SCN_NO_DEFER_SPEC_EXC: u32 = 0x0000_4000; -/// Section content can be accessed relative to GP -pub const IMAGE_SCN_GPREL: u32 = 0x0000_8000; -pub const IMAGE_SCN_MEM_FARDATA: u32 = 0x0000_8000; -//      IMAGE_SCN_MEM_SYSHEAP  - Obsolete    0x00010000 -pub const IMAGE_SCN_MEM_PURGEABLE: u32 = 0x0002_0000; -pub const IMAGE_SCN_MEM_16BIT: u32 = 0x0002_0000; -pub const IMAGE_SCN_MEM_LOCKED: u32 = 0x0004_0000; -pub const IMAGE_SCN_MEM_PRELOAD: u32 = 0x0008_0000; - -pub const IMAGE_SCN_ALIGN_1BYTES: u32 = 0x0010_0000; -pub const IMAGE_SCN_ALIGN_2BYTES: u32 = 0x0020_0000; -pub const IMAGE_SCN_ALIGN_4BYTES: u32 = 0x0030_0000; -pub const IMAGE_SCN_ALIGN_8BYTES: u32 = 0x0040_0000; -/// Default alignment if no others are specified. -pub const IMAGE_SCN_ALIGN_16BYTES: u32 = 0x0050_0000; -pub const IMAGE_SCN_ALIGN_32BYTES: u32 = 0x0060_0000; -pub const IMAGE_SCN_ALIGN_64BYTES: u32 = 0x0070_0000; -pub const IMAGE_SCN_ALIGN_128BYTES: u32 = 0x0080_0000; -pub const IMAGE_SCN_ALIGN_256BYTES: u32 = 0x0090_0000; -pub const IMAGE_SCN_ALIGN_512BYTES: u32 = 0x00A0_0000; -pub const IMAGE_SCN_ALIGN_1024BYTES: u32 = 0x00B0_0000; -pub const IMAGE_SCN_ALIGN_2048BYTES: u32 = 0x00C0_0000; -pub const IMAGE_SCN_ALIGN_4096BYTES: u32 = 0x00D0_0000; -pub const IMAGE_SCN_ALIGN_8192BYTES: u32 = 0x00E0_0000; -// Unused                                    0x00F0_0000 -pub const IMAGE_SCN_ALIGN_MASK: u32 = 0x00F0_0000; - -/// Section contains extended relocations. -pub const IMAGE_SCN_LNK_NRELOC_OVFL: u32 = 0x0100_0000; -/// Section can be discarded. -pub const IMAGE_SCN_MEM_DISCARDABLE: u32 = 0x0200_0000; -/// Section is not cacheable. -pub const IMAGE_SCN_MEM_NOT_CACHED: u32 = 0x0400_0000; -/// Section is not pageable. -pub const IMAGE_SCN_MEM_NOT_PAGED: u32 = 0x0800_0000; -/// Section is shareable. -pub const IMAGE_SCN_MEM_SHARED: u32 = 0x1000_0000; -/// Section is executable. -pub const IMAGE_SCN_MEM_EXECUTE: u32 = 0x2000_0000; -/// Section is readable. -pub const IMAGE_SCN_MEM_READ: u32 = 0x4000_0000; -/// Section is writeable. -pub const IMAGE_SCN_MEM_WRITE: u32 = 0x8000_0000; - -// -// TLS Characteristic Flags -// -/// Tls index is scaled -pub const IMAGE_SCN_SCALE_INDEX: u32 = 0x0000_0001; - -// -// Symbol format. -// - -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageSymbol { -    /// If first 4 bytes are 0, then second 4 bytes are offset into string table. -    pub name: [u8; 8], -    pub value: U32Bytes<LE>, -    pub section_number: U16Bytes<LE>, -    pub typ: U16Bytes<LE>, -    pub storage_class: u8, -    pub number_of_aux_symbols: u8, -} - -pub const IMAGE_SIZEOF_SYMBOL: usize = 18; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageSymbolBytes(pub [u8; IMAGE_SIZEOF_SYMBOL]); - -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageSymbolEx { -    /// If first 4 bytes are 0, then second 4 bytes are offset into string table. -    pub name: [u8; 8], -    pub value: U32Bytes<LE>, -    pub section_number: I32Bytes<LE>, -    pub typ: U16Bytes<LE>, -    pub storage_class: u8, -    pub number_of_aux_symbols: u8, -} - -pub const IMAGE_SIZEOF_SYMBOL_EX: usize = 20; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageSymbolExBytes(pub [u8; IMAGE_SIZEOF_SYMBOL_EX]); - -// Values for `ImageSymbol::section_number`. -// -// Symbols have a section number of the section in which they are -// defined. Otherwise, section numbers have the following meanings: - -/// Symbol is undefined or is common. -pub const IMAGE_SYM_UNDEFINED: i32 = 0; -/// Symbol is an absolute value. -pub const IMAGE_SYM_ABSOLUTE: i32 = -1; -/// Symbol is a special debug item. -pub const IMAGE_SYM_DEBUG: i32 = -2; -/// Values 0xFF00-0xFFFF are special -pub const IMAGE_SYM_SECTION_MAX: u16 = 0xFEFF; -pub const IMAGE_SYM_SECTION_MAX_EX: u32 = 0x7fff_ffff; - -// Values for `ImageSymbol::typ` (basic component). - -/// no type. -pub const IMAGE_SYM_TYPE_NULL: u16 = 0x0000; -pub const IMAGE_SYM_TYPE_VOID: u16 = 0x0001; -/// type character. -pub const IMAGE_SYM_TYPE_CHAR: u16 = 0x0002; -/// type short integer. -pub const IMAGE_SYM_TYPE_SHORT: u16 = 0x0003; -pub const IMAGE_SYM_TYPE_INT: u16 = 0x0004; -pub const IMAGE_SYM_TYPE_LONG: u16 = 0x0005; -pub const IMAGE_SYM_TYPE_FLOAT: u16 = 0x0006; -pub const IMAGE_SYM_TYPE_DOUBLE: u16 = 0x0007; -pub const IMAGE_SYM_TYPE_STRUCT: u16 = 0x0008; -pub const IMAGE_SYM_TYPE_UNION: u16 = 0x0009; -/// enumeration. -pub const IMAGE_SYM_TYPE_ENUM: u16 = 0x000A; -/// member of enumeration. -pub const IMAGE_SYM_TYPE_MOE: u16 = 0x000B; -pub const IMAGE_SYM_TYPE_BYTE: u16 = 0x000C; -pub const IMAGE_SYM_TYPE_WORD: u16 = 0x000D; -pub const IMAGE_SYM_TYPE_UINT: u16 = 0x000E; -pub const IMAGE_SYM_TYPE_DWORD: u16 = 0x000F; -pub const IMAGE_SYM_TYPE_PCODE: u16 = 0x8000; - -// Values for `ImageSymbol::typ` (derived component). - -/// no derived type. -pub const IMAGE_SYM_DTYPE_NULL: u16 = 0; -/// pointer. -pub const IMAGE_SYM_DTYPE_POINTER: u16 = 1; -/// function. -pub const IMAGE_SYM_DTYPE_FUNCTION: u16 = 2; -/// array. -pub const IMAGE_SYM_DTYPE_ARRAY: u16 = 3; - -// Values for `ImageSymbol::storage_class`. -pub const IMAGE_SYM_CLASS_END_OF_FUNCTION: u8 = 0xff; -pub const IMAGE_SYM_CLASS_NULL: u8 = 0x00; -pub const IMAGE_SYM_CLASS_AUTOMATIC: u8 = 0x01; -pub const IMAGE_SYM_CLASS_EXTERNAL: u8 = 0x02; -pub const IMAGE_SYM_CLASS_STATIC: u8 = 0x03; -pub const IMAGE_SYM_CLASS_REGISTER: u8 = 0x04; -pub const IMAGE_SYM_CLASS_EXTERNAL_DEF: u8 = 0x05; -pub const IMAGE_SYM_CLASS_LABEL: u8 = 0x06; -pub const IMAGE_SYM_CLASS_UNDEFINED_LABEL: u8 = 0x07; -pub const IMAGE_SYM_CLASS_MEMBER_OF_STRUCT: u8 = 0x08; -pub const IMAGE_SYM_CLASS_ARGUMENT: u8 = 0x09; -pub const IMAGE_SYM_CLASS_STRUCT_TAG: u8 = 0x0A; -pub const IMAGE_SYM_CLASS_MEMBER_OF_UNION: u8 = 0x0B; -pub const IMAGE_SYM_CLASS_UNION_TAG: u8 = 0x0C; -pub const IMAGE_SYM_CLASS_TYPE_DEFINITION: u8 = 0x0D; -pub const IMAGE_SYM_CLASS_UNDEFINED_STATIC: u8 = 0x0E; -pub const IMAGE_SYM_CLASS_ENUM_TAG: u8 = 0x0F; -pub const IMAGE_SYM_CLASS_MEMBER_OF_ENUM: u8 = 0x10; -pub const IMAGE_SYM_CLASS_REGISTER_PARAM: u8 = 0x11; -pub const IMAGE_SYM_CLASS_BIT_FIELD: u8 = 0x12; - -pub const IMAGE_SYM_CLASS_FAR_EXTERNAL: u8 = 0x44; - -pub const IMAGE_SYM_CLASS_BLOCK: u8 = 0x64; -pub const IMAGE_SYM_CLASS_FUNCTION: u8 = 0x65; -pub const IMAGE_SYM_CLASS_END_OF_STRUCT: u8 = 0x66; -pub const IMAGE_SYM_CLASS_FILE: u8 = 0x67; -// new -pub const IMAGE_SYM_CLASS_SECTION: u8 = 0x68; -pub const IMAGE_SYM_CLASS_WEAK_EXTERNAL: u8 = 0x69; - -pub const IMAGE_SYM_CLASS_CLR_TOKEN: u8 = 0x6B; - -// type packing constants - -pub const N_BTMASK: u16 = 0x000F; -pub const N_TMASK: u16 = 0x0030; -pub const N_TMASK1: u16 = 0x00C0; -pub const N_TMASK2: u16 = 0x00F0; -pub const N_BTSHFT: usize = 4; -pub const N_TSHIFT: usize = 2; - -pub const IMAGE_SYM_DTYPE_SHIFT: usize = N_BTSHFT; - -// -// Auxiliary entry format. -// - -// Used for both ImageSymbol and ImageSymbolEx (with padding). -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAuxSymbolTokenDef { -    /// IMAGE_AUX_SYMBOL_TYPE -    pub aux_type: u8, -    /// Must be 0 -    pub reserved1: u8, -    pub symbol_table_index: U32Bytes<LE>, -    /// Must be 0 -    pub reserved2: [u8; 12], -} - -pub const IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF: u16 = 1; - -/// Auxiliary symbol format 1: function definitions. -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAuxSymbolFunction { -    pub tag_index: U32Bytes<LE>, -    pub total_size: U32Bytes<LE>, -    pub pointer_to_linenumber: U32Bytes<LE>, -    pub pointer_to_next_function: U32Bytes<LE>, -    pub unused: [u8; 2], -} - -/// Auxiliary symbol format 2: .bf and .ef symbols. -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAuxSymbolFunctionBeginEnd { -    pub unused1: [u8; 4], -    /// declaration line number -    pub linenumber: U16Bytes<LE>, -    pub unused2: [u8; 6], -    pub pointer_to_next_function: U32Bytes<LE>, -    pub unused3: [u8; 2], -} - -/// Auxiliary symbol format 3: weak externals. -/// -/// Used for both `ImageSymbol` and `ImageSymbolEx` (both with padding). -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAuxSymbolWeak { -    /// the weak extern default symbol index -    pub weak_default_sym_index: U32Bytes<LE>, -    pub weak_search_type: U32Bytes<LE>, -} - -/// Auxiliary symbol format 5: sections. -/// -/// Used for both `ImageSymbol` and `ImageSymbolEx` (with padding). -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAuxSymbolSection { -    /// section length -    pub length: U32Bytes<LE>, -    /// number of relocation entries -    pub number_of_relocations: U16Bytes<LE>, -    /// number of line numbers -    pub number_of_linenumbers: U16Bytes<LE>, -    /// checksum for communal -    pub check_sum: U32Bytes<LE>, -    /// section number to associate with -    pub number: U16Bytes<LE>, -    /// communal selection type -    pub selection: u8, -    pub reserved: u8, -    /// high bits of the section number -    pub high_number: U16Bytes<LE>, -} - -// Used for both ImageSymbol and ImageSymbolEx (both with padding). -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAuxSymbolCrc { -    pub crc: U32Bytes<LE>, -} - -// -// Communal selection types. -// - -pub const IMAGE_COMDAT_SELECT_NODUPLICATES: u8 = 1; -pub const IMAGE_COMDAT_SELECT_ANY: u8 = 2; -pub const IMAGE_COMDAT_SELECT_SAME_SIZE: u8 = 3; -pub const IMAGE_COMDAT_SELECT_EXACT_MATCH: u8 = 4; -pub const IMAGE_COMDAT_SELECT_ASSOCIATIVE: u8 = 5; -pub const IMAGE_COMDAT_SELECT_LARGEST: u8 = 6; -pub const IMAGE_COMDAT_SELECT_NEWEST: u8 = 7; - -pub const IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY: u16 = 1; -pub const IMAGE_WEAK_EXTERN_SEARCH_LIBRARY: u16 = 2; -pub const IMAGE_WEAK_EXTERN_SEARCH_ALIAS: u16 = 3; -pub const IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY: u16 = 4; - -// -// Relocation format. -// - -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageRelocation { -    /// Also `RelocCount` when IMAGE_SCN_LNK_NRELOC_OVFL is set -    pub virtual_address: U32Bytes<LE>, -    pub symbol_table_index: U32Bytes<LE>, -    pub typ: U16Bytes<LE>, -} - -// -// I386 relocation types. -// -/// Reference is absolute, no relocation is necessary -pub const IMAGE_REL_I386_ABSOLUTE: u16 = 0x0000; -/// Direct 16-bit reference to the symbols virtual address -pub const IMAGE_REL_I386_DIR16: u16 = 0x0001; -/// PC-relative 16-bit reference to the symbols virtual address -pub const IMAGE_REL_I386_REL16: u16 = 0x0002; -/// Direct 32-bit reference to the symbols virtual address -pub const IMAGE_REL_I386_DIR32: u16 = 0x0006; -/// Direct 32-bit reference to the symbols virtual address, base not included -pub const IMAGE_REL_I386_DIR32NB: u16 = 0x0007; -/// Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address -pub const IMAGE_REL_I386_SEG12: u16 = 0x0009; -pub const IMAGE_REL_I386_SECTION: u16 = 0x000A; -pub const IMAGE_REL_I386_SECREL: u16 = 0x000B; -/// clr token -pub const IMAGE_REL_I386_TOKEN: u16 = 0x000C; -/// 7 bit offset from base of section containing target -pub const IMAGE_REL_I386_SECREL7: u16 = 0x000D; -/// PC-relative 32-bit reference to the symbols virtual address -pub const IMAGE_REL_I386_REL32: u16 = 0x0014; - -// -// MIPS relocation types. -// -/// Reference is absolute, no relocation is necessary -pub const IMAGE_REL_MIPS_ABSOLUTE: u16 = 0x0000; -pub const IMAGE_REL_MIPS_REFHALF: u16 = 0x0001; -pub const IMAGE_REL_MIPS_REFWORD: u16 = 0x0002; -pub const IMAGE_REL_MIPS_JMPADDR: u16 = 0x0003; -pub const IMAGE_REL_MIPS_REFHI: u16 = 0x0004; -pub const IMAGE_REL_MIPS_REFLO: u16 = 0x0005; -pub const IMAGE_REL_MIPS_GPREL: u16 = 0x0006; -pub const IMAGE_REL_MIPS_LITERAL: u16 = 0x0007; -pub const IMAGE_REL_MIPS_SECTION: u16 = 0x000A; -pub const IMAGE_REL_MIPS_SECREL: u16 = 0x000B; -/// Low 16-bit section relative reference (used for >32k TLS) -pub const IMAGE_REL_MIPS_SECRELLO: u16 = 0x000C; -/// High 16-bit section relative reference (used for >32k TLS) -pub const IMAGE_REL_MIPS_SECRELHI: u16 = 0x000D; -/// clr token -pub const IMAGE_REL_MIPS_TOKEN: u16 = 0x000E; -pub const IMAGE_REL_MIPS_JMPADDR16: u16 = 0x0010; -pub const IMAGE_REL_MIPS_REFWORDNB: u16 = 0x0022; -pub const IMAGE_REL_MIPS_PAIR: u16 = 0x0025; - -// -// Alpha Relocation types. -// -pub const IMAGE_REL_ALPHA_ABSOLUTE: u16 = 0x0000; -pub const IMAGE_REL_ALPHA_REFLONG: u16 = 0x0001; -pub const IMAGE_REL_ALPHA_REFQUAD: u16 = 0x0002; -pub const IMAGE_REL_ALPHA_GPREL32: u16 = 0x0003; -pub const IMAGE_REL_ALPHA_LITERAL: u16 = 0x0004; -pub const IMAGE_REL_ALPHA_LITUSE: u16 = 0x0005; -pub const IMAGE_REL_ALPHA_GPDISP: u16 = 0x0006; -pub const IMAGE_REL_ALPHA_BRADDR: u16 = 0x0007; -pub const IMAGE_REL_ALPHA_HINT: u16 = 0x0008; -pub const IMAGE_REL_ALPHA_INLINE_REFLONG: u16 = 0x0009; -pub const IMAGE_REL_ALPHA_REFHI: u16 = 0x000A; -pub const IMAGE_REL_ALPHA_REFLO: u16 = 0x000B; -pub const IMAGE_REL_ALPHA_PAIR: u16 = 0x000C; -pub const IMAGE_REL_ALPHA_MATCH: u16 = 0x000D; -pub const IMAGE_REL_ALPHA_SECTION: u16 = 0x000E; -pub const IMAGE_REL_ALPHA_SECREL: u16 = 0x000F; -pub const IMAGE_REL_ALPHA_REFLONGNB: u16 = 0x0010; -/// Low 16-bit section relative reference -pub const IMAGE_REL_ALPHA_SECRELLO: u16 = 0x0011; -/// High 16-bit section relative reference -pub const IMAGE_REL_ALPHA_SECRELHI: u16 = 0x0012; -/// High 16 bits of 48 bit reference -pub const IMAGE_REL_ALPHA_REFQ3: u16 = 0x0013; -/// Middle 16 bits of 48 bit reference -pub const IMAGE_REL_ALPHA_REFQ2: u16 = 0x0014; -/// Low 16 bits of 48 bit reference -pub const IMAGE_REL_ALPHA_REFQ1: u16 = 0x0015; -/// Low 16-bit GP relative reference -pub const IMAGE_REL_ALPHA_GPRELLO: u16 = 0x0016; -/// High 16-bit GP relative reference -pub const IMAGE_REL_ALPHA_GPRELHI: u16 = 0x0017; - -// -// IBM PowerPC relocation types. -// -/// NOP -pub const IMAGE_REL_PPC_ABSOLUTE: u16 = 0x0000; -/// 64-bit address -pub const IMAGE_REL_PPC_ADDR64: u16 = 0x0001; -/// 32-bit address -pub const IMAGE_REL_PPC_ADDR32: u16 = 0x0002; -/// 26-bit address, shifted left 2 (branch absolute) -pub const IMAGE_REL_PPC_ADDR24: u16 = 0x0003; -/// 16-bit address -pub const IMAGE_REL_PPC_ADDR16: u16 = 0x0004; -/// 16-bit address, shifted left 2 (load doubleword) -pub const IMAGE_REL_PPC_ADDR14: u16 = 0x0005; -/// 26-bit PC-relative offset, shifted left 2 (branch relative) -pub const IMAGE_REL_PPC_REL24: u16 = 0x0006; -/// 16-bit PC-relative offset, shifted left 2 (br cond relative) -pub const IMAGE_REL_PPC_REL14: u16 = 0x0007; -/// 16-bit offset from TOC base -pub const IMAGE_REL_PPC_TOCREL16: u16 = 0x0008; -/// 16-bit offset from TOC base, shifted left 2 (load doubleword) -pub const IMAGE_REL_PPC_TOCREL14: u16 = 0x0009; - -/// 32-bit addr w/o image base -pub const IMAGE_REL_PPC_ADDR32NB: u16 = 0x000A; -/// va of containing section (as in an image sectionhdr) -pub const IMAGE_REL_PPC_SECREL: u16 = 0x000B; -/// sectionheader number -pub const IMAGE_REL_PPC_SECTION: u16 = 0x000C; -/// substitute TOC restore instruction iff symbol is glue code -pub const IMAGE_REL_PPC_IFGLUE: u16 = 0x000D; -/// symbol is glue code; virtual address is TOC restore instruction -pub const IMAGE_REL_PPC_IMGLUE: u16 = 0x000E; -/// va of containing section (limited to 16 bits) -pub const IMAGE_REL_PPC_SECREL16: u16 = 0x000F; -pub const IMAGE_REL_PPC_REFHI: u16 = 0x0010; -pub const IMAGE_REL_PPC_REFLO: u16 = 0x0011; -pub const IMAGE_REL_PPC_PAIR: u16 = 0x0012; -/// Low 16-bit section relative reference (used for >32k TLS) -pub const IMAGE_REL_PPC_SECRELLO: u16 = 0x0013; -/// High 16-bit section relative reference (used for >32k TLS) -pub const IMAGE_REL_PPC_SECRELHI: u16 = 0x0014; -pub const IMAGE_REL_PPC_GPREL: u16 = 0x0015; -/// clr token -pub const IMAGE_REL_PPC_TOKEN: u16 = 0x0016; - -/// mask to isolate above values in IMAGE_RELOCATION.Type -pub const IMAGE_REL_PPC_TYPEMASK: u16 = 0x00FF; - -// Flag bits in `ImageRelocation::typ`. - -/// subtract reloc value rather than adding it -pub const IMAGE_REL_PPC_NEG: u16 = 0x0100; -/// fix branch prediction bit to predict branch taken -pub const IMAGE_REL_PPC_BRTAKEN: u16 = 0x0200; -/// fix branch prediction bit to predict branch not taken -pub const IMAGE_REL_PPC_BRNTAKEN: u16 = 0x0400; -/// toc slot defined in file (or, data in toc) -pub const IMAGE_REL_PPC_TOCDEFN: u16 = 0x0800; - -// -// Hitachi SH3 relocation types. -// -/// No relocation -pub const IMAGE_REL_SH3_ABSOLUTE: u16 = 0x0000; -/// 16 bit direct -pub const IMAGE_REL_SH3_DIRECT16: u16 = 0x0001; -/// 32 bit direct -pub const IMAGE_REL_SH3_DIRECT32: u16 = 0x0002; -/// 8 bit direct, -128..255 -pub const IMAGE_REL_SH3_DIRECT8: u16 = 0x0003; -/// 8 bit direct .W (0 ext.) -pub const IMAGE_REL_SH3_DIRECT8_WORD: u16 = 0x0004; -/// 8 bit direct .L (0 ext.) -pub const IMAGE_REL_SH3_DIRECT8_LONG: u16 = 0x0005; -/// 4 bit direct (0 ext.) -pub const IMAGE_REL_SH3_DIRECT4: u16 = 0x0006; -/// 4 bit direct .W (0 ext.) -pub const IMAGE_REL_SH3_DIRECT4_WORD: u16 = 0x0007; -/// 4 bit direct .L (0 ext.) -pub const IMAGE_REL_SH3_DIRECT4_LONG: u16 = 0x0008; -/// 8 bit PC relative .W -pub const IMAGE_REL_SH3_PCREL8_WORD: u16 = 0x0009; -/// 8 bit PC relative .L -pub const IMAGE_REL_SH3_PCREL8_LONG: u16 = 0x000A; -/// 12 LSB PC relative .W -pub const IMAGE_REL_SH3_PCREL12_WORD: u16 = 0x000B; -/// Start of EXE section -pub const IMAGE_REL_SH3_STARTOF_SECTION: u16 = 0x000C; -/// Size of EXE section -pub const IMAGE_REL_SH3_SIZEOF_SECTION: u16 = 0x000D; -/// Section table index -pub const IMAGE_REL_SH3_SECTION: u16 = 0x000E; -/// Offset within section -pub const IMAGE_REL_SH3_SECREL: u16 = 0x000F; -/// 32 bit direct not based -pub const IMAGE_REL_SH3_DIRECT32_NB: u16 = 0x0010; -/// GP-relative addressing -pub const IMAGE_REL_SH3_GPREL4_LONG: u16 = 0x0011; -/// clr token -pub const IMAGE_REL_SH3_TOKEN: u16 = 0x0012; -/// Offset from current instruction in longwords -/// if not NOMODE, insert the inverse of the low bit at bit 32 to select PTA/PTB -pub const IMAGE_REL_SHM_PCRELPT: u16 = 0x0013; -/// Low bits of 32-bit address -pub const IMAGE_REL_SHM_REFLO: u16 = 0x0014; -/// High bits of 32-bit address -pub const IMAGE_REL_SHM_REFHALF: u16 = 0x0015; -/// Low bits of relative reference -pub const IMAGE_REL_SHM_RELLO: u16 = 0x0016; -/// High bits of relative reference -pub const IMAGE_REL_SHM_RELHALF: u16 = 0x0017; -/// offset operand for relocation -pub const IMAGE_REL_SHM_PAIR: u16 = 0x0018; - -/// relocation ignores section mode -pub const IMAGE_REL_SH_NOMODE: u16 = 0x8000; - -/// No relocation required -pub const IMAGE_REL_ARM_ABSOLUTE: u16 = 0x0000; -/// 32 bit address -pub const IMAGE_REL_ARM_ADDR32: u16 = 0x0001; -/// 32 bit address w/o image base -pub const IMAGE_REL_ARM_ADDR32NB: u16 = 0x0002; -/// 24 bit offset << 2 & sign ext. -pub const IMAGE_REL_ARM_BRANCH24: u16 = 0x0003; -/// Thumb: 2 11 bit offsets -pub const IMAGE_REL_ARM_BRANCH11: u16 = 0x0004; -/// clr token -pub const IMAGE_REL_ARM_TOKEN: u16 = 0x0005; -/// GP-relative addressing (ARM) -pub const IMAGE_REL_ARM_GPREL12: u16 = 0x0006; -/// GP-relative addressing (Thumb) -pub const IMAGE_REL_ARM_GPREL7: u16 = 0x0007; -pub const IMAGE_REL_ARM_BLX24: u16 = 0x0008; -pub const IMAGE_REL_ARM_BLX11: u16 = 0x0009; -/// 32-bit relative address from byte following reloc -pub const IMAGE_REL_ARM_REL32: u16 = 0x000A; -/// Section table index -pub const IMAGE_REL_ARM_SECTION: u16 = 0x000E; -/// Offset within section -pub const IMAGE_REL_ARM_SECREL: u16 = 0x000F; -/// ARM: MOVW/MOVT -pub const IMAGE_REL_ARM_MOV32A: u16 = 0x0010; -/// ARM: MOVW/MOVT (deprecated) -pub const IMAGE_REL_ARM_MOV32: u16 = 0x0010; -/// Thumb: MOVW/MOVT -pub const IMAGE_REL_ARM_MOV32T: u16 = 0x0011; -/// Thumb: MOVW/MOVT (deprecated) -pub const IMAGE_REL_THUMB_MOV32: u16 = 0x0011; -/// Thumb: 32-bit conditional B -pub const IMAGE_REL_ARM_BRANCH20T: u16 = 0x0012; -/// Thumb: 32-bit conditional B (deprecated) -pub const IMAGE_REL_THUMB_BRANCH20: u16 = 0x0012; -/// Thumb: 32-bit B or BL -pub const IMAGE_REL_ARM_BRANCH24T: u16 = 0x0014; -/// Thumb: 32-bit B or BL (deprecated) -pub const IMAGE_REL_THUMB_BRANCH24: u16 = 0x0014; -/// Thumb: BLX immediate -pub const IMAGE_REL_ARM_BLX23T: u16 = 0x0015; -/// Thumb: BLX immediate (deprecated) -pub const IMAGE_REL_THUMB_BLX23: u16 = 0x0015; - -pub const IMAGE_REL_AM_ABSOLUTE: u16 = 0x0000; -pub const IMAGE_REL_AM_ADDR32: u16 = 0x0001; -pub const IMAGE_REL_AM_ADDR32NB: u16 = 0x0002; -pub const IMAGE_REL_AM_CALL32: u16 = 0x0003; -pub const IMAGE_REL_AM_FUNCINFO: u16 = 0x0004; -pub const IMAGE_REL_AM_REL32_1: u16 = 0x0005; -pub const IMAGE_REL_AM_REL32_2: u16 = 0x0006; -pub const IMAGE_REL_AM_SECREL: u16 = 0x0007; -pub const IMAGE_REL_AM_SECTION: u16 = 0x0008; -pub const IMAGE_REL_AM_TOKEN: u16 = 0x0009; - -// -// ARM64 relocations types. -// - -/// No relocation required -pub const IMAGE_REL_ARM64_ABSOLUTE: u16 = 0x0000; -/// 32 bit address. Review! do we need it? -pub const IMAGE_REL_ARM64_ADDR32: u16 = 0x0001; -/// 32 bit address w/o image base (RVA: for Data/PData/XData) -pub const IMAGE_REL_ARM64_ADDR32NB: u16 = 0x0002; -/// 26 bit offset << 2 & sign ext. for B & BL -pub const IMAGE_REL_ARM64_BRANCH26: u16 = 0x0003; -/// ADRP -pub const IMAGE_REL_ARM64_PAGEBASE_REL21: u16 = 0x0004; -/// ADR -pub const IMAGE_REL_ARM64_REL21: u16 = 0x0005; -/// ADD/ADDS (immediate) with zero shift, for page offset -pub const IMAGE_REL_ARM64_PAGEOFFSET_12A: u16 = 0x0006; -/// LDR (indexed, unsigned immediate), for page offset -pub const IMAGE_REL_ARM64_PAGEOFFSET_12L: u16 = 0x0007; -/// Offset within section -pub const IMAGE_REL_ARM64_SECREL: u16 = 0x0008; -/// ADD/ADDS (immediate) with zero shift, for bit 0:11 of section offset -pub const IMAGE_REL_ARM64_SECREL_LOW12A: u16 = 0x0009; -/// ADD/ADDS (immediate) with zero shift, for bit 12:23 of section offset -pub const IMAGE_REL_ARM64_SECREL_HIGH12A: u16 = 0x000A; -/// LDR (indexed, unsigned immediate), for bit 0:11 of section offset -pub const IMAGE_REL_ARM64_SECREL_LOW12L: u16 = 0x000B; -pub const IMAGE_REL_ARM64_TOKEN: u16 = 0x000C; -/// Section table index -pub const IMAGE_REL_ARM64_SECTION: u16 = 0x000D; -/// 64 bit address -pub const IMAGE_REL_ARM64_ADDR64: u16 = 0x000E; -/// 19 bit offset << 2 & sign ext. for conditional B -pub const IMAGE_REL_ARM64_BRANCH19: u16 = 0x000F; -/// TBZ/TBNZ -pub const IMAGE_REL_ARM64_BRANCH14: u16 = 0x0010; -/// 32-bit relative address from byte following reloc -pub const IMAGE_REL_ARM64_REL32: u16 = 0x0011; - -// -// x64 relocations -// -/// Reference is absolute, no relocation is necessary -pub const IMAGE_REL_AMD64_ABSOLUTE: u16 = 0x0000; -/// 64-bit address (VA). -pub const IMAGE_REL_AMD64_ADDR64: u16 = 0x0001; -/// 32-bit address (VA). -pub const IMAGE_REL_AMD64_ADDR32: u16 = 0x0002; -/// 32-bit address w/o image base (RVA). -pub const IMAGE_REL_AMD64_ADDR32NB: u16 = 0x0003; -/// 32-bit relative address from byte following reloc -pub const IMAGE_REL_AMD64_REL32: u16 = 0x0004; -/// 32-bit relative address from byte distance 1 from reloc -pub const IMAGE_REL_AMD64_REL32_1: u16 = 0x0005; -/// 32-bit relative address from byte distance 2 from reloc -pub const IMAGE_REL_AMD64_REL32_2: u16 = 0x0006; -/// 32-bit relative address from byte distance 3 from reloc -pub const IMAGE_REL_AMD64_REL32_3: u16 = 0x0007; -/// 32-bit relative address from byte distance 4 from reloc -pub const IMAGE_REL_AMD64_REL32_4: u16 = 0x0008; -/// 32-bit relative address from byte distance 5 from reloc -pub const IMAGE_REL_AMD64_REL32_5: u16 = 0x0009; -/// Section index -pub const IMAGE_REL_AMD64_SECTION: u16 = 0x000A; -/// 32 bit offset from base of section containing target -pub const IMAGE_REL_AMD64_SECREL: u16 = 0x000B; -/// 7 bit unsigned offset from base of section containing target -pub const IMAGE_REL_AMD64_SECREL7: u16 = 0x000C; -/// 32 bit metadata token -pub const IMAGE_REL_AMD64_TOKEN: u16 = 0x000D; -/// 32 bit signed span-dependent value emitted into object -pub const IMAGE_REL_AMD64_SREL32: u16 = 0x000E; -pub const IMAGE_REL_AMD64_PAIR: u16 = 0x000F; -/// 32 bit signed span-dependent value applied at link time -pub const IMAGE_REL_AMD64_SSPAN32: u16 = 0x0010; -pub const IMAGE_REL_AMD64_EHANDLER: u16 = 0x0011; -/// Indirect branch to an import -pub const IMAGE_REL_AMD64_IMPORT_BR: u16 = 0x0012; -/// Indirect call to an import -pub const IMAGE_REL_AMD64_IMPORT_CALL: u16 = 0x0013; -/// Indirect branch to a CFG check -pub const IMAGE_REL_AMD64_CFG_BR: u16 = 0x0014; -/// Indirect branch to a CFG check, with REX.W prefix -pub const IMAGE_REL_AMD64_CFG_BR_REX: u16 = 0x0015; -/// Indirect call to a CFG check -pub const IMAGE_REL_AMD64_CFG_CALL: u16 = 0x0016; -/// Indirect branch to a target in RAX (no CFG) -pub const IMAGE_REL_AMD64_INDIR_BR: u16 = 0x0017; -/// Indirect branch to a target in RAX, with REX.W prefix (no CFG) -pub const IMAGE_REL_AMD64_INDIR_BR_REX: u16 = 0x0018; -/// Indirect call to a target in RAX (no CFG) -pub const IMAGE_REL_AMD64_INDIR_CALL: u16 = 0x0019; -/// Indirect branch for a switch table using Reg 0 (RAX) -pub const IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_FIRST: u16 = 0x0020; -/// Indirect branch for a switch table using Reg 15 (R15) -pub const IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_LAST: u16 = 0x002F; - -// -// IA64 relocation types. -// -pub const IMAGE_REL_IA64_ABSOLUTE: u16 = 0x0000; -pub const IMAGE_REL_IA64_IMM14: u16 = 0x0001; -pub const IMAGE_REL_IA64_IMM22: u16 = 0x0002; -pub const IMAGE_REL_IA64_IMM64: u16 = 0x0003; -pub const IMAGE_REL_IA64_DIR32: u16 = 0x0004; -pub const IMAGE_REL_IA64_DIR64: u16 = 0x0005; -pub const IMAGE_REL_IA64_PCREL21B: u16 = 0x0006; -pub const IMAGE_REL_IA64_PCREL21M: u16 = 0x0007; -pub const IMAGE_REL_IA64_PCREL21F: u16 = 0x0008; -pub const IMAGE_REL_IA64_GPREL22: u16 = 0x0009; -pub const IMAGE_REL_IA64_LTOFF22: u16 = 0x000A; -pub const IMAGE_REL_IA64_SECTION: u16 = 0x000B; -pub const IMAGE_REL_IA64_SECREL22: u16 = 0x000C; -pub const IMAGE_REL_IA64_SECREL64I: u16 = 0x000D; -pub const IMAGE_REL_IA64_SECREL32: u16 = 0x000E; -// -pub const IMAGE_REL_IA64_DIR32NB: u16 = 0x0010; -pub const IMAGE_REL_IA64_SREL14: u16 = 0x0011; -pub const IMAGE_REL_IA64_SREL22: u16 = 0x0012; -pub const IMAGE_REL_IA64_SREL32: u16 = 0x0013; -pub const IMAGE_REL_IA64_UREL32: u16 = 0x0014; -/// This is always a BRL and never converted -pub const IMAGE_REL_IA64_PCREL60X: u16 = 0x0015; -/// If possible, convert to MBB bundle with NOP.B in slot 1 -pub const IMAGE_REL_IA64_PCREL60B: u16 = 0x0016; -/// If possible, convert to MFB bundle with NOP.F in slot 1 -pub const IMAGE_REL_IA64_PCREL60F: u16 = 0x0017; -/// If possible, convert to MIB bundle with NOP.I in slot 1 -pub const IMAGE_REL_IA64_PCREL60I: u16 = 0x0018; -/// If possible, convert to MMB bundle with NOP.M in slot 1 -pub const IMAGE_REL_IA64_PCREL60M: u16 = 0x0019; -pub const IMAGE_REL_IA64_IMMGPREL64: u16 = 0x001A; -/// clr token -pub const IMAGE_REL_IA64_TOKEN: u16 = 0x001B; -pub const IMAGE_REL_IA64_GPREL32: u16 = 0x001C; -pub const IMAGE_REL_IA64_ADDEND: u16 = 0x001F; - -// -// CEF relocation types. -// -/// Reference is absolute, no relocation is necessary -pub const IMAGE_REL_CEF_ABSOLUTE: u16 = 0x0000; -/// 32-bit address (VA). -pub const IMAGE_REL_CEF_ADDR32: u16 = 0x0001; -/// 64-bit address (VA). -pub const IMAGE_REL_CEF_ADDR64: u16 = 0x0002; -/// 32-bit address w/o image base (RVA). -pub const IMAGE_REL_CEF_ADDR32NB: u16 = 0x0003; -/// Section index -pub const IMAGE_REL_CEF_SECTION: u16 = 0x0004; -/// 32 bit offset from base of section containing target -pub const IMAGE_REL_CEF_SECREL: u16 = 0x0005; -/// 32 bit metadata token -pub const IMAGE_REL_CEF_TOKEN: u16 = 0x0006; - -// -// clr relocation types. -// -/// Reference is absolute, no relocation is necessary -pub const IMAGE_REL_CEE_ABSOLUTE: u16 = 0x0000; -/// 32-bit address (VA). -pub const IMAGE_REL_CEE_ADDR32: u16 = 0x0001; -/// 64-bit address (VA). -pub const IMAGE_REL_CEE_ADDR64: u16 = 0x0002; -/// 32-bit address w/o image base (RVA). -pub const IMAGE_REL_CEE_ADDR32NB: u16 = 0x0003; -/// Section index -pub const IMAGE_REL_CEE_SECTION: u16 = 0x0004; -/// 32 bit offset from base of section containing target -pub const IMAGE_REL_CEE_SECREL: u16 = 0x0005; -/// 32 bit metadata token -pub const IMAGE_REL_CEE_TOKEN: u16 = 0x0006; - -/// No relocation required -pub const IMAGE_REL_M32R_ABSOLUTE: u16 = 0x0000; -/// 32 bit address -pub const IMAGE_REL_M32R_ADDR32: u16 = 0x0001; -/// 32 bit address w/o image base -pub const IMAGE_REL_M32R_ADDR32NB: u16 = 0x0002; -/// 24 bit address -pub const IMAGE_REL_M32R_ADDR24: u16 = 0x0003; -/// GP relative addressing -pub const IMAGE_REL_M32R_GPREL16: u16 = 0x0004; -/// 24 bit offset << 2 & sign ext. -pub const IMAGE_REL_M32R_PCREL24: u16 = 0x0005; -/// 16 bit offset << 2 & sign ext. -pub const IMAGE_REL_M32R_PCREL16: u16 = 0x0006; -/// 8 bit offset << 2 & sign ext. -pub const IMAGE_REL_M32R_PCREL8: u16 = 0x0007; -/// 16 MSBs -pub const IMAGE_REL_M32R_REFHALF: u16 = 0x0008; -/// 16 MSBs; adj for LSB sign ext. -pub const IMAGE_REL_M32R_REFHI: u16 = 0x0009; -/// 16 LSBs -pub const IMAGE_REL_M32R_REFLO: u16 = 0x000A; -/// Link HI and LO -pub const IMAGE_REL_M32R_PAIR: u16 = 0x000B; -/// Section table index -pub const IMAGE_REL_M32R_SECTION: u16 = 0x000C; -/// 32 bit section relative reference -pub const IMAGE_REL_M32R_SECREL32: u16 = 0x000D; -/// clr token -pub const IMAGE_REL_M32R_TOKEN: u16 = 0x000E; - -/// No relocation required -pub const IMAGE_REL_EBC_ABSOLUTE: u16 = 0x0000; -/// 32 bit address w/o image base -pub const IMAGE_REL_EBC_ADDR32NB: u16 = 0x0001; -/// 32-bit relative address from byte following reloc -pub const IMAGE_REL_EBC_REL32: u16 = 0x0002; -/// Section table index -pub const IMAGE_REL_EBC_SECTION: u16 = 0x0003; -/// Offset within section -pub const IMAGE_REL_EBC_SECREL: u16 = 0x0004; - -/* -// TODO? -#define EXT_IMM64(Value, Address, Size, InstPos, ValPos)  /* Intel-IA64-Filler */           \ -    Value |= (((ULONGLONG)((*(Address) >> InstPos) & (((ULONGLONG)1 << Size) - 1))) << ValPos)  // Intel-IA64-Filler - -#define INS_IMM64(Value, Address, Size, InstPos, ValPos)  /* Intel-IA64-Filler */\ -    *(PDWORD)Address = (*(PDWORD)Address & ~(((1 << Size) - 1) << InstPos)) | /* Intel-IA64-Filler */\ -          ((DWORD)((((ULONGLONG)Value >> ValPos) & (((ULONGLONG)1 << Size) - 1))) << InstPos)  // Intel-IA64-Filler -*/ - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM7B_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM7B_SIZE_X: u16 = 7; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X: u16 = 4; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM7B_VAL_POS_X: u16 = 0; - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM9D_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM9D_SIZE_X: u16 = 9; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X: u16 = 18; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM9D_VAL_POS_X: u16 = 7; - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM5C_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM5C_SIZE_X: u16 = 5; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X: u16 = 13; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM5C_VAL_POS_X: u16 = 16; - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IC_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IC_SIZE_X: u16 = 1; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IC_INST_WORD_POS_X: u16 = 12; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IC_VAL_POS_X: u16 = 21; - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41A_INST_WORD_X: u16 = 1; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41A_SIZE_X: u16 = 10; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41A_INST_WORD_POS_X: u16 = 14; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41A_VAL_POS_X: u16 = 22; - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41B_INST_WORD_X: u16 = 1; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41B_SIZE_X: u16 = 8; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41B_INST_WORD_POS_X: u16 = 24; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41B_VAL_POS_X: u16 = 32; - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41C_INST_WORD_X: u16 = 2; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41C_SIZE_X: u16 = 23; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41C_INST_WORD_POS_X: u16 = 0; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_IMM41C_VAL_POS_X: u16 = 40; - -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_SIGN_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_SIGN_SIZE_X: u16 = 1; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_SIGN_INST_WORD_POS_X: u16 = 27; -/// Intel-IA64-Filler -pub const EMARCH_ENC_I17_SIGN_VAL_POS_X: u16 = 63; - -/// Intel-IA64-Filler -pub const X3_OPCODE_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const X3_OPCODE_SIZE_X: u16 = 4; -/// Intel-IA64-Filler -pub const X3_OPCODE_INST_WORD_POS_X: u16 = 28; -/// Intel-IA64-Filler -pub const X3_OPCODE_SIGN_VAL_POS_X: u16 = 0; - -/// Intel-IA64-Filler -pub const X3_I_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const X3_I_SIZE_X: u16 = 1; -/// Intel-IA64-Filler -pub const X3_I_INST_WORD_POS_X: u16 = 27; -/// Intel-IA64-Filler -pub const X3_I_SIGN_VAL_POS_X: u16 = 59; - -/// Intel-IA64-Filler -pub const X3_D_WH_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const X3_D_WH_SIZE_X: u16 = 3; -/// Intel-IA64-Filler -pub const X3_D_WH_INST_WORD_POS_X: u16 = 24; -/// Intel-IA64-Filler -pub const X3_D_WH_SIGN_VAL_POS_X: u16 = 0; - -/// Intel-IA64-Filler -pub const X3_IMM20_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const X3_IMM20_SIZE_X: u16 = 20; -/// Intel-IA64-Filler -pub const X3_IMM20_INST_WORD_POS_X: u16 = 4; -/// Intel-IA64-Filler -pub const X3_IMM20_SIGN_VAL_POS_X: u16 = 0; - -/// Intel-IA64-Filler -pub const X3_IMM39_1_INST_WORD_X: u16 = 2; -/// Intel-IA64-Filler -pub const X3_IMM39_1_SIZE_X: u16 = 23; -/// Intel-IA64-Filler -pub const X3_IMM39_1_INST_WORD_POS_X: u16 = 0; -/// Intel-IA64-Filler -pub const X3_IMM39_1_SIGN_VAL_POS_X: u16 = 36; - -/// Intel-IA64-Filler -pub const X3_IMM39_2_INST_WORD_X: u16 = 1; -/// Intel-IA64-Filler -pub const X3_IMM39_2_SIZE_X: u16 = 16; -/// Intel-IA64-Filler -pub const X3_IMM39_2_INST_WORD_POS_X: u16 = 16; -/// Intel-IA64-Filler -pub const X3_IMM39_2_SIGN_VAL_POS_X: u16 = 20; - -/// Intel-IA64-Filler -pub const X3_P_INST_WORD_X: u16 = 3; -/// Intel-IA64-Filler -pub const X3_P_SIZE_X: u16 = 4; -/// Intel-IA64-Filler -pub const X3_P_INST_WORD_POS_X: u16 = 0; -/// Intel-IA64-Filler -pub const X3_P_SIGN_VAL_POS_X: u16 = 0; - -/// Intel-IA64-Filler -pub const X3_TMPLT_INST_WORD_X: u16 = 0; -/// Intel-IA64-Filler -pub const X3_TMPLT_SIZE_X: u16 = 4; -/// Intel-IA64-Filler -pub const X3_TMPLT_INST_WORD_POS_X: u16 = 0; -/// Intel-IA64-Filler -pub const X3_TMPLT_SIGN_VAL_POS_X: u16 = 0; - -/// Intel-IA64-Filler -pub const X3_BTYPE_QP_INST_WORD_X: u16 = 2; -/// Intel-IA64-Filler -pub const X3_BTYPE_QP_SIZE_X: u16 = 9; -/// Intel-IA64-Filler -pub const X3_BTYPE_QP_INST_WORD_POS_X: u16 = 23; -/// Intel-IA64-Filler -pub const X3_BTYPE_QP_INST_VAL_POS_X: u16 = 0; - -/// Intel-IA64-Filler -pub const X3_EMPTY_INST_WORD_X: u16 = 1; -/// Intel-IA64-Filler -pub const X3_EMPTY_SIZE_X: u16 = 2; -/// Intel-IA64-Filler -pub const X3_EMPTY_INST_WORD_POS_X: u16 = 14; -/// Intel-IA64-Filler -pub const X3_EMPTY_INST_VAL_POS_X: u16 = 0; - -// -// Line number format. -// - -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageLinenumber { -    /// Symbol table index of function name if Linenumber is 0. -    /// Otherwise virtual address of line number. -    pub symbol_table_index_or_virtual_address: U32Bytes<LE>, -    /// Line number. -    pub linenumber: U16Bytes<LE>, -} - -// -// Based relocation format. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageBaseRelocation { -    pub virtual_address: U32<LE>, -    pub size_of_block: U32<LE>, -    //  pub type_offset[1]: U16<LE>, -} - -// -// Based relocation types. -// - -pub const IMAGE_REL_BASED_ABSOLUTE: u16 = 0; -pub const IMAGE_REL_BASED_HIGH: u16 = 1; -pub const IMAGE_REL_BASED_LOW: u16 = 2; -pub const IMAGE_REL_BASED_HIGHLOW: u16 = 3; -pub const IMAGE_REL_BASED_HIGHADJ: u16 = 4; -pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_5: u16 = 5; -pub const IMAGE_REL_BASED_RESERVED: u16 = 6; -pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_7: u16 = 7; -pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_8: u16 = 8; -pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_9: u16 = 9; -pub const IMAGE_REL_BASED_DIR64: u16 = 10; - -// -// Platform-specific based relocation types. -// - -pub const IMAGE_REL_BASED_IA64_IMM64: u16 = 9; - -pub const IMAGE_REL_BASED_MIPS_JMPADDR: u16 = 5; -pub const IMAGE_REL_BASED_MIPS_JMPADDR16: u16 = 9; - -pub const IMAGE_REL_BASED_ARM_MOV32: u16 = 5; -pub const IMAGE_REL_BASED_THUMB_MOV32: u16 = 7; - -pub const IMAGE_REL_BASED_RISCV_HIGH20: u16 = 5; -pub const IMAGE_REL_BASED_RISCV_LOW12I: u16 = 7; -pub const IMAGE_REL_BASED_RISCV_LOW12S: u16 = 8; - -// -// Archive format. -// - -pub const IMAGE_ARCHIVE_START_SIZE: usize = 8; -pub const IMAGE_ARCHIVE_START: &[u8; 8] = b"!<arch>\n"; -pub const IMAGE_ARCHIVE_END: &[u8] = b"`\n"; -pub const IMAGE_ARCHIVE_PAD: &[u8] = b"\n"; -pub const IMAGE_ARCHIVE_LINKER_MEMBER: &[u8; 16] = b"/               "; -pub const IMAGE_ARCHIVE_LONGNAMES_MEMBER: &[u8; 16] = b"//              "; -pub const IMAGE_ARCHIVE_HYBRIDMAP_MEMBER: &[u8; 16] = b"/<HYBRIDMAP>/   "; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageArchiveMemberHeader { -    /// File member name - `/' terminated. -    pub name: [u8; 16], -    /// File member date - decimal. -    pub date: [u8; 12], -    /// File member user id - decimal. -    pub user_id: [u8; 6], -    /// File member group id - decimal. -    pub group_id: [u8; 6], -    /// File member mode - octal. -    pub mode: [u8; 8], -    /// File member size - decimal. -    pub size: [u8; 10], -    /// String to end header. -    pub end_header: [u8; 2], -} - -pub const IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR: u16 = 60; - -// -// DLL support. -// - -// -// Export Format -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageExportDirectory { -    pub characteristics: U32<LE>, -    pub time_date_stamp: U32<LE>, -    pub major_version: U16<LE>, -    pub minor_version: U16<LE>, -    pub name: U32<LE>, -    pub base: U32<LE>, -    pub number_of_functions: U32<LE>, -    pub number_of_names: U32<LE>, -    /// RVA from base of image -    pub address_of_functions: U32<LE>, -    /// RVA from base of image -    pub address_of_names: U32<LE>, -    /// RVA from base of image -    pub address_of_name_ordinals: U32<LE>, -} - -// -// Import Format -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageImportByName { -    pub hint: U16<LE>, -    //pub name: [i8; 1], -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageThunkData64(pub U64<LE>); -/* -    union { -/// PBYTE -        pub forwarder_string: U64<LE>, -/// PDWORD -        pub function: U64<LE>, -        pub ordinal: U64<LE>, -/// PIMAGE_IMPORT_BY_NAME -        pub address_of_data: U64<LE>, -    } u1; -*/ - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageThunkData32(pub U32<LE>); -/* -    union { -/// PBYTE -        pub forwarder_string: U32<LE>, -/// PDWORD -        pub function: U32<LE>, -        pub ordinal: U32<LE>, -/// PIMAGE_IMPORT_BY_NAME -        pub address_of_data: U32<LE>, -    } u1; -} -*/ - -pub const IMAGE_ORDINAL_FLAG64: u64 = 0x8000000000000000; -pub const IMAGE_ORDINAL_FLAG32: u32 = 0x80000000; - -/* -#define IMAGE_ORDINAL64(Ordinal) (Ordinal & 0xffff) -#define IMAGE_ORDINAL32(Ordinal) (Ordinal & 0xffff) -#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) -#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0) - -*/ - -// -// Thread Local Storage -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageTlsDirectory64 { -    pub start_address_of_raw_data: U64<LE>, -    pub end_address_of_raw_data: U64<LE>, -    /// PDWORD -    pub address_of_index: U64<LE>, -    /// PIMAGE_TLS_CALLBACK *; -    pub address_of_call_backs: U64<LE>, -    pub size_of_zero_fill: U32<LE>, -    pub characteristics: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageTlsDirectory32 { -    pub start_address_of_raw_data: U32<LE>, -    pub end_address_of_raw_data: U32<LE>, -    /// PDWORD -    pub address_of_index: U32<LE>, -    /// PIMAGE_TLS_CALLBACK * -    pub address_of_call_backs: U32<LE>, -    pub size_of_zero_fill: U32<LE>, -    pub characteristics: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageImportDescriptor { -    /// RVA to original unbound IAT (`ImageThunkData32`/`ImageThunkData64`) -    /// 0 for terminating null import descriptor -    pub original_first_thunk: U32Bytes<LE>, -    /// 0 if not bound, -    /// -1 if bound, and real date\time stamp -    ///     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) -    /// O.W. date/time stamp of DLL bound to (Old BIND) -    pub time_date_stamp: U32Bytes<LE>, -    /// -1 if no forwarders -    pub forwarder_chain: U32Bytes<LE>, -    pub name: U32Bytes<LE>, -    /// RVA to IAT (if bound this IAT has actual addresses) -    pub first_thunk: U32Bytes<LE>, -} - -impl ImageImportDescriptor { -    /// Tell whether this import descriptor is the null descriptor -    /// (used to mark the end of the iterator array in a PE) -    pub fn is_null(&self) -> bool { -        self.original_first_thunk.get(LE) == 0 -            && self.time_date_stamp.get(LE) == 0 -            && self.forwarder_chain.get(LE) == 0 -            && self.name.get(LE) == 0 -            && self.first_thunk.get(LE) == 0 -    } -} - -// -// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageBoundImportDescriptor { -    pub time_date_stamp: U32<LE>, -    pub offset_module_name: U16<LE>, -    pub number_of_module_forwarder_refs: U16<LE>, -    // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageBoundForwarderRef { -    pub time_date_stamp: U32<LE>, -    pub offset_module_name: U16<LE>, -    pub reserved: U16<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDelayloadDescriptor { -    pub attributes: U32<LE>, - -    /// RVA to the name of the target library (NULL-terminate ASCII string) -    pub dll_name_rva: U32<LE>, -    /// RVA to the HMODULE caching location (PHMODULE) -    pub module_handle_rva: U32<LE>, -    /// RVA to the start of the IAT (PIMAGE_THUNK_DATA) -    pub import_address_table_rva: U32<LE>, -    /// RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData) -    pub import_name_table_rva: U32<LE>, -    /// RVA to an optional bound IAT -    pub bound_import_address_table_rva: U32<LE>, -    /// RVA to an optional unload info table -    pub unload_information_table_rva: U32<LE>, -    /// 0 if not bound, otherwise, date/time of the target DLL -    pub time_date_stamp: U32<LE>, -} - -impl ImageDelayloadDescriptor { -    /// Tell whether this delay-load import descriptor is the null descriptor -    /// (used to mark the end of the iterator array in a PE) -    pub fn is_null(&self) -> bool { -        self.attributes.get(LE) == 0 -            && self.dll_name_rva.get(LE) == 0 -            && self.module_handle_rva.get(LE) == 0 -            && self.import_address_table_rva.get(LE) == 0 -            && self.import_name_table_rva.get(LE) == 0 -            && self.bound_import_address_table_rva.get(LE) == 0 -            && self.unload_information_table_rva.get(LE) == 0 -            && self.time_date_stamp.get(LE) == 0 -    } -} - -/// Delay load version 2 flag for `ImageDelayloadDescriptor::attributes`. -pub const IMAGE_DELAYLOAD_RVA_BASED: u32 = 0x8000_0000; - -// -// Resource Format. -// - -// -// Resource directory consists of two counts, following by a variable length -// array of directory entries.  The first count is the number of entries at -// beginning of the array that have actual names associated with each entry. -// The entries are in ascending order, case insensitive strings.  The second -// count is the number of entries that immediately follow the named entries. -// This second count identifies the number of entries that have 16-bit integer -// Ids as their name.  These entries are also sorted in ascending order. -// -// This structure allows fast lookup by either name or number, but for any -// given resource entry only one form of lookup is supported, not both. -// This is consistent with the syntax of the .RC file and the .RES file. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageResourceDirectory { -    pub characteristics: U32<LE>, -    pub time_date_stamp: U32<LE>, -    pub major_version: U16<LE>, -    pub minor_version: U16<LE>, -    pub number_of_named_entries: U16<LE>, -    pub number_of_id_entries: U16<LE>, -} - -pub const IMAGE_RESOURCE_NAME_IS_STRING: u32 = 0x8000_0000; -pub const IMAGE_RESOURCE_DATA_IS_DIRECTORY: u32 = 0x8000_0000; -// -// Each directory contains the 32-bit Name of the entry and an offset, -// relative to the beginning of the resource directory of the data associated -// with this directory entry.  If the name of the entry is an actual text -// string instead of an integer Id, then the high order bit of the name field -// is set to one and the low order 31-bits are an offset, relative to the -// beginning of the resource directory of the string, which is of type -// IMAGE_RESOURCE_DIRECTORY_STRING.  Otherwise the high bit is clear and the -// low-order 16-bits are the integer Id that identify this resource directory -// entry. If the directory entry is yet another resource directory (i.e. a -// subdirectory), then the high order bit of the offset field will be -// set to indicate this.  Otherwise the high bit is clear and the offset -// field points to a resource data entry. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageResourceDirectoryEntry { -    pub name_or_id: U32<LE>, -    pub offset_to_data_or_directory: U32<LE>, -} - -// -// For resource directory entries that have actual string names, the Name -// field of the directory entry points to an object of the following type. -// All of these string objects are stored together after the last resource -// directory entry and before the first resource data object.  This minimizes -// the impact of these variable length objects on the alignment of the fixed -// size directory entry objects. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageResourceDirectoryString { -    pub length: U16<LE>, -    //pub name_string: [i8; 1], -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageResourceDirStringU { -    pub length: U16<LE>, -    //pub name_string: [U16<LE>; 1], -} - -// -// Each resource data entry describes a leaf node in the resource directory -// tree.  It contains an offset, relative to the beginning of the resource -// directory of the data for the resource, a size field that gives the number -// of bytes of data at that offset, a CodePage that should be used when -// decoding code point values within the resource data.  Typically for new -// applications the code page would be the unicode code page. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageResourceDataEntry { -    /// RVA of the data. -    pub offset_to_data: U32<LE>, -    pub size: U32<LE>, -    pub code_page: U32<LE>, -    pub reserved: U32<LE>, -} - -// Resource type: https://docs.microsoft.com/en-us/windows/win32/menurc/resource-types - -/// ID for: Hardware-dependent cursor resource. -pub const RT_CURSOR: u16 = 1; -/// ID for: Bitmap resource. -pub const RT_BITMAP: u16 = 2; -/// ID for: Hardware-dependent icon resource. -pub const RT_ICON: u16 = 3; -/// ID for: Menu resource. -pub const RT_MENU: u16 = 4; -/// ID for: Dialog box. -pub const RT_DIALOG: u16 = 5; -/// ID for: String-table entry. -pub const RT_STRING: u16 = 6; -/// ID for: Font directory resource. -pub const RT_FONTDIR: u16 = 7; -/// ID for: Font resource. -pub const RT_FONT: u16 = 8; -/// ID for: Accelerator table. -pub const RT_ACCELERATOR: u16 = 9; -/// ID for: Application-defined resource (raw data). -pub const RT_RCDATA: u16 = 10; -/// ID for: Message-table entry. -pub const RT_MESSAGETABLE: u16 = 11; -/// ID for: Hardware-independent cursor resource. -pub const RT_GROUP_CURSOR: u16 = 12; -/// ID for: Hardware-independent icon resource. -pub const RT_GROUP_ICON: u16 = 14; -/// ID for: Version resource. -pub const RT_VERSION: u16 = 16; -/// ID for: Allows a resource editing tool to associate a string with an .rc file. -pub const RT_DLGINCLUDE: u16 = 17; -/// ID for: Plug and Play resource. -pub const RT_PLUGPLAY: u16 = 19; -/// ID for: VXD. -pub const RT_VXD: u16 = 20; -/// ID for: Animated cursor. -pub const RT_ANICURSOR: u16 = 21; -/// ID for: Animated icon. -pub const RT_ANIICON: u16 = 22; -/// ID for: HTML resource. -pub const RT_HTML: u16 = 23; -/// ID for: Side-by-Side Assembly Manifest. -pub const RT_MANIFEST: u16 = 24; - -// -// Code Integrity in loadconfig (CI) -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageLoadConfigCodeIntegrity { -    /// Flags to indicate if CI information is available, etc. -    pub flags: U16<LE>, -    /// 0xFFFF means not available -    pub catalog: U16<LE>, -    pub catalog_offset: U32<LE>, -    /// Additional bitmask to be defined later -    pub reserved: U32<LE>, -} - -// -// Dynamic value relocation table in loadconfig -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDynamicRelocationTable { -    pub version: U32<LE>, -    pub size: U32<LE>, -    // DynamicRelocations: [ImageDynamicRelocation; 0], -} - -// -// Dynamic value relocation entries following IMAGE_DYNAMIC_RELOCATION_TABLE -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDynamicRelocation32 { -    pub symbol: U32<LE>, -    pub base_reloc_size: U32<LE>, -    // BaseRelocations: [ImageBaseRelocation; 0], -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDynamicRelocation64 { -    pub symbol: U64<LE>, -    pub base_reloc_size: U32<LE>, -    // BaseRelocations: [ImageBaseRelocation; 0], -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDynamicRelocation32V2 { -    pub header_size: U32<LE>, -    pub fixup_info_size: U32<LE>, -    pub symbol: U32<LE>, -    pub symbol_group: U32<LE>, -    pub flags: U32<LE>, -    // ...     variable length header fields -    // pub     fixup_info: [u8; fixup_info_size] -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDynamicRelocation64V2 { -    pub header_size: U32<LE>, -    pub fixup_info_size: U32<LE>, -    pub symbol: U64<LE>, -    pub symbol_group: U32<LE>, -    pub flags: U32<LE>, -    // ...     variable length header fields -    // pub     fixup_info[u8; fixup_info_size] -} - -// -// Defined symbolic dynamic relocation entries. -// - -pub const IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE: u32 = 0x0000_0001; -pub const IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE: u32 = 0x0000_0002; -pub const IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER: u32 = 0x0000_0003; -pub const IMAGE_DYNAMIC_RELOCATION_GUARD_INDIR_CONTROL_TRANSFER: u32 = 0x0000_0004; -pub const IMAGE_DYNAMIC_RELOCATION_GUARD_SWITCHTABLE_BRANCH: u32 = 0x0000_0005; - -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImagePrologueDynamicRelocationHeader { -    pub prologue_byte_count: u8, -    // pub prologue_bytes: [u8; prologue_byte_count], -} - -// This struct has alignment 1. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageEpilogueDynamicRelocationHeader { -    pub epilogue_count: U32Bytes<LE>, -    pub epilogue_byte_count: u8, -    pub branch_descriptor_element_size: u8, -    pub branch_descriptor_count: U16Bytes<LE>, -    // pub branch_descriptors[...], -    // pub branch_descriptor_bit_map[...], -} - -/* -// TODO? bitfields -// TODO: unaligned? -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageImportControlTransferDynamicRelocation { -    DWORD       PageRelativeOffset : 12; -    DWORD       IndirectCall       : 1; -    DWORD       IATIndex           : 19; -} - -// TODO: unaligned? -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageIndirControlTransferDynamicRelocation { -    WORD        PageRelativeOffset : 12; -    WORD        IndirectCall       : 1; -    WORD        RexWPrefix         : 1; -    WORD        CfgCheck           : 1; -    WORD        Reserved           : 1; -} - -// TODO: unaligned? -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageSwitchtableBranchDynamicRelocation { -    WORD        PageRelativeOffset : 12; -    WORD        RegisterNumber     : 4; -} -*/ - -// -// Load Configuration Directory Entry -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageLoadConfigDirectory32 { -    pub size: U32<LE>, -    pub time_date_stamp: U32<LE>, -    pub major_version: U16<LE>, -    pub minor_version: U16<LE>, -    pub global_flags_clear: U32<LE>, -    pub global_flags_set: U32<LE>, -    pub critical_section_default_timeout: U32<LE>, -    pub de_commit_free_block_threshold: U32<LE>, -    pub de_commit_total_free_threshold: U32<LE>, -    /// VA -    pub lock_prefix_table: U32<LE>, -    pub maximum_allocation_size: U32<LE>, -    pub virtual_memory_threshold: U32<LE>, -    pub process_heap_flags: U32<LE>, -    pub process_affinity_mask: U32<LE>, -    pub csd_version: U16<LE>, -    pub dependent_load_flags: U16<LE>, -    /// VA -    pub edit_list: U32<LE>, -    /// VA -    pub security_cookie: U32<LE>, -    /// VA -    pub sehandler_table: U32<LE>, -    pub sehandler_count: U32<LE>, -    /// VA -    pub guard_cf_check_function_pointer: U32<LE>, -    /// VA -    pub guard_cf_dispatch_function_pointer: U32<LE>, -    /// VA -    pub guard_cf_function_table: U32<LE>, -    pub guard_cf_function_count: U32<LE>, -    pub guard_flags: U32<LE>, -    pub code_integrity: ImageLoadConfigCodeIntegrity, -    /// VA -    pub guard_address_taken_iat_entry_table: U32<LE>, -    pub guard_address_taken_iat_entry_count: U32<LE>, -    /// VA -    pub guard_long_jump_target_table: U32<LE>, -    pub guard_long_jump_target_count: U32<LE>, -    /// VA -    pub dynamic_value_reloc_table: U32<LE>, -    pub chpe_metadata_pointer: U32<LE>, -    /// VA -    pub guard_rf_failure_routine: U32<LE>, -    /// VA -    pub guard_rf_failure_routine_function_pointer: U32<LE>, -    pub dynamic_value_reloc_table_offset: U32<LE>, -    pub dynamic_value_reloc_table_section: U16<LE>, -    pub reserved2: U16<LE>, -    /// VA -    pub guard_rf_verify_stack_pointer_function_pointer: U32<LE>, -    pub hot_patch_table_offset: U32<LE>, -    pub reserved3: U32<LE>, -    /// VA -    pub enclave_configuration_pointer: U32<LE>, -    /// VA -    pub volatile_metadata_pointer: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageLoadConfigDirectory64 { -    pub size: U32<LE>, -    pub time_date_stamp: U32<LE>, -    pub major_version: U16<LE>, -    pub minor_version: U16<LE>, -    pub global_flags_clear: U32<LE>, -    pub global_flags_set: U32<LE>, -    pub critical_section_default_timeout: U32<LE>, -    pub de_commit_free_block_threshold: U64<LE>, -    pub de_commit_total_free_threshold: U64<LE>, -    /// VA -    pub lock_prefix_table: U64<LE>, -    pub maximum_allocation_size: U64<LE>, -    pub virtual_memory_threshold: U64<LE>, -    pub process_affinity_mask: U64<LE>, -    pub process_heap_flags: U32<LE>, -    pub csd_version: U16<LE>, -    pub dependent_load_flags: U16<LE>, -    /// VA -    pub edit_list: U64<LE>, -    /// VA -    pub security_cookie: U64<LE>, -    /// VA -    pub sehandler_table: U64<LE>, -    pub sehandler_count: U64<LE>, -    /// VA -    pub guard_cf_check_function_pointer: U64<LE>, -    /// VA -    pub guard_cf_dispatch_function_pointer: U64<LE>, -    /// VA -    pub guard_cf_function_table: U64<LE>, -    pub guard_cf_function_count: U64<LE>, -    pub guard_flags: U32<LE>, -    pub code_integrity: ImageLoadConfigCodeIntegrity, -    /// VA -    pub guard_address_taken_iat_entry_table: U64<LE>, -    pub guard_address_taken_iat_entry_count: U64<LE>, -    /// VA -    pub guard_long_jump_target_table: U64<LE>, -    pub guard_long_jump_target_count: U64<LE>, -    /// VA -    pub dynamic_value_reloc_table: U64<LE>, -    /// VA -    pub chpe_metadata_pointer: U64<LE>, -    /// VA -    pub guard_rf_failure_routine: U64<LE>, -    /// VA -    pub guard_rf_failure_routine_function_pointer: U64<LE>, -    pub dynamic_value_reloc_table_offset: U32<LE>, -    pub dynamic_value_reloc_table_section: U16<LE>, -    pub reserved2: U16<LE>, -    /// VA -    pub guard_rf_verify_stack_pointer_function_pointer: U64<LE>, -    pub hot_patch_table_offset: U32<LE>, -    pub reserved3: U32<LE>, -    /// VA -    pub enclave_configuration_pointer: U64<LE>, -    /// VA -    pub volatile_metadata_pointer: U64<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageHotPatchInfo { -    pub version: U32<LE>, -    pub size: U32<LE>, -    pub sequence_number: U32<LE>, -    pub base_image_list: U32<LE>, -    pub base_image_count: U32<LE>, -    /// Version 2 and later -    pub buffer_offset: U32<LE>, -    /// Version 3 and later -    pub extra_patch_size: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageHotPatchBase { -    pub sequence_number: U32<LE>, -    pub flags: U32<LE>, -    pub original_time_date_stamp: U32<LE>, -    pub original_check_sum: U32<LE>, -    pub code_integrity_info: U32<LE>, -    pub code_integrity_size: U32<LE>, -    pub patch_table: U32<LE>, -    /// Version 2 and later -    pub buffer_offset: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageHotPatchHashes { -    pub sha256: [u8; 32], -    pub sha1: [u8; 20], -} - -pub const IMAGE_HOT_PATCH_BASE_OBLIGATORY: u32 = 0x0000_0001; -pub const IMAGE_HOT_PATCH_BASE_CAN_ROLL_BACK: u32 = 0x0000_0002; - -pub const IMAGE_HOT_PATCH_CHUNK_INVERSE: u32 = 0x8000_0000; -pub const IMAGE_HOT_PATCH_CHUNK_OBLIGATORY: u32 = 0x4000_0000; -pub const IMAGE_HOT_PATCH_CHUNK_RESERVED: u32 = 0x3FF0_3000; -pub const IMAGE_HOT_PATCH_CHUNK_TYPE: u32 = 0x000F_C000; -pub const IMAGE_HOT_PATCH_CHUNK_SOURCE_RVA: u32 = 0x0000_8000; -pub const IMAGE_HOT_PATCH_CHUNK_TARGET_RVA: u32 = 0x0000_4000; -pub const IMAGE_HOT_PATCH_CHUNK_SIZE: u32 = 0x0000_0FFF; - -pub const IMAGE_HOT_PATCH_NONE: u32 = 0x0000_0000; -pub const IMAGE_HOT_PATCH_FUNCTION: u32 = 0x0001_C000; -pub const IMAGE_HOT_PATCH_ABSOLUTE: u32 = 0x0002_C000; -pub const IMAGE_HOT_PATCH_REL32: u32 = 0x0003_C000; -pub const IMAGE_HOT_PATCH_CALL_TARGET: u32 = 0x0004_4000; -pub const IMAGE_HOT_PATCH_INDIRECT: u32 = 0x0005_C000; -pub const IMAGE_HOT_PATCH_NO_CALL_TARGET: u32 = 0x0006_4000; -pub const IMAGE_HOT_PATCH_DYNAMIC_VALUE: u32 = 0x0007_8000; - -/// Module performs control flow integrity checks using system-supplied support -pub const IMAGE_GUARD_CF_INSTRUMENTED: u32 = 0x0000_0100; -/// Module performs control flow and write integrity checks -pub const IMAGE_GUARD_CFW_INSTRUMENTED: u32 = 0x0000_0200; -/// Module contains valid control flow target metadata -pub const IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT: u32 = 0x0000_0400; -/// Module does not make use of the /GS security cookie -pub const IMAGE_GUARD_SECURITY_COOKIE_UNUSED: u32 = 0x0000_0800; -/// Module supports read only delay load IAT -pub const IMAGE_GUARD_PROTECT_DELAYLOAD_IAT: u32 = 0x0000_1000; -/// Delayload import table in its own .didat section (with nothing else in it) that can be freely reprotected -pub const IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION: u32 = 0x0000_2000; -/// Module contains suppressed export information. -/// -/// This also infers that the address taken taken IAT table is also present in the load config. -pub const IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT: u32 = 0x0000_4000; -/// Module enables suppression of exports -pub const IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION: u32 = 0x0000_8000; -/// Module contains longjmp target information -pub const IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT: u32 = 0x0001_0000; -/// Module contains return flow instrumentation and metadata -pub const IMAGE_GUARD_RF_INSTRUMENTED: u32 = 0x0002_0000; -/// Module requests that the OS enable return flow protection -pub const IMAGE_GUARD_RF_ENABLE: u32 = 0x0004_0000; -/// Module requests that the OS enable return flow protection in strict mode -pub const IMAGE_GUARD_RF_STRICT: u32 = 0x0008_0000; -/// Module was built with retpoline support -pub const IMAGE_GUARD_RETPOLINE_PRESENT: u32 = 0x0010_0000; - -/// Stride of Guard CF function table encoded in these bits (additional count of bytes per element) -pub const IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK: u32 = 0xF000_0000; -/// Shift to right-justify Guard CF function table stride -pub const IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT: u32 = 28; - -// -// GFIDS table entry flags. -// - -/// The containing GFID entry is suppressed -pub const IMAGE_GUARD_FLAG_FID_SUPPRESSED: u16 = 0x01; -/// The containing GFID entry is export suppressed -pub const IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED: u16 = 0x02; - -// -// WIN CE Exception table format -// - -// -// Function table entry format.  Function table is pointed to by the -// IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry. -// - -/* -// TODO? bitfields -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageCeRuntimeFunctionEntry { -    pub func_start: U32<LE>, -    DWORD PrologLen : 8; -    DWORD FuncLen : 22; -    DWORD ThirtyTwoBit : 1; -    DWORD ExceptionFlag : 1; -} -*/ - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageArmRuntimeFunctionEntry { -    pub begin_address: U32<LE>, -    pub unwind_data: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageArm64RuntimeFunctionEntry { -    pub begin_address: U32<LE>, -    pub unwind_data: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAlpha64RuntimeFunctionEntry { -    pub begin_address: U64<LE>, -    pub end_address: U64<LE>, -    pub exception_handler: U64<LE>, -    pub handler_data: U64<LE>, -    pub prolog_end_address: U64<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageAlphaRuntimeFunctionEntry { -    pub begin_address: U32<LE>, -    pub end_address: U32<LE>, -    pub exception_handler: U32<LE>, -    pub handler_data: U32<LE>, -    pub prolog_end_address: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageRuntimeFunctionEntry { -    pub begin_address: U32<LE>, -    pub end_address: U32<LE>, -    pub unwind_info_address_or_data: U32<LE>, -} - -// -// Software enclave information -// - -pub const IMAGE_ENCLAVE_LONG_ID_LENGTH: usize = 32; -pub const IMAGE_ENCLAVE_SHORT_ID_LENGTH: usize = 16; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageEnclaveConfig32 { -    pub size: U32<LE>, -    pub minimum_required_config_size: U32<LE>, -    pub policy_flags: U32<LE>, -    pub number_of_imports: U32<LE>, -    pub import_list: U32<LE>, -    pub import_entry_size: U32<LE>, -    pub family_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH], -    pub image_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH], -    pub image_version: U32<LE>, -    pub security_version: U32<LE>, -    pub enclave_size: U32<LE>, -    pub number_of_threads: U32<LE>, -    pub enclave_flags: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageEnclaveConfig64 { -    pub size: U32<LE>, -    pub minimum_required_config_size: U32<LE>, -    pub policy_flags: U32<LE>, -    pub number_of_imports: U32<LE>, -    pub import_list: U32<LE>, -    pub import_entry_size: U32<LE>, -    pub family_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH], -    pub image_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH], -    pub image_version: U32<LE>, -    pub security_version: U32<LE>, -    pub enclave_size: U64<LE>, -    pub number_of_threads: U32<LE>, -    pub enclave_flags: U32<LE>, -} - -//pub const IMAGE_ENCLAVE_MINIMUM_CONFIG_SIZE: usize = FIELD_OFFSET(IMAGE_ENCLAVE_CONFIG, EnclaveFlags); - -pub const IMAGE_ENCLAVE_POLICY_DEBUGGABLE: u32 = 0x0000_0001; - -pub const IMAGE_ENCLAVE_FLAG_PRIMARY_IMAGE: u32 = 0x0000_0001; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageEnclaveImport { -    pub match_type: U32<LE>, -    pub minimum_security_version: U32<LE>, -    pub unique_or_author_id: [u8; IMAGE_ENCLAVE_LONG_ID_LENGTH], -    pub family_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH], -    pub image_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH], -    pub import_name: U32<LE>, -    pub reserved: U32<LE>, -} - -pub const IMAGE_ENCLAVE_IMPORT_MATCH_NONE: u32 = 0x0000_0000; -pub const IMAGE_ENCLAVE_IMPORT_MATCH_UNIQUE_ID: u32 = 0x0000_0001; -pub const IMAGE_ENCLAVE_IMPORT_MATCH_AUTHOR_ID: u32 = 0x0000_0002; -pub const IMAGE_ENCLAVE_IMPORT_MATCH_FAMILY_ID: u32 = 0x0000_0003; -pub const IMAGE_ENCLAVE_IMPORT_MATCH_IMAGE_ID: u32 = 0x0000_0004; - -// -// Debug Format -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDebugDirectory { -    pub characteristics: U32<LE>, -    pub time_date_stamp: U32<LE>, -    pub major_version: U16<LE>, -    pub minor_version: U16<LE>, -    pub typ: U32<LE>, -    pub size_of_data: U32<LE>, -    pub address_of_raw_data: U32<LE>, -    pub pointer_to_raw_data: U32<LE>, -} - -pub const IMAGE_DEBUG_TYPE_UNKNOWN: u32 = 0; -pub const IMAGE_DEBUG_TYPE_COFF: u32 = 1; -pub const IMAGE_DEBUG_TYPE_CODEVIEW: u32 = 2; -pub const IMAGE_DEBUG_TYPE_FPO: u32 = 3; -pub const IMAGE_DEBUG_TYPE_MISC: u32 = 4; -pub const IMAGE_DEBUG_TYPE_EXCEPTION: u32 = 5; -pub const IMAGE_DEBUG_TYPE_FIXUP: u32 = 6; -pub const IMAGE_DEBUG_TYPE_OMAP_TO_SRC: u32 = 7; -pub const IMAGE_DEBUG_TYPE_OMAP_FROM_SRC: u32 = 8; -pub const IMAGE_DEBUG_TYPE_BORLAND: u32 = 9; -pub const IMAGE_DEBUG_TYPE_RESERVED10: u32 = 10; -pub const IMAGE_DEBUG_TYPE_CLSID: u32 = 11; -pub const IMAGE_DEBUG_TYPE_VC_FEATURE: u32 = 12; -pub const IMAGE_DEBUG_TYPE_POGO: u32 = 13; -pub const IMAGE_DEBUG_TYPE_ILTCG: u32 = 14; -pub const IMAGE_DEBUG_TYPE_MPX: u32 = 15; -pub const IMAGE_DEBUG_TYPE_REPRO: u32 = 16; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageCoffSymbolsHeader { -    pub number_of_symbols: U32<LE>, -    pub lva_to_first_symbol: U32<LE>, -    pub number_of_linenumbers: U32<LE>, -    pub lva_to_first_linenumber: U32<LE>, -    pub rva_to_first_byte_of_code: U32<LE>, -    pub rva_to_last_byte_of_code: U32<LE>, -    pub rva_to_first_byte_of_data: U32<LE>, -    pub rva_to_last_byte_of_data: U32<LE>, -} - -pub const FRAME_FPO: u16 = 0; -pub const FRAME_TRAP: u16 = 1; -pub const FRAME_TSS: u16 = 2; -pub const FRAME_NONFPO: u16 = 3; - -/* -// TODO? bitfields -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FpoData { -/// offset 1st byte of function code -    pub ul_off_start: U32<LE>, -/// # bytes in function -    pub cb_proc_size: U32<LE>, -/// # bytes in locals/4 -    pub cdw_locals: U32<LE>, -/// # bytes in params/4 -    pub cdw_params: U16<LE>, -/// # bytes in prolog -    WORD        cbProlog : 8; -/// # regs saved -    WORD        cbRegs   : 3; -/// TRUE if SEH in func -    WORD        fHasSEH  : 1; -/// TRUE if EBP has been allocated -    WORD        fUseBP   : 1; -/// reserved for future use -    WORD        reserved : 1; -/// frame type -    WORD        cbFrame  : 2; -} -pub const SIZEOF_RFPO_DATA: usize = 16; -*/ - -pub const IMAGE_DEBUG_MISC_EXENAME: u16 = 1; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageDebugMisc { -    /// type of misc data, see defines -    pub data_type: U32<LE>, -    /// total length of record, rounded to four byte multiple. -    pub length: U32<LE>, -    /// TRUE if data is unicode string -    pub unicode: u8, -    pub reserved: [u8; 3], -    // Actual data -    //pub data: [u8; 1], -} - -// -// Function table extracted from MIPS/ALPHA/IA64 images.  Does not contain -// information needed only for runtime support.  Just those fields for -// each entry needed by a debugger. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageFunctionEntry { -    pub starting_address: U32<LE>, -    pub ending_address: U32<LE>, -    pub end_of_prologue: U32<LE>, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageFunctionEntry64 { -    pub starting_address: U64<LE>, -    pub ending_address: U64<LE>, -    pub end_of_prologue_or_unwind_info_address: U64<LE>, -} - -// -// Debugging information can be stripped from an image file and placed -// in a separate .DBG file, whose file name part is the same as the -// image file name part (e.g. symbols for CMD.EXE could be stripped -// and placed in CMD.DBG).  This is indicated by the IMAGE_FILE_DEBUG_STRIPPED -// flag in the Characteristics field of the file header.  The beginning of -// the .DBG file contains the following structure which captures certain -// information from the image file.  This allows a debug to proceed even if -// the original image file is not accessible.  This header is followed by -// zero of more IMAGE_SECTION_HEADER structures, followed by zero or more -// IMAGE_DEBUG_DIRECTORY structures.  The latter structures and those in -// the image file contain file offsets relative to the beginning of the -// .DBG file. -// -// If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure -// is left in the image file, but not mapped.  This allows a debugger to -// compute the name of the .DBG file, from the name of the image in the -// IMAGE_DEBUG_MISC structure. -// - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageSeparateDebugHeader { -    pub signature: U16<LE>, -    pub flags: U16<LE>, -    pub machine: U16<LE>, -    pub characteristics: U16<LE>, -    pub time_date_stamp: U32<LE>, -    pub check_sum: U32<LE>, -    pub image_base: U32<LE>, -    pub size_of_image: U32<LE>, -    pub number_of_sections: U32<LE>, -    pub exported_names_size: U32<LE>, -    pub debug_directory_size: U32<LE>, -    pub section_alignment: U32<LE>, -    pub reserved: [U32<LE>; 2], -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct NonPagedDebugInfo { -    pub signature: U16<LE>, -    pub flags: U16<LE>, -    pub size: U32<LE>, -    pub machine: U16<LE>, -    pub characteristics: U16<LE>, -    pub time_date_stamp: U32<LE>, -    pub check_sum: U32<LE>, -    pub size_of_image: U32<LE>, -    pub image_base: U64<LE>, -    //debug_directory_size -    //ImageDebugDirectory -} - -pub const IMAGE_SEPARATE_DEBUG_SIGNATURE: u16 = 0x4944; -pub const NON_PAGED_DEBUG_SIGNATURE: u16 = 0x494E; - -pub const IMAGE_SEPARATE_DEBUG_FLAGS_MASK: u16 = 0x8000; -/// when DBG was updated, the old checksum didn't match. -pub const IMAGE_SEPARATE_DEBUG_MISMATCH: u16 = 0x8000; - -// -//  The .arch section is made up of headers, each describing an amask position/value -//  pointing to an array of IMAGE_ARCHITECTURE_ENTRY's.  Each "array" (both the header -//  and entry arrays) are terminiated by a quadword of 0xffffffffL. -// -//  NOTE: There may be quadwords of 0 sprinkled around and must be skipped. -// - -/* -// TODO? bitfields -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageArchitectureHeader { -    /// 1 -> code section depends on mask bit -    /// 0 -> new instruction depends on mask bit -    unsigned int AmaskValue: 1; -    /// MBZ -    int :7; -    /// Amask bit in question for this fixup -    unsigned int AmaskShift: 8; -    /// MBZ -    int :16; -    /// RVA into .arch section to array of ARCHITECTURE_ENTRY's -    pub first_entry_rva: U32<LE>, -} -*/ - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageArchitectureEntry { -    /// RVA of instruction to fixup -    pub fixup_inst_rva: U32<LE>, -    /// fixup instruction (see alphaops.h) -    pub new_inst: U32<LE>, -} - -// The following structure defines the new import object.  Note the values of the first two fields, -// which must be set as stated in order to differentiate old and new import members. -// Following this structure, the linker emits two null-terminated strings used to recreate the -// import at the time of use.  The first string is the import's name, the second is the dll's name. - -pub const IMPORT_OBJECT_HDR_SIG2: u16 = 0xffff; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImportObjectHeader { -    /// Must be IMAGE_FILE_MACHINE_UNKNOWN -    pub sig1: U16<LE>, -    /// Must be IMPORT_OBJECT_HDR_SIG2. -    pub sig2: U16<LE>, -    pub version: U16<LE>, -    pub machine: U16<LE>, -    /// Time/date stamp -    pub time_date_stamp: U32<LE>, -    /// particularly useful for incremental links -    pub size_of_data: U32<LE>, - -    /// if grf & IMPORT_OBJECT_ORDINAL -    pub ordinal_or_hint: U16<LE>, - -    // WORD    Type : 2; -    // WORD    NameType : 3; -    // WORD    Reserved : 11; -    pub name_type: U16<LE>, -} - -pub const IMPORT_OBJECT_TYPE_MASK: u16 = 0b11; -pub const IMPORT_OBJECT_TYPE_SHIFT: u16 = 0; -pub const IMPORT_OBJECT_CODE: u16 = 0; -pub const IMPORT_OBJECT_DATA: u16 = 1; -pub const IMPORT_OBJECT_CONST: u16 = 2; - -pub const IMPORT_OBJECT_NAME_MASK: u16 = 0b111; -pub const IMPORT_OBJECT_NAME_SHIFT: u16 = 2; -/// Import by ordinal -pub const IMPORT_OBJECT_ORDINAL: u16 = 0; -/// Import name == public symbol name. -pub const IMPORT_OBJECT_NAME: u16 = 1; -/// Import name == public symbol name skipping leading ?, @, or optionally _. -pub const IMPORT_OBJECT_NAME_NO_PREFIX: u16 = 2; -/// Import name == public symbol name skipping leading ?, @, or optionally _ and truncating at first @. -pub const IMPORT_OBJECT_NAME_UNDECORATE: u16 = 3; -/// Import name == a name is explicitly provided after the DLL name. -pub const IMPORT_OBJECT_NAME_EXPORTAS: u16 = 4; - -// COM+ Header entry point flags. -pub const COMIMAGE_FLAGS_ILONLY: u32 = 0x0000_0001; -pub const COMIMAGE_FLAGS_32BITREQUIRED: u32 = 0x0000_0002; -pub const COMIMAGE_FLAGS_IL_LIBRARY: u32 = 0x0000_0004; -pub const COMIMAGE_FLAGS_STRONGNAMESIGNED: u32 = 0x0000_0008; -pub const COMIMAGE_FLAGS_NATIVE_ENTRYPOINT: u32 = 0x0000_0010; -pub const COMIMAGE_FLAGS_TRACKDEBUGDATA: u32 = 0x0001_0000; -pub const COMIMAGE_FLAGS_32BITPREFERRED: u32 = 0x0002_0000; - -// Version flags for image. -pub const COR_VERSION_MAJOR_V2: u16 = 2; -pub const COR_VERSION_MAJOR: u16 = COR_VERSION_MAJOR_V2; -pub const COR_VERSION_MINOR: u16 = 5; -pub const COR_DELETED_NAME_LENGTH: usize = 8; -pub const COR_VTABLEGAP_NAME_LENGTH: usize = 8; - -// Maximum size of a NativeType descriptor. -pub const NATIVE_TYPE_MAX_CB: u16 = 1; -pub const COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE: u16 = 0xFF; - -// Consts for the MIH FLAGS -pub const IMAGE_COR_MIH_METHODRVA: u16 = 0x01; -pub const IMAGE_COR_MIH_EHRVA: u16 = 0x02; -pub const IMAGE_COR_MIH_BASICBLOCK: u16 = 0x08; - -// V-table constants -/// V-table slots are 32-bits in size. -pub const COR_VTABLE_32BIT: u16 = 0x01; -/// V-table slots are 64-bits in size. -pub const COR_VTABLE_64BIT: u16 = 0x02; -/// If set, transition from unmanaged. -pub const COR_VTABLE_FROM_UNMANAGED: u16 = 0x04; -/// If set, transition from unmanaged with keeping the current appdomain. -pub const COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN: u16 = 0x08; -/// Call most derived method described by -pub const COR_VTABLE_CALL_MOST_DERIVED: u16 = 0x10; - -// EATJ constants -/// Size of a jump thunk reserved range. -pub const IMAGE_COR_EATJ_THUNK_SIZE: usize = 32; - -// Max name lengths -pub const MAX_CLASS_NAME: usize = 1024; -pub const MAX_PACKAGE_NAME: usize = 1024; - -// CLR 2.0 header structure. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ImageCor20Header { -    // Header versioning -    pub cb: U32<LE>, -    pub major_runtime_version: U16<LE>, -    pub minor_runtime_version: U16<LE>, - -    // Symbol table and startup information -    pub meta_data: ImageDataDirectory, -    pub flags: U32<LE>, - -    // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint. -    // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint. -    pub entry_point_token_or_rva: U32<LE>, - -    // Binding information -    pub resources: ImageDataDirectory, -    pub strong_name_signature: ImageDataDirectory, - -    // Regular fixup and binding information -    pub code_manager_table: ImageDataDirectory, -    pub vtable_fixups: ImageDataDirectory, -    pub export_address_table_jumps: ImageDataDirectory, - -    // Precompiled image info (internal use only - set to zero) -    pub managed_native_header: ImageDataDirectory, -} - -unsafe_impl_pod!( -    ImageDosHeader, -    ImageOs2Header, -    ImageVxdHeader, -    ImageFileHeader, -    ImageDataDirectory, -    ImageOptionalHeader32, -    ImageRomOptionalHeader, -    ImageOptionalHeader64, -    ImageNtHeaders64, -    ImageNtHeaders32, -    ImageRomHeaders, -    Guid, -    AnonObjectHeader, -    AnonObjectHeaderV2, -    AnonObjectHeaderBigobj, -    ImageSectionHeader, -    ImageSymbol, -    ImageSymbolBytes, -    ImageSymbolEx, -    ImageSymbolExBytes, -    ImageAuxSymbolTokenDef, -    ImageAuxSymbolFunction, -    ImageAuxSymbolFunctionBeginEnd, -    ImageAuxSymbolWeak, -    ImageAuxSymbolSection, -    ImageAuxSymbolCrc, -    ImageRelocation, -    ImageLinenumber, -    ImageBaseRelocation, -    ImageArchiveMemberHeader, -    ImageExportDirectory, -    ImageImportByName, -    ImageThunkData64, -    ImageThunkData32, -    ImageTlsDirectory64, -    ImageTlsDirectory32, -    ImageImportDescriptor, -    ImageBoundImportDescriptor, -    ImageBoundForwarderRef, -    ImageDelayloadDescriptor, -    ImageResourceDirectory, -    ImageResourceDirectoryEntry, -    ImageResourceDirectoryString, -    ImageResourceDirStringU, -    ImageResourceDataEntry, -    ImageLoadConfigCodeIntegrity, -    ImageDynamicRelocationTable, -    ImageDynamicRelocation32, -    ImageDynamicRelocation64, -    ImageDynamicRelocation32V2, -    ImageDynamicRelocation64V2, -    ImagePrologueDynamicRelocationHeader, -    ImageEpilogueDynamicRelocationHeader, -    //ImageImportControlTransferDynamicRelocation, -    //ImageIndirControlTransferDynamicRelocation, -    //ImageSwitchtableBranchDynamicRelocation, -    ImageLoadConfigDirectory32, -    ImageLoadConfigDirectory64, -    ImageHotPatchInfo, -    ImageHotPatchBase, -    ImageHotPatchHashes, -    //ImageCeRuntimeFunctionEntry, -    ImageArmRuntimeFunctionEntry, -    ImageArm64RuntimeFunctionEntry, -    ImageAlpha64RuntimeFunctionEntry, -    ImageAlphaRuntimeFunctionEntry, -    ImageRuntimeFunctionEntry, -    ImageEnclaveConfig32, -    ImageEnclaveConfig64, -    ImageEnclaveImport, -    ImageDebugDirectory, -    ImageCoffSymbolsHeader, -    //FpoData, -    ImageDebugMisc, -    ImageFunctionEntry, -    ImageFunctionEntry64, -    ImageSeparateDebugHeader, -    NonPagedDebugInfo, -    //ImageArchitectureHeader, -    ImageArchitectureEntry, -    ImportObjectHeader, -    ImageCor20Header, -    MaskedRichHeaderEntry, -); diff --git a/vendor/object/src/pod.rs b/vendor/object/src/pod.rs deleted file mode 100644 index 8ee7816..0000000 --- a/vendor/object/src/pod.rs +++ /dev/null @@ -1,239 +0,0 @@ -//! Tools for converting file format structures to and from bytes. -//! -//! This module should be replaced once rust provides safe transmutes. - -// This module provides functions for both read and write features. -#![cfg_attr( -    not(all(feature = "read_core", feature = "write_core")), -    allow(dead_code) -)] - -use core::{mem, result, slice}; - -type Result<T> = result::Result<T, ()>; - -/// A trait for types that can safely be converted from and to byte slices. -/// -/// # Safety -/// A type that is `Pod` must: -/// - be `#[repr(C)]` or `#[repr(transparent)]` -/// - have no invalid byte values -/// - have no padding -pub unsafe trait Pod: Copy + 'static {} - -/// Cast a byte slice to a `Pod` type. -/// -/// Returns the type and the tail of the slice. -#[inline] -pub fn from_bytes<T: Pod>(data: &[u8]) -> Result<(&T, &[u8])> { -    let size = mem::size_of::<T>(); -    let tail = data.get(size..).ok_or(())?; -    let ptr = data.as_ptr(); -    if (ptr as usize) % mem::align_of::<T>() != 0 { -        return Err(()); -    } -    // Safety: -    // The alignment and size are checked by this function. -    // The Pod trait ensures the type is valid to cast from bytes. -    let val = unsafe { &*ptr.cast() }; -    Ok((val, tail)) -} - -/// Cast a mutable byte slice to a `Pod` type. -/// -/// Returns the type and the tail of the slice. -#[inline] -pub fn from_bytes_mut<T: Pod>(data: &mut [u8]) -> Result<(&mut T, &mut [u8])> { -    let size = mem::size_of::<T>(); -    if size > data.len() { -        return Err(()); -    } -    let (data, tail) = data.split_at_mut(size); -    let ptr = data.as_mut_ptr(); -    if (ptr as usize) % mem::align_of::<T>() != 0 { -        return Err(()); -    } -    // Safety: -    // The alignment and size are checked by this function. -    // The Pod trait ensures the type is valid to cast from bytes. -    let val = unsafe { &mut *ptr.cast() }; -    Ok((val, tail)) -} - -/// Cast a byte slice to a slice of a `Pod` type. -/// -/// Returns the type slice and the tail of the byte slice. -#[inline] -pub fn slice_from_bytes<T: Pod>(data: &[u8], count: usize) -> Result<(&[T], &[u8])> { -    let size = count.checked_mul(mem::size_of::<T>()).ok_or(())?; -    let tail = data.get(size..).ok_or(())?; -    let ptr = data.as_ptr(); -    if (ptr as usize) % mem::align_of::<T>() != 0 { -        return Err(()); -    } -    // Safety: -    // The alignment and size are checked by this function. -    // The Pod trait ensures the type is valid to cast from bytes. -    let slice = unsafe { slice::from_raw_parts(ptr.cast(), count) }; -    Ok((slice, tail)) -} - -/// Cast a mutable byte slice to a slice of a `Pod` type. -/// -/// Returns the type slice and the tail of the byte slice. -#[inline] -pub fn slice_from_bytes_mut<T: Pod>( -    data: &mut [u8], -    count: usize, -) -> Result<(&mut [T], &mut [u8])> { -    let size = count.checked_mul(mem::size_of::<T>()).ok_or(())?; -    if size > data.len() { -        return Err(()); -    } -    let (data, tail) = data.split_at_mut(size); -    let ptr = data.as_mut_ptr(); -    if (ptr as usize) % mem::align_of::<T>() != 0 { -        return Err(()); -    } -    // Safety: -    // The alignment and size are checked by this function. -    // The Pod trait ensures the type is valid to cast from bytes. -    let slice = unsafe { slice::from_raw_parts_mut(ptr.cast(), count) }; -    Ok((slice, tail)) -} - -/// Cast a `Pod` type to a byte slice. -#[inline] -pub fn bytes_of<T: Pod>(val: &T) -> &[u8] { -    let size = mem::size_of::<T>(); -    // Safety: -    // Any alignment is allowed. -    // The size is determined in this function. -    // The Pod trait ensures the type is valid to cast to bytes. -    unsafe { slice::from_raw_parts(slice::from_ref(val).as_ptr().cast(), size) } -} - -/// Cast a `Pod` type to a mutable byte slice. -#[inline] -pub fn bytes_of_mut<T: Pod>(val: &mut T) -> &mut [u8] { -    let size = mem::size_of::<T>(); -    // Safety: -    // Any alignment is allowed. -    // The size is determined in this function. -    // The Pod trait ensures the type is valid to cast to bytes. -    unsafe { slice::from_raw_parts_mut(slice::from_mut(val).as_mut_ptr().cast(), size) } -} - -/// Cast a slice of a `Pod` type to a byte slice. -#[inline] -pub fn bytes_of_slice<T: Pod>(val: &[T]) -> &[u8] { -    let size = val.len().wrapping_mul(mem::size_of::<T>()); -    // Safety: -    // Any alignment is allowed. -    // The size is determined in this function. -    // The Pod trait ensures the type is valid to cast to bytes. -    unsafe { slice::from_raw_parts(val.as_ptr().cast(), size) } -} - -/// Cast a slice of a `Pod` type to a mutable byte slice. -#[inline] -pub fn bytes_of_slice_mut<T: Pod>(val: &mut [T]) -> &mut [u8] { -    let size = val.len().wrapping_mul(mem::size_of::<T>()); -    // Safety: -    // Any alignment is allowed. -    // The size is determined in this function. -    // The Pod trait ensures the type is valid to cast to bytes. -    unsafe { slice::from_raw_parts_mut(val.as_mut_ptr().cast(), size) } -} - -macro_rules! unsafe_impl_pod { -    ($($struct_name:ident),+ $(,)?) => { -        $( -            unsafe impl Pod for $struct_name { } -        )+ -    } -} - -unsafe_impl_pod!(u8, u16, u32, u64); - -#[cfg(test)] -mod tests { -    use super::*; - -    #[test] -    fn single() { -        let x = u32::to_be(0x0123_4567); -        let mut x_mut = x; -        let bytes = bytes_of(&x); -        let bytes_mut = bytes_of_mut(&mut x_mut); -        assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67]); -        assert_eq!(bytes, bytes_mut); - -        let x16 = [u16::to_be(0x0123), u16::to_be(0x4567)]; - -        let (y, tail) = from_bytes::<u32>(bytes).unwrap(); -        let (y_mut, tail_mut) = from_bytes_mut::<u32>(bytes_mut).unwrap(); -        assert_eq!(*y, x); -        assert_eq!(y, y_mut); -        assert_eq!(tail, &[]); -        assert_eq!(tail, tail_mut); - -        let (y, tail) = from_bytes::<u16>(bytes).unwrap(); -        let (y_mut, tail_mut) = from_bytes_mut::<u16>(bytes_mut).unwrap(); -        assert_eq!(*y, x16[0]); -        assert_eq!(y, y_mut); -        assert_eq!(tail, &bytes[2..]); -        assert_eq!(tail, tail_mut); - -        let (y, tail) = from_bytes::<u16>(&bytes[2..]).unwrap(); -        let (y_mut, tail_mut) = from_bytes_mut::<u16>(&mut bytes_mut[2..]).unwrap(); -        assert_eq!(*y, x16[1]); -        assert_eq!(y, y_mut); -        assert_eq!(tail, &[]); -        assert_eq!(tail, tail_mut); - -        assert_eq!(from_bytes::<u16>(&bytes[1..]), Err(())); -        assert_eq!(from_bytes::<u16>(&bytes[3..]), Err(())); -        assert_eq!(from_bytes::<u16>(&bytes[4..]), Err(())); -        assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[1..]), Err(())); -        assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[3..]), Err(())); -        assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[4..]), Err(())); -    } - -    #[test] -    fn slice() { -        let x = [ -            u16::to_be(0x0123), -            u16::to_be(0x4567), -            u16::to_be(0x89ab), -            u16::to_be(0xcdef), -        ]; -        let mut x_mut = x; - -        let bytes = bytes_of_slice(&x); -        let bytes_mut = bytes_of_slice_mut(&mut x_mut); -        assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]); -        assert_eq!(bytes, bytes_mut); - -        let (y, tail) = slice_from_bytes::<u16>(bytes, 4).unwrap(); -        let (y_mut, tail_mut) = slice_from_bytes_mut::<u16>(bytes_mut, 4).unwrap(); -        assert_eq!(y, x); -        assert_eq!(y, y_mut); -        assert_eq!(tail, &[]); -        assert_eq!(tail, tail_mut); - -        let (y, tail) = slice_from_bytes::<u16>(&bytes[2..], 2).unwrap(); -        let (y_mut, tail_mut) = slice_from_bytes::<u16>(&mut bytes_mut[2..], 2).unwrap(); -        assert_eq!(y, &x[1..3]); -        assert_eq!(y, y_mut); -        assert_eq!(tail, &bytes[6..]); -        assert_eq!(tail, tail_mut); - -        assert_eq!(slice_from_bytes::<u16>(bytes, 5), Err(())); -        assert_eq!(slice_from_bytes::<u16>(&bytes[2..], 4), Err(())); -        assert_eq!(slice_from_bytes::<u16>(&bytes[1..], 2), Err(())); -        assert_eq!(slice_from_bytes_mut::<u16>(bytes_mut, 5), Err(())); -        assert_eq!(slice_from_bytes_mut::<u16>(&mut bytes_mut[2..], 4), Err(())); -        assert_eq!(slice_from_bytes_mut::<u16>(&mut bytes_mut[1..], 2), Err(())); -    } -} diff --git a/vendor/object/src/read/any.rs b/vendor/object/src/read/any.rs deleted file mode 100644 index a14e56d..0000000 --- a/vendor/object/src/read/any.rs +++ /dev/null @@ -1,1328 +0,0 @@ -use alloc::fmt; -use alloc::vec::Vec; -use core::marker::PhantomData; - -#[cfg(feature = "coff")] -use crate::read::coff; -#[cfg(feature = "elf")] -use crate::read::elf; -#[cfg(feature = "macho")] -use crate::read::macho; -#[cfg(feature = "pe")] -use crate::read::pe; -#[cfg(feature = "wasm")] -use crate::read::wasm; -#[cfg(feature = "xcoff")] -use crate::read::xcoff; -use crate::read::{ -    self, Architecture, BinaryFormat, CodeView, ComdatKind, CompressedData, CompressedFileRange, -    Error, Export, FileFlags, FileKind, Import, Object, ObjectComdat, ObjectKind, ObjectMap, -    ObjectSection, ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadRef, Relocation, Result, -    SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind, -    SymbolMap, SymbolMapName, SymbolScope, SymbolSection, -}; -#[allow(unused_imports)] -use crate::{AddressSize, Endian, Endianness, SubArchitecture}; - -/// Evaluate an expression on the contents of a file format enum. -/// -/// This is a hack to avoid virtual calls. -macro_rules! with_inner { -    ($inner:expr, $enum:ident, | $var:ident | $body:expr) => { -        match $inner { -            #[cfg(feature = "coff")] -            $enum::Coff(ref $var) => $body, -            #[cfg(feature = "coff")] -            $enum::CoffBig(ref $var) => $body, -            #[cfg(feature = "elf")] -            $enum::Elf32(ref $var) => $body, -            #[cfg(feature = "elf")] -            $enum::Elf64(ref $var) => $body, -            #[cfg(feature = "macho")] -            $enum::MachO32(ref $var) => $body, -            #[cfg(feature = "macho")] -            $enum::MachO64(ref $var) => $body, -            #[cfg(feature = "pe")] -            $enum::Pe32(ref $var) => $body, -            #[cfg(feature = "pe")] -            $enum::Pe64(ref $var) => $body, -            #[cfg(feature = "wasm")] -            $enum::Wasm(ref $var) => $body, -            #[cfg(feature = "xcoff")] -            $enum::Xcoff32(ref $var) => $body, -            #[cfg(feature = "xcoff")] -            $enum::Xcoff64(ref $var) => $body, -        } -    }; -} - -macro_rules! with_inner_mut { -    ($inner:expr, $enum:ident, | $var:ident | $body:expr) => { -        match $inner { -            #[cfg(feature = "coff")] -            $enum::Coff(ref mut $var) => $body, -            #[cfg(feature = "coff")] -            $enum::CoffBig(ref mut $var) => $body, -            #[cfg(feature = "elf")] -            $enum::Elf32(ref mut $var) => $body, -            #[cfg(feature = "elf")] -            $enum::Elf64(ref mut $var) => $body, -            #[cfg(feature = "macho")] -            $enum::MachO32(ref mut $var) => $body, -            #[cfg(feature = "macho")] -            $enum::MachO64(ref mut $var) => $body, -            #[cfg(feature = "pe")] -            $enum::Pe32(ref mut $var) => $body, -            #[cfg(feature = "pe")] -            $enum::Pe64(ref mut $var) => $body, -            #[cfg(feature = "wasm")] -            $enum::Wasm(ref mut $var) => $body, -            #[cfg(feature = "xcoff")] -            $enum::Xcoff32(ref mut $var) => $body, -            #[cfg(feature = "xcoff")] -            $enum::Xcoff64(ref mut $var) => $body, -        } -    }; -} - -/// Like `with_inner!`, but wraps the result in another enum. -macro_rules! map_inner { -    ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => { -        match $inner { -            #[cfg(feature = "coff")] -            $from::Coff(ref $var) => $to::Coff($body), -            #[cfg(feature = "coff")] -            $from::CoffBig(ref $var) => $to::CoffBig($body), -            #[cfg(feature = "elf")] -            $from::Elf32(ref $var) => $to::Elf32($body), -            #[cfg(feature = "elf")] -            $from::Elf64(ref $var) => $to::Elf64($body), -            #[cfg(feature = "macho")] -            $from::MachO32(ref $var) => $to::MachO32($body), -            #[cfg(feature = "macho")] -            $from::MachO64(ref $var) => $to::MachO64($body), -            #[cfg(feature = "pe")] -            $from::Pe32(ref $var) => $to::Pe32($body), -            #[cfg(feature = "pe")] -            $from::Pe64(ref $var) => $to::Pe64($body), -            #[cfg(feature = "wasm")] -            $from::Wasm(ref $var) => $to::Wasm($body), -            #[cfg(feature = "xcoff")] -            $from::Xcoff32(ref $var) => $to::Xcoff32($body), -            #[cfg(feature = "xcoff")] -            $from::Xcoff64(ref $var) => $to::Xcoff64($body), -        } -    }; -} - -/// Like `map_inner!`, but the result is a Result or Option. -macro_rules! map_inner_option { -    ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => { -        match $inner { -            #[cfg(feature = "coff")] -            $from::Coff(ref $var) => $body.map($to::Coff), -            #[cfg(feature = "coff")] -            $from::CoffBig(ref $var) => $body.map($to::CoffBig), -            #[cfg(feature = "elf")] -            $from::Elf32(ref $var) => $body.map($to::Elf32), -            #[cfg(feature = "elf")] -            $from::Elf64(ref $var) => $body.map($to::Elf64), -            #[cfg(feature = "macho")] -            $from::MachO32(ref $var) => $body.map($to::MachO32), -            #[cfg(feature = "macho")] -            $from::MachO64(ref $var) => $body.map($to::MachO64), -            #[cfg(feature = "pe")] -            $from::Pe32(ref $var) => $body.map($to::Pe32), -            #[cfg(feature = "pe")] -            $from::Pe64(ref $var) => $body.map($to::Pe64), -            #[cfg(feature = "wasm")] -            $from::Wasm(ref $var) => $body.map($to::Wasm), -            #[cfg(feature = "xcoff")] -            $from::Xcoff32(ref $var) => $body.map($to::Xcoff32), -            #[cfg(feature = "xcoff")] -            $from::Xcoff64(ref $var) => $body.map($to::Xcoff64), -        } -    }; -} - -macro_rules! map_inner_option_mut { -    ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => { -        match $inner { -            #[cfg(feature = "coff")] -            $from::Coff(ref mut $var) => $body.map($to::Coff), -            #[cfg(feature = "coff")] -            $from::CoffBig(ref mut $var) => $body.map($to::CoffBig), -            #[cfg(feature = "elf")] -            $from::Elf32(ref mut $var) => $body.map($to::Elf32), -            #[cfg(feature = "elf")] -            $from::Elf64(ref mut $var) => $body.map($to::Elf64), -            #[cfg(feature = "macho")] -            $from::MachO32(ref mut $var) => $body.map($to::MachO32), -            #[cfg(feature = "macho")] -            $from::MachO64(ref mut $var) => $body.map($to::MachO64), -            #[cfg(feature = "pe")] -            $from::Pe32(ref mut $var) => $body.map($to::Pe32), -            #[cfg(feature = "pe")] -            $from::Pe64(ref mut $var) => $body.map($to::Pe64), -            #[cfg(feature = "wasm")] -            $from::Wasm(ref mut $var) => $body.map($to::Wasm), -            #[cfg(feature = "xcoff")] -            $from::Xcoff32(ref mut $var) => $body.map($to::Xcoff32), -            #[cfg(feature = "xcoff")] -            $from::Xcoff64(ref mut $var) => $body.map($to::Xcoff64), -        } -    }; -} - -/// Call `next` for a file format iterator. -macro_rules! next_inner { -    ($inner:expr, $from:ident, $to:ident) => { -        match $inner { -            #[cfg(feature = "coff")] -            $from::Coff(ref mut iter) => iter.next().map($to::Coff), -            #[cfg(feature = "coff")] -            $from::CoffBig(ref mut iter) => iter.next().map($to::CoffBig), -            #[cfg(feature = "elf")] -            $from::Elf32(ref mut iter) => iter.next().map($to::Elf32), -            #[cfg(feature = "elf")] -            $from::Elf64(ref mut iter) => iter.next().map($to::Elf64), -            #[cfg(feature = "macho")] -            $from::MachO32(ref mut iter) => iter.next().map($to::MachO32), -            #[cfg(feature = "macho")] -            $from::MachO64(ref mut iter) => iter.next().map($to::MachO64), -            #[cfg(feature = "pe")] -            $from::Pe32(ref mut iter) => iter.next().map($to::Pe32), -            #[cfg(feature = "pe")] -            $from::Pe64(ref mut iter) => iter.next().map($to::Pe64), -            #[cfg(feature = "wasm")] -            $from::Wasm(ref mut iter) => iter.next().map($to::Wasm), -            #[cfg(feature = "xcoff")] -            $from::Xcoff32(ref mut iter) => iter.next().map($to::Xcoff32), -            #[cfg(feature = "xcoff")] -            $from::Xcoff64(ref mut iter) => iter.next().map($to::Xcoff64), -        } -    }; -} - -/// An object file that can be any supported file format. -/// -/// Most functionality is provided by the [`Object`] trait implementation. -#[derive(Debug)] -#[non_exhaustive] -#[allow(missing_docs)] -pub enum File<'data, R: ReadRef<'data> = &'data [u8]> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffFile<'data, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigFile<'data, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfFile32<'data, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfFile64<'data, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOFile32<'data, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOFile64<'data, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeFile32<'data, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeFile64<'data, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmFile<'data, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffFile32<'data, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffFile64<'data, R>), -} - -impl<'data, R: ReadRef<'data>> File<'data, R> { -    /// Parse the raw file data. -    pub fn parse(data: R) -> Result<Self> { -        Ok(match FileKind::parse(data)? { -            #[cfg(feature = "elf")] -            FileKind::Elf32 => File::Elf32(elf::ElfFile32::parse(data)?), -            #[cfg(feature = "elf")] -            FileKind::Elf64 => File::Elf64(elf::ElfFile64::parse(data)?), -            #[cfg(feature = "macho")] -            FileKind::MachO32 => File::MachO32(macho::MachOFile32::parse(data)?), -            #[cfg(feature = "macho")] -            FileKind::MachO64 => File::MachO64(macho::MachOFile64::parse(data)?), -            #[cfg(feature = "wasm")] -            FileKind::Wasm => File::Wasm(wasm::WasmFile::parse(data)?), -            #[cfg(feature = "pe")] -            FileKind::Pe32 => File::Pe32(pe::PeFile32::parse(data)?), -            #[cfg(feature = "pe")] -            FileKind::Pe64 => File::Pe64(pe::PeFile64::parse(data)?), -            #[cfg(feature = "coff")] -            FileKind::Coff => File::Coff(coff::CoffFile::parse(data)?), -            #[cfg(feature = "coff")] -            FileKind::CoffBig => File::CoffBig(coff::CoffBigFile::parse(data)?), -            #[cfg(feature = "xcoff")] -            FileKind::Xcoff32 => File::Xcoff32(xcoff::XcoffFile32::parse(data)?), -            #[cfg(feature = "xcoff")] -            FileKind::Xcoff64 => File::Xcoff64(xcoff::XcoffFile64::parse(data)?), -            #[allow(unreachable_patterns)] -            _ => return Err(Error("Unsupported file format")), -        }) -    } - -    /// Parse a Mach-O image from the dyld shared cache. -    #[cfg(feature = "macho")] -    pub fn parse_dyld_cache_image<'cache, E: Endian>( -        image: &macho::DyldCacheImage<'data, 'cache, E, R>, -    ) -> Result<Self> { -        Ok(match image.cache.architecture().address_size() { -            Some(AddressSize::U64) => { -                File::MachO64(macho::MachOFile64::parse_dyld_cache_image(image)?) -            } -            Some(AddressSize::U32) => { -                File::MachO32(macho::MachOFile32::parse_dyld_cache_image(image)?) -            } -            _ => return Err(Error("Unsupported file format")), -        }) -    } - -    /// Return the file format. -    pub fn format(&self) -> BinaryFormat { -        match self { -            #[cfg(feature = "coff")] -            File::Coff(_) | File::CoffBig(_) => BinaryFormat::Coff, -            #[cfg(feature = "elf")] -            File::Elf32(_) | File::Elf64(_) => BinaryFormat::Elf, -            #[cfg(feature = "macho")] -            File::MachO32(_) | File::MachO64(_) => BinaryFormat::MachO, -            #[cfg(feature = "pe")] -            File::Pe32(_) | File::Pe64(_) => BinaryFormat::Pe, -            #[cfg(feature = "wasm")] -            File::Wasm(_) => BinaryFormat::Wasm, -            #[cfg(feature = "xcoff")] -            File::Xcoff32(_) | File::Xcoff64(_) => BinaryFormat::Xcoff, -        } -    } -} - -impl<'data, R: ReadRef<'data>> read::private::Sealed for File<'data, R> {} - -impl<'data, 'file, R> Object<'data, 'file> for File<'data, R> -where -    'data: 'file, -    R: 'file + ReadRef<'data>, -{ -    type Segment = Segment<'data, 'file, R>; -    type SegmentIterator = SegmentIterator<'data, 'file, R>; -    type Section = Section<'data, 'file, R>; -    type SectionIterator = SectionIterator<'data, 'file, R>; -    type Comdat = Comdat<'data, 'file, R>; -    type ComdatIterator = ComdatIterator<'data, 'file, R>; -    type Symbol = Symbol<'data, 'file, R>; -    type SymbolIterator = SymbolIterator<'data, 'file, R>; -    type SymbolTable = SymbolTable<'data, 'file, R>; -    type DynamicRelocationIterator = DynamicRelocationIterator<'data, 'file, R>; - -    fn architecture(&self) -> Architecture { -        with_inner!(self, File, |x| x.architecture()) -    } - -    fn sub_architecture(&self) -> Option<SubArchitecture> { -        with_inner!(self, File, |x| x.sub_architecture()) -    } - -    fn is_little_endian(&self) -> bool { -        with_inner!(self, File, |x| x.is_little_endian()) -    } - -    fn is_64(&self) -> bool { -        with_inner!(self, File, |x| x.is_64()) -    } - -    fn kind(&self) -> ObjectKind { -        with_inner!(self, File, |x| x.kind()) -    } - -    fn segments(&'file self) -> SegmentIterator<'data, 'file, R> { -        SegmentIterator { -            inner: map_inner!(self, File, SegmentIteratorInternal, |x| x.segments()), -        } -    } - -    fn section_by_name_bytes(&'file self, section_name: &[u8]) -> Option<Section<'data, 'file, R>> { -        map_inner_option!(self, File, SectionInternal, |x| x -            .section_by_name_bytes(section_name)) -        .map(|inner| Section { inner }) -    } - -    fn section_by_index(&'file self, index: SectionIndex) -> Result<Section<'data, 'file, R>> { -        map_inner_option!(self, File, SectionInternal, |x| x.section_by_index(index)) -            .map(|inner| Section { inner }) -    } - -    fn sections(&'file self) -> SectionIterator<'data, 'file, R> { -        SectionIterator { -            inner: map_inner!(self, File, SectionIteratorInternal, |x| x.sections()), -        } -    } - -    fn comdats(&'file self) -> ComdatIterator<'data, 'file, R> { -        ComdatIterator { -            inner: map_inner!(self, File, ComdatIteratorInternal, |x| x.comdats()), -        } -    } - -    fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<Symbol<'data, 'file, R>> { -        map_inner_option!(self, File, SymbolInternal, |x| x -            .symbol_by_index(index) -            .map(|x| (x, PhantomData))) -        .map(|inner| Symbol { inner }) -    } - -    fn symbols(&'file self) -> SymbolIterator<'data, 'file, R> { -        SymbolIterator { -            inner: map_inner!(self, File, SymbolIteratorInternal, |x| ( -                x.symbols(), -                PhantomData -            )), -        } -    } - -    fn symbol_table(&'file self) -> Option<SymbolTable<'data, 'file, R>> { -        map_inner_option!(self, File, SymbolTableInternal, |x| x -            .symbol_table() -            .map(|x| (x, PhantomData))) -        .map(|inner| SymbolTable { inner }) -    } - -    fn dynamic_symbols(&'file self) -> SymbolIterator<'data, 'file, R> { -        SymbolIterator { -            inner: map_inner!(self, File, SymbolIteratorInternal, |x| ( -                x.dynamic_symbols(), -                PhantomData -            )), -        } -    } - -    fn dynamic_symbol_table(&'file self) -> Option<SymbolTable<'data, 'file, R>> { -        map_inner_option!(self, File, SymbolTableInternal, |x| x -            .dynamic_symbol_table() -            .map(|x| (x, PhantomData))) -        .map(|inner| SymbolTable { inner }) -    } - -    #[cfg(feature = "elf")] -    fn dynamic_relocations(&'file self) -> Option<DynamicRelocationIterator<'data, 'file, R>> { -        let inner = match self { -            File::Elf32(ref elf) => { -                DynamicRelocationIteratorInternal::Elf32(elf.dynamic_relocations()?) -            } -            File::Elf64(ref elf) => { -                DynamicRelocationIteratorInternal::Elf64(elf.dynamic_relocations()?) -            } -            #[allow(unreachable_patterns)] -            _ => return None, -        }; -        Some(DynamicRelocationIterator { inner }) -    } - -    #[cfg(not(feature = "elf"))] -    fn dynamic_relocations(&'file self) -> Option<DynamicRelocationIterator<'data, 'file, R>> { -        None -    } - -    fn symbol_map(&self) -> SymbolMap<SymbolMapName<'data>> { -        with_inner!(self, File, |x| x.symbol_map()) -    } - -    fn object_map(&self) -> ObjectMap<'data> { -        with_inner!(self, File, |x| x.object_map()) -    } - -    fn imports(&self) -> Result<Vec<Import<'data>>> { -        with_inner!(self, File, |x| x.imports()) -    } - -    fn exports(&self) -> Result<Vec<Export<'data>>> { -        with_inner!(self, File, |x| x.exports()) -    } - -    fn has_debug_symbols(&self) -> bool { -        with_inner!(self, File, |x| x.has_debug_symbols()) -    } - -    #[inline] -    fn mach_uuid(&self) -> Result<Option<[u8; 16]>> { -        with_inner!(self, File, |x| x.mach_uuid()) -    } - -    #[inline] -    fn build_id(&self) -> Result<Option<&'data [u8]>> { -        with_inner!(self, File, |x| x.build_id()) -    } - -    #[inline] -    fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> { -        with_inner!(self, File, |x| x.gnu_debuglink()) -    } - -    #[inline] -    fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> { -        with_inner!(self, File, |x| x.gnu_debugaltlink()) -    } - -    #[inline] -    fn pdb_info(&self) -> Result<Option<CodeView<'_>>> { -        with_inner!(self, File, |x| x.pdb_info()) -    } - -    fn relative_address_base(&self) -> u64 { -        with_inner!(self, File, |x| x.relative_address_base()) -    } - -    fn entry(&self) -> u64 { -        with_inner!(self, File, |x| x.entry()) -    } - -    fn flags(&self) -> FileFlags { -        with_inner!(self, File, |x| x.flags()) -    } -} - -/// An iterator for the loadable segments in a [`File`]. -#[derive(Debug)] -pub struct SegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: SegmentIteratorInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum SegmentIteratorInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffSegmentIterator<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigSegmentIterator<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfSegmentIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfSegmentIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOSegmentIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOSegmentIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeSegmentIterator32<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeSegmentIterator64<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmSegmentIterator<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffSegmentIterator32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffSegmentIterator64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> Iterator for SegmentIterator<'data, 'file, R> { -    type Item = Segment<'data, 'file, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        next_inner!(self.inner, SegmentIteratorInternal, SegmentInternal) -            .map(|inner| Segment { inner }) -    } -} - -/// A loadable segment in a [`File`]. -/// -/// Most functionality is provided by the [`ObjectSegment`] trait implementation. -pub struct Segment<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: SegmentInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum SegmentInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffSegment<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigSegment<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfSegment32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfSegment64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOSegment32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOSegment64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeSegment32<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeSegment64<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmSegment<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffSegment32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffSegment64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Segment<'data, 'file, R> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        // It's painful to do much better than this -        let mut s = f.debug_struct("Segment"); -        match self.name() { -            Ok(Some(ref name)) => { -                s.field("name", name); -            } -            Ok(None) => {} -            Err(_) => { -                s.field("name", &"<invalid>"); -            } -        } -        s.field("address", &self.address()) -            .field("size", &self.size()) -            .finish() -    } -} - -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Segment<'data, 'file, R> {} - -impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'file, R> { -    fn address(&self) -> u64 { -        with_inner!(self.inner, SegmentInternal, |x| x.address()) -    } - -    fn size(&self) -> u64 { -        with_inner!(self.inner, SegmentInternal, |x| x.size()) -    } - -    fn align(&self) -> u64 { -        with_inner!(self.inner, SegmentInternal, |x| x.align()) -    } - -    fn file_range(&self) -> (u64, u64) { -        with_inner!(self.inner, SegmentInternal, |x| x.file_range()) -    } - -    fn data(&self) -> Result<&'data [u8]> { -        with_inner!(self.inner, SegmentInternal, |x| x.data()) -    } - -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> { -        with_inner!(self.inner, SegmentInternal, |x| x.data_range(address, size)) -    } - -    fn name_bytes(&self) -> Result<Option<&[u8]>> { -        with_inner!(self.inner, SegmentInternal, |x| x.name_bytes()) -    } - -    fn name(&self) -> Result<Option<&str>> { -        with_inner!(self.inner, SegmentInternal, |x| x.name()) -    } - -    fn flags(&self) -> SegmentFlags { -        with_inner!(self.inner, SegmentInternal, |x| x.flags()) -    } -} - -/// An iterator for the sections in a [`File`]. -#[derive(Debug)] -pub struct SectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: SectionIteratorInternal<'data, 'file, R>, -} - -// we wrap our enums in a struct so that they are kept private. -#[derive(Debug)] -enum SectionIteratorInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffSectionIterator<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigSectionIterator<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfSectionIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfSectionIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOSectionIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOSectionIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeSectionIterator32<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeSectionIterator64<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmSectionIterator<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffSectionIterator32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffSectionIterator64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionIterator<'data, 'file, R> { -    type Item = Section<'data, 'file, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        next_inner!(self.inner, SectionIteratorInternal, SectionInternal) -            .map(|inner| Section { inner }) -    } -} - -/// A section in a [`File`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -pub struct Section<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: SectionInternal<'data, 'file, R>, -} - -enum SectionInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffSection<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigSection<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfSection32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfSection64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOSection32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOSection64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeSection32<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeSection64<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmSection<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffSection32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffSection64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Section<'data, 'file, R> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        // It's painful to do much better than this -        let mut s = f.debug_struct("Section"); -        match self.segment_name() { -            Ok(Some(ref name)) => { -                s.field("segment", name); -            } -            Ok(None) => {} -            Err(_) => { -                s.field("segment", &"<invalid>"); -            } -        } -        s.field("name", &self.name().unwrap_or("<invalid>")) -            .field("address", &self.address()) -            .field("size", &self.size()) -            .field("align", &self.align()) -            .field("kind", &self.kind()) -            .field("flags", &self.flags()) -            .finish() -    } -} - -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Section<'data, 'file, R> {} - -impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'file, R> { -    type RelocationIterator = SectionRelocationIterator<'data, 'file, R>; - -    fn index(&self) -> SectionIndex { -        with_inner!(self.inner, SectionInternal, |x| x.index()) -    } - -    fn address(&self) -> u64 { -        with_inner!(self.inner, SectionInternal, |x| x.address()) -    } - -    fn size(&self) -> u64 { -        with_inner!(self.inner, SectionInternal, |x| x.size()) -    } - -    fn align(&self) -> u64 { -        with_inner!(self.inner, SectionInternal, |x| x.align()) -    } - -    fn file_range(&self) -> Option<(u64, u64)> { -        with_inner!(self.inner, SectionInternal, |x| x.file_range()) -    } - -    fn data(&self) -> Result<&'data [u8]> { -        with_inner!(self.inner, SectionInternal, |x| x.data()) -    } - -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> { -        with_inner!(self.inner, SectionInternal, |x| x.data_range(address, size)) -    } - -    fn compressed_file_range(&self) -> Result<CompressedFileRange> { -        with_inner!(self.inner, SectionInternal, |x| x.compressed_file_range()) -    } - -    fn compressed_data(&self) -> Result<CompressedData<'data>> { -        with_inner!(self.inner, SectionInternal, |x| x.compressed_data()) -    } - -    fn name_bytes(&self) -> Result<&[u8]> { -        with_inner!(self.inner, SectionInternal, |x| x.name_bytes()) -    } - -    fn name(&self) -> Result<&str> { -        with_inner!(self.inner, SectionInternal, |x| x.name()) -    } - -    fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { -        with_inner!(self.inner, SectionInternal, |x| x.segment_name_bytes()) -    } - -    fn segment_name(&self) -> Result<Option<&str>> { -        with_inner!(self.inner, SectionInternal, |x| x.segment_name()) -    } - -    fn kind(&self) -> SectionKind { -        with_inner!(self.inner, SectionInternal, |x| x.kind()) -    } - -    fn relocations(&self) -> SectionRelocationIterator<'data, 'file, R> { -        SectionRelocationIterator { -            inner: map_inner!( -                self.inner, -                SectionInternal, -                SectionRelocationIteratorInternal, -                |x| x.relocations() -            ), -        } -    } - -    fn flags(&self) -> SectionFlags { -        with_inner!(self.inner, SectionInternal, |x| x.flags()) -    } -} - -/// An iterator for the COMDAT section groups in a [`File`]. -#[derive(Debug)] -pub struct ComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: ComdatIteratorInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum ComdatIteratorInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffComdatIterator<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigComdatIterator<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfComdatIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfComdatIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOComdatIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOComdatIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeComdatIterator32<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeComdatIterator64<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmComdatIterator<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffComdatIterator32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffComdatIterator64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatIterator<'data, 'file, R> { -    type Item = Comdat<'data, 'file, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        next_inner!(self.inner, ComdatIteratorInternal, ComdatInternal) -            .map(|inner| Comdat { inner }) -    } -} - -/// A COMDAT section group in a [`File`]. -/// -/// Most functionality is provided by the [`ObjectComdat`] trait implementation. -pub struct Comdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: ComdatInternal<'data, 'file, R>, -} - -enum ComdatInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffComdat<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigComdat<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfComdat32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfComdat64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOComdat32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOComdat64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeComdat32<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeComdat64<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmComdat<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffComdat32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffComdat64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Comdat<'data, 'file, R> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        let mut s = f.debug_struct("Comdat"); -        s.field("symbol", &self.symbol()) -            .field("name", &self.name().unwrap_or("<invalid>")) -            .field("kind", &self.kind()) -            .finish() -    } -} - -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Comdat<'data, 'file, R> {} - -impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for Comdat<'data, 'file, R> { -    type SectionIterator = ComdatSectionIterator<'data, 'file, R>; - -    fn kind(&self) -> ComdatKind { -        with_inner!(self.inner, ComdatInternal, |x| x.kind()) -    } - -    fn symbol(&self) -> SymbolIndex { -        with_inner!(self.inner, ComdatInternal, |x| x.symbol()) -    } - -    fn name_bytes(&self) -> Result<&[u8]> { -        with_inner!(self.inner, ComdatInternal, |x| x.name_bytes()) -    } - -    fn name(&self) -> Result<&str> { -        with_inner!(self.inner, ComdatInternal, |x| x.name()) -    } - -    fn sections(&self) -> ComdatSectionIterator<'data, 'file, R> { -        ComdatSectionIterator { -            inner: map_inner!( -                self.inner, -                ComdatInternal, -                ComdatSectionIteratorInternal, -                |x| x.sections() -            ), -        } -    } -} - -/// An iterator for the sections in a [`Comdat`]. -#[derive(Debug)] -pub struct ComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: ComdatSectionIteratorInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum ComdatSectionIteratorInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffComdatSectionIterator<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigComdatSectionIterator<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfComdatSectionIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfComdatSectionIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachOComdatSectionIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachOComdatSectionIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeComdatSectionIterator32<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeComdatSectionIterator64<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmComdatSectionIterator<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffComdatSectionIterator32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffComdatSectionIterator64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatSectionIterator<'data, 'file, R> { -    type Item = SectionIndex; - -    fn next(&mut self) -> Option<Self::Item> { -        with_inner_mut!(self.inner, ComdatSectionIteratorInternal, |x| x.next()) -    } -} - -/// A symbol table in a [`File`]. -/// -/// Most functionality is provided by the [`ObjectSymbolTable`] trait implementation. -#[derive(Debug)] -pub struct SymbolTable<'data, 'file, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    inner: SymbolTableInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum SymbolTableInternal<'data, 'file, R> -where -    R: ReadRef<'data>, -{ -    #[cfg(feature = "coff")] -    Coff((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "coff")] -    CoffBig((coff::CoffBigSymbolTable<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "elf")] -    Elf32( -        ( -            elf::ElfSymbolTable32<'data, 'file, Endianness, R>, -            PhantomData<R>, -        ), -    ), -    #[cfg(feature = "elf")] -    Elf64( -        ( -            elf::ElfSymbolTable64<'data, 'file, Endianness, R>, -            PhantomData<R>, -        ), -    ), -    #[cfg(feature = "macho")] -    MachO32( -        ( -            macho::MachOSymbolTable32<'data, 'file, Endianness, R>, -            PhantomData<()>, -        ), -    ), -    #[cfg(feature = "macho")] -    MachO64( -        ( -            macho::MachOSymbolTable64<'data, 'file, Endianness, R>, -            PhantomData<()>, -        ), -    ), -    #[cfg(feature = "pe")] -    Pe32((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "pe")] -    Pe64((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "wasm")] -    Wasm((wasm::WasmSymbolTable<'data, 'file>, PhantomData<R>)), -    #[cfg(feature = "xcoff")] -    Xcoff32((xcoff::XcoffSymbolTable32<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "xcoff")] -    Xcoff64((xcoff::XcoffSymbolTable64<'data, 'file, R>, PhantomData<R>)), -} - -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for SymbolTable<'data, 'file, R> {} - -impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> for SymbolTable<'data, 'file, R> { -    type Symbol = Symbol<'data, 'file, R>; -    type SymbolIterator = SymbolIterator<'data, 'file, R>; - -    fn symbols(&self) -> Self::SymbolIterator { -        SymbolIterator { -            inner: map_inner!( -                self.inner, -                SymbolTableInternal, -                SymbolIteratorInternal, -                |x| (x.0.symbols(), PhantomData) -            ), -        } -    } - -    fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> { -        map_inner_option!(self.inner, SymbolTableInternal, SymbolInternal, |x| x -            .0 -            .symbol_by_index(index) -            .map(|x| (x, PhantomData))) -        .map(|inner| Symbol { inner }) -    } -} - -/// An iterator for the symbols in a [`SymbolTable`]. -#[derive(Debug)] -pub struct SymbolIterator<'data, 'file, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    inner: SymbolIteratorInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum SymbolIteratorInternal<'data, 'file, R> -where -    R: ReadRef<'data>, -{ -    #[cfg(feature = "coff")] -    Coff((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "coff")] -    CoffBig((coff::CoffBigSymbolIterator<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "elf")] -    Elf32( -        ( -            elf::ElfSymbolIterator32<'data, 'file, Endianness, R>, -            PhantomData<R>, -        ), -    ), -    #[cfg(feature = "elf")] -    Elf64( -        ( -            elf::ElfSymbolIterator64<'data, 'file, Endianness, R>, -            PhantomData<R>, -        ), -    ), -    #[cfg(feature = "macho")] -    MachO32( -        ( -            macho::MachOSymbolIterator32<'data, 'file, Endianness, R>, -            PhantomData<()>, -        ), -    ), -    #[cfg(feature = "macho")] -    MachO64( -        ( -            macho::MachOSymbolIterator64<'data, 'file, Endianness, R>, -            PhantomData<()>, -        ), -    ), -    #[cfg(feature = "pe")] -    Pe32((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "pe")] -    Pe64((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "wasm")] -    Wasm((wasm::WasmSymbolIterator<'data, 'file>, PhantomData<R>)), -    #[cfg(feature = "xcoff")] -    Xcoff32( -        ( -            xcoff::XcoffSymbolIterator32<'data, 'file, R>, -            PhantomData<R>, -        ), -    ), -    #[cfg(feature = "xcoff")] -    Xcoff64( -        ( -            xcoff::XcoffSymbolIterator64<'data, 'file, R>, -            PhantomData<R>, -        ), -    ), -} - -impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file, R> { -    type Item = Symbol<'data, 'file, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        map_inner_option_mut!(self.inner, SymbolIteratorInternal, SymbolInternal, |iter| { -            iter.0.next().map(|x| (x, PhantomData)) -        }) -        .map(|inner| Symbol { inner }) -    } -} - -/// An symbol in a [`SymbolTable`]. -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -pub struct Symbol<'data, 'file, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    inner: SymbolInternal<'data, 'file, R>, -} - -enum SymbolInternal<'data, 'file, R> -where -    R: ReadRef<'data>, -{ -    #[cfg(feature = "coff")] -    Coff((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "coff")] -    CoffBig((coff::CoffBigSymbol<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "elf")] -    Elf32( -        ( -            elf::ElfSymbol32<'data, 'file, Endianness, R>, -            PhantomData<R>, -        ), -    ), -    #[cfg(feature = "elf")] -    Elf64( -        ( -            elf::ElfSymbol64<'data, 'file, Endianness, R>, -            PhantomData<R>, -        ), -    ), -    #[cfg(feature = "macho")] -    MachO32( -        ( -            macho::MachOSymbol32<'data, 'file, Endianness, R>, -            PhantomData<()>, -        ), -    ), -    #[cfg(feature = "macho")] -    MachO64( -        ( -            macho::MachOSymbol64<'data, 'file, Endianness, R>, -            PhantomData<()>, -        ), -    ), -    #[cfg(feature = "pe")] -    Pe32((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "pe")] -    Pe64((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "wasm")] -    Wasm((wasm::WasmSymbol<'data, 'file>, PhantomData<R>)), -    #[cfg(feature = "xcoff")] -    Xcoff32((xcoff::XcoffSymbol32<'data, 'file, R>, PhantomData<R>)), -    #[cfg(feature = "xcoff")] -    Xcoff64((xcoff::XcoffSymbol64<'data, 'file, R>, PhantomData<R>)), -} - -impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Symbol<'data, 'file, R> { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("Symbol") -            .field("name", &self.name().unwrap_or("<invalid>")) -            .field("address", &self.address()) -            .field("size", &self.size()) -            .field("kind", &self.kind()) -            .field("section", &self.section()) -            .field("scope", &self.scope()) -            .field("weak", &self.is_weak()) -            .field("flags", &self.flags()) -            .finish() -    } -} - -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Symbol<'data, 'file, R> {} - -impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'file, R> { -    fn index(&self) -> SymbolIndex { -        with_inner!(self.inner, SymbolInternal, |x| x.0.index()) -    } - -    fn name_bytes(&self) -> Result<&'data [u8]> { -        with_inner!(self.inner, SymbolInternal, |x| x.0.name_bytes()) -    } - -    fn name(&self) -> Result<&'data str> { -        with_inner!(self.inner, SymbolInternal, |x| x.0.name()) -    } - -    fn address(&self) -> u64 { -        with_inner!(self.inner, SymbolInternal, |x| x.0.address()) -    } - -    fn size(&self) -> u64 { -        with_inner!(self.inner, SymbolInternal, |x| x.0.size()) -    } - -    fn kind(&self) -> SymbolKind { -        with_inner!(self.inner, SymbolInternal, |x| x.0.kind()) -    } - -    fn section(&self) -> SymbolSection { -        with_inner!(self.inner, SymbolInternal, |x| x.0.section()) -    } - -    fn is_undefined(&self) -> bool { -        with_inner!(self.inner, SymbolInternal, |x| x.0.is_undefined()) -    } - -    fn is_definition(&self) -> bool { -        with_inner!(self.inner, SymbolInternal, |x| x.0.is_definition()) -    } - -    fn is_common(&self) -> bool { -        with_inner!(self.inner, SymbolInternal, |x| x.0.is_common()) -    } - -    fn is_weak(&self) -> bool { -        with_inner!(self.inner, SymbolInternal, |x| x.0.is_weak()) -    } - -    fn scope(&self) -> SymbolScope { -        with_inner!(self.inner, SymbolInternal, |x| x.0.scope()) -    } - -    fn is_global(&self) -> bool { -        with_inner!(self.inner, SymbolInternal, |x| x.0.is_global()) -    } - -    fn is_local(&self) -> bool { -        with_inner!(self.inner, SymbolInternal, |x| x.0.is_local()) -    } - -    fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> { -        with_inner!(self.inner, SymbolInternal, |x| x.0.flags()) -    } -} - -/// An iterator for the dynamic relocation entries in a [`File`]. -#[derive(Debug)] -pub struct DynamicRelocationIterator<'data, 'file, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    inner: DynamicRelocationIteratorInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum DynamicRelocationIteratorInternal<'data, 'file, R> -where -    R: ReadRef<'data>, -{ -    #[cfg(feature = "elf")] -    Elf32(elf::ElfDynamicRelocationIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfDynamicRelocationIterator64<'data, 'file, Endianness, R>), -    // We need to always use the lifetime parameters. -    #[allow(unused)] -    None(PhantomData<(&'data (), &'file (), R)>), -} - -impl<'data, 'file, R: ReadRef<'data>> Iterator for DynamicRelocationIterator<'data, 'file, R> { -    type Item = (u64, Relocation); - -    fn next(&mut self) -> Option<Self::Item> { -        match self.inner { -            #[cfg(feature = "elf")] -            DynamicRelocationIteratorInternal::Elf32(ref mut elf) => elf.next(), -            #[cfg(feature = "elf")] -            DynamicRelocationIteratorInternal::Elf64(ref mut elf) => elf.next(), -            DynamicRelocationIteratorInternal::None(_) => None, -        } -    } -} - -/// An iterator for the relocation entries in a [`Section`]. -#[derive(Debug)] -pub struct SectionRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { -    inner: SectionRelocationIteratorInternal<'data, 'file, R>, -} - -#[derive(Debug)] -enum SectionRelocationIteratorInternal<'data, 'file, R: ReadRef<'data>> { -    #[cfg(feature = "coff")] -    Coff(coff::CoffRelocationIterator<'data, 'file, R>), -    #[cfg(feature = "coff")] -    CoffBig(coff::CoffBigRelocationIterator<'data, 'file, R>), -    #[cfg(feature = "elf")] -    Elf32(elf::ElfSectionRelocationIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "elf")] -    Elf64(elf::ElfSectionRelocationIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO32(macho::MachORelocationIterator32<'data, 'file, Endianness, R>), -    #[cfg(feature = "macho")] -    MachO64(macho::MachORelocationIterator64<'data, 'file, Endianness, R>), -    #[cfg(feature = "pe")] -    Pe32(pe::PeRelocationIterator<'data, 'file, R>), -    #[cfg(feature = "pe")] -    Pe64(pe::PeRelocationIterator<'data, 'file, R>), -    #[cfg(feature = "wasm")] -    Wasm(wasm::WasmRelocationIterator<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff32(xcoff::XcoffRelocationIterator32<'data, 'file, R>), -    #[cfg(feature = "xcoff")] -    Xcoff64(xcoff::XcoffRelocationIterator64<'data, 'file, R>), -} - -impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionRelocationIterator<'data, 'file, R> { -    type Item = (u64, Relocation); - -    fn next(&mut self) -> Option<Self::Item> { -        with_inner_mut!(self.inner, SectionRelocationIteratorInternal, |x| x.next()) -    } -} diff --git a/vendor/object/src/read/archive.rs b/vendor/object/src/read/archive.rs deleted file mode 100644 index 5d4ec4a..0000000 --- a/vendor/object/src/read/archive.rs +++ /dev/null @@ -1,759 +0,0 @@ -//! Support for archive files. -//! -//! ## Example -//!  ```no_run -//! use object::{Object, ObjectSection}; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads an archive and displays the name of each member. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let file = object::read::archive::ArchiveFile::parse(&*data)?; -//!     for member in file.members() { -//!         let member = member?; -//!         println!("{}", String::from_utf8_lossy(member.name())); -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` - -use core::convert::TryInto; - -use crate::archive; -use crate::read::{self, Bytes, Error, ReadError, ReadRef}; - -/// The kind of archive format. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum ArchiveKind { -    /// There are no special files that indicate the archive format. -    Unknown, -    /// The GNU (or System V) archive format. -    Gnu, -    /// The GNU (or System V) archive format with 64-bit symbol table. -    Gnu64, -    /// The BSD archive format. -    Bsd, -    /// The BSD archive format with 64-bit symbol table. -    /// -    /// This is used for Darwin. -    Bsd64, -    /// The Windows COFF archive format. -    Coff, -    /// The AIX big archive format. -    AixBig, -} - -/// The list of members in the archive. -#[derive(Debug, Clone, Copy)] -enum Members<'data> { -    Common { -        offset: u64, -        end_offset: u64, -    }, -    AixBig { -        index: &'data [archive::AixMemberOffset], -    }, -} - -/// A partially parsed archive file. -#[derive(Debug, Clone, Copy)] -pub struct ArchiveFile<'data, R: ReadRef<'data> = &'data [u8]> { -    data: R, -    kind: ArchiveKind, -    members: Members<'data>, -    symbols: (u64, u64), -    names: &'data [u8], -} - -impl<'data, R: ReadRef<'data>> ArchiveFile<'data, R> { -    /// Parse the archive header and special members. -    pub fn parse(data: R) -> read::Result<Self> { -        let len = data.len().read_error("Unknown archive length")?; -        let mut tail = 0; -        let magic = data -            .read_bytes(&mut tail, archive::MAGIC.len() as u64) -            .read_error("Invalid archive size")?; - -        if magic == archive::AIX_BIG_MAGIC { -            return Self::parse_aixbig(data); -        } else if magic != archive::MAGIC { -            return Err(Error("Unsupported archive identifier")); -        } - -        let mut members_offset = tail; -        let members_end_offset = len; - -        let mut file = ArchiveFile { -            data, -            kind: ArchiveKind::Unknown, -            members: Members::Common { -                offset: 0, -                end_offset: 0, -            }, -            symbols: (0, 0), -            names: &[], -        }; - -        // The first few members may be special, so parse them. -        // GNU has: -        // - "/" or "/SYM64/": symbol table (optional) -        // - "//": names table (optional) -        // COFF has: -        // - "/": first linker member -        // - "/": second linker member -        // - "//": names table -        // BSD has: -        // - "__.SYMDEF" or "__.SYMDEF SORTED": symbol table (optional) -        // BSD 64-bit has: -        // - "__.SYMDEF_64" or "__.SYMDEF_64 SORTED": symbol table (optional) -        // BSD may use the extended name for the symbol table. This is handled -        // by `ArchiveMember::parse`. -        if tail < len { -            let member = ArchiveMember::parse(data, &mut tail, &[])?; -            if member.name == b"/" { -                // GNU symbol table (unless we later determine this is COFF). -                file.kind = ArchiveKind::Gnu; -                file.symbols = member.file_range(); -                members_offset = tail; - -                if tail < len { -                    let member = ArchiveMember::parse(data, &mut tail, &[])?; -                    if member.name == b"/" { -                        // COFF linker member. -                        file.kind = ArchiveKind::Coff; -                        file.symbols = member.file_range(); -                        members_offset = tail; - -                        if tail < len { -                            let member = ArchiveMember::parse(data, &mut tail, &[])?; -                            if member.name == b"//" { -                                // COFF names table. -                                file.names = member.data(data)?; -                                members_offset = tail; -                            } -                        } -                    } else if member.name == b"//" { -                        // GNU names table. -                        file.names = member.data(data)?; -                        members_offset = tail; -                    } -                } -            } else if member.name == b"/SYM64/" { -                // GNU 64-bit symbol table. -                file.kind = ArchiveKind::Gnu64; -                file.symbols = member.file_range(); -                members_offset = tail; - -                if tail < len { -                    let member = ArchiveMember::parse(data, &mut tail, &[])?; -                    if member.name == b"//" { -                        // GNU names table. -                        file.names = member.data(data)?; -                        members_offset = tail; -                    } -                } -            } else if member.name == b"//" { -                // GNU names table. -                file.kind = ArchiveKind::Gnu; -                file.names = member.data(data)?; -                members_offset = tail; -            } else if member.name == b"__.SYMDEF" || member.name == b"__.SYMDEF SORTED" { -                // BSD symbol table. -                file.kind = ArchiveKind::Bsd; -                file.symbols = member.file_range(); -                members_offset = tail; -            } else if member.name == b"__.SYMDEF_64" || member.name == b"__.SYMDEF_64 SORTED" { -                // BSD 64-bit symbol table. -                file.kind = ArchiveKind::Bsd64; -                file.symbols = member.file_range(); -                members_offset = tail; -            } else { -                // TODO: This could still be a BSD file. We leave this as unknown for now. -            } -        } -        file.members = Members::Common { -            offset: members_offset, -            end_offset: members_end_offset, -        }; -        Ok(file) -    } - -    fn parse_aixbig(data: R) -> read::Result<Self> { -        let mut tail = 0; - -        let file_header = data -            .read::<archive::AixFileHeader>(&mut tail) -            .read_error("Invalid AIX big archive file header")?; -        // Caller already validated this. -        debug_assert_eq!(file_header.magic, archive::AIX_BIG_MAGIC); - -        let mut file = ArchiveFile { -            data, -            kind: ArchiveKind::AixBig, -            members: Members::AixBig { index: &[] }, -            symbols: (0, 0), -            names: &[], -        }; - -        // Read the span of symbol table. -        let symtbl64 = parse_u64_digits(&file_header.gst64off, 10) -            .read_error("Invalid offset to 64-bit symbol table in AIX big archive")?; -        if symtbl64 > 0 { -            // The symbol table is also a file with header. -            let member = ArchiveMember::parse_aixbig(data, symtbl64)?; -            file.symbols = member.file_range(); -        } else { -            let symtbl = parse_u64_digits(&file_header.gstoff, 10) -                .read_error("Invalid offset to symbol table in AIX big archive")?; -            if symtbl > 0 { -                // The symbol table is also a file with header. -                let member = ArchiveMember::parse_aixbig(data, symtbl)?; -                file.symbols = member.file_range(); -            } -        } - -        // Big archive member index table lists file entries with offsets and names. -        // To avoid potential infinite loop (members are double-linked list), the -        // iterator goes through the index instead of real members. -        let member_table_offset = parse_u64_digits(&file_header.memoff, 10) -            .read_error("Invalid offset for member table of AIX big archive")?; -        if member_table_offset == 0 { -            // The offset would be zero if archive contains no file. -            return Ok(file); -        } - -        // The member index table is also a file with header. -        let member = ArchiveMember::parse_aixbig(data, member_table_offset)?; -        let mut member_data = Bytes(member.data(data)?); - -        // Structure of member index table: -        // Number of entries (20 bytes) -        // Offsets of each entry (20*N bytes) -        // Names string table (the rest of bytes to fill size defined in header) -        let members_count_bytes = member_data -            .read_slice::<u8>(20) -            .read_error("Missing member count in AIX big archive")?; -        let members_count = parse_u64_digits(members_count_bytes, 10) -            .and_then(|size| size.try_into().ok()) -            .read_error("Invalid member count in AIX big archive")?; -        let index = member_data -            .read_slice::<archive::AixMemberOffset>(members_count) -            .read_error("Member count overflow in AIX big archive")?; -        file.members = Members::AixBig { index }; - -        Ok(file) -    } - -    /// Return the archive format. -    #[inline] -    pub fn kind(&self) -> ArchiveKind { -        self.kind -    } - -    /// Iterate over the members of the archive. -    /// -    /// This does not return special members. -    #[inline] -    pub fn members(&self) -> ArchiveMemberIterator<'data, R> { -        ArchiveMemberIterator { -            data: self.data, -            members: self.members, -            names: self.names, -        } -    } -} - -/// An iterator over the members of an archive. -#[derive(Debug)] -pub struct ArchiveMemberIterator<'data, R: ReadRef<'data> = &'data [u8]> { -    data: R, -    members: Members<'data>, -    names: &'data [u8], -} - -impl<'data, R: ReadRef<'data>> Iterator for ArchiveMemberIterator<'data, R> { -    type Item = read::Result<ArchiveMember<'data>>; - -    fn next(&mut self) -> Option<Self::Item> { -        match &mut self.members { -            Members::Common { -                ref mut offset, -                ref mut end_offset, -            } => { -                if *offset >= *end_offset { -                    return None; -                } -                let member = ArchiveMember::parse(self.data, offset, self.names); -                if member.is_err() { -                    *offset = *end_offset; -                } -                Some(member) -            } -            Members::AixBig { ref mut index } => match **index { -                [] => None, -                [ref first, ref rest @ ..] => { -                    *index = rest; -                    let member = ArchiveMember::parse_aixbig_index(self.data, first); -                    if member.is_err() { -                        *index = &[]; -                    } -                    Some(member) -                } -            }, -        } -    } -} - -/// An archive member header. -#[derive(Debug, Clone, Copy)] -enum MemberHeader<'data> { -    /// Common header used by many formats. -    Common(&'data archive::Header), -    /// AIX big archive header -    AixBig(&'data archive::AixHeader), -} - -/// A partially parsed archive member. -#[derive(Debug)] -pub struct ArchiveMember<'data> { -    header: MemberHeader<'data>, -    name: &'data [u8], -    offset: u64, -    size: u64, -} - -impl<'data> ArchiveMember<'data> { -    /// Parse the member header, name, and file data in an archive with the common format. -    /// -    /// This reads the extended name (if any) and adjusts the file size. -    fn parse<R: ReadRef<'data>>( -        data: R, -        offset: &mut u64, -        names: &'data [u8], -    ) -> read::Result<Self> { -        let header = data -            .read::<archive::Header>(offset) -            .read_error("Invalid archive member header")?; -        if header.terminator != archive::TERMINATOR { -            return Err(Error("Invalid archive terminator")); -        } - -        let mut file_offset = *offset; -        let mut file_size = -            parse_u64_digits(&header.size, 10).read_error("Invalid archive member size")?; -        *offset = offset -            .checked_add(file_size) -            .read_error("Archive member size is too large")?; -        // Entries are padded to an even number of bytes. -        if (file_size & 1) != 0 { -            *offset = offset.saturating_add(1); -        } - -        let name = if header.name[0] == b'/' && (header.name[1] as char).is_ascii_digit() { -            // Read file name from the names table. -            parse_sysv_extended_name(&header.name[1..], names) -                .read_error("Invalid archive extended name offset")? -        } else if &header.name[..3] == b"#1/" && (header.name[3] as char).is_ascii_digit() { -            // Read file name from the start of the file data. -            parse_bsd_extended_name(&header.name[3..], data, &mut file_offset, &mut file_size) -                .read_error("Invalid archive extended name length")? -        } else if header.name[0] == b'/' { -            let name_len = memchr::memchr(b' ', &header.name).unwrap_or(header.name.len()); -            &header.name[..name_len] -        } else { -            let name_len = memchr::memchr(b'/', &header.name) -                .or_else(|| memchr::memchr(b' ', &header.name)) -                .unwrap_or(header.name.len()); -            &header.name[..name_len] -        }; - -        Ok(ArchiveMember { -            header: MemberHeader::Common(header), -            name, -            offset: file_offset, -            size: file_size, -        }) -    } - -    /// Parse a member index entry in an AIX big archive, -    /// and then parse the member header, name, and file data. -    fn parse_aixbig_index<R: ReadRef<'data>>( -        data: R, -        index: &archive::AixMemberOffset, -    ) -> read::Result<Self> { -        let offset = parse_u64_digits(&index.0, 10) -            .read_error("Invalid AIX big archive file member offset")?; -        Self::parse_aixbig(data, offset) -    } - -    /// Parse the member header, name, and file data in an AIX big archive. -    fn parse_aixbig<R: ReadRef<'data>>(data: R, mut offset: u64) -> read::Result<Self> { -        // The format was described at -        // https://www.ibm.com/docs/en/aix/7.3?topic=formats-ar-file-format-big -        let header = data -            .read::<archive::AixHeader>(&mut offset) -            .read_error("Invalid AIX big archive member header")?; -        let name_length = parse_u64_digits(&header.namlen, 10) -            .read_error("Invalid AIX big archive member name length")?; -        let name = data -            .read_bytes(&mut offset, name_length) -            .read_error("Invalid AIX big archive member name")?; - -        // The actual data for a file member begins at the first even-byte boundary beyond the -        // member header and continues for the number of bytes specified by the ar_size field. The -        // ar command inserts null bytes for padding where necessary. -        if offset & 1 != 0 { -            offset = offset.saturating_add(1); -        } -        // Because of the even-byte boundary, we have to read and check terminator after header. -        let terminator = data -            .read_bytes(&mut offset, 2) -            .read_error("Invalid AIX big archive terminator")?; -        if terminator != archive::TERMINATOR { -            return Err(Error("Invalid AIX big archive terminator")); -        } - -        let size = parse_u64_digits(&header.size, 10) -            .read_error("Invalid archive member size in AIX big archive")?; -        Ok(ArchiveMember { -            header: MemberHeader::AixBig(header), -            name, -            offset, -            size, -        }) -    } - -    /// Return the raw header that is common to many archive formats. -    /// -    /// Returns `None` if this archive does not use the common header format. -    #[inline] -    pub fn header(&self) -> Option<&'data archive::Header> { -        match self.header { -            MemberHeader::Common(header) => Some(header), -            _ => None, -        } -    } - -    /// Return the raw header for AIX big archives. -    /// -    /// Returns `None` if this is not an AIX big archive. -    #[inline] -    pub fn aix_header(&self) -> Option<&'data archive::AixHeader> { -        match self.header { -            MemberHeader::AixBig(header) => Some(header), -            _ => None, -        } -    } - -    /// Return the parsed file name. -    /// -    /// This may be an extended file name. -    #[inline] -    pub fn name(&self) -> &'data [u8] { -        self.name -    } - -    /// Parse the file modification timestamp from the header. -    #[inline] -    pub fn date(&self) -> Option<u64> { -        match &self.header { -            MemberHeader::Common(header) => parse_u64_digits(&header.date, 10), -            MemberHeader::AixBig(header) => parse_u64_digits(&header.date, 10), -        } -    } - -    /// Parse the user ID from the header. -    #[inline] -    pub fn uid(&self) -> Option<u64> { -        match &self.header { -            MemberHeader::Common(header) => parse_u64_digits(&header.uid, 10), -            MemberHeader::AixBig(header) => parse_u64_digits(&header.uid, 10), -        } -    } - -    /// Parse the group ID from the header. -    #[inline] -    pub fn gid(&self) -> Option<u64> { -        match &self.header { -            MemberHeader::Common(header) => parse_u64_digits(&header.gid, 10), -            MemberHeader::AixBig(header) => parse_u64_digits(&header.gid, 10), -        } -    } - -    /// Parse the file mode from the header. -    #[inline] -    pub fn mode(&self) -> Option<u64> { -        match &self.header { -            MemberHeader::Common(header) => parse_u64_digits(&header.mode, 8), -            MemberHeader::AixBig(header) => parse_u64_digits(&header.mode, 8), -        } -    } - -    /// Return the offset and size of the file data. -    pub fn file_range(&self) -> (u64, u64) { -        (self.offset, self.size) -    } - -    /// Return the file data. -    #[inline] -    pub fn data<R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [u8]> { -        data.read_bytes_at(self.offset, self.size) -            .read_error("Archive member size is too large") -    } -} - -// Ignores bytes starting from the first space. -fn parse_u64_digits(digits: &[u8], radix: u32) -> Option<u64> { -    if let [b' ', ..] = digits { -        return None; -    } -    let mut result: u64 = 0; -    for &c in digits { -        if c == b' ' { -            return Some(result); -        } else { -            let x = (c as char).to_digit(radix)?; -            result = result -                .checked_mul(u64::from(radix))? -                .checked_add(u64::from(x))?; -        } -    } -    Some(result) -} - -fn parse_sysv_extended_name<'data>(digits: &[u8], names: &'data [u8]) -> Result<&'data [u8], ()> { -    let offset = parse_u64_digits(digits, 10).ok_or(())?; -    let offset = offset.try_into().map_err(|_| ())?; -    let name_data = names.get(offset..).ok_or(())?; -    let name = match memchr::memchr2(b'/', b'\0', name_data) { -        Some(len) => &name_data[..len], -        None => name_data, -    }; -    Ok(name) -} - -/// Modifies `data` to start after the extended name. -fn parse_bsd_extended_name<'data, R: ReadRef<'data>>( -    digits: &[u8], -    data: R, -    offset: &mut u64, -    size: &mut u64, -) -> Result<&'data [u8], ()> { -    let len = parse_u64_digits(digits, 10).ok_or(())?; -    *size = size.checked_sub(len).ok_or(())?; -    let name_data = data.read_bytes(offset, len)?; -    let name = match memchr::memchr(b'\0', name_data) { -        Some(len) => &name_data[..len], -        None => name_data, -    }; -    Ok(name) -} - -#[cfg(test)] -mod tests { -    use super::*; - -    #[test] -    fn kind() { -        let data = b"!<arch>\n"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Unknown); - -        let data = b"\ -            !<arch>\n\ -            /                                               4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Gnu); - -        let data = b"\ -            !<arch>\n\ -            //                                              4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Gnu); - -        let data = b"\ -            !<arch>\n\ -            /                                               4         `\n\ -            0000\ -            //                                              4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Gnu); - -        let data = b"\ -            !<arch>\n\ -            /SYM64/                                         4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Gnu64); - -        let data = b"\ -            !<arch>\n\ -            /SYM64/                                         4         `\n\ -            0000\ -            //                                              4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Gnu64); - -        let data = b"\ -            !<arch>\n\ -            __.SYMDEF                                       4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Bsd); - -        let data = b"\ -            !<arch>\n\ -            #1/9                                            13        `\n\ -            __.SYMDEF0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Bsd); - -        let data = b"\ -            !<arch>\n\ -            #1/16                                           20        `\n\ -            __.SYMDEF SORTED0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Bsd); - -        let data = b"\ -            !<arch>\n\ -            __.SYMDEF_64                                    4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Bsd64); - -        let data = b"\ -            !<arch>\n\ -            #1/12                                           16        `\n\ -            __.SYMDEF_640000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Bsd64); - -        let data = b"\ -            !<arch>\n\ -            #1/19                                           23        `\n\ -            __.SYMDEF_64 SORTED0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Bsd64); - -        let data = b"\ -            !<arch>\n\ -            /                                               4         `\n\ -            0000\ -            /                                               4         `\n\ -            0000\ -            //                                              4         `\n\ -            0000"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Coff); - -        let data = b"\ -            <bigaf>\n\ -            0                   0                   \ -            0                   0                   \ -            0                   128                 \ -            6                   0                   \ -            0                   \0\0\0\0\0\0\0\0\0\0\0\0\ -            \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -            \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -            \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -        let archive = ArchiveFile::parse(&data[..]).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::AixBig); -    } - -    #[test] -    fn gnu_names() { -        let data = b"\ -            !<arch>\n\ -            //                                              18        `\n\ -            0123456789abcdef/\n\ -            s p a c e/      0           0     0     644     4         `\n\ -            0000\ -            0123456789abcde/0           0     0     644     3         `\n\ -            odd\n\ -            /0              0           0     0     644     4         `\n\ -            even"; -        let data = &data[..]; -        let archive = ArchiveFile::parse(data).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Gnu); -        let mut members = archive.members(); - -        let member = members.next().unwrap().unwrap(); -        assert_eq!(member.name(), b"s p a c e"); -        assert_eq!(member.data(data).unwrap(), &b"0000"[..]); - -        let member = members.next().unwrap().unwrap(); -        assert_eq!(member.name(), b"0123456789abcde"); -        assert_eq!(member.data(data).unwrap(), &b"odd"[..]); - -        let member = members.next().unwrap().unwrap(); -        assert_eq!(member.name(), b"0123456789abcdef"); -        assert_eq!(member.data(data).unwrap(), &b"even"[..]); - -        assert!(members.next().is_none()); -    } - -    #[test] -    fn bsd_names() { -        let data = b"\ -            !<arch>\n\ -            0123456789abcde 0           0     0     644     3         `\n\ -            odd\n\ -            #1/16           0           0     0     644     20        `\n\ -            0123456789abcdefeven"; -        let data = &data[..]; -        let archive = ArchiveFile::parse(data).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::Unknown); -        let mut members = archive.members(); - -        let member = members.next().unwrap().unwrap(); -        assert_eq!(member.name(), b"0123456789abcde"); -        assert_eq!(member.data(data).unwrap(), &b"odd"[..]); - -        let member = members.next().unwrap().unwrap(); -        assert_eq!(member.name(), b"0123456789abcdef"); -        assert_eq!(member.data(data).unwrap(), &b"even"[..]); - -        assert!(members.next().is_none()); -    } - -    #[test] -    fn aix_names() { -        let data = b"\ -            <bigaf>\n\ -            396                 0                   0                   \ -            128                 262                 0                   \ -            4                   262                 0                   \ -            1662610370  223         1           644         16  \ -            0123456789abcdef`\nord\n\ -            4                   396                 128                 \ -            1662610374  223         1           644         16  \ -            fedcba9876543210`\nrev\n\ -            94                  0                   262                 \ -            0           0           0           0           0   \ -            `\n2                   128                 \ -            262                 0123456789abcdef\0fedcba9876543210\0"; -        let data = &data[..]; -        let archive = ArchiveFile::parse(data).unwrap(); -        assert_eq!(archive.kind(), ArchiveKind::AixBig); -        let mut members = archive.members(); - -        let member = members.next().unwrap().unwrap(); -        assert_eq!(member.name(), b"0123456789abcdef"); -        assert_eq!(member.data(data).unwrap(), &b"ord\n"[..]); - -        let member = members.next().unwrap().unwrap(); -        assert_eq!(member.name(), b"fedcba9876543210"); -        assert_eq!(member.data(data).unwrap(), &b"rev\n"[..]); - -        assert!(members.next().is_none()); -    } -} diff --git a/vendor/object/src/read/coff/comdat.rs b/vendor/object/src/read/coff/comdat.rs deleted file mode 100644 index 90c29be..0000000 --- a/vendor/object/src/read/coff/comdat.rs +++ /dev/null @@ -1,211 +0,0 @@ -use core::str; - -use crate::endian::LittleEndian as LE; -use crate::pe; -use crate::read::{ -    self, ComdatKind, ObjectComdat, ReadError, ReadRef, Result, SectionIndex, SymbolIndex, -}; - -use super::{CoffFile, CoffHeader, ImageSymbol}; - -/// An iterator for the COMDAT section groups in a [`CoffBigFile`](super::CoffBigFile). -pub type CoffBigComdatIterator<'data, 'file, R = &'data [u8]> = -    CoffComdatIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// An iterator for the COMDAT section groups in a [`CoffFile`]. -#[derive(Debug)] -pub struct CoffComdatIterator< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    pub(super) file: &'file CoffFile<'data, R, Coff>, -    pub(super) index: usize, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator -    for CoffComdatIterator<'data, 'file, R, Coff> -{ -    type Item = CoffComdat<'data, 'file, R, Coff>; - -    fn next(&mut self) -> Option<Self::Item> { -        loop { -            let index = self.index; -            let symbol = self.file.common.symbols.symbol(index).ok()?; -            self.index += 1 + symbol.number_of_aux_symbols() as usize; -            if let Some(comdat) = CoffComdat::parse(self.file, symbol, index) { -                return Some(comdat); -            } -        } -    } -} - -/// A COMDAT section group in a [`CoffBigFile`](super::CoffBigFile). -/// -/// Most functionality is provided by the [`ObjectComdat`] trait implementation. -pub type CoffBigComdat<'data, 'file, R = &'data [u8]> = -    CoffComdat<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// A COMDAT section group in a [`CoffFile`]. -/// -/// Most functionality is provided by the [`ObjectComdat`] trait implementation. -#[derive(Debug)] -pub struct CoffComdat< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    file: &'file CoffFile<'data, R, Coff>, -    symbol_index: SymbolIndex, -    symbol: &'data Coff::ImageSymbol, -    selection: u8, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffComdat<'data, 'file, R, Coff> { -    fn parse( -        file: &'file CoffFile<'data, R, Coff>, -        section_symbol: &'data Coff::ImageSymbol, -        index: usize, -    ) -> Option<CoffComdat<'data, 'file, R, Coff>> { -        // Must be a section symbol. -        if !section_symbol.has_aux_section() { -            return None; -        } - -        // Auxiliary record must have a non-associative selection. -        let aux = file.common.symbols.aux_section(index).ok()?; -        let selection = aux.selection; -        if selection == 0 || selection == pe::IMAGE_COMDAT_SELECT_ASSOCIATIVE { -            return None; -        } - -        // Find the COMDAT symbol. -        let mut symbol_index = index; -        let mut symbol = section_symbol; -        let section_number = section_symbol.section_number(); -        loop { -            symbol_index += 1 + symbol.number_of_aux_symbols() as usize; -            symbol = file.common.symbols.symbol(symbol_index).ok()?; -            if section_number == symbol.section_number() { -                break; -            } -        } - -        Some(CoffComdat { -            file, -            symbol_index: SymbolIndex(symbol_index), -            symbol, -            selection, -        }) -    } -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed -    for CoffComdat<'data, 'file, R, Coff> -{ -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectComdat<'data> -    for CoffComdat<'data, 'file, R, Coff> -{ -    type SectionIterator = CoffComdatSectionIterator<'data, 'file, R, Coff>; - -    #[inline] -    fn kind(&self) -> ComdatKind { -        match self.selection { -            pe::IMAGE_COMDAT_SELECT_NODUPLICATES => ComdatKind::NoDuplicates, -            pe::IMAGE_COMDAT_SELECT_ANY => ComdatKind::Any, -            pe::IMAGE_COMDAT_SELECT_SAME_SIZE => ComdatKind::SameSize, -            pe::IMAGE_COMDAT_SELECT_EXACT_MATCH => ComdatKind::ExactMatch, -            pe::IMAGE_COMDAT_SELECT_LARGEST => ComdatKind::Largest, -            pe::IMAGE_COMDAT_SELECT_NEWEST => ComdatKind::Newest, -            _ => ComdatKind::Unknown, -        } -    } - -    #[inline] -    fn symbol(&self) -> SymbolIndex { -        self.symbol_index -    } - -    #[inline] -    fn name_bytes(&self) -> Result<&[u8]> { -        // Find the name of first symbol referring to the section. -        self.symbol.name(self.file.common.symbols.strings()) -    } - -    #[inline] -    fn name(&self) -> Result<&str> { -        let bytes = self.name_bytes()?; -        str::from_utf8(bytes) -            .ok() -            .read_error("Non UTF-8 COFF COMDAT name") -    } - -    #[inline] -    fn sections(&self) -> Self::SectionIterator { -        CoffComdatSectionIterator { -            file: self.file, -            section_number: self.symbol.section_number(), -            index: 0, -        } -    } -} - -/// An iterator for the sections in a COMDAT section group in a [`CoffBigFile`](super::CoffBigFile). -pub type CoffBigComdatSectionIterator<'data, 'file, R = &'data [u8]> = -    CoffComdatSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// An iterator for the sections in a COMDAT section group in a [`CoffFile`]. -#[derive(Debug)] -pub struct CoffComdatSectionIterator< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    file: &'file CoffFile<'data, R, Coff>, -    section_number: i32, -    index: usize, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator -    for CoffComdatSectionIterator<'data, 'file, R, Coff> -{ -    type Item = SectionIndex; - -    fn next(&mut self) -> Option<Self::Item> { -        // Find associated COMDAT symbols. -        // TODO: it seems gcc doesn't use associated symbols for this -        loop { -            let index = self.index; -            let symbol = self.file.common.symbols.symbol(index).ok()?; -            self.index += 1 + symbol.number_of_aux_symbols() as usize; - -            // Must be a section symbol. -            if !symbol.has_aux_section() { -                continue; -            } - -            let section_number = symbol.section_number(); - -            let aux = self.file.common.symbols.aux_section(index).ok()?; -            if aux.selection == pe::IMAGE_COMDAT_SELECT_ASSOCIATIVE { -                let number = if Coff::is_type_bigobj() { -                    u32::from(aux.number.get(LE)) | (u32::from(aux.high_number.get(LE)) << 16) -                } else { -                    u32::from(aux.number.get(LE)) -                }; -                if number as i32 == self.section_number { -                    return Some(SectionIndex(section_number as usize)); -                } -            } else if aux.selection != 0 { -                if section_number == self.section_number { -                    return Some(SectionIndex(section_number as usize)); -                } -            } -        } -    } -} 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) -    } -} diff --git a/vendor/object/src/read/coff/import.rs b/vendor/object/src/read/coff/import.rs deleted file mode 100644 index a296ac3..0000000 --- a/vendor/object/src/read/coff/import.rs +++ /dev/null @@ -1,220 +0,0 @@ -//! Support for reading short import files. -//! -//! These are used by some Windows linkers as a more compact way to describe -//! dynamically imported symbols. - -use crate::read::{Architecture, Error, ReadError, ReadRef, Result}; -use crate::{pe, ByteString, Bytes, LittleEndian as LE, SubArchitecture}; - -/// A Windows short form description of a symbol to import. -/// -/// Used in Windows import libraries to provide a mapping from -/// a symbol name to a DLL export. This is not an object file. -/// -/// This is a file that starts with [`pe::ImportObjectHeader`], and corresponds -/// to [`crate::FileKind::CoffImport`]. -#[derive(Debug, Clone)] -pub struct ImportFile<'data> { -    header: &'data pe::ImportObjectHeader, -    kind: ImportType, -    dll: ByteString<'data>, -    symbol: ByteString<'data>, -    import: Option<ByteString<'data>>, -} - -impl<'data> ImportFile<'data> { -    /// Parse it. -    pub fn parse<R: ReadRef<'data>>(data: R) -> Result<Self> { -        let mut offset = 0; -        let header = pe::ImportObjectHeader::parse(data, &mut offset)?; -        let data = header.parse_data(data, &mut offset)?; - -        // Unmangles a name by removing a `?`, `@` or `_` prefix. -        fn strip_prefix(s: &[u8]) -> &[u8] { -            match s.split_first() { -                Some((b, rest)) if [b'?', b'@', b'_'].contains(b) => rest, -                _ => s, -            } -        } -        Ok(Self { -            header, -            dll: data.dll, -            symbol: data.symbol, -            kind: match header.import_type() { -                pe::IMPORT_OBJECT_CODE => ImportType::Code, -                pe::IMPORT_OBJECT_DATA => ImportType::Data, -                pe::IMPORT_OBJECT_CONST => ImportType::Const, -                _ => return Err(Error("Invalid COFF import library import type")), -            }, -            import: match header.name_type() { -                pe::IMPORT_OBJECT_ORDINAL => None, -                pe::IMPORT_OBJECT_NAME => Some(data.symbol()), -                pe::IMPORT_OBJECT_NAME_NO_PREFIX => Some(strip_prefix(data.symbol())), -                pe::IMPORT_OBJECT_NAME_UNDECORATE => Some( -                    strip_prefix(data.symbol()) -                        .split(|&b| b == b'@') -                        .next() -                        .unwrap(), -                ), -                pe::IMPORT_OBJECT_NAME_EXPORTAS => data.export(), -                _ => return Err(Error("Unknown COFF import library name type")), -            } -            .map(ByteString), -        }) -    } - -    /// Get the machine type. -    pub fn architecture(&self) -> Architecture { -        match self.header.machine.get(LE) { -            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, -        } -    } - -    /// Get the sub machine type, if available. -    pub fn sub_architecture(&self) -> Option<SubArchitecture> { -        match self.header.machine.get(LE) { -            pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC), -            _ => None, -        } -    } - -    /// The public symbol name. -    pub fn symbol(&self) -> &'data [u8] { -        self.symbol.0 -    } - -    /// The name of the DLL to import the symbol from. -    pub fn dll(&self) -> &'data [u8] { -        self.dll.0 -    } - -    /// The name exported from the DLL. -    pub fn import(&self) -> ImportName<'data> { -        match self.import { -            Some(name) => ImportName::Name(name.0), -            None => ImportName::Ordinal(self.header.ordinal_or_hint.get(LE)), -        } -    } - -    /// The type of import. Usually either a function or data. -    pub fn import_type(&self) -> ImportType { -        self.kind -    } -} - -/// The name or ordinal to import from a DLL. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ImportName<'data> { -    /// Import by ordinal. Ordinarily this is a 1-based index. -    Ordinal(u16), -    /// Import by name. -    Name(&'data [u8]), -} - -/// The kind of import symbol. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum ImportType { -    /// An executable code symbol. -    Code, -    /// A data symbol. -    Data, -    /// A constant value. -    Const, -} - -impl pe::ImportObjectHeader { -    /// Read the short import header. -    /// -    /// Also checks that the signature and version are valid. -    /// Directly following this header will be the string data. -    pub fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> Result<&'data Self> { -        let header = data -            .read::<pe::ImportObjectHeader>(offset) -            .read_error("Invalid COFF import library header size")?; -        if header.sig1.get(LE) != 0 || header.sig2.get(LE) != pe::IMPORT_OBJECT_HDR_SIG2 { -            Err(Error("Invalid COFF import library header")) -        } else if header.version.get(LE) != 0 { -            Err(Error("Unknown COFF import library header version")) -        } else { -            Ok(header) -        } -    } - -    /// Parse the data following the header. -    pub fn parse_data<'data, R: ReadRef<'data>>( -        &self, -        data: R, -        offset: &mut u64, -    ) -> Result<ImportObjectData<'data>> { -        let mut data = Bytes( -            data.read_bytes(offset, u64::from(self.size_of_data.get(LE))) -                .read_error("Invalid COFF import library data size")?, -        ); -        let symbol = data -            .read_string() -            .map(ByteString) -            .read_error("Could not read COFF import library symbol name")?; -        let dll = data -            .read_string() -            .map(ByteString) -            .read_error("Could not read COFF import library DLL name")?; -        let export = if self.name_type() == pe::IMPORT_OBJECT_NAME_EXPORTAS { -            data.read_string() -                .map(ByteString) -                .map(Some) -                .read_error("Could not read COFF import library export name")? -        } else { -            None -        }; -        Ok(ImportObjectData { -            symbol, -            dll, -            export, -        }) -    } - -    /// The type of import. -    /// -    /// This is one of the `IMPORT_OBJECT_*` constants. -    pub fn import_type(&self) -> u16 { -        self.name_type.get(LE) & pe::IMPORT_OBJECT_TYPE_MASK -    } - -    /// The type of import name. -    /// -    /// This is one of the `IMPORT_OBJECT_*` constants. -    pub fn name_type(&self) -> u16 { -        (self.name_type.get(LE) >> pe::IMPORT_OBJECT_NAME_SHIFT) & pe::IMPORT_OBJECT_NAME_MASK -    } -} - -/// The data following [`pe::ImportObjectHeader`]. -#[derive(Debug, Clone)] -pub struct ImportObjectData<'data> { -    symbol: ByteString<'data>, -    dll: ByteString<'data>, -    export: Option<ByteString<'data>>, -} - -impl<'data> ImportObjectData<'data> { -    /// The public symbol name. -    pub fn symbol(&self) -> &'data [u8] { -        self.symbol.0 -    } - -    /// The name of the DLL to import the symbol from. -    pub fn dll(&self) -> &'data [u8] { -        self.dll.0 -    } - -    /// The name exported from the DLL. -    /// -    /// This is only set if the name is not derived from the symbol name. -    pub fn export(&self) -> Option<&'data [u8]> { -        self.export.map(|export| export.0) -    } -} diff --git a/vendor/object/src/read/coff/mod.rs b/vendor/object/src/read/coff/mod.rs deleted file mode 100644 index de397da..0000000 --- a/vendor/object/src/read/coff/mod.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! Support for reading Windows COFF files. -//! -//! Traits are used to abstract over the difference between COFF object files -//! and COFF bigobj files. The primary trait for this is [`CoffHeader`]. -//! -//! ## High level API -//! -//! [`CoffFile`] implements the [`Object`](crate::read::Object) trait for -//! COFF files. [`CoffFile`] is parameterised by [`CoffHeader`]. -//! The default parameter allows reading regular COFF object files, -//! while the type alias [`CoffBigFile`] allows reading COFF bigobj files. -//! -//! [`ImportFile`] allows reading COFF short imports that are used in import -//! libraries. Currently these are not integrated with the unified read API. -//! -//! ## Low level API -//! -//! The [`CoffHeader`] trait can be directly used to parse both COFF -//! object files (which start with [`pe::ImageFileHeader`]) and COFF bigobj -//! files (which start with [`pe::AnonObjectHeaderBigobj`]). -//! -//! ### Example for low level API -//!  ```no_run -//! use object::pe; -//! use object::read::coff::{CoffHeader, ImageSymbol as _}; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads a file and displays the name of each section and symbol. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let mut offset = 0; -//!     let header = pe::ImageFileHeader::parse(&*data, &mut offset)?; -//!     let sections = header.sections(&*data, offset)?; -//!     let symbols = header.symbols(&*data)?; -//!     for section in sections.iter() { -//!         println!("{}", String::from_utf8_lossy(section.name(symbols.strings())?)); -//!     } -//!     for (_index, symbol) in symbols.iter() { -//!         println!("{}", String::from_utf8_lossy(symbol.name(symbols.strings())?)); -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` -#[cfg(doc)] -use crate::pe; - -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 import; -pub use import::*; diff --git a/vendor/object/src/read/coff/relocation.rs b/vendor/object/src/read/coff/relocation.rs deleted file mode 100644 index e990944..0000000 --- a/vendor/object/src/read/coff/relocation.rs +++ /dev/null @@ -1,106 +0,0 @@ -use alloc::fmt; -use core::slice; - -use crate::endian::LittleEndian as LE; -use crate::pe; -use crate::read::{ -    ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, SymbolIndex, -}; - -use super::{CoffFile, CoffHeader}; - -/// An iterator for the relocations in a [`CoffBigSection`](super::CoffBigSection). -pub type CoffBigRelocationIterator<'data, 'file, R = &'data [u8]> = -    CoffRelocationIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// An iterator for the relocations in a [`CoffSection`](super::CoffSection). -pub struct CoffRelocationIterator< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    pub(super) file: &'file CoffFile<'data, R, Coff>, -    pub(super) iter: slice::Iter<'data, pe::ImageRelocation>, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator -    for CoffRelocationIterator<'data, 'file, R, Coff> -{ -    type Item = (u64, Relocation); - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|relocation| { -            let (kind, size, addend) = match self.file.header.machine() { -                pe::IMAGE_FILE_MACHINE_ARMNT => match relocation.typ.get(LE) { -                    pe::IMAGE_REL_ARM_ADDR32 => (RelocationKind::Absolute, 32, 0), -                    pe::IMAGE_REL_ARM_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), -                    pe::IMAGE_REL_ARM_REL32 => (RelocationKind::Relative, 32, -4), -                    pe::IMAGE_REL_ARM_SECTION => (RelocationKind::SectionIndex, 16, 0), -                    pe::IMAGE_REL_ARM_SECREL => (RelocationKind::SectionOffset, 32, 0), -                    typ => (RelocationKind::Coff(typ), 0, 0), -                }, -                pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => { -                    match relocation.typ.get(LE) { -                        pe::IMAGE_REL_ARM64_ADDR32 => (RelocationKind::Absolute, 32, 0), -                        pe::IMAGE_REL_ARM64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), -                        pe::IMAGE_REL_ARM64_SECREL => (RelocationKind::SectionOffset, 32, 0), -                        pe::IMAGE_REL_ARM64_SECTION => (RelocationKind::SectionIndex, 16, 0), -                        pe::IMAGE_REL_ARM64_ADDR64 => (RelocationKind::Absolute, 64, 0), -                        pe::IMAGE_REL_ARM64_REL32 => (RelocationKind::Relative, 32, -4), -                        typ => (RelocationKind::Coff(typ), 0, 0), -                    } -                } -                pe::IMAGE_FILE_MACHINE_I386 => match relocation.typ.get(LE) { -                    pe::IMAGE_REL_I386_DIR16 => (RelocationKind::Absolute, 16, 0), -                    pe::IMAGE_REL_I386_REL16 => (RelocationKind::Relative, 16, 0), -                    pe::IMAGE_REL_I386_DIR32 => (RelocationKind::Absolute, 32, 0), -                    pe::IMAGE_REL_I386_DIR32NB => (RelocationKind::ImageOffset, 32, 0), -                    pe::IMAGE_REL_I386_SECTION => (RelocationKind::SectionIndex, 16, 0), -                    pe::IMAGE_REL_I386_SECREL => (RelocationKind::SectionOffset, 32, 0), -                    pe::IMAGE_REL_I386_SECREL7 => (RelocationKind::SectionOffset, 7, 0), -                    pe::IMAGE_REL_I386_REL32 => (RelocationKind::Relative, 32, -4), -                    typ => (RelocationKind::Coff(typ), 0, 0), -                }, -                pe::IMAGE_FILE_MACHINE_AMD64 => match relocation.typ.get(LE) { -                    pe::IMAGE_REL_AMD64_ADDR64 => (RelocationKind::Absolute, 64, 0), -                    pe::IMAGE_REL_AMD64_ADDR32 => (RelocationKind::Absolute, 32, 0), -                    pe::IMAGE_REL_AMD64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), -                    pe::IMAGE_REL_AMD64_REL32 => (RelocationKind::Relative, 32, -4), -                    pe::IMAGE_REL_AMD64_REL32_1 => (RelocationKind::Relative, 32, -5), -                    pe::IMAGE_REL_AMD64_REL32_2 => (RelocationKind::Relative, 32, -6), -                    pe::IMAGE_REL_AMD64_REL32_3 => (RelocationKind::Relative, 32, -7), -                    pe::IMAGE_REL_AMD64_REL32_4 => (RelocationKind::Relative, 32, -8), -                    pe::IMAGE_REL_AMD64_REL32_5 => (RelocationKind::Relative, 32, -9), -                    pe::IMAGE_REL_AMD64_SECTION => (RelocationKind::SectionIndex, 16, 0), -                    pe::IMAGE_REL_AMD64_SECREL => (RelocationKind::SectionOffset, 32, 0), -                    pe::IMAGE_REL_AMD64_SECREL7 => (RelocationKind::SectionOffset, 7, 0), -                    typ => (RelocationKind::Coff(typ), 0, 0), -                }, -                _ => (RelocationKind::Coff(relocation.typ.get(LE)), 0, 0), -            }; -            let target = RelocationTarget::Symbol(SymbolIndex( -                relocation.symbol_table_index.get(LE) as usize, -            )); -            ( -                u64::from(relocation.virtual_address.get(LE)), -                Relocation { -                    kind, -                    encoding: RelocationEncoding::Generic, -                    size, -                    target, -                    addend, -                    implicit_addend: true, -                }, -            ) -        }) -    } -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> fmt::Debug -    for CoffRelocationIterator<'data, 'file, R, Coff> -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("CoffRelocationIterator").finish() -    } -} diff --git a/vendor/object/src/read/coff/section.rs b/vendor/object/src/read/coff/section.rs deleted file mode 100644 index 84a3fa9..0000000 --- a/vendor/object/src/read/coff/section.rs +++ /dev/null @@ -1,585 +0,0 @@ -use core::convert::TryFrom; -use core::{iter, result, slice, str}; - -use crate::endian::LittleEndian as LE; -use crate::pe; -use crate::read::util::StringTable; -use crate::read::{ -    self, CompressedData, CompressedFileRange, Error, ObjectSection, ObjectSegment, ReadError, -    ReadRef, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags, -}; - -use super::{CoffFile, CoffHeader, CoffRelocationIterator}; - -/// The table of section headers in a COFF or PE file. -/// -/// Returned by [`CoffHeader::sections`] and -/// [`ImageNtHeaders::sections`](crate::read::pe::ImageNtHeaders::sections). -#[derive(Debug, Default, Clone, Copy)] -pub struct SectionTable<'data> { -    sections: &'data [pe::ImageSectionHeader], -} - -impl<'data> SectionTable<'data> { -    /// Parse the section table. -    /// -    /// `data` must be the entire file data. -    /// `offset` must be after the optional file header. -    pub fn parse<Coff: CoffHeader, R: ReadRef<'data>>( -        header: &Coff, -        data: R, -        offset: u64, -    ) -> Result<Self> { -        let sections = data -            .read_slice_at(offset, header.number_of_sections() as usize) -            .read_error("Invalid COFF/PE section headers")?; -        Ok(SectionTable { sections }) -    } - -    /// Iterate over the section headers. -    /// -    /// Warning: sections indices start at 1. -    #[inline] -    pub fn iter(&self) -> slice::Iter<'data, pe::ImageSectionHeader> { -        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: usize) -> read::Result<&'data pe::ImageSectionHeader> { -        self.sections -            .get(index.wrapping_sub(1)) -            .read_error("Invalid COFF/PE section index") -    } - -    /// Return the section header with the given name. -    /// -    /// The returned index is 1-based. -    /// -    /// Ignores sections with invalid names. -    pub fn section_by_name<R: ReadRef<'data>>( -        &self, -        strings: StringTable<'data, R>, -        name: &[u8], -    ) -> Option<(usize, &'data pe::ImageSectionHeader)> { -        self.sections -            .iter() -            .enumerate() -            .find(|(_, section)| section.name(strings) == Ok(name)) -            .map(|(index, section)| (index + 1, section)) -    } - -    /// Compute the maximum file offset used by sections. -    /// -    /// This will usually match the end of file, unless the PE file has a -    /// [data overlay](https://security.stackexchange.com/questions/77336/how-is-the-file-overlay-read-by-an-exe-virus) -    pub fn max_section_file_offset(&self) -> u64 { -        let mut max = 0; -        for section in self.iter() { -            match (section.pointer_to_raw_data.get(LE) as u64) -                .checked_add(section.size_of_raw_data.get(LE) as u64) -            { -                None => { -                    // This cannot happen, we're suming two u32 into a u64 -                    continue; -                } -                Some(end_of_section) => { -                    if end_of_section > max { -                        max = end_of_section; -                    } -                } -            } -        } -        max -    } -} - -/// An iterator for the loadable sections in a [`CoffBigFile`](super::CoffBigFile). -pub type CoffBigSegmentIterator<'data, 'file, R = &'data [u8]> = -    CoffSegmentIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// An iterator for the loadable sections in a [`CoffFile`]. -#[derive(Debug)] -pub struct CoffSegmentIterator< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    pub(super) file: &'file CoffFile<'data, R, Coff>, -    pub(super) iter: slice::Iter<'data, pe::ImageSectionHeader>, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator -    for CoffSegmentIterator<'data, 'file, R, Coff> -{ -    type Item = CoffSegment<'data, 'file, R, Coff>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|section| CoffSegment { -            file: self.file, -            section, -        }) -    } -} - -/// A loadable section in a [`CoffBigFile`](super::CoffBigFile). -/// -/// Most functionality is provided by the [`ObjectSegment`] trait implementation. -pub type CoffBigSegment<'data, 'file, R = &'data [u8]> = -    CoffSegment<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// A loadable section in a [`CoffFile`]. -/// -/// Most functionality is provided by the [`ObjectSegment`] trait implementation. -#[derive(Debug)] -pub struct CoffSegment< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    pub(super) file: &'file CoffFile<'data, R, Coff>, -    pub(super) section: &'data pe::ImageSectionHeader, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSegment<'data, 'file, R, Coff> { -    fn bytes(&self) -> Result<&'data [u8]> { -        self.section -            .coff_data(self.file.data) -            .read_error("Invalid COFF section offset or size") -    } -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed -    for CoffSegment<'data, 'file, R, Coff> -{ -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSegment<'data> -    for CoffSegment<'data, 'file, R, Coff> -{ -    #[inline] -    fn address(&self) -> u64 { -        u64::from(self.section.virtual_address.get(LE)) -    } - -    #[inline] -    fn size(&self) -> u64 { -        u64::from(self.section.virtual_size.get(LE)) -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.section.coff_alignment() -    } - -    #[inline] -    fn file_range(&self) -> (u64, u64) { -        let (offset, size) = self.section.coff_file_range().unwrap_or((0, 0)); -        (u64::from(offset), u64::from(size)) -    } - -    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, -        )) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<Option<&[u8]>> { -        self.section -            .name(self.file.common.symbols.strings()) -            .map(Some) -    } - -    #[inline] -    fn name(&self) -> Result<Option<&str>> { -        let name = self.section.name(self.file.common.symbols.strings())?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 COFF section name") -            .map(Some) -    } - -    #[inline] -    fn flags(&self) -> SegmentFlags { -        let characteristics = self.section.characteristics.get(LE); -        SegmentFlags::Coff { characteristics } -    } -} - -/// An iterator for the sections in a [`CoffBigFile`](super::CoffBigFile). -pub type CoffBigSectionIterator<'data, 'file, R = &'data [u8]> = -    CoffSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// An iterator for the sections in a [`CoffFile`]. -#[derive(Debug)] -pub struct CoffSectionIterator< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    pub(super) file: &'file CoffFile<'data, R, Coff>, -    pub(super) iter: iter::Enumerate<slice::Iter<'data, pe::ImageSectionHeader>>, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator -    for CoffSectionIterator<'data, 'file, R, Coff> -{ -    type Item = CoffSection<'data, 'file, R, Coff>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|(index, section)| CoffSection { -            file: self.file, -            index: SectionIndex(index + 1), -            section, -        }) -    } -} - -/// A section in a [`CoffBigFile`](super::CoffBigFile). -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -pub type CoffBigSection<'data, 'file, R = &'data [u8]> = -    CoffSection<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// A section in a [`CoffFile`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -#[derive(Debug)] -pub struct CoffSection< -    'data, -    'file, -    R: ReadRef<'data> = &'data [u8], -    Coff: CoffHeader = pe::ImageFileHeader, -> { -    pub(super) file: &'file CoffFile<'data, R, Coff>, -    pub(super) index: SectionIndex, -    pub(super) section: &'data pe::ImageSectionHeader, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSection<'data, 'file, R, Coff> { -    fn bytes(&self) -> Result<&'data [u8]> { -        self.section -            .coff_data(self.file.data) -            .read_error("Invalid COFF section offset or size") -    } -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed -    for CoffSection<'data, 'file, R, Coff> -{ -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSection<'data> -    for CoffSection<'data, 'file, R, Coff> -{ -    type RelocationIterator = CoffRelocationIterator<'data, 'file, R, Coff>; - -    #[inline] -    fn index(&self) -> SectionIndex { -        self.index -    } - -    #[inline] -    fn address(&self) -> u64 { -        u64::from(self.section.virtual_address.get(LE)) -    } - -    #[inline] -    fn size(&self) -> u64 { -        // TODO: This may need to be the length from the auxiliary symbol for this section. -        u64::from(self.section.size_of_raw_data.get(LE)) -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.section.coff_alignment() -    } - -    #[inline] -    fn file_range(&self) -> Option<(u64, u64)> { -        let (offset, size) = self.section.coff_file_range()?; -        Some((u64::from(offset), u64::from(size))) -    } - -    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, -        )) -    } - -    #[inline] -    fn compressed_file_range(&self) -> Result<CompressedFileRange> { -        Ok(CompressedFileRange::none(self.file_range())) -    } - -    #[inline] -    fn compressed_data(&self) -> Result<CompressedData<'data>> { -        self.data().map(CompressedData::none) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<&[u8]> { -        self.section.name(self.file.common.symbols.strings()) -    } - -    #[inline] -    fn name(&self) -> Result<&str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 COFF section name") -    } - -    #[inline] -    fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { -        Ok(None) -    } - -    #[inline] -    fn segment_name(&self) -> Result<Option<&str>> { -        Ok(None) -    } - -    #[inline] -    fn kind(&self) -> SectionKind { -        self.section.kind() -    } - -    fn relocations(&self) -> CoffRelocationIterator<'data, 'file, R, Coff> { -        let relocations = self.section.coff_relocations(self.file.data).unwrap_or(&[]); -        CoffRelocationIterator { -            file: self.file, -            iter: relocations.iter(), -        } -    } - -    fn flags(&self) -> SectionFlags { -        SectionFlags::Coff { -            characteristics: self.section.characteristics.get(LE), -        } -    } -} - -impl pe::ImageSectionHeader { -    pub(crate) fn kind(&self) -> SectionKind { -        let characteristics = self.characteristics.get(LE); -        if characteristics & (pe::IMAGE_SCN_CNT_CODE | pe::IMAGE_SCN_MEM_EXECUTE) != 0 { -            SectionKind::Text -        } else if characteristics & pe::IMAGE_SCN_CNT_INITIALIZED_DATA != 0 { -            if characteristics & pe::IMAGE_SCN_MEM_DISCARDABLE != 0 { -                SectionKind::Other -            } else if characteristics & pe::IMAGE_SCN_MEM_WRITE != 0 { -                SectionKind::Data -            } else { -                SectionKind::ReadOnlyData -            } -        } else if characteristics & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 { -            SectionKind::UninitializedData -        } else if characteristics & pe::IMAGE_SCN_LNK_INFO != 0 { -            SectionKind::Linker -        } else { -            SectionKind::Unknown -        } -    } -} - -impl pe::ImageSectionHeader { -    /// Return the string table offset of the section name. -    /// -    /// Returns `Ok(None)` if the name doesn't use the string table -    /// and can be obtained with `raw_name` instead. -    pub fn name_offset(&self) -> Result<Option<u32>> { -        let bytes = &self.name; -        if bytes[0] != b'/' { -            return Ok(None); -        } - -        if bytes[1] == b'/' { -            let mut offset = 0; -            for byte in bytes[2..].iter() { -                let digit = match byte { -                    b'A'..=b'Z' => byte - b'A', -                    b'a'..=b'z' => byte - b'a' + 26, -                    b'0'..=b'9' => byte - b'0' + 52, -                    b'+' => 62, -                    b'/' => 63, -                    _ => return Err(Error("Invalid COFF section name base-64 offset")), -                }; -                offset = offset * 64 + digit as u64; -            } -            u32::try_from(offset) -                .ok() -                .read_error("Invalid COFF section name base-64 offset") -                .map(Some) -        } else { -            let mut offset = 0; -            for byte in bytes[1..].iter() { -                let digit = match byte { -                    b'0'..=b'9' => byte - b'0', -                    0 => break, -                    _ => return Err(Error("Invalid COFF section name base-10 offset")), -                }; -                offset = offset * 10 + digit as u32; -            } -            Ok(Some(offset)) -        } -    } - -    /// Return the section name. -    /// -    /// This handles decoding names that are offsets into the symbol string table. -    pub fn name<'data, R: ReadRef<'data>>( -        &'data self, -        strings: StringTable<'data, R>, -    ) -> Result<&'data [u8]> { -        if let Some(offset) = self.name_offset()? { -            strings -                .get(offset) -                .read_error("Invalid COFF section name offset") -        } else { -            Ok(self.raw_name()) -        } -    } - -    /// Return the raw section name. -    pub fn raw_name(&self) -> &[u8] { -        let bytes = &self.name; -        match memchr::memchr(b'\0', bytes) { -            Some(end) => &bytes[..end], -            None => &bytes[..], -        } -    } - -    /// Return the offset and size of the section in a COFF file. -    /// -    /// Returns `None` for sections that have no data in the file. -    pub fn coff_file_range(&self) -> Option<(u32, u32)> { -        if self.characteristics.get(LE) & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 { -            None -        } else { -            let offset = self.pointer_to_raw_data.get(LE); -            // Note: virtual size is not used for COFF. -            let size = self.size_of_raw_data.get(LE); -            Some((offset, size)) -        } -    } - -    /// Return the section data in a COFF file. -    /// -    /// Returns `Ok(&[])` if the section has no data. -    /// Returns `Err` for invalid values. -    pub fn coff_data<'data, R: ReadRef<'data>>(&self, data: R) -> result::Result<&'data [u8], ()> { -        if let Some((offset, size)) = self.coff_file_range() { -            data.read_bytes_at(offset.into(), size.into()) -        } else { -            Ok(&[]) -        } -    } - -    /// Return the section alignment in bytes. -    /// -    /// This is only valid for sections in a COFF file. -    pub fn coff_alignment(&self) -> u64 { -        match self.characteristics.get(LE) & pe::IMAGE_SCN_ALIGN_MASK { -            pe::IMAGE_SCN_ALIGN_1BYTES => 1, -            pe::IMAGE_SCN_ALIGN_2BYTES => 2, -            pe::IMAGE_SCN_ALIGN_4BYTES => 4, -            pe::IMAGE_SCN_ALIGN_8BYTES => 8, -            pe::IMAGE_SCN_ALIGN_16BYTES => 16, -            pe::IMAGE_SCN_ALIGN_32BYTES => 32, -            pe::IMAGE_SCN_ALIGN_64BYTES => 64, -            pe::IMAGE_SCN_ALIGN_128BYTES => 128, -            pe::IMAGE_SCN_ALIGN_256BYTES => 256, -            pe::IMAGE_SCN_ALIGN_512BYTES => 512, -            pe::IMAGE_SCN_ALIGN_1024BYTES => 1024, -            pe::IMAGE_SCN_ALIGN_2048BYTES => 2048, -            pe::IMAGE_SCN_ALIGN_4096BYTES => 4096, -            pe::IMAGE_SCN_ALIGN_8192BYTES => 8192, -            _ => 16, -        } -    } - -    /// Read the relocations in a COFF file. -    /// -    /// `data` must be the entire file data. -    pub fn coff_relocations<'data, R: ReadRef<'data>>( -        &self, -        data: R, -    ) -> read::Result<&'data [pe::ImageRelocation]> { -        let mut pointer = self.pointer_to_relocations.get(LE).into(); -        let mut number: usize = self.number_of_relocations.get(LE).into(); -        if number == core::u16::MAX.into() -            && self.characteristics.get(LE) & pe::IMAGE_SCN_LNK_NRELOC_OVFL != 0 -        { -            // Extended relocations. Read first relocation (which contains extended count) & adjust -            // relocations pointer. -            let extended_relocation_info = data -                .read_at::<pe::ImageRelocation>(pointer) -                .read_error("Invalid COFF relocation offset or number")?; -            number = extended_relocation_info.virtual_address.get(LE) as usize; -            if number == 0 { -                return Err(Error("Invalid COFF relocation number")); -            } -            pointer += core::mem::size_of::<pe::ImageRelocation>() as u64; -            // Extended relocation info does not contribute to the count of sections. -            number -= 1; -        } -        data.read_slice_at(pointer, number) -            .read_error("Invalid COFF relocation offset or number") -    } -} - -#[cfg(test)] -mod tests { -    use super::*; - -    #[test] -    fn name_offset() { -        let mut section = pe::ImageSectionHeader::default(); -        section.name = *b"xxxxxxxx"; -        assert_eq!(section.name_offset(), Ok(None)); -        section.name = *b"/0\0\0\0\0\0\0"; -        assert_eq!(section.name_offset(), Ok(Some(0))); -        section.name = *b"/9999999"; -        assert_eq!(section.name_offset(), Ok(Some(999_9999))); -        section.name = *b"//AAAAAA"; -        assert_eq!(section.name_offset(), Ok(Some(0))); -        section.name = *b"//D/////"; -        assert_eq!(section.name_offset(), Ok(Some(0xffff_ffff))); -        section.name = *b"//EAAAAA"; -        assert!(section.name_offset().is_err()); -        section.name = *b"////////"; -        assert!(section.name_offset().is_err()); -    } -} diff --git a/vendor/object/src/read/coff/symbol.rs b/vendor/object/src/read/coff/symbol.rs deleted file mode 100644 index 4f8a0c6..0000000 --- a/vendor/object/src/read/coff/symbol.rs +++ /dev/null @@ -1,635 +0,0 @@ -use alloc::fmt; -use alloc::vec::Vec; -use core::convert::TryInto; -use core::fmt::Debug; -use core::str; - -use super::{CoffCommon, CoffHeader, SectionTable}; -use crate::endian::{LittleEndian as LE, U32Bytes}; -use crate::pe; -use crate::pod::{bytes_of, bytes_of_slice, Pod}; -use crate::read::util::StringTable; -use crate::read::{ -    self, Bytes, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex, -    SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry, SymbolScope, SymbolSection, -}; - -/// A table of symbol entries in a COFF or PE file. -/// -/// Also includes the string table used for the symbol names. -/// -/// Returned by [`CoffHeader::symbols`] and -/// [`ImageNtHeaders::symbols`](crate::read::pe::ImageNtHeaders::symbols). -#[derive(Debug)] -pub struct SymbolTable<'data, R = &'data [u8], Coff = pe::ImageFileHeader> -where -    R: ReadRef<'data>, -    Coff: CoffHeader, -{ -    symbols: &'data [Coff::ImageSymbolBytes], -    strings: StringTable<'data, R>, -} - -impl<'data, R: ReadRef<'data>, Coff: CoffHeader> Default for SymbolTable<'data, R, Coff> { -    fn default() -> Self { -        Self { -            symbols: &[], -            strings: StringTable::default(), -        } -    } -} - -impl<'data, R: ReadRef<'data>, Coff: CoffHeader> SymbolTable<'data, R, Coff> { -    /// Read the symbol table. -    pub fn parse(header: &Coff, data: R) -> Result<Self> { -        // The symbol table may not be present. -        let mut offset = header.pointer_to_symbol_table().into(); -        let (symbols, strings) = if offset != 0 { -            let symbols = data -                .read_slice(&mut offset, header.number_of_symbols() as usize) -                .read_error("Invalid COFF symbol table offset or size")?; - -            // Note: don't update data when reading length; the length includes itself. -            let length = data -                .read_at::<U32Bytes<_>>(offset) -                .read_error("Missing COFF string table")? -                .get(LE); -            let str_end = offset -                .checked_add(length as u64) -                .read_error("Invalid COFF string table length")?; -            let strings = StringTable::new(data, offset, str_end); - -            (symbols, strings) -        } else { -            (&[][..], StringTable::default()) -        }; - -        Ok(SymbolTable { symbols, strings }) -    } - -    /// Return the string table used for the symbol names. -    #[inline] -    pub fn strings(&self) -> StringTable<'data, R> { -        self.strings -    } - -    /// 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() -    } - -    /// Iterate over the symbols. -    #[inline] -    pub fn iter<'table>(&'table self) -> SymbolIterator<'data, 'table, R, Coff> { -        SymbolIterator { -            symbols: self, -            index: 0, -        } -    } - -    /// Return the symbol table entry at the given index. -    #[inline] -    pub fn symbol(&self, index: usize) -> Result<&'data Coff::ImageSymbol> { -        self.get::<Coff::ImageSymbol>(index, 0) -    } - -    /// Return the auxiliary function symbol for the symbol table entry at the given index. -    /// -    /// Note that the index is of the symbol, not the first auxiliary record. -    #[inline] -    pub fn aux_function(&self, index: usize) -> Result<&'data pe::ImageAuxSymbolFunction> { -        self.get::<pe::ImageAuxSymbolFunction>(index, 1) -    } - -    /// Return the auxiliary section symbol for the symbol table entry at the given index. -    /// -    /// Note that the index is of the symbol, not the first auxiliary record. -    #[inline] -    pub fn aux_section(&self, index: usize) -> Result<&'data pe::ImageAuxSymbolSection> { -        self.get::<pe::ImageAuxSymbolSection>(index, 1) -    } - -    /// Return the auxiliary file name for the symbol table entry at the given index. -    /// -    /// Note that the index is of the symbol, not the first auxiliary record. -    pub fn aux_file_name(&self, index: usize, aux_count: u8) -> Result<&'data [u8]> { -        let entries = index -            .checked_add(1) -            .and_then(|x| Some(x..x.checked_add(aux_count.into())?)) -            .and_then(|x| self.symbols.get(x)) -            .read_error("Invalid COFF symbol index")?; -        let bytes = bytes_of_slice(entries); -        // The name is padded with nulls. -        Ok(match memchr::memchr(b'\0', bytes) { -            Some(end) => &bytes[..end], -            None => bytes, -        }) -    } - -    /// Return the symbol table entry or auxiliary record at the given index and offset. -    pub fn get<T: Pod>(&self, index: usize, offset: usize) -> Result<&'data T> { -        let bytes = index -            .checked_add(offset) -            .and_then(|x| self.symbols.get(x)) -            .read_error("Invalid COFF symbol index")?; -        Bytes(bytes_of(bytes)) -            .read() -            .read_error("Invalid COFF symbol data") -    } - -    /// Construct a map from addresses to a user-defined map entry. -    pub fn map<Entry: SymbolMapEntry, F: Fn(&'data Coff::ImageSymbol) -> Option<Entry>>( -        &self, -        f: F, -    ) -> SymbolMap<Entry> { -        let mut symbols = Vec::with_capacity(self.symbols.len()); -        for (_, symbol) in self.iter() { -            if !symbol.is_definition() { -                continue; -            } -            if let Some(entry) = f(symbol) { -                symbols.push(entry); -            } -        } -        SymbolMap::new(symbols) -    } -} - -/// An iterator for symbol entries in a COFF or PE file. -/// -/// Yields the index and symbol structure for each symbol. -#[derive(Debug)] -pub struct SymbolIterator<'data, 'table, R = &'data [u8], Coff = pe::ImageFileHeader> -where -    R: ReadRef<'data>, -    Coff: CoffHeader, -{ -    symbols: &'table SymbolTable<'data, R, Coff>, -    index: usize, -} - -impl<'data, 'table, R: ReadRef<'data>, Coff: CoffHeader> Iterator -    for SymbolIterator<'data, 'table, R, Coff> -{ -    type Item = (usize, &'data Coff::ImageSymbol); - -    fn next(&mut self) -> Option<Self::Item> { -        let index = self.index; -        let symbol = self.symbols.symbol(index).ok()?; -        self.index += 1 + symbol.number_of_aux_symbols() as usize; -        Some((index, symbol)) -    } -} - -/// A symbol table in a [`CoffBigFile`](super::CoffBigFile). -pub type CoffBigSymbolTable<'data, 'file, R = &'data [u8]> = -    CoffSymbolTable<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// A symbol table in a [`CoffFile`](super::CoffFile) -/// or [`PeFile`](crate::read::pe::PeFile). -#[derive(Debug, Clone, Copy)] -pub struct CoffSymbolTable<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> -where -    R: ReadRef<'data>, -    Coff: CoffHeader, -{ -    pub(crate) file: &'file CoffCommon<'data, R, Coff>, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed -    for CoffSymbolTable<'data, 'file, R, Coff> -{ -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbolTable<'data> -    for CoffSymbolTable<'data, 'file, R, Coff> -{ -    type Symbol = CoffSymbol<'data, 'file, R, Coff>; -    type SymbolIterator = CoffSymbolIterator<'data, 'file, R, Coff>; - -    fn symbols(&self) -> Self::SymbolIterator { -        CoffSymbolIterator { -            file: self.file, -            index: 0, -        } -    } - -    fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> { -        let symbol = self.file.symbols.symbol(index.0)?; -        Ok(CoffSymbol { -            file: self.file, -            index, -            symbol, -        }) -    } -} - -/// An iterator for the symbols in a [`CoffBigFile`](super::CoffBigFile). -pub type CoffBigSymbolIterator<'data, 'file, R = &'data [u8]> = -    CoffSymbolIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// An iterator for the symbols in a [`CoffFile`](super::CoffFile) -/// or [`PeFile`](crate::read::pe::PeFile). -pub struct CoffSymbolIterator<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> -where -    R: ReadRef<'data>, -    Coff: CoffHeader, -{ -    pub(crate) file: &'file CoffCommon<'data, R, Coff>, -    pub(crate) index: usize, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> fmt::Debug -    for CoffSymbolIterator<'data, 'file, R, Coff> -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("CoffSymbolIterator").finish() -    } -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator -    for CoffSymbolIterator<'data, 'file, R, Coff> -{ -    type Item = CoffSymbol<'data, 'file, R, Coff>; - -    fn next(&mut self) -> Option<Self::Item> { -        let index = self.index; -        let symbol = self.file.symbols.symbol(index).ok()?; -        self.index += 1 + symbol.number_of_aux_symbols() as usize; -        Some(CoffSymbol { -            file: self.file, -            index: SymbolIndex(index), -            symbol, -        }) -    } -} - -/// A symbol in a [`CoffBigFile`](super::CoffBigFile). -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -pub type CoffBigSymbol<'data, 'file, R = &'data [u8]> = -    CoffSymbol<'data, 'file, R, pe::AnonObjectHeaderBigobj>; - -/// A symbol in a [`CoffFile`](super::CoffFile) or [`PeFile`](crate::read::pe::PeFile). -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -#[derive(Debug, Clone, Copy)] -pub struct CoffSymbol<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> -where -    R: ReadRef<'data>, -    Coff: CoffHeader, -{ -    pub(crate) file: &'file CoffCommon<'data, R, Coff>, -    pub(crate) index: SymbolIndex, -    pub(crate) symbol: &'data Coff::ImageSymbol, -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSymbol<'data, 'file, R, Coff> { -    #[inline] -    /// Get the raw `ImageSymbol` struct. -    pub fn raw_symbol(&self) -> &'data Coff::ImageSymbol { -        self.symbol -    } -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed -    for CoffSymbol<'data, 'file, R, Coff> -{ -} - -impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbol<'data> -    for CoffSymbol<'data, 'file, R, Coff> -{ -    #[inline] -    fn index(&self) -> SymbolIndex { -        self.index -    } - -    fn name_bytes(&self) -> read::Result<&'data [u8]> { -        if self.symbol.has_aux_file_name() { -            self.file -                .symbols -                .aux_file_name(self.index.0, self.symbol.number_of_aux_symbols()) -        } else { -            self.symbol.name(self.file.symbols.strings()) -        } -    } - -    fn name(&self) -> read::Result<&'data str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 COFF symbol name") -    } - -    fn address(&self) -> u64 { -        // Only return an address for storage classes that we know use an address. -        match self.symbol.storage_class() { -            pe::IMAGE_SYM_CLASS_STATIC -            | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL -            | pe::IMAGE_SYM_CLASS_LABEL => {} -            pe::IMAGE_SYM_CLASS_EXTERNAL => { -                if self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED { -                    // Undefined or common data, neither of which have an address. -                    return 0; -                } -            } -            _ => return 0, -        } -        self.symbol -            .address(self.file.image_base, &self.file.sections) -            .unwrap_or(0) -    } - -    fn size(&self) -> u64 { -        match self.symbol.storage_class() { -            pe::IMAGE_SYM_CLASS_STATIC => { -                // Section symbols may duplicate the size from the section table. -                if self.symbol.has_aux_section() { -                    if let Ok(aux) = self.file.symbols.aux_section(self.index.0) { -                        u64::from(aux.length.get(LE)) -                    } else { -                        0 -                    } -                } else { -                    0 -                } -            } -            pe::IMAGE_SYM_CLASS_EXTERNAL => { -                if self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED { -                    // For undefined symbols, symbol.value is 0 and the size is 0. -                    // For common data, symbol.value is the size. -                    u64::from(self.symbol.value()) -                } else if self.symbol.has_aux_function() { -                    // Function symbols may have a size. -                    if let Ok(aux) = self.file.symbols.aux_function(self.index.0) { -                        u64::from(aux.total_size.get(LE)) -                    } else { -                        0 -                    } -                } else { -                    0 -                } -            } -            // Most symbols don't have sizes. -            _ => 0, -        } -    } - -    fn kind(&self) -> SymbolKind { -        let derived_kind = if self.symbol.derived_type() == pe::IMAGE_SYM_DTYPE_FUNCTION { -            SymbolKind::Text -        } else { -            SymbolKind::Data -        }; -        match self.symbol.storage_class() { -            pe::IMAGE_SYM_CLASS_STATIC => { -                if self.symbol.has_aux_section() { -                    SymbolKind::Section -                } else { -                    derived_kind -                } -            } -            pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => derived_kind, -            pe::IMAGE_SYM_CLASS_SECTION => SymbolKind::Section, -            pe::IMAGE_SYM_CLASS_FILE => SymbolKind::File, -            pe::IMAGE_SYM_CLASS_LABEL => SymbolKind::Label, -            _ => SymbolKind::Unknown, -        } -    } - -    fn section(&self) -> SymbolSection { -        match self.symbol.section_number() { -            pe::IMAGE_SYM_UNDEFINED => { -                if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL { -                    if self.symbol.value() == 0 { -                        SymbolSection::Undefined -                    } else { -                        SymbolSection::Common -                    } -                } else if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_SECTION { -                    SymbolSection::Undefined -                } else { -                    SymbolSection::Unknown -                } -            } -            pe::IMAGE_SYM_ABSOLUTE => SymbolSection::Absolute, -            pe::IMAGE_SYM_DEBUG => { -                if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_FILE { -                    SymbolSection::None -                } else { -                    SymbolSection::Unknown -                } -            } -            index if index > 0 => SymbolSection::Section(SectionIndex(index as usize)), -            _ => SymbolSection::Unknown, -        } -    } - -    #[inline] -    fn is_undefined(&self) -> bool { -        self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL -            && self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED -            && self.symbol.value() == 0 -    } - -    #[inline] -    fn is_definition(&self) -> bool { -        self.symbol.is_definition() -    } - -    #[inline] -    fn is_common(&self) -> bool { -        self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL -            && self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED -            && self.symbol.value() != 0 -    } - -    #[inline] -    fn is_weak(&self) -> bool { -        self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL -    } - -    #[inline] -    fn scope(&self) -> SymbolScope { -        match self.symbol.storage_class() { -            pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => { -                // TODO: determine if symbol is exported -                SymbolScope::Linkage -            } -            _ => SymbolScope::Compilation, -        } -    } - -    #[inline] -    fn is_global(&self) -> bool { -        match self.symbol.storage_class() { -            pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => true, -            _ => false, -        } -    } - -    #[inline] -    fn is_local(&self) -> bool { -        !self.is_global() -    } - -    fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> { -        if self.symbol.has_aux_section() { -            if let Ok(aux) = self.file.symbols.aux_section(self.index.0) { -                let number = if Coff::is_type_bigobj() { -                    u32::from(aux.number.get(LE)) | (u32::from(aux.high_number.get(LE)) << 16) -                } else { -                    u32::from(aux.number.get(LE)) -                }; -                return SymbolFlags::CoffSection { -                    selection: aux.selection, -                    associative_section: if number == 0 { -                        None -                    } else { -                        Some(SectionIndex(number as usize)) -                    }, -                }; -            } -        } -        SymbolFlags::None -    } -} - -/// A trait for generic access to [`pe::ImageSymbol`] and [`pe::ImageSymbolEx`]. -#[allow(missing_docs)] -pub trait ImageSymbol: Debug + Pod { -    fn raw_name(&self) -> &[u8; 8]; -    fn value(&self) -> u32; -    fn section_number(&self) -> i32; -    fn typ(&self) -> u16; -    fn storage_class(&self) -> u8; -    fn number_of_aux_symbols(&self) -> u8; - -    /// Parse a COFF symbol name. -    /// -    /// `strings` must be the string table used for symbol names. -    fn name<'data, R: ReadRef<'data>>( -        &'data self, -        strings: StringTable<'data, R>, -    ) -> Result<&'data [u8]> { -        let name = self.raw_name(); -        if name[0] == 0 { -            // If the name starts with 0 then the last 4 bytes are a string table offset. -            let offset = u32::from_le_bytes(name[4..8].try_into().unwrap()); -            strings -                .get(offset) -                .read_error("Invalid COFF symbol name offset") -        } else { -            // The name is inline and padded with nulls. -            Ok(match memchr::memchr(b'\0', name) { -                Some(end) => &name[..end], -                None => &name[..], -            }) -        } -    } - -    /// Return the symbol address. -    /// -    /// This takes into account the image base and the section address. -    fn address(&self, image_base: u64, sections: &SectionTable<'_>) -> Result<u64> { -        let section_number = self.section_number() as usize; -        let section = sections.section(section_number)?; -        let virtual_address = u64::from(section.virtual_address.get(LE)); -        let value = u64::from(self.value()); -        Ok(image_base + virtual_address + value) -    } - -    /// Return true if the symbol is a definition of a function or data object. -    fn is_definition(&self) -> bool { -        if self.section_number() <= 0 { -            return false; -        } -        match self.storage_class() { -            pe::IMAGE_SYM_CLASS_STATIC => !self.has_aux_section(), -            pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => true, -            _ => false, -        } -    } - -    /// Return true if the symbol has an auxiliary file name. -    fn has_aux_file_name(&self) -> bool { -        self.number_of_aux_symbols() > 0 && self.storage_class() == pe::IMAGE_SYM_CLASS_FILE -    } - -    /// Return true if the symbol has an auxiliary function symbol. -    fn has_aux_function(&self) -> bool { -        self.number_of_aux_symbols() > 0 && self.derived_type() == pe::IMAGE_SYM_DTYPE_FUNCTION -    } - -    /// Return true if the symbol has an auxiliary section symbol. -    fn has_aux_section(&self) -> bool { -        self.number_of_aux_symbols() > 0 -            && self.storage_class() == pe::IMAGE_SYM_CLASS_STATIC -            && self.typ() == 0 -    } - -    fn base_type(&self) -> u16 { -        self.typ() & pe::N_BTMASK -    } - -    fn derived_type(&self) -> u16 { -        (self.typ() & pe::N_TMASK) >> pe::N_BTSHFT -    } -} - -impl ImageSymbol for pe::ImageSymbol { -    fn raw_name(&self) -> &[u8; 8] { -        &self.name -    } -    fn value(&self) -> u32 { -        self.value.get(LE) -    } -    fn section_number(&self) -> i32 { -        let section_number = self.section_number.get(LE); -        if section_number >= pe::IMAGE_SYM_SECTION_MAX { -            (section_number as i16) as i32 -        } else { -            section_number as i32 -        } -    } -    fn typ(&self) -> u16 { -        self.typ.get(LE) -    } -    fn storage_class(&self) -> u8 { -        self.storage_class -    } -    fn number_of_aux_symbols(&self) -> u8 { -        self.number_of_aux_symbols -    } -} - -impl ImageSymbol for pe::ImageSymbolEx { -    fn raw_name(&self) -> &[u8; 8] { -        &self.name -    } -    fn value(&self) -> u32 { -        self.value.get(LE) -    } -    fn section_number(&self) -> i32 { -        self.section_number.get(LE) -    } -    fn typ(&self) -> u16 { -        self.typ.get(LE) -    } -    fn storage_class(&self) -> u8 { -        self.storage_class -    } -    fn number_of_aux_symbols(&self) -> u8 { -        self.number_of_aux_symbols -    } -} diff --git a/vendor/object/src/read/elf/attributes.rs b/vendor/object/src/read/elf/attributes.rs deleted file mode 100644 index bf6f35c..0000000 --- a/vendor/object/src/read/elf/attributes.rs +++ /dev/null @@ -1,307 +0,0 @@ -use core::convert::TryInto; - -use crate::elf; -use crate::endian; -use crate::read::{Bytes, Error, ReadError, Result}; - -use super::FileHeader; - -/// An ELF attributes section. -/// -/// This may be a GNU attributes section, or an architecture specific attributes section. -/// -/// An attributes section contains a series of [`AttributesSubsection`]. -/// -/// Returned by [`SectionHeader::attributes`](super::SectionHeader::attributes) -/// and [`SectionHeader::gnu_attributes`](super::SectionHeader::gnu_attributes). -#[derive(Debug, Clone)] -pub struct AttributesSection<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    version: u8, -    data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSection<'data, Elf> { -    /// Parse an ELF attributes section given the section data. -    pub fn new(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> { -        let mut data = Bytes(data); - -        // Skip the version field that is one byte long. -        let version = *data -            .read::<u8>() -            .read_error("Invalid ELF attributes section offset or size")?; - -        Ok(AttributesSection { -            endian, -            version, -            data, -        }) -    } - -    /// Return the version of the attributes section. -    pub fn version(&self) -> u8 { -        self.version -    } - -    /// Return an iterator over the subsections. -    pub fn subsections(&self) -> Result<AttributesSubsectionIterator<'data, Elf>> { -        // There is currently only one format version. -        if self.version != b'A' { -            return Err(Error("Unsupported ELF attributes section version")); -        } - -        Ok(AttributesSubsectionIterator { -            endian: self.endian, -            data: self.data, -        }) -    } -} - -/// An iterator for the subsections in an [`AttributesSection`]. -#[derive(Debug, Clone)] -pub struct AttributesSubsectionIterator<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> { -    /// Return the next subsection. -    pub fn next(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> { -        if self.data.is_empty() { -            return Ok(None); -        } - -        let result = self.parse(); -        if result.is_err() { -            self.data = Bytes(&[]); -        } -        result -    } - -    fn parse(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> { -        // First read the subsection length. -        let mut data = self.data; -        let length = data -            .read::<endian::U32Bytes<Elf::Endian>>() -            .read_error("ELF attributes section is too short")? -            .get(self.endian); - -        // Now read the entire subsection, updating self.data. -        let mut data = self -            .data -            .read_bytes(length as usize) -            .read_error("Invalid ELF attributes subsection length")?; -        // Skip the subsection length field. -        data.skip(4) -            .read_error("Invalid ELF attributes subsection length")?; - -        let vendor = data -            .read_string() -            .read_error("Invalid ELF attributes vendor")?; - -        Ok(Some(AttributesSubsection { -            endian: self.endian, -            length, -            vendor, -            data, -        })) -    } -} - -/// A subsection in an [`AttributesSection`]. -/// -/// A subsection is identified by a vendor name.  It contains a series of -/// [`AttributesSubsubsection`]. -#[derive(Debug, Clone)] -pub struct AttributesSubsection<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    length: u32, -    vendor: &'data [u8], -    data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSubsection<'data, Elf> { -    /// Return the length of the attributes subsection. -    pub fn length(&self) -> u32 { -        self.length -    } - -    /// Return the vendor name of the attributes subsection. -    pub fn vendor(&self) -> &'data [u8] { -        self.vendor -    } - -    /// Return an iterator over the sub-subsections. -    pub fn subsubsections(&self) -> AttributesSubsubsectionIterator<'data, Elf> { -        AttributesSubsubsectionIterator { -            endian: self.endian, -            data: self.data, -        } -    } -} - -/// An iterator for the sub-subsections in an [`AttributesSubsection`]. -#[derive(Debug, Clone)] -pub struct AttributesSubsubsectionIterator<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> { -    /// Return the next sub-subsection. -    pub fn next(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> { -        if self.data.is_empty() { -            return Ok(None); -        } - -        let result = self.parse(); -        if result.is_err() { -            self.data = Bytes(&[]); -        } -        result -    } - -    fn parse(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> { -        // The format of a sub-section looks like this: -        // -        // <file-tag> <size> <attribute>* -        // | <section-tag> <size> <section-number>* 0 <attribute>* -        // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* -        let mut data = self.data; -        let tag = *data -            .read::<u8>() -            .read_error("ELF attributes subsection is too short")?; -        let length = data -            .read::<endian::U32Bytes<Elf::Endian>>() -            .read_error("ELF attributes subsection is too short")? -            .get(self.endian); - -        // Now read the entire sub-subsection, updating self.data. -        let mut data = self -            .data -            .read_bytes(length as usize) -            .read_error("Invalid ELF attributes sub-subsection length")?; -        // Skip the tag and sub-subsection size field. -        data.skip(1 + 4) -            .read_error("Invalid ELF attributes sub-subsection length")?; - -        let indices = if tag == elf::Tag_Section || tag == elf::Tag_Symbol { -            data.read_string() -                .map(Bytes) -                .read_error("Missing ELF attributes sub-subsection indices")? -        } else if tag == elf::Tag_File { -            Bytes(&[]) -        } else { -            return Err(Error("Unimplemented ELF attributes sub-subsection tag")); -        }; - -        Ok(Some(AttributesSubsubsection { -            tag, -            length, -            indices, -            data, -        })) -    } -} - -/// A sub-subsection in an [`AttributesSubsection`]. -/// -/// A sub-subsection is identified by a tag.  It contains an optional series of indices, -/// followed by a series of attributes. -#[derive(Debug, Clone)] -pub struct AttributesSubsubsection<'data> { -    tag: u8, -    length: u32, -    indices: Bytes<'data>, -    data: Bytes<'data>, -} - -impl<'data> AttributesSubsubsection<'data> { -    /// Return the tag of the attributes sub-subsection. -    pub fn tag(&self) -> u8 { -        self.tag -    } - -    /// Return the length of the attributes sub-subsection. -    pub fn length(&self) -> u32 { -        self.length -    } - -    /// Return the data containing the indices. -    pub fn indices_data(&self) -> &'data [u8] { -        self.indices.0 -    } - -    /// Return the indices. -    /// -    /// This will be section indices if the tag is `Tag_Section`, -    /// or symbol indices if the tag is `Tag_Symbol`, -    /// and otherwise it will be empty. -    pub fn indices(&self) -> AttributeIndexIterator<'data> { -        AttributeIndexIterator { data: self.indices } -    } - -    /// Return the data containing the attributes. -    pub fn attributes_data(&self) -> &'data [u8] { -        self.data.0 -    } - -    /// Return a parser for the data containing the attributes. -    pub fn attributes(&self) -> AttributeReader<'data> { -        AttributeReader { data: self.data } -    } -} - -/// An iterator over the indices in an [`AttributesSubsubsection`]. -#[derive(Debug, Clone)] -pub struct AttributeIndexIterator<'data> { -    data: Bytes<'data>, -} - -impl<'data> AttributeIndexIterator<'data> { -    /// Parse the next index. -    pub fn next(&mut self) -> Result<Option<u32>> { -        if self.data.is_empty() { -            return Ok(None); -        } -        let err = "Invalid ELF attribute index"; -        self.data -            .read_uleb128() -            .read_error(err)? -            .try_into() -            .map_err(|_| ()) -            .read_error(err) -            .map(Some) -    } -} - -/// A parser for the attributes in an [`AttributesSubsubsection`]. -/// -/// The parser relies on the caller to know the format of the data for each attribute tag. -#[derive(Debug, Clone)] -pub struct AttributeReader<'data> { -    data: Bytes<'data>, -} - -impl<'data> AttributeReader<'data> { -    /// Parse a tag. -    pub fn read_tag(&mut self) -> Result<Option<u64>> { -        if self.data.is_empty() { -            return Ok(None); -        } -        let err = "Invalid ELF attribute tag"; -        self.data.read_uleb128().read_error(err).map(Some) -    } - -    /// Parse an integer value. -    pub fn read_integer(&mut self) -> Result<u64> { -        let err = "Invalid ELF attribute integer value"; -        self.data.read_uleb128().read_error(err) -    } - -    /// Parse a string value. -    pub fn read_string(&mut self) -> Result<&'data [u8]> { -        let err = "Invalid ELF attribute string value"; -        self.data.read_string().read_error(err) -    } -} diff --git a/vendor/object/src/read/elf/comdat.rs b/vendor/object/src/read/elf/comdat.rs deleted file mode 100644 index 882d253..0000000 --- a/vendor/object/src/read/elf/comdat.rs +++ /dev/null @@ -1,162 +0,0 @@ -use core::fmt::Debug; -use core::{iter, slice, str}; - -use crate::elf; -use crate::endian::{Endianness, U32Bytes}; -use crate::read::{self, ComdatKind, ObjectComdat, ReadError, ReadRef, SectionIndex, SymbolIndex}; - -use super::{ElfFile, FileHeader, SectionHeader, Sym}; - -/// An iterator for the COMDAT section groups in an [`ElfFile32`](super::ElfFile32). -pub type ElfComdatIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfComdatIterator<'data, 'file, elf::FileHeader32<Endian>, R>; -/// An iterator for the COMDAT section groups in an [`ElfFile64`](super::ElfFile64). -pub type ElfComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfComdatIterator<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// An iterator for the COMDAT section groups in an [`ElfFile`]. -#[derive(Debug)] -pub struct ElfComdatIterator<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file ElfFile<'data, Elf, R>, -    pub(super) iter: iter::Enumerate<slice::Iter<'data, Elf::SectionHeader>>, -} - -impl<'data, 'file, Elf, R> Iterator for ElfComdatIterator<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    type Item = ElfComdat<'data, 'file, Elf, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        for (_index, section) in self.iter.by_ref() { -            if let Some(comdat) = ElfComdat::parse(self.file, section) { -                return Some(comdat); -            } -        } -        None -    } -} - -/// A COMDAT section group in an [`ElfFile32`](super::ElfFile32). -pub type ElfComdat32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfComdat<'data, 'file, elf::FileHeader32<Endian>, R>; -/// A COMDAT section group in an [`ElfFile64`](super::ElfFile64). -pub type ElfComdat64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfComdat<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// A COMDAT section group in an [`ElfFile`]. -/// -/// Most functionality is provided by the [`ObjectComdat`] trait implementation. -#[derive(Debug)] -pub struct ElfComdat<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    file: &'file ElfFile<'data, Elf, R>, -    section: &'data Elf::SectionHeader, -    sections: &'data [U32Bytes<Elf::Endian>], -} - -impl<'data, 'file, Elf, R> ElfComdat<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    fn parse( -        file: &'file ElfFile<'data, Elf, R>, -        section: &'data Elf::SectionHeader, -    ) -> Option<ElfComdat<'data, 'file, Elf, R>> { -        let (flag, sections) = section.group(file.endian, file.data).ok()??; -        if flag != elf::GRP_COMDAT { -            return None; -        } -        Some(ElfComdat { -            file, -            section, -            sections, -        }) -    } -} - -impl<'data, 'file, Elf, R> read::private::Sealed for ElfComdat<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Elf, R> ObjectComdat<'data> for ElfComdat<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    type SectionIterator = ElfComdatSectionIterator<'data, 'file, Elf, R>; - -    #[inline] -    fn kind(&self) -> ComdatKind { -        ComdatKind::Any -    } - -    #[inline] -    fn symbol(&self) -> SymbolIndex { -        SymbolIndex(self.section.sh_info(self.file.endian) as usize) -    } - -    fn name_bytes(&self) -> read::Result<&[u8]> { -        // FIXME: check sh_link -        let index = self.section.sh_info(self.file.endian) as usize; -        let symbol = self.file.symbols.symbol(index)?; -        symbol.name(self.file.endian, self.file.symbols.strings()) -    } - -    fn name(&self) -> read::Result<&str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 ELF COMDAT name") -    } - -    fn sections(&self) -> Self::SectionIterator { -        ElfComdatSectionIterator { -            file: self.file, -            sections: self.sections.iter(), -        } -    } -} - -/// An iterator for the sections in a COMDAT section group in an [`ElfFile32`](super::ElfFile32). -pub type ElfComdatSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfComdatSectionIterator<'data, 'file, elf::FileHeader32<Endian>, R>; -/// An iterator for the sections in a COMDAT section group in an [`ElfFile64`](super::ElfFile64). -pub type ElfComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfComdatSectionIterator<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// An iterator for the sections in a COMDAT section group in an [`ElfFile`]. -#[derive(Debug)] -pub struct ElfComdatSectionIterator<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    file: &'file ElfFile<'data, Elf, R>, -    sections: slice::Iter<'data, U32Bytes<Elf::Endian>>, -} - -impl<'data, 'file, Elf, R> Iterator for ElfComdatSectionIterator<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    type Item = SectionIndex; - -    fn next(&mut self) -> Option<Self::Item> { -        let index = self.sections.next()?; -        Some(SectionIndex(index.get(self.file.endian) as usize)) -    } -} diff --git a/vendor/object/src/read/elf/compression.rs b/vendor/object/src/read/elf/compression.rs deleted file mode 100644 index de2533f..0000000 --- a/vendor/object/src/read/elf/compression.rs +++ /dev/null @@ -1,56 +0,0 @@ -use core::fmt::Debug; - -use crate::elf; -use crate::endian; -use crate::pod::Pod; - -/// A trait for generic access to [`elf::CompressionHeader32`] and [`elf::CompressionHeader64`]. -#[allow(missing_docs)] -pub trait CompressionHeader: Debug + Pod { -    type Word: Into<u64>; -    type Endian: endian::Endian; - -    fn ch_type(&self, endian: Self::Endian) -> u32; -    fn ch_size(&self, endian: Self::Endian) -> Self::Word; -    fn ch_addralign(&self, endian: Self::Endian) -> Self::Word; -} - -impl<Endian: endian::Endian> CompressionHeader for elf::CompressionHeader32<Endian> { -    type Word = u32; -    type Endian = Endian; - -    #[inline] -    fn ch_type(&self, endian: Self::Endian) -> u32 { -        self.ch_type.get(endian) -    } - -    #[inline] -    fn ch_size(&self, endian: Self::Endian) -> Self::Word { -        self.ch_size.get(endian) -    } - -    #[inline] -    fn ch_addralign(&self, endian: Self::Endian) -> Self::Word { -        self.ch_addralign.get(endian) -    } -} - -impl<Endian: endian::Endian> CompressionHeader for elf::CompressionHeader64<Endian> { -    type Word = u64; -    type Endian = Endian; - -    #[inline] -    fn ch_type(&self, endian: Self::Endian) -> u32 { -        self.ch_type.get(endian) -    } - -    #[inline] -    fn ch_size(&self, endian: Self::Endian) -> Self::Word { -        self.ch_size.get(endian) -    } - -    #[inline] -    fn ch_addralign(&self, endian: Self::Endian) -> Self::Word { -        self.ch_addralign.get(endian) -    } -} diff --git a/vendor/object/src/read/elf/dynamic.rs b/vendor/object/src/read/elf/dynamic.rs deleted file mode 100644 index 1661434..0000000 --- a/vendor/object/src/read/elf/dynamic.rs +++ /dev/null @@ -1,117 +0,0 @@ -use core::convert::TryInto; -use core::fmt::Debug; - -use crate::elf; -use crate::endian; -use crate::pod::Pod; -use crate::read::{ReadError, Result, StringTable}; - -/// A trait for generic access to [`elf::Dyn32`] and [`elf::Dyn64`]. -#[allow(missing_docs)] -pub trait Dyn: Debug + Pod { -    type Word: Into<u64>; -    type Endian: endian::Endian; - -    fn d_tag(&self, endian: Self::Endian) -> Self::Word; -    fn d_val(&self, endian: Self::Endian) -> Self::Word; - -    /// Try to convert the tag to a `u32`. -    fn tag32(&self, endian: Self::Endian) -> Option<u32> { -        self.d_tag(endian).into().try_into().ok() -    } - -    /// Try to convert the value to a `u32`. -    fn val32(&self, endian: Self::Endian) -> Option<u32> { -        self.d_val(endian).into().try_into().ok() -    } - -    /// Return true if the value is an offset in the dynamic string table. -    fn is_string(&self, endian: Self::Endian) -> bool { -        if let Some(tag) = self.tag32(endian) { -            match tag { -                elf::DT_NEEDED -                | elf::DT_SONAME -                | elf::DT_RPATH -                | elf::DT_RUNPATH -                | elf::DT_AUXILIARY -                | elf::DT_FILTER => true, -                _ => false, -            } -        } else { -            false -        } -    } - -    /// Use the value to get a string in a string table. -    /// -    /// Does not check for an appropriate tag. -    fn string<'data>( -        &self, -        endian: Self::Endian, -        strings: StringTable<'data>, -    ) -> Result<&'data [u8]> { -        self.val32(endian) -            .and_then(|val| strings.get(val).ok()) -            .read_error("Invalid ELF dyn string") -    } - -    /// Return true if the value is an address. -    fn is_address(&self, endian: Self::Endian) -> bool { -        if let Some(tag) = self.tag32(endian) { -            match tag { -                elf::DT_PLTGOT -                | elf::DT_HASH -                | elf::DT_STRTAB -                | elf::DT_SYMTAB -                | elf::DT_RELA -                | elf::DT_INIT -                | elf::DT_FINI -                | elf::DT_SYMBOLIC -                | elf::DT_REL -                | elf::DT_DEBUG -                | elf::DT_JMPREL -                | elf::DT_FINI_ARRAY -                | elf::DT_INIT_ARRAY -                | elf::DT_PREINIT_ARRAY -                | elf::DT_SYMTAB_SHNDX -                | elf::DT_VERDEF -                | elf::DT_VERNEED -                | elf::DT_VERSYM -                | elf::DT_ADDRRNGLO..=elf::DT_ADDRRNGHI => true, -                _ => false, -            } -        } else { -            false -        } -    } -} - -impl<Endian: endian::Endian> Dyn for elf::Dyn32<Endian> { -    type Word = u32; -    type Endian = Endian; - -    #[inline] -    fn d_tag(&self, endian: Self::Endian) -> Self::Word { -        self.d_tag.get(endian) -    } - -    #[inline] -    fn d_val(&self, endian: Self::Endian) -> Self::Word { -        self.d_val.get(endian) -    } -} - -impl<Endian: endian::Endian> Dyn for elf::Dyn64<Endian> { -    type Word = u64; -    type Endian = Endian; - -    #[inline] -    fn d_tag(&self, endian: Self::Endian) -> Self::Word { -        self.d_tag.get(endian) -    } - -    #[inline] -    fn d_val(&self, endian: Self::Endian) -> Self::Word { -        self.d_val.get(endian) -    } -} diff --git a/vendor/object/src/read/elf/file.rs b/vendor/object/src/read/elf/file.rs deleted file mode 100644 index 14ba568..0000000 --- a/vendor/object/src/read/elf/file.rs +++ /dev/null @@ -1,916 +0,0 @@ -use alloc::vec::Vec; -use core::convert::TryInto; -use core::fmt::Debug; -use core::mem; - -use crate::read::{ -    self, util, Architecture, ByteString, Bytes, Error, Export, FileFlags, Import, Object, -    ObjectKind, ReadError, ReadRef, SectionIndex, StringTable, SymbolIndex, -}; -use crate::{elf, endian, Endian, Endianness, Pod, U32}; - -use super::{ -    CompressionHeader, Dyn, ElfComdat, ElfComdatIterator, ElfDynamicRelocationIterator, ElfSection, -    ElfSectionIterator, ElfSegment, ElfSegmentIterator, ElfSymbol, ElfSymbolIterator, -    ElfSymbolTable, NoteHeader, ProgramHeader, Rel, Rela, RelocationSections, SectionHeader, -    SectionTable, Sym, SymbolTable, -}; - -/// A 32-bit ELF object file. -/// -/// This is a file that starts with [`elf::FileHeader32`], and corresponds -/// to [`crate::FileKind::Elf32`]. -pub type ElfFile32<'data, Endian = Endianness, R = &'data [u8]> = -    ElfFile<'data, elf::FileHeader32<Endian>, R>; -/// A 64-bit ELF object file. -/// -/// This is a file that starts with [`elf::FileHeader64`], and corresponds -/// to [`crate::FileKind::Elf64`]. -pub type ElfFile64<'data, Endian = Endianness, R = &'data [u8]> = -    ElfFile<'data, elf::FileHeader64<Endian>, R>; - -/// A partially parsed ELF file. -/// -/// Most functionality is provided by the [`Object`] trait implementation. -#[derive(Debug)] -pub struct ElfFile<'data, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) endian: Elf::Endian, -    pub(super) data: R, -    pub(super) header: &'data Elf, -    pub(super) segments: &'data [Elf::ProgramHeader], -    pub(super) sections: SectionTable<'data, Elf, R>, -    pub(super) relocations: RelocationSections, -    pub(super) symbols: SymbolTable<'data, Elf, R>, -    pub(super) dynamic_symbols: SymbolTable<'data, Elf, R>, -} - -impl<'data, Elf, R> ElfFile<'data, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    /// Parse the raw ELF file data. -    pub fn parse(data: R) -> read::Result<Self> { -        let header = Elf::parse(data)?; -        let endian = header.endian()?; -        let segments = header.program_headers(endian, data)?; -        let sections = header.sections(endian, data)?; -        let symbols = sections.symbols(endian, data, elf::SHT_SYMTAB)?; -        // TODO: get dynamic symbols from DT_SYMTAB if there are no sections -        let dynamic_symbols = sections.symbols(endian, data, elf::SHT_DYNSYM)?; -        // The API we provide requires a mapping from section to relocations, so build it now. -        let relocations = sections.relocation_sections(endian, symbols.section())?; - -        Ok(ElfFile { -            endian, -            data, -            header, -            segments, -            sections, -            relocations, -            symbols, -            dynamic_symbols, -        }) -    } - -    /// Returns the endianness. -    pub fn endian(&self) -> Elf::Endian { -        self.endian -    } - -    /// Returns the raw data. -    pub fn data(&self) -> R { -        self.data -    } - -    /// Returns the raw ELF file header. -    pub fn raw_header(&self) -> &'data Elf { -        self.header -    } - -    /// Returns the raw ELF segments. -    pub fn raw_segments(&self) -> &'data [Elf::ProgramHeader] { -        self.segments -    } - -    fn raw_section_by_name<'file>( -        &'file self, -        section_name: &[u8], -    ) -> Option<ElfSection<'data, 'file, Elf, R>> { -        self.sections -            .section_by_name(self.endian, section_name) -            .map(|(index, section)| ElfSection { -                file: self, -                index: SectionIndex(index), -                section, -            }) -    } - -    #[cfg(feature = "compression")] -    fn zdebug_section_by_name<'file>( -        &'file self, -        section_name: &[u8], -    ) -> Option<ElfSection<'data, 'file, Elf, R>> { -        if !section_name.starts_with(b".debug_") { -            return None; -        } -        let mut name = Vec::with_capacity(section_name.len() + 1); -        name.extend_from_slice(b".zdebug_"); -        name.extend_from_slice(§ion_name[7..]); -        self.raw_section_by_name(&name) -    } - -    #[cfg(not(feature = "compression"))] -    fn zdebug_section_by_name<'file>( -        &'file self, -        _section_name: &[u8], -    ) -> Option<ElfSection<'data, 'file, Elf, R>> { -        None -    } -} - -impl<'data, Elf, R> read::private::Sealed for ElfFile<'data, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Elf, R> Object<'data, 'file> for ElfFile<'data, Elf, R> -where -    'data: 'file, -    Elf: FileHeader, -    R: 'file + ReadRef<'data>, -{ -    type Segment = ElfSegment<'data, 'file, Elf, R>; -    type SegmentIterator = ElfSegmentIterator<'data, 'file, Elf, R>; -    type Section = ElfSection<'data, 'file, Elf, R>; -    type SectionIterator = ElfSectionIterator<'data, 'file, Elf, R>; -    type Comdat = ElfComdat<'data, 'file, Elf, R>; -    type ComdatIterator = ElfComdatIterator<'data, 'file, Elf, R>; -    type Symbol = ElfSymbol<'data, 'file, Elf, R>; -    type SymbolIterator = ElfSymbolIterator<'data, 'file, Elf, R>; -    type SymbolTable = ElfSymbolTable<'data, 'file, Elf, R>; -    type DynamicRelocationIterator = ElfDynamicRelocationIterator<'data, 'file, Elf, R>; - -    fn architecture(&self) -> Architecture { -        match ( -            self.header.e_machine(self.endian), -            self.header.is_class_64(), -        ) { -            (elf::EM_AARCH64, true) => Architecture::Aarch64, -            (elf::EM_AARCH64, false) => Architecture::Aarch64_Ilp32, -            (elf::EM_ARM, _) => Architecture::Arm, -            (elf::EM_AVR, _) => Architecture::Avr, -            (elf::EM_BPF, _) => Architecture::Bpf, -            (elf::EM_CSKY, _) => Architecture::Csky, -            (elf::EM_386, _) => Architecture::I386, -            (elf::EM_X86_64, false) => Architecture::X86_64_X32, -            (elf::EM_X86_64, true) => Architecture::X86_64, -            (elf::EM_HEXAGON, _) => Architecture::Hexagon, -            (elf::EM_LOONGARCH, true) => Architecture::LoongArch64, -            (elf::EM_MIPS, false) => Architecture::Mips, -            (elf::EM_MIPS, true) => Architecture::Mips64, -            (elf::EM_MSP430, _) => Architecture::Msp430, -            (elf::EM_PPC, _) => Architecture::PowerPc, -            (elf::EM_PPC64, _) => Architecture::PowerPc64, -            (elf::EM_RISCV, false) => Architecture::Riscv32, -            (elf::EM_RISCV, true) => Architecture::Riscv64, -            // This is either s390 or s390x, depending on the ELF class. -            // We only support the 64-bit variant s390x here. -            (elf::EM_S390, true) => Architecture::S390x, -            (elf::EM_SBF, _) => Architecture::Sbf, -            (elf::EM_SHARC, false) => Architecture::Sharc, -            (elf::EM_SPARCV9, true) => Architecture::Sparc64, -            (elf::EM_XTENSA, false) => Architecture::Xtensa, -            _ => Architecture::Unknown, -        } -    } - -    #[inline] -    fn is_little_endian(&self) -> bool { -        self.header.is_little_endian() -    } - -    #[inline] -    fn is_64(&self) -> bool { -        self.header.is_class_64() -    } - -    fn kind(&self) -> ObjectKind { -        match self.header.e_type(self.endian) { -            elf::ET_REL => ObjectKind::Relocatable, -            elf::ET_EXEC => ObjectKind::Executable, -            // TODO: check for `DF_1_PIE`? -            elf::ET_DYN => ObjectKind::Dynamic, -            elf::ET_CORE => ObjectKind::Core, -            _ => ObjectKind::Unknown, -        } -    } - -    fn segments(&'file self) -> ElfSegmentIterator<'data, 'file, Elf, R> { -        ElfSegmentIterator { -            file: self, -            iter: self.segments.iter(), -        } -    } - -    fn section_by_name_bytes( -        &'file self, -        section_name: &[u8], -    ) -> Option<ElfSection<'data, 'file, Elf, R>> { -        self.raw_section_by_name(section_name) -            .or_else(|| self.zdebug_section_by_name(section_name)) -    } - -    fn section_by_index( -        &'file self, -        index: SectionIndex, -    ) -> read::Result<ElfSection<'data, 'file, Elf, R>> { -        let section = self.sections.section(index)?; -        Ok(ElfSection { -            file: self, -            index, -            section, -        }) -    } - -    fn sections(&'file self) -> ElfSectionIterator<'data, 'file, Elf, R> { -        ElfSectionIterator { -            file: self, -            iter: self.sections.iter().enumerate(), -        } -    } - -    fn comdats(&'file self) -> ElfComdatIterator<'data, 'file, Elf, R> { -        ElfComdatIterator { -            file: self, -            iter: self.sections.iter().enumerate(), -        } -    } - -    fn symbol_by_index( -        &'file self, -        index: SymbolIndex, -    ) -> read::Result<ElfSymbol<'data, 'file, Elf, R>> { -        let symbol = self.symbols.symbol(index.0)?; -        Ok(ElfSymbol { -            endian: self.endian, -            symbols: &self.symbols, -            index, -            symbol, -        }) -    } - -    fn symbols(&'file self) -> ElfSymbolIterator<'data, 'file, Elf, R> { -        ElfSymbolIterator { -            endian: self.endian, -            symbols: &self.symbols, -            index: 0, -        } -    } - -    fn symbol_table(&'file self) -> Option<ElfSymbolTable<'data, 'file, Elf, R>> { -        if self.symbols.is_empty() { -            return None; -        } -        Some(ElfSymbolTable { -            endian: self.endian, -            symbols: &self.symbols, -        }) -    } - -    fn dynamic_symbols(&'file self) -> ElfSymbolIterator<'data, 'file, Elf, R> { -        ElfSymbolIterator { -            endian: self.endian, -            symbols: &self.dynamic_symbols, -            index: 0, -        } -    } - -    fn dynamic_symbol_table(&'file self) -> Option<ElfSymbolTable<'data, 'file, Elf, R>> { -        if self.dynamic_symbols.is_empty() { -            return None; -        } -        Some(ElfSymbolTable { -            endian: self.endian, -            symbols: &self.dynamic_symbols, -        }) -    } - -    fn dynamic_relocations( -        &'file self, -    ) -> Option<ElfDynamicRelocationIterator<'data, 'file, Elf, R>> { -        Some(ElfDynamicRelocationIterator { -            section_index: SectionIndex(1), -            file: self, -            relocations: None, -        }) -    } - -    fn imports(&self) -> read::Result<Vec<Import<'data>>> { -        let mut imports = Vec::new(); -        for symbol in self.dynamic_symbols.iter() { -            if symbol.is_undefined(self.endian) { -                let name = symbol.name(self.endian, self.dynamic_symbols.strings())?; -                if !name.is_empty() { -                    // TODO: use symbol versioning to determine library -                    imports.push(Import { -                        name: ByteString(name), -                        library: ByteString(&[]), -                    }); -                } -            } -        } -        Ok(imports) -    } - -    fn exports(&self) -> read::Result<Vec<Export<'data>>> { -        let mut exports = Vec::new(); -        for symbol in self.dynamic_symbols.iter() { -            if symbol.is_definition(self.endian) { -                let name = symbol.name(self.endian, self.dynamic_symbols.strings())?; -                let address = symbol.st_value(self.endian).into(); -                exports.push(Export { -                    name: ByteString(name), -                    address, -                }); -            } -        } -        Ok(exports) -    } - -    fn has_debug_symbols(&self) -> bool { -        for section in self.sections.iter() { -            if let Ok(name) = self.sections.section_name(self.endian, section) { -                if name == b".debug_info" || name == b".zdebug_info" { -                    return true; -                } -            } -        } -        false -    } - -    fn build_id(&self) -> read::Result<Option<&'data [u8]>> { -        let endian = self.endian; -        // Use section headers if present, otherwise use program headers. -        if !self.sections.is_empty() { -            for section in self.sections.iter() { -                if let Some(mut notes) = section.notes(endian, self.data)? { -                    while let Some(note) = notes.next()? { -                        if note.name() == elf::ELF_NOTE_GNU -                            && note.n_type(endian) == elf::NT_GNU_BUILD_ID -                        { -                            return Ok(Some(note.desc())); -                        } -                    } -                } -            } -        } else { -            for segment in self.segments { -                if let Some(mut notes) = segment.notes(endian, self.data)? { -                    while let Some(note) = notes.next()? { -                        if note.name() == elf::ELF_NOTE_GNU -                            && note.n_type(endian) == elf::NT_GNU_BUILD_ID -                        { -                            return Ok(Some(note.desc())); -                        } -                    } -                } -            } -        } -        Ok(None) -    } - -    fn gnu_debuglink(&self) -> read::Result<Option<(&'data [u8], u32)>> { -        let section = match self.raw_section_by_name(b".gnu_debuglink") { -            Some(section) => section, -            None => return Ok(None), -        }; -        let data = section -            .section -            .data(self.endian, self.data) -            .read_error("Invalid ELF .gnu_debuglink section offset or size") -            .map(Bytes)?; -        let filename = data -            .read_string_at(0) -            .read_error("Missing ELF .gnu_debuglink filename")?; -        let crc_offset = util::align(filename.len() + 1, 4); -        let crc = data -            .read_at::<U32<_>>(crc_offset) -            .read_error("Missing ELF .gnu_debuglink crc")? -            .get(self.endian); -        Ok(Some((filename, crc))) -    } - -    fn gnu_debugaltlink(&self) -> read::Result<Option<(&'data [u8], &'data [u8])>> { -        let section = match self.raw_section_by_name(b".gnu_debugaltlink") { -            Some(section) => section, -            None => return Ok(None), -        }; -        let mut data = section -            .section -            .data(self.endian, self.data) -            .read_error("Invalid ELF .gnu_debugaltlink section offset or size") -            .map(Bytes)?; -        let filename = data -            .read_string() -            .read_error("Missing ELF .gnu_debugaltlink filename")?; -        let build_id = data.0; -        Ok(Some((filename, build_id))) -    } - -    fn relative_address_base(&self) -> u64 { -        0 -    } - -    fn entry(&self) -> u64 { -        self.header.e_entry(self.endian).into() -    } - -    fn flags(&self) -> FileFlags { -        FileFlags::Elf { -            os_abi: self.header.e_ident().os_abi, -            abi_version: self.header.e_ident().abi_version, -            e_flags: self.header.e_flags(self.endian), -        } -    } -} - -/// A trait for generic access to [`elf::FileHeader32`] and [`elf::FileHeader64`]. -#[allow(missing_docs)] -pub trait FileHeader: Debug + Pod { -    // Ideally this would be a `u64: From<Word>`, but can't express that. -    type Word: Into<u64>; -    type Sword: Into<i64>; -    type Endian: endian::Endian; -    type ProgramHeader: ProgramHeader<Elf = Self, Endian = Self::Endian, Word = Self::Word>; -    type SectionHeader: SectionHeader<Elf = Self, Endian = Self::Endian, Word = Self::Word>; -    type CompressionHeader: CompressionHeader<Endian = Self::Endian, Word = Self::Word>; -    type NoteHeader: NoteHeader<Endian = Self::Endian>; -    type Dyn: Dyn<Endian = Self::Endian, Word = Self::Word>; -    type Sym: Sym<Endian = Self::Endian, Word = Self::Word>; -    type Rel: Rel<Endian = Self::Endian, Word = Self::Word>; -    type Rela: Rela<Endian = Self::Endian, Word = Self::Word> + From<Self::Rel>; - -    /// Return true if this type is a 64-bit header. -    /// -    /// This is a property of the type, not a value in the header data. -    fn is_type_64(&self) -> bool; - -    /// Return true if this type is a 64-bit header. -    /// -    /// This is a property of the type, not a value in the header data. -    /// -    /// This is the same as [`Self::is_type_64`], but is non-dispatchable. -    fn is_type_64_sized() -> bool -    where -        Self: Sized; - -    fn e_ident(&self) -> &elf::Ident; -    fn e_type(&self, endian: Self::Endian) -> u16; -    fn e_machine(&self, endian: Self::Endian) -> u16; -    fn e_version(&self, endian: Self::Endian) -> u32; -    fn e_entry(&self, endian: Self::Endian) -> Self::Word; -    fn e_phoff(&self, endian: Self::Endian) -> Self::Word; -    fn e_shoff(&self, endian: Self::Endian) -> Self::Word; -    fn e_flags(&self, endian: Self::Endian) -> u32; -    fn e_ehsize(&self, endian: Self::Endian) -> u16; -    fn e_phentsize(&self, endian: Self::Endian) -> u16; -    fn e_phnum(&self, endian: Self::Endian) -> u16; -    fn e_shentsize(&self, endian: Self::Endian) -> u16; -    fn e_shnum(&self, endian: Self::Endian) -> u16; -    fn e_shstrndx(&self, endian: Self::Endian) -> u16; - -    // Provided methods. - -    /// Read the file header. -    /// -    /// Also checks that the ident field in the file header is a supported format. -    fn parse<'data, R: ReadRef<'data>>(data: R) -> read::Result<&'data Self> { -        let header = data -            .read_at::<Self>(0) -            .read_error("Invalid ELF header size or alignment")?; -        if !header.is_supported() { -            return Err(Error("Unsupported ELF header")); -        } -        // TODO: Check self.e_ehsize? -        Ok(header) -    } - -    /// Check that the ident field in the file header is a supported format. -    /// -    /// This checks the magic number, version, class, and endianness. -    fn is_supported(&self) -> bool { -        let ident = self.e_ident(); -        // TODO: Check self.e_version too? Requires endian though. -        ident.magic == elf::ELFMAG -            && (self.is_type_64() || self.is_class_32()) -            && (!self.is_type_64() || self.is_class_64()) -            && (self.is_little_endian() || self.is_big_endian()) -            && ident.version == elf::EV_CURRENT -    } - -    fn is_class_32(&self) -> bool { -        self.e_ident().class == elf::ELFCLASS32 -    } - -    fn is_class_64(&self) -> bool { -        self.e_ident().class == elf::ELFCLASS64 -    } - -    fn is_little_endian(&self) -> bool { -        self.e_ident().data == elf::ELFDATA2LSB -    } - -    fn is_big_endian(&self) -> bool { -        self.e_ident().data == elf::ELFDATA2MSB -    } - -    fn endian(&self) -> read::Result<Self::Endian> { -        Self::Endian::from_big_endian(self.is_big_endian()).read_error("Unsupported ELF endian") -    } - -    /// Return the first section header, if present. -    /// -    /// Section 0 is a special case because getting the section headers normally -    /// requires `shnum`, but `shnum` may be in the first section header. -    fn section_0<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> read::Result<Option<&'data Self::SectionHeader>> { -        let shoff: u64 = self.e_shoff(endian).into(); -        if shoff == 0 { -            // No section headers is ok. -            return Ok(None); -        } -        let shentsize = usize::from(self.e_shentsize(endian)); -        if shentsize != mem::size_of::<Self::SectionHeader>() { -            // Section header size must match. -            return Err(Error("Invalid ELF section header entry size")); -        } -        data.read_at(shoff) -            .map(Some) -            .read_error("Invalid ELF section header offset or size") -    } - -    /// Return the `e_phnum` field of the header. Handles extended values. -    /// -    /// Returns `Err` for invalid values. -    fn phnum<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> read::Result<usize> { -        let e_phnum = self.e_phnum(endian); -        if e_phnum < elf::PN_XNUM { -            Ok(e_phnum as usize) -        } else if let Some(section_0) = self.section_0(endian, data)? { -            Ok(section_0.sh_info(endian) as usize) -        } else { -            // Section 0 must exist if e_phnum overflows. -            Err(Error("Missing ELF section headers for e_phnum overflow")) -        } -    } - -    /// Return the `e_shnum` field of the header. Handles extended values. -    /// -    /// Returns `Err` for invalid values. -    fn shnum<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> read::Result<usize> { -        let e_shnum = self.e_shnum(endian); -        if e_shnum > 0 { -            Ok(e_shnum as usize) -        } else if let Some(section_0) = self.section_0(endian, data)? { -            section_0 -                .sh_size(endian) -                .into() -                .try_into() -                .ok() -                .read_error("Invalid ELF extended e_shnum") -        } else { -            // No section headers is ok. -            Ok(0) -        } -    } - -    /// Return the `e_shstrndx` field of the header. Handles extended values. -    /// -    /// Returns `Err` for invalid values (including if the index is 0). -    fn shstrndx<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> read::Result<u32> { -        let e_shstrndx = self.e_shstrndx(endian); -        let index = if e_shstrndx != elf::SHN_XINDEX { -            e_shstrndx.into() -        } else if let Some(section_0) = self.section_0(endian, data)? { -            section_0.sh_link(endian) -        } else { -            // Section 0 must exist if we're trying to read e_shstrndx. -            return Err(Error("Missing ELF section headers for e_shstrndx overflow")); -        }; -        if index == 0 { -            return Err(Error("Missing ELF e_shstrndx")); -        } -        Ok(index) -    } - -    /// Return the slice of program headers. -    /// -    /// Returns `Ok(&[])` if there are no program headers. -    /// Returns `Err` for invalid values. -    fn program_headers<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> read::Result<&'data [Self::ProgramHeader]> { -        let phoff: u64 = self.e_phoff(endian).into(); -        if phoff == 0 { -            // No program headers is ok. -            return Ok(&[]); -        } -        let phnum = self.phnum(endian, data)?; -        if phnum == 0 { -            // No program headers is ok. -            return Ok(&[]); -        } -        let phentsize = self.e_phentsize(endian) as usize; -        if phentsize != mem::size_of::<Self::ProgramHeader>() { -            // Program header size must match. -            return Err(Error("Invalid ELF program header entry size")); -        } -        data.read_slice_at(phoff, phnum) -            .read_error("Invalid ELF program header size or alignment") -    } - -    /// Return the slice of section headers. -    /// -    /// Returns `Ok(&[])` if there are no section headers. -    /// Returns `Err` for invalid values. -    fn section_headers<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> read::Result<&'data [Self::SectionHeader]> { -        let shoff: u64 = self.e_shoff(endian).into(); -        if shoff == 0 { -            // No section headers is ok. -            return Ok(&[]); -        } -        let shnum = self.shnum(endian, data)?; -        if shnum == 0 { -            // No section headers is ok. -            return Ok(&[]); -        } -        let shentsize = usize::from(self.e_shentsize(endian)); -        if shentsize != mem::size_of::<Self::SectionHeader>() { -            // Section header size must match. -            return Err(Error("Invalid ELF section header entry size")); -        } -        data.read_slice_at(shoff, shnum) -            .read_error("Invalid ELF section header offset/size/alignment") -    } - -    /// Return the string table for the section headers. -    fn section_strings<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -        sections: &[Self::SectionHeader], -    ) -> read::Result<StringTable<'data, R>> { -        if sections.is_empty() { -            return Ok(StringTable::default()); -        } -        let index = self.shstrndx(endian, data)? as usize; -        let shstrtab = sections.get(index).read_error("Invalid ELF e_shstrndx")?; -        let strings = if let Some((shstrtab_offset, shstrtab_size)) = shstrtab.file_range(endian) { -            let shstrtab_end = shstrtab_offset -                .checked_add(shstrtab_size) -                .read_error("Invalid ELF shstrtab size")?; -            StringTable::new(data, shstrtab_offset, shstrtab_end) -        } else { -            StringTable::default() -        }; -        Ok(strings) -    } - -    /// Return the section table. -    fn sections<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> read::Result<SectionTable<'data, Self, R>> { -        let sections = self.section_headers(endian, data)?; -        let strings = self.section_strings(endian, data, sections)?; -        Ok(SectionTable::new(sections, strings)) -    } - -    /// Returns whether this is a mips64el elf file. -    fn is_mips64el(&self, endian: Self::Endian) -> bool { -        self.is_class_64() && self.is_little_endian() && self.e_machine(endian) == elf::EM_MIPS -    } -} - -impl<Endian: endian::Endian> FileHeader for elf::FileHeader32<Endian> { -    type Word = u32; -    type Sword = i32; -    type Endian = Endian; -    type ProgramHeader = elf::ProgramHeader32<Endian>; -    type SectionHeader = elf::SectionHeader32<Endian>; -    type CompressionHeader = elf::CompressionHeader32<Endian>; -    type NoteHeader = elf::NoteHeader32<Endian>; -    type Dyn = elf::Dyn32<Endian>; -    type Sym = elf::Sym32<Endian>; -    type Rel = elf::Rel32<Endian>; -    type Rela = elf::Rela32<Endian>; - -    #[inline] -    fn is_type_64(&self) -> bool { -        false -    } - -    #[inline] -    fn is_type_64_sized() -> bool -    where -        Self: Sized, -    { -        false -    } - -    #[inline] -    fn e_ident(&self) -> &elf::Ident { -        &self.e_ident -    } - -    #[inline] -    fn e_type(&self, endian: Self::Endian) -> u16 { -        self.e_type.get(endian) -    } - -    #[inline] -    fn e_machine(&self, endian: Self::Endian) -> u16 { -        self.e_machine.get(endian) -    } - -    #[inline] -    fn e_version(&self, endian: Self::Endian) -> u32 { -        self.e_version.get(endian) -    } - -    #[inline] -    fn e_entry(&self, endian: Self::Endian) -> Self::Word { -        self.e_entry.get(endian) -    } - -    #[inline] -    fn e_phoff(&self, endian: Self::Endian) -> Self::Word { -        self.e_phoff.get(endian) -    } - -    #[inline] -    fn e_shoff(&self, endian: Self::Endian) -> Self::Word { -        self.e_shoff.get(endian) -    } - -    #[inline] -    fn e_flags(&self, endian: Self::Endian) -> u32 { -        self.e_flags.get(endian) -    } - -    #[inline] -    fn e_ehsize(&self, endian: Self::Endian) -> u16 { -        self.e_ehsize.get(endian) -    } - -    #[inline] -    fn e_phentsize(&self, endian: Self::Endian) -> u16 { -        self.e_phentsize.get(endian) -    } - -    #[inline] -    fn e_phnum(&self, endian: Self::Endian) -> u16 { -        self.e_phnum.get(endian) -    } - -    #[inline] -    fn e_shentsize(&self, endian: Self::Endian) -> u16 { -        self.e_shentsize.get(endian) -    } - -    #[inline] -    fn e_shnum(&self, endian: Self::Endian) -> u16 { -        self.e_shnum.get(endian) -    } - -    #[inline] -    fn e_shstrndx(&self, endian: Self::Endian) -> u16 { -        self.e_shstrndx.get(endian) -    } -} - -impl<Endian: endian::Endian> FileHeader for elf::FileHeader64<Endian> { -    type Word = u64; -    type Sword = i64; -    type Endian = Endian; -    type ProgramHeader = elf::ProgramHeader64<Endian>; -    type SectionHeader = elf::SectionHeader64<Endian>; -    type CompressionHeader = elf::CompressionHeader64<Endian>; -    type NoteHeader = elf::NoteHeader32<Endian>; -    type Dyn = elf::Dyn64<Endian>; -    type Sym = elf::Sym64<Endian>; -    type Rel = elf::Rel64<Endian>; -    type Rela = elf::Rela64<Endian>; - -    #[inline] -    fn is_type_64(&self) -> bool { -        true -    } - -    #[inline] -    fn is_type_64_sized() -> bool -    where -        Self: Sized, -    { -        true -    } - -    #[inline] -    fn e_ident(&self) -> &elf::Ident { -        &self.e_ident -    } - -    #[inline] -    fn e_type(&self, endian: Self::Endian) -> u16 { -        self.e_type.get(endian) -    } - -    #[inline] -    fn e_machine(&self, endian: Self::Endian) -> u16 { -        self.e_machine.get(endian) -    } - -    #[inline] -    fn e_version(&self, endian: Self::Endian) -> u32 { -        self.e_version.get(endian) -    } - -    #[inline] -    fn e_entry(&self, endian: Self::Endian) -> Self::Word { -        self.e_entry.get(endian) -    } - -    #[inline] -    fn e_phoff(&self, endian: Self::Endian) -> Self::Word { -        self.e_phoff.get(endian) -    } - -    #[inline] -    fn e_shoff(&self, endian: Self::Endian) -> Self::Word { -        self.e_shoff.get(endian) -    } - -    #[inline] -    fn e_flags(&self, endian: Self::Endian) -> u32 { -        self.e_flags.get(endian) -    } - -    #[inline] -    fn e_ehsize(&self, endian: Self::Endian) -> u16 { -        self.e_ehsize.get(endian) -    } - -    #[inline] -    fn e_phentsize(&self, endian: Self::Endian) -> u16 { -        self.e_phentsize.get(endian) -    } - -    #[inline] -    fn e_phnum(&self, endian: Self::Endian) -> u16 { -        self.e_phnum.get(endian) -    } - -    #[inline] -    fn e_shentsize(&self, endian: Self::Endian) -> u16 { -        self.e_shentsize.get(endian) -    } - -    #[inline] -    fn e_shnum(&self, endian: Self::Endian) -> u16 { -        self.e_shnum.get(endian) -    } - -    #[inline] -    fn e_shstrndx(&self, endian: Self::Endian) -> u16 { -        self.e_shstrndx.get(endian) -    } -} diff --git a/vendor/object/src/read/elf/hash.rs b/vendor/object/src/read/elf/hash.rs deleted file mode 100644 index b0130cc..0000000 --- a/vendor/object/src/read/elf/hash.rs +++ /dev/null @@ -1,224 +0,0 @@ -use core::mem; - -use crate::elf; -use crate::read::{ReadError, ReadRef, Result}; -use crate::{U32, U64}; - -use super::{FileHeader, Sym, SymbolTable, Version, VersionTable}; - -/// A SysV symbol hash table in an ELF file. -/// -/// Returned by [`SectionHeader::hash`](super::SectionHeader::hash). -#[derive(Debug)] -pub struct HashTable<'data, Elf: FileHeader> { -    buckets: &'data [U32<Elf::Endian>], -    chains: &'data [U32<Elf::Endian>], -} - -impl<'data, Elf: FileHeader> HashTable<'data, Elf> { -    /// Parse a SysV hash table. -    /// -    /// `data` should be from an [`elf::SHT_HASH`] section, or from a -    /// segment pointed to via the [`elf::DT_HASH`] entry. -    /// -    /// The header is read at offset 0 in the given `data`. -    pub fn parse(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> { -        let mut offset = 0; -        let header = data -            .read::<elf::HashHeader<Elf::Endian>>(&mut offset) -            .read_error("Invalid hash header")?; -        let buckets = data -            .read_slice(&mut offset, header.bucket_count.get(endian) as usize) -            .read_error("Invalid hash buckets")?; -        let chains = data -            .read_slice(&mut offset, header.chain_count.get(endian) as usize) -            .read_error("Invalid hash chains")?; -        Ok(HashTable { buckets, chains }) -    } - -    /// Return the symbol table length. -    pub fn symbol_table_length(&self) -> u32 { -        self.chains.len() as u32 -    } - -    /// Use the hash table to find the symbol table entry with the given name, hash and version. -    pub fn find<R: ReadRef<'data>>( -        &self, -        endian: Elf::Endian, -        name: &[u8], -        hash: u32, -        version: Option<&Version<'_>>, -        symbols: &SymbolTable<'data, Elf, R>, -        versions: &VersionTable<'data, Elf>, -    ) -> Option<(usize, &'data Elf::Sym)> { -        // Get the chain start from the bucket for this hash. -        let mut index = self.buckets[(hash as usize) % self.buckets.len()].get(endian) as usize; -        // Avoid infinite loop. -        let mut i = 0; -        let strings = symbols.strings(); -        while index != 0 && i < self.chains.len() { -            if let Ok(symbol) = symbols.symbol(index) { -                if symbol.name(endian, strings) == Ok(name) -                    && versions.matches(endian, index, version) -                { -                    return Some((index, symbol)); -                } -            } -            index = self.chains.get(index)?.get(endian) as usize; -            i += 1; -        } -        None -    } -} - -/// A GNU symbol hash table in an ELF file. -/// -/// Returned by [`SectionHeader::gnu_hash`](super::SectionHeader::gnu_hash). -#[derive(Debug)] -pub struct GnuHashTable<'data, Elf: FileHeader> { -    symbol_base: u32, -    bloom_shift: u32, -    bloom_filters: &'data [u8], -    buckets: &'data [U32<Elf::Endian>], -    values: &'data [U32<Elf::Endian>], -} - -impl<'data, Elf: FileHeader> GnuHashTable<'data, Elf> { -    /// Parse a GNU hash table. -    /// -    /// `data` should be from an [`elf::SHT_GNU_HASH`] section, or from a -    /// segment pointed to via the [`elf::DT_GNU_HASH`] entry. -    /// -    /// The header is read at offset 0 in the given `data`. -    /// -    /// The header does not contain a length field, and so all of `data` -    /// will be used as the hash table values. It does not matter if this -    /// is longer than needed, and this will often the case when accessing -    /// the hash table via the [`elf::DT_GNU_HASH`] entry. -    pub fn parse(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> { -        let mut offset = 0; -        let header = data -            .read::<elf::GnuHashHeader<Elf::Endian>>(&mut offset) -            .read_error("Invalid GNU hash header")?; -        let bloom_len = -            u64::from(header.bloom_count.get(endian)) * mem::size_of::<Elf::Word>() as u64; -        let bloom_filters = data -            .read_bytes(&mut offset, bloom_len) -            .read_error("Invalid GNU hash bloom filters")?; -        let buckets = data -            .read_slice(&mut offset, header.bucket_count.get(endian) as usize) -            .read_error("Invalid GNU hash buckets")?; -        let chain_count = (data.len() - offset as usize) / 4; -        let values = data -            .read_slice(&mut offset, chain_count) -            .read_error("Invalid GNU hash values")?; -        Ok(GnuHashTable { -            symbol_base: header.symbol_base.get(endian), -            bloom_shift: header.bloom_shift.get(endian), -            bloom_filters, -            buckets, -            values, -        }) -    } - -    /// Return the symbol table index of the first symbol in the hash table. -    pub fn symbol_base(&self) -> u32 { -        self.symbol_base -    } - -    /// Determine the symbol table length by finding the last entry in the hash table. -    /// -    /// Returns `None` if the hash table is empty or invalid. -    pub fn symbol_table_length(&self, endian: Elf::Endian) -> Option<u32> { -        // Ensure we find a non-empty bucket. -        if self.symbol_base == 0 { -            return None; -        } - -        // Find the highest chain index in a bucket. -        let mut max_symbol = 0; -        for bucket in self.buckets { -            let bucket = bucket.get(endian); -            if max_symbol < bucket { -                max_symbol = bucket; -            } -        } - -        // Find the end of the chain. -        for value in self -            .values -            .get(max_symbol.checked_sub(self.symbol_base)? as usize..)? -        { -            max_symbol += 1; -            if value.get(endian) & 1 != 0 { -                return Some(max_symbol); -            } -        } - -        None -    } - -    /// Use the hash table to find the symbol table entry with the given name, hash, and version. -    pub fn find<R: ReadRef<'data>>( -        &self, -        endian: Elf::Endian, -        name: &[u8], -        hash: u32, -        version: Option<&Version<'_>>, -        symbols: &SymbolTable<'data, Elf, R>, -        versions: &VersionTable<'data, Elf>, -    ) -> Option<(usize, &'data Elf::Sym)> { -        let word_bits = mem::size_of::<Elf::Word>() as u32 * 8; - -        // Test against bloom filter. -        let bloom_count = self.bloom_filters.len() / mem::size_of::<Elf::Word>(); -        let offset = -            ((hash / word_bits) & (bloom_count as u32 - 1)) * mem::size_of::<Elf::Word>() as u32; -        let filter = if word_bits == 64 { -            self.bloom_filters -                .read_at::<U64<Elf::Endian>>(offset.into()) -                .ok()? -                .get(endian) -        } else { -            self.bloom_filters -                .read_at::<U32<Elf::Endian>>(offset.into()) -                .ok()? -                .get(endian) -                .into() -        }; -        if filter & (1 << (hash % word_bits)) == 0 { -            return None; -        } -        if filter & (1 << ((hash >> self.bloom_shift) % word_bits)) == 0 { -            return None; -        } - -        // Get the chain start from the bucket for this hash. -        let mut index = self.buckets[(hash as usize) % self.buckets.len()].get(endian) as usize; -        if index == 0 { -            return None; -        } - -        // Test symbols in the chain. -        let strings = symbols.strings(); -        let symbols = symbols.symbols().get(index..)?; -        let values = self -            .values -            .get(index.checked_sub(self.symbol_base as usize)?..)?; -        for (symbol, value) in symbols.iter().zip(values.iter()) { -            let value = value.get(endian); -            if value | 1 == hash | 1 { -                if symbol.name(endian, strings) == Ok(name) -                    && versions.matches(endian, index, version) -                { -                    return Some((index, symbol)); -                } -            } -            if value & 1 != 0 { -                break; -            } -            index += 1; -        } -        None -    } -} diff --git a/vendor/object/src/read/elf/mod.rs b/vendor/object/src/read/elf/mod.rs deleted file mode 100644 index 66931bd..0000000 --- a/vendor/object/src/read/elf/mod.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! Support for reading ELF files. -//! -//! Traits are used to abstract over the difference between 32-bit and 64-bit ELF. -//! The primary trait for this is [`FileHeader`]. -//! -//! ## High level API -//! -//! [`ElfFile`] implements the [`Object`](crate::read::Object) trait for ELF files. -//! [`ElfFile`] is parameterised by [`FileHeader`] to allow reading both 32-bit and -//! 64-bit ELF. There are type aliases for these parameters ([`ElfFile32`] and -//! [`ElfFile64`]). -//! -//! ## Low level API -//! -//! The [`FileHeader`] trait can be directly used to parse both [`elf::FileHeader32`] -//! and [`elf::FileHeader64`]. -//! -//! ### Example for low level API -//!  ```no_run -//! use object::elf; -//! use object::read::elf::{FileHeader, Sym}; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads a file and displays the name of each symbol. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let elf = elf::FileHeader64::<object::Endianness>::parse(&*data)?; -//!     let endian = elf.endian()?; -//!     let sections = elf.sections(endian, &*data)?; -//!     let symbols = sections.symbols(endian, &*data, elf::SHT_SYMTAB)?; -//!     for symbol in symbols.iter() { -//!         let name = symbol.name(endian, symbols.strings())?; -//!         println!("{}", String::from_utf8_lossy(name)); -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` -#[cfg(doc)] -use crate::elf; - -mod file; -pub use file::*; - -mod segment; -pub use segment::*; - -mod section; -pub use section::*; - -mod symbol; -pub use symbol::*; - -mod relocation; -pub use relocation::*; - -mod comdat; -pub use comdat::*; - -mod dynamic; -pub use dynamic::*; - -mod compression; -pub use compression::*; - -mod note; -pub use note::*; - -mod hash; -pub use hash::*; - -mod version; -pub use version::*; - -mod attributes; -pub use attributes::*; diff --git a/vendor/object/src/read/elf/note.rs b/vendor/object/src/read/elf/note.rs deleted file mode 100644 index e2beef9..0000000 --- a/vendor/object/src/read/elf/note.rs +++ /dev/null @@ -1,271 +0,0 @@ -use core::fmt::Debug; -use core::mem; - -use crate::elf; -use crate::endian::{self, U32}; -use crate::pod::Pod; -use crate::read::util; -use crate::read::{self, Bytes, Error, ReadError}; - -use super::FileHeader; - -/// An iterator over the notes in an ELF section or segment. -/// -/// Returned [`ProgramHeader::notes`](super::ProgramHeader::notes) -/// and [`SectionHeader::notes`](super::SectionHeader::notes). -#[derive(Debug)] -pub struct NoteIterator<'data, Elf> -where -    Elf: FileHeader, -{ -    endian: Elf::Endian, -    align: usize, -    data: Bytes<'data>, -} - -impl<'data, Elf> NoteIterator<'data, Elf> -where -    Elf: FileHeader, -{ -    /// An iterator over the notes in an ELF section or segment. -    /// -    /// `align` should be from the `p_align` field of the segment, -    /// or the `sh_addralign` field of the section. Supported values are -    /// either 4 or 8, but values less than 4 are treated as 4. -    /// This matches the behaviour of binutils. -    /// -    /// Returns `Err` if `align` is invalid. -    pub fn new(endian: Elf::Endian, align: Elf::Word, data: &'data [u8]) -> read::Result<Self> { -        let align = match align.into() { -            0u64..=4 => 4, -            8 => 8, -            _ => return Err(Error("Invalid ELF note alignment")), -        }; -        // TODO: check data alignment? -        Ok(NoteIterator { -            endian, -            align, -            data: Bytes(data), -        }) -    } - -    /// Returns the next note. -    pub fn next(&mut self) -> read::Result<Option<Note<'data, Elf>>> { -        let mut data = self.data; -        if data.is_empty() { -            return Ok(None); -        } - -        let header = data -            .read_at::<Elf::NoteHeader>(0) -            .read_error("ELF note is too short")?; - -        // The name has no alignment requirement. -        let offset = mem::size_of::<Elf::NoteHeader>(); -        let namesz = header.n_namesz(self.endian) as usize; -        let name = data -            .read_bytes_at(offset, namesz) -            .read_error("Invalid ELF note namesz")? -            .0; - -        // The descriptor must be aligned. -        let offset = util::align(offset + namesz, self.align); -        let descsz = header.n_descsz(self.endian) as usize; -        let desc = data -            .read_bytes_at(offset, descsz) -            .read_error("Invalid ELF note descsz")? -            .0; - -        // The next note (if any) must be aligned. -        let offset = util::align(offset + descsz, self.align); -        if data.skip(offset).is_err() { -            data = Bytes(&[]); -        } -        self.data = data; - -        Ok(Some(Note { header, name, desc })) -    } -} - -/// A parsed [`NoteHeader`]. -#[derive(Debug)] -pub struct Note<'data, Elf> -where -    Elf: FileHeader, -{ -    header: &'data Elf::NoteHeader, -    name: &'data [u8], -    desc: &'data [u8], -} - -impl<'data, Elf: FileHeader> Note<'data, Elf> { -    /// Return the `n_type` field of the `NoteHeader`. -    /// -    /// The meaning of this field is determined by `name`. -    pub fn n_type(&self, endian: Elf::Endian) -> u32 { -        self.header.n_type(endian) -    } - -    /// Return the `n_namesz` field of the `NoteHeader`. -    pub fn n_namesz(&self, endian: Elf::Endian) -> u32 { -        self.header.n_namesz(endian) -    } - -    /// Return the `n_descsz` field of the `NoteHeader`. -    pub fn n_descsz(&self, endian: Elf::Endian) -> u32 { -        self.header.n_descsz(endian) -    } - -    /// Return the bytes for the name field following the `NoteHeader`. -    /// -    /// This field is usually a string including one or more trailing null bytes -    /// (but it is not required to be). -    /// -    /// The length of this field is given by `n_namesz`. -    pub fn name_bytes(&self) -> &'data [u8] { -        self.name -    } - -    /// Return the bytes for the name field following the `NoteHeader`, -    /// excluding all trailing null bytes. -    pub fn name(&self) -> &'data [u8] { -        let mut name = self.name; -        while let [rest @ .., 0] = name { -            name = rest; -        } -        name -    } - -    /// Return the bytes for the desc field following the `NoteHeader`. -    /// -    /// The length of this field is given by `n_descsz`. The meaning -    /// of this field is determined by `name` and `n_type`. -    pub fn desc(&self) -> &'data [u8] { -        self.desc -    } - -    /// Return an iterator for properties if this note's type is [`elf::NT_GNU_PROPERTY_TYPE_0`]. -    pub fn gnu_properties( -        &self, -        endian: Elf::Endian, -    ) -> Option<GnuPropertyIterator<'data, Elf::Endian>> { -        if self.name() != elf::ELF_NOTE_GNU || self.n_type(endian) != elf::NT_GNU_PROPERTY_TYPE_0 { -            return None; -        } -        // Use the ELF class instead of the section alignment. -        // This matches what other parsers do. -        let align = if Elf::is_type_64_sized() { 8 } else { 4 }; -        Some(GnuPropertyIterator { -            endian, -            align, -            data: Bytes(self.desc), -        }) -    } -} - -/// A trait for generic access to [`elf::NoteHeader32`] and [`elf::NoteHeader64`]. -#[allow(missing_docs)] -pub trait NoteHeader: Debug + Pod { -    type Endian: endian::Endian; - -    fn n_namesz(&self, endian: Self::Endian) -> u32; -    fn n_descsz(&self, endian: Self::Endian) -> u32; -    fn n_type(&self, endian: Self::Endian) -> u32; -} - -impl<Endian: endian::Endian> NoteHeader for elf::NoteHeader32<Endian> { -    type Endian = Endian; - -    #[inline] -    fn n_namesz(&self, endian: Self::Endian) -> u32 { -        self.n_namesz.get(endian) -    } - -    #[inline] -    fn n_descsz(&self, endian: Self::Endian) -> u32 { -        self.n_descsz.get(endian) -    } - -    #[inline] -    fn n_type(&self, endian: Self::Endian) -> u32 { -        self.n_type.get(endian) -    } -} - -impl<Endian: endian::Endian> NoteHeader for elf::NoteHeader64<Endian> { -    type Endian = Endian; - -    #[inline] -    fn n_namesz(&self, endian: Self::Endian) -> u32 { -        self.n_namesz.get(endian) -    } - -    #[inline] -    fn n_descsz(&self, endian: Self::Endian) -> u32 { -        self.n_descsz.get(endian) -    } - -    #[inline] -    fn n_type(&self, endian: Self::Endian) -> u32 { -        self.n_type.get(endian) -    } -} - -/// An iterator for the properties in a [`elf::NT_GNU_PROPERTY_TYPE_0`] note. -/// -/// Returned by [`Note::gnu_properties`]. -#[derive(Debug)] -pub struct GnuPropertyIterator<'data, Endian: endian::Endian> { -    endian: Endian, -    align: usize, -    data: Bytes<'data>, -} - -impl<'data, Endian: endian::Endian> GnuPropertyIterator<'data, Endian> { -    /// Returns the next property. -    pub fn next(&mut self) -> read::Result<Option<GnuProperty<'data>>> { -        let mut data = self.data; -        if data.is_empty() { -            return Ok(None); -        } - -        (|| -> Result<_, ()> { -            let pr_type = data.read_at::<U32<Endian>>(0)?.get(self.endian); -            let pr_datasz = data.read_at::<U32<Endian>>(4)?.get(self.endian) as usize; -            let pr_data = data.read_bytes_at(8, pr_datasz)?.0; -            data.skip(util::align(8 + pr_datasz, self.align))?; -            self.data = data; -            Ok(Some(GnuProperty { pr_type, pr_data })) -        })() -        .read_error("Invalid ELF GNU property") -    } -} - -/// A property in a [`elf::NT_GNU_PROPERTY_TYPE_0`] note. -#[derive(Debug)] -pub struct GnuProperty<'data> { -    pr_type: u32, -    pr_data: &'data [u8], -} - -impl<'data> GnuProperty<'data> { -    /// Return the property type. -    /// -    /// This is one of the `GNU_PROPERTY_*` constants. -    pub fn pr_type(&self) -> u32 { -        self.pr_type -    } - -    /// Return the property data. -    pub fn pr_data(&self) -> &'data [u8] { -        self.pr_data -    } - -    /// Parse the property data as an unsigned 32-bit integer. -    pub fn data_u32<E: endian::Endian>(&self, endian: E) -> read::Result<u32> { -        Bytes(self.pr_data) -            .read_at::<U32<E>>(0) -            .read_error("Invalid ELF GNU property data") -            .map(|val| val.get(endian)) -    } -} diff --git a/vendor/object/src/read/elf/relocation.rs b/vendor/object/src/read/elf/relocation.rs deleted file mode 100644 index aac1574..0000000 --- a/vendor/object/src/read/elf/relocation.rs +++ /dev/null @@ -1,628 +0,0 @@ -use alloc::fmt; -use alloc::vec::Vec; -use core::fmt::Debug; -use core::slice; - -use crate::elf; -use crate::endian::{self, Endianness}; -use crate::pod::Pod; -use crate::read::{ -    self, Error, ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, -    SectionIndex, SymbolIndex, -}; - -use super::{ElfFile, FileHeader, SectionHeader, SectionTable}; - -/// A mapping from section index to associated relocation sections. -#[derive(Debug)] -pub struct 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. -    pub fn parse<'data, Elf: FileHeader, R: ReadRef<'data>>( -        endian: Elf::Endian, -        sections: &SectionTable<'data, Elf, R>, -        symbol_section: SectionIndex, -    ) -> read::Result<Self> { -        let mut 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 = SectionIndex(section.sh_link(endian) as usize); -                if sh_link != symbol_section { -                    continue; -                } - -                let sh_info = section.sh_info(endian) as usize; -                if sh_info == 0 { -                    // Skip dynamic relocations. -                    continue; -                } -                if sh_info >= relocations.len() { -                    return Err(Error("Invalid ELF sh_info for relocation section")); -                } - -                // Handle multiple relocation sections by chaining them. -                let next = relocations[sh_info]; -                relocations[sh_info] = 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. -    pub fn get(&self, index: usize) -> Option<usize> { -        self.relocations.get(index).cloned().filter(|x| *x != 0) -    } -} - -pub(super) enum ElfRelaIterator<'data, Elf: FileHeader> { -    Rel(slice::Iter<'data, Elf::Rel>), -    Rela(slice::Iter<'data, Elf::Rela>), -} - -impl<'data, Elf: FileHeader> ElfRelaIterator<'data, Elf> { -    fn is_rel(&self) -> bool { -        match self { -            ElfRelaIterator::Rel(_) => true, -            ElfRelaIterator::Rela(_) => false, -        } -    } -} - -impl<'data, Elf: FileHeader> Iterator for ElfRelaIterator<'data, Elf> { -    type Item = Elf::Rela; - -    fn next(&mut self) -> Option<Self::Item> { -        match self { -            ElfRelaIterator::Rel(ref mut i) => i.next().cloned().map(Self::Item::from), -            ElfRelaIterator::Rela(ref mut i) => i.next().cloned(), -        } -    } -} - -/// An iterator for the dynamic relocations in an [`ElfFile32`](super::ElfFile32). -pub type ElfDynamicRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>; -/// An iterator for the dynamic relocations in an [`ElfFile64`](super::ElfFile64). -pub type ElfDynamicRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// An iterator for the dynamic relocations in an [`ElfFile`]. -pub struct 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); - -    fn next(&mut self) -> Option<Self::Item> { -        let endian = self.file.endian; -        loop { -            if let Some(ref mut relocations) = self.relocations { -                if let Some(reloc) = relocations.next() { -                    let relocation = -                        parse_relocation(self.file.header, endian, reloc, relocations.is_rel()); -                    return Some((reloc.r_offset(endian).into(), relocation)); -                } -                self.relocations = None; -            } - -            let section = self.file.sections.section(self.section_index).ok()?; -            self.section_index.0 += 1; - -            let sh_link = SectionIndex(section.sh_link(endian) as usize); -            if sh_link != self.file.dynamic_symbols.section() { -                continue; -            } - -            match section.sh_type(endian) { -                elf::SHT_REL => { -                    if let Ok(relocations) = section.data_as_array(endian, self.file.data) { -                        self.relocations = Some(ElfRelaIterator::Rel(relocations.iter())); -                    } -                } -                elf::SHT_RELA => { -                    if let Ok(relocations) = section.data_as_array(endian, self.file.data) { -                        self.relocations = Some(ElfRelaIterator::Rela(relocations.iter())); -                    } -                } -                _ => {} -            } -        } -    } -} - -impl<'data, 'file, Elf, R> fmt::Debug for ElfDynamicRelocationIterator<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("ElfDynamicRelocationIterator").finish() -    } -} - -/// An iterator for the relocations for an [`ElfSection32`](super::ElfSection32). -pub type ElfSectionRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSectionRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>; -/// An iterator for the relocations for an [`ElfSection64`](super::ElfSection64). -pub type ElfSectionRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSectionRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// An iterator for the relocations for an [`ElfSection`](super::ElfSection). -pub struct 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); - -    fn next(&mut self) -> Option<Self::Item> { -        let endian = self.file.endian; -        loop { -            if let Some(ref mut relocations) = self.relocations { -                if let Some(reloc) = relocations.next() { -                    let relocation = -                        parse_relocation(self.file.header, endian, reloc, relocations.is_rel()); -                    return Some((reloc.r_offset(endian).into(), relocation)); -                } -                self.relocations = None; -            } -            self.section_index = SectionIndex(self.file.relocations.get(self.section_index.0)?); -            // The construction of RelocationSections ensures section_index is valid. -            let section = self.file.sections.section(self.section_index).unwrap(); -            match section.sh_type(endian) { -                elf::SHT_REL => { -                    if let Ok(relocations) = section.data_as_array(endian, self.file.data) { -                        self.relocations = Some(ElfRelaIterator::Rel(relocations.iter())); -                    } -                } -                elf::SHT_RELA => { -                    if let Ok(relocations) = section.data_as_array(endian, self.file.data) { -                        self.relocations = Some(ElfRelaIterator::Rela(relocations.iter())); -                    } -                } -                _ => {} -            } -        } -    } -} - -impl<'data, 'file, Elf, R> fmt::Debug for ElfSectionRelocationIterator<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("ElfSectionRelocationIterator").finish() -    } -} - -fn parse_relocation<Elf: FileHeader>( -    header: &Elf, -    endian: Elf::Endian, -    reloc: Elf::Rela, -    implicit_addend: bool, -) -> Relocation { -    let mut encoding = RelocationEncoding::Generic; -    let is_mips64el = header.is_mips64el(endian); -    let (kind, size) = match header.e_machine(endian) { -        elf::EM_AARCH64 => { -            if header.is_type_64() { -                match reloc.r_type(endian, false) { -                    elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64), -                    elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32), -                    elf::R_AARCH64_ABS16 => (RelocationKind::Absolute, 16), -                    elf::R_AARCH64_PREL64 => (RelocationKind::Relative, 64), -                    elf::R_AARCH64_PREL32 => (RelocationKind::Relative, 32), -                    elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16), -                    elf::R_AARCH64_CALL26 => { -                        encoding = RelocationEncoding::AArch64Call; -                        (RelocationKind::PltRelative, 26) -                    } -                    r_type => (RelocationKind::Elf(r_type), 0), -                } -            } else { -                match reloc.r_type(endian, false) { -                    elf::R_AARCH64_P32_ABS32 => (RelocationKind::Absolute, 32), -                    r_type => (RelocationKind::Elf(r_type), 0), -                } -            } -        } -        elf::EM_ARM => match reloc.r_type(endian, false) { -            elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_AVR => match reloc.r_type(endian, false) { -            elf::R_AVR_32 => (RelocationKind::Absolute, 32), -            elf::R_AVR_16 => (RelocationKind::Absolute, 16), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_BPF => match reloc.r_type(endian, false) { -            elf::R_BPF_64_64 => (RelocationKind::Absolute, 64), -            elf::R_BPF_64_32 => (RelocationKind::Absolute, 32), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_CSKY => match reloc.r_type(endian, false) { -            elf::R_CKCORE_ADDR32 => (RelocationKind::Absolute, 32), -            elf::R_CKCORE_PCREL32 => (RelocationKind::Relative, 32), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_386 => match reloc.r_type(endian, false) { -            elf::R_386_32 => (RelocationKind::Absolute, 32), -            elf::R_386_PC32 => (RelocationKind::Relative, 32), -            elf::R_386_GOT32 => (RelocationKind::Got, 32), -            elf::R_386_PLT32 => (RelocationKind::PltRelative, 32), -            elf::R_386_GOTOFF => (RelocationKind::GotBaseOffset, 32), -            elf::R_386_GOTPC => (RelocationKind::GotBaseRelative, 32), -            elf::R_386_16 => (RelocationKind::Absolute, 16), -            elf::R_386_PC16 => (RelocationKind::Relative, 16), -            elf::R_386_8 => (RelocationKind::Absolute, 8), -            elf::R_386_PC8 => (RelocationKind::Relative, 8), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_X86_64 => match reloc.r_type(endian, false) { -            elf::R_X86_64_64 => (RelocationKind::Absolute, 64), -            elf::R_X86_64_PC32 => (RelocationKind::Relative, 32), -            elf::R_X86_64_GOT32 => (RelocationKind::Got, 32), -            elf::R_X86_64_PLT32 => (RelocationKind::PltRelative, 32), -            elf::R_X86_64_GOTPCREL => (RelocationKind::GotRelative, 32), -            elf::R_X86_64_32 => (RelocationKind::Absolute, 32), -            elf::R_X86_64_32S => { -                encoding = RelocationEncoding::X86Signed; -                (RelocationKind::Absolute, 32) -            } -            elf::R_X86_64_16 => (RelocationKind::Absolute, 16), -            elf::R_X86_64_PC16 => (RelocationKind::Relative, 16), -            elf::R_X86_64_8 => (RelocationKind::Absolute, 8), -            elf::R_X86_64_PC8 => (RelocationKind::Relative, 8), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_HEXAGON => match reloc.r_type(endian, false) { -            elf::R_HEX_32 => (RelocationKind::Absolute, 32), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_LOONGARCH => match reloc.r_type(endian, false) { -            elf::R_LARCH_32 => (RelocationKind::Absolute, 32), -            elf::R_LARCH_64 => (RelocationKind::Absolute, 64), -            elf::R_LARCH_32_PCREL => (RelocationKind::Relative, 32), -            elf::R_LARCH_64_PCREL => (RelocationKind::Relative, 64), -            elf::R_LARCH_B16 => { -                encoding = RelocationEncoding::LoongArchBranch; -                (RelocationKind::Relative, 16) -            } -            elf::R_LARCH_B21 => { -                encoding = RelocationEncoding::LoongArchBranch; -                (RelocationKind::Relative, 21) -            } -            elf::R_LARCH_B26 => { -                encoding = RelocationEncoding::LoongArchBranch; -                (RelocationKind::Relative, 26) -            } -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) { -            elf::R_MIPS_16 => (RelocationKind::Absolute, 16), -            elf::R_MIPS_32 => (RelocationKind::Absolute, 32), -            elf::R_MIPS_64 => (RelocationKind::Absolute, 64), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_MSP430 => match reloc.r_type(endian, false) { -            elf::R_MSP430_32 => (RelocationKind::Absolute, 32), -            elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_PPC => match reloc.r_type(endian, false) { -            elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_PPC64 => match reloc.r_type(endian, false) { -            elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32), -            elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_RISCV => match reloc.r_type(endian, false) { -            elf::R_RISCV_32 => (RelocationKind::Absolute, 32), -            elf::R_RISCV_64 => (RelocationKind::Absolute, 64), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_S390 => match reloc.r_type(endian, false) { -            elf::R_390_8 => (RelocationKind::Absolute, 8), -            elf::R_390_16 => (RelocationKind::Absolute, 16), -            elf::R_390_32 => (RelocationKind::Absolute, 32), -            elf::R_390_64 => (RelocationKind::Absolute, 64), -            elf::R_390_PC16 => (RelocationKind::Relative, 16), -            elf::R_390_PC32 => (RelocationKind::Relative, 32), -            elf::R_390_PC64 => (RelocationKind::Relative, 64), -            elf::R_390_PC16DBL => { -                encoding = RelocationEncoding::S390xDbl; -                (RelocationKind::Relative, 16) -            } -            elf::R_390_PC32DBL => { -                encoding = RelocationEncoding::S390xDbl; -                (RelocationKind::Relative, 32) -            } -            elf::R_390_PLT16DBL => { -                encoding = RelocationEncoding::S390xDbl; -                (RelocationKind::PltRelative, 16) -            } -            elf::R_390_PLT32DBL => { -                encoding = RelocationEncoding::S390xDbl; -                (RelocationKind::PltRelative, 32) -            } -            elf::R_390_GOT16 => (RelocationKind::Got, 16), -            elf::R_390_GOT32 => (RelocationKind::Got, 32), -            elf::R_390_GOT64 => (RelocationKind::Got, 64), -            elf::R_390_GOTENT => { -                encoding = RelocationEncoding::S390xDbl; -                (RelocationKind::GotRelative, 32) -            } -            elf::R_390_GOTOFF16 => (RelocationKind::GotBaseOffset, 16), -            elf::R_390_GOTOFF32 => (RelocationKind::GotBaseOffset, 32), -            elf::R_390_GOTOFF64 => (RelocationKind::GotBaseOffset, 64), -            elf::R_390_GOTPC => (RelocationKind::GotBaseRelative, 64), -            elf::R_390_GOTPCDBL => { -                encoding = RelocationEncoding::S390xDbl; -                (RelocationKind::GotBaseRelative, 32) -            } -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_SBF => match reloc.r_type(endian, false) { -            elf::R_SBF_64_64 => (RelocationKind::Absolute, 64), -            elf::R_SBF_64_32 => (RelocationKind::Absolute, 32), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_SHARC => match reloc.r_type(endian, false) { -            elf::R_SHARC_ADDR24_V3 => { -                encoding = RelocationEncoding::SharcTypeA; -                (RelocationKind::Absolute, 24) -            } -            elf::R_SHARC_ADDR32_V3 => { -                encoding = RelocationEncoding::SharcTypeA; -                (RelocationKind::Absolute, 32) -            } -            elf::R_SHARC_ADDR_VAR_V3 => { -                encoding = RelocationEncoding::Generic; -                (RelocationKind::Absolute, 32) -            } -            elf::R_SHARC_PCRSHORT_V3 => { -                encoding = RelocationEncoding::SharcTypeA; -                (RelocationKind::Relative, 6) -            } -            elf::R_SHARC_PCRLONG_V3 => { -                encoding = RelocationEncoding::SharcTypeA; -                (RelocationKind::Relative, 24) -            } -            elf::R_SHARC_DATA6_V3 => { -                encoding = RelocationEncoding::SharcTypeA; -                (RelocationKind::Absolute, 6) -            } -            elf::R_SHARC_DATA16_V3 => { -                encoding = RelocationEncoding::SharcTypeA; -                (RelocationKind::Absolute, 16) -            } -            elf::R_SHARC_DATA6_VISA_V3 => { -                encoding = RelocationEncoding::SharcTypeB; -                (RelocationKind::Absolute, 6) -            } -            elf::R_SHARC_DATA7_VISA_V3 => { -                encoding = RelocationEncoding::SharcTypeB; -                (RelocationKind::Absolute, 7) -            } -            elf::R_SHARC_DATA16_VISA_V3 => { -                encoding = RelocationEncoding::SharcTypeB; -                (RelocationKind::Absolute, 16) -            } -            elf::R_SHARC_PCR6_VISA_V3 => { -                encoding = RelocationEncoding::SharcTypeB; -                (RelocationKind::Relative, 16) -            } -            elf::R_SHARC_ADDR_VAR16_V3 => { -                encoding = RelocationEncoding::Generic; -                (RelocationKind::Absolute, 16) -            } -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => { -            match reloc.r_type(endian, false) { -                elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32), -                elf::R_SPARC_64 | elf::R_SPARC_UA64 => (RelocationKind::Absolute, 64), -                r_type => (RelocationKind::Elf(r_type), 0), -            } -        } -        elf::EM_XTENSA => match reloc.r_type(endian, false) { -            elf::R_XTENSA_32 => (RelocationKind::Absolute, 32), -            elf::R_XTENSA_32_PCREL => (RelocationKind::Relative, 32), -            r_type => (RelocationKind::Elf(r_type), 0), -        }, -        _ => (RelocationKind::Elf(reloc.r_type(endian, false)), 0), -    }; -    let sym = reloc.r_sym(endian, is_mips64el) as usize; -    let target = if sym == 0 { -        RelocationTarget::Absolute -    } else { -        RelocationTarget::Symbol(SymbolIndex(sym)) -    }; -    Relocation { -        kind, -        encoding, -        size, -        target, -        addend: reloc.r_addend(endian).into(), -        implicit_addend, -    } -} - -/// A trait for generic access to [`elf::Rel32`] and [`elf::Rel64`]. -#[allow(missing_docs)] -pub trait Rel: Debug + Pod + Clone { -    type Word: Into<u64>; -    type Sword: Into<i64>; -    type Endian: endian::Endian; - -    fn r_offset(&self, endian: Self::Endian) -> Self::Word; -    fn r_info(&self, endian: Self::Endian) -> Self::Word; -    fn r_sym(&self, endian: Self::Endian) -> u32; -    fn r_type(&self, endian: Self::Endian) -> u32; -} - -impl<Endian: endian::Endian> Rel for elf::Rel32<Endian> { -    type Word = u32; -    type Sword = i32; -    type Endian = Endian; - -    #[inline] -    fn r_offset(&self, endian: Self::Endian) -> Self::Word { -        self.r_offset.get(endian) -    } - -    #[inline] -    fn r_info(&self, endian: Self::Endian) -> Self::Word { -        self.r_info.get(endian) -    } - -    #[inline] -    fn r_sym(&self, endian: Self::Endian) -> u32 { -        self.r_sym(endian) -    } - -    #[inline] -    fn r_type(&self, endian: Self::Endian) -> u32 { -        self.r_type(endian) -    } -} - -impl<Endian: endian::Endian> Rel for elf::Rel64<Endian> { -    type Word = u64; -    type Sword = i64; -    type Endian = Endian; - -    #[inline] -    fn r_offset(&self, endian: Self::Endian) -> Self::Word { -        self.r_offset.get(endian) -    } - -    #[inline] -    fn r_info(&self, endian: Self::Endian) -> Self::Word { -        self.r_info.get(endian) -    } - -    #[inline] -    fn r_sym(&self, endian: Self::Endian) -> u32 { -        self.r_sym(endian) -    } - -    #[inline] -    fn r_type(&self, endian: Self::Endian) -> u32 { -        self.r_type(endian) -    } -} - -/// A trait for generic access to [`elf::Rela32`] and [`elf::Rela64`]. -#[allow(missing_docs)] -pub trait Rela: Debug + Pod + Clone { -    type Word: Into<u64>; -    type Sword: Into<i64>; -    type Endian: endian::Endian; - -    fn r_offset(&self, endian: Self::Endian) -> Self::Word; -    fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word; -    fn r_addend(&self, endian: Self::Endian) -> Self::Sword; -    fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32; -    fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32; -} - -impl<Endian: endian::Endian> Rela for elf::Rela32<Endian> { -    type Word = u32; -    type Sword = i32; -    type Endian = Endian; - -    #[inline] -    fn r_offset(&self, endian: Self::Endian) -> Self::Word { -        self.r_offset.get(endian) -    } - -    #[inline] -    fn r_info(&self, endian: Self::Endian, _is_mips64el: bool) -> Self::Word { -        self.r_info.get(endian) -    } - -    #[inline] -    fn r_addend(&self, endian: Self::Endian) -> Self::Sword { -        self.r_addend.get(endian) -    } - -    #[inline] -    fn r_sym(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 { -        self.r_sym(endian) -    } - -    #[inline] -    fn r_type(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 { -        self.r_type(endian) -    } -} - -impl<Endian: endian::Endian> Rela for elf::Rela64<Endian> { -    type Word = u64; -    type Sword = i64; -    type Endian = Endian; - -    #[inline] -    fn r_offset(&self, endian: Self::Endian) -> Self::Word { -        self.r_offset.get(endian) -    } - -    #[inline] -    fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word { -        self.get_r_info(endian, is_mips64el) -    } - -    #[inline] -    fn r_addend(&self, endian: Self::Endian) -> Self::Sword { -        self.r_addend.get(endian) -    } - -    #[inline] -    fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32 { -        self.r_sym(endian, is_mips64el) -    } - -    #[inline] -    fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32 { -        self.r_type(endian, is_mips64el) -    } -} diff --git a/vendor/object/src/read/elf/section.rs b/vendor/object/src/read/elf/section.rs deleted file mode 100644 index 2b5ae01..0000000 --- a/vendor/object/src/read/elf/section.rs +++ /dev/null @@ -1,1150 +0,0 @@ -use core::fmt::Debug; -use core::{iter, mem, slice, str}; - -use crate::elf; -use crate::endian::{self, Endianness, U32Bytes}; -use crate::pod::Pod; -use crate::read::{ -    self, Bytes, CompressedData, CompressedFileRange, CompressionFormat, Error, ObjectSection, -    ReadError, ReadRef, SectionFlags, SectionIndex, SectionKind, StringTable, -}; - -use super::{ -    AttributesSection, CompressionHeader, ElfFile, ElfSectionRelocationIterator, FileHeader, -    GnuHashTable, HashTable, NoteIterator, RelocationSections, SymbolTable, VerdefIterator, -    VerneedIterator, VersionTable, -}; - -/// 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, Default, Clone, Copy)] -pub struct SectionTable<'data, Elf: FileHeader, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    sections: &'data [Elf::SectionHeader], -    strings: StringTable<'data, R>, -} - -impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> { -    /// Create a new section table. -    #[inline] -    pub fn new(sections: &'data [Elf::SectionHeader], strings: StringTable<'data, R>) -> Self { -        SectionTable { sections, strings } -    } - -    /// Iterate over the section headers. -    #[inline] -    pub fn iter(&self) -> slice::Iter<'data, Elf::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. -    pub fn section(&self, index: SectionIndex) -> read::Result<&'data Elf::SectionHeader> { -        self.sections -            .get(index.0) -            .read_error("Invalid ELF section index") -    } - -    /// Return the section header with the given name. -    /// -    /// Ignores sections with invalid names. -    pub fn section_by_name( -        &self, -        endian: Elf::Endian, -        name: &[u8], -    ) -> Option<(usize, &'data Elf::SectionHeader)> { -        self.sections -            .iter() -            .enumerate() -            .find(|(_, section)| self.section_name(endian, section) == Ok(name)) -    } - -    /// Return the section name for the given section header. -    pub fn section_name( -        &self, -        endian: Elf::Endian, -        section: &'data Elf::SectionHeader, -    ) -> read::Result<&'data [u8]> { -        section.name(endian, self.strings) -    } - -    /// Return the string table at the given section index. -    /// -    /// Returns an error if the section is not a string table. -    #[inline] -    pub fn strings( -        &self, -        endian: Elf::Endian, -        data: R, -        index: SectionIndex, -    ) -> read::Result<StringTable<'data, R>> { -        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] -    pub fn 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); - -        let (index, section) = match self -            .iter() -            .enumerate() -            .find(|s| s.1.sh_type(endian) == sh_type) -        { -            Some(s) => s, -            None => return Ok(SymbolTable::default()), -        }; - -        SymbolTable::parse(endian, data, self, SectionIndex(index), section) -    } - -    /// Return the symbol table at the given section index. -    /// -    /// Returns an error if the section is not a symbol table. -    #[inline] -    pub fn 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] -    pub fn 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. -    pub fn dynamic( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<(&'data [Elf::Dyn], SectionIndex)>> { -        for section in self.sections { -            if let 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. -    pub fn hash_header( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<&'data elf::HashHeader<Elf::Endian>>> { -        for section in self.sections { -            if let 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. -    pub fn hash( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<(HashTable<'data, Elf>, SectionIndex)>> { -        for section in self.sections { -            if let 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. -    pub fn gnu_hash_header( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<&'data elf::GnuHashHeader<Elf::Endian>>> { -        for section in self.sections { -            if let 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. -    pub fn gnu_hash( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<(GnuHashTable<'data, Elf>, SectionIndex)>> { -        for section in self.sections { -            if let 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. -    pub fn gnu_versym( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<(&'data [elf::Versym<Elf::Endian>], SectionIndex)>> { -        for section in self.sections { -            if let 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. -    pub fn gnu_verdef( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<(VerdefIterator<'data, Elf>, SectionIndex)>> { -        for section in self.sections { -            if let 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. -    pub fn gnu_verneed( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<(VerneedIterator<'data, Elf>, SectionIndex)>> { -        for section in self.sections { -            if let 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. -    pub fn versions( -        &self, -        endian: Elf::Endian, -        data: R, -    ) -> read::Result<Option<VersionTable<'data, Elf>>> { -        let (versyms, link) = match self.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). -pub type 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). -pub type 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)] -pub struct ElfSectionIterator<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file ElfFile<'data, Elf, R>, -    pub(super) iter: iter::Enumerate<slice::Iter<'data, Elf::SectionHeader>>, -} - -impl<'data, 'file, Elf, R> Iterator for ElfSectionIterator<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    type Item = ElfSection<'data, 'file, Elf, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|(index, section)| ElfSection { -            index: SectionIndex(index), -            file: self.file, -            section, -        }) -    } -} - -/// A section in an [`ElfFile32`](super::ElfFile32). -pub type ElfSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSection<'data, 'file, elf::FileHeader32<Endian>, R>; -/// A section in an [`ElfFile64`](super::ElfFile64). -pub type 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)] -pub struct 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> { -    fn bytes(&self) -> read::Result<&'data [u8]> { -        self.section -            .data(self.file.endian, self.file.data) -            .read_error("Invalid ELF section size or offset") -    } - -    fn maybe_compressed(&self) -> read::Result<Option<CompressedFileRange>> { -        let endian = self.file.endian; -        if let Some((header, offset, compressed_size)) = -            self.section.compression(endian, self.file.data)? -        { -            let format = match header.ch_type(endian) { -                elf::ELFCOMPRESS_ZLIB => CompressionFormat::Zlib, -                elf::ELFCOMPRESS_ZSTD => CompressionFormat::Zstandard, -                _ => return Err(Error("Unsupported ELF compression type")), -            }; -            let uncompressed_size = header.ch_size(endian).into(); -            Ok(Some(CompressedFileRange { -                format, -                offset, -                compressed_size, -                uncompressed_size, -            })) -        } else { -            Ok(None) -        } -    } - -    /// Try GNU-style "ZLIB" header decompression. -    fn maybe_compressed_gnu(&self) -> read::Result<Option<CompressedFileRange>> { -        let name = match self.name() { -            Ok(name) => name, -            // I think it's ok to ignore this error? -            Err(_) => return Ok(None), -        }; -        if !name.starts_with(".zdebug_") { -            return Ok(None); -        } -        let (section_offset, section_size) = self -            .section -            .file_range(self.file.endian) -            .read_error("Invalid ELF GNU compressed section type")?; -        let mut offset = section_offset; -        let data = self.file.data; -        // Assume ZLIB-style uncompressed data is no more than 4GB to avoid accidentally -        // huge allocations. This also reduces the chance of accidentally matching on a -        // .debug_str that happens to start with "ZLIB". -        if data -            .read_bytes(&mut offset, 8) -            .read_error("ELF GNU compressed section is too short")? -            != b"ZLIB\0\0\0\0" -        { -            return Err(Error("Invalid ELF GNU compressed section header")); -        } -        let uncompressed_size = data -            .read::<U32Bytes<_>>(&mut offset) -            .read_error("ELF GNU compressed section is too short")? -            .get(endian::BigEndian) -            .into(); -        let compressed_size = section_size -            .checked_sub(offset - section_offset) -            .read_error("ELF GNU compressed section is too short")?; -        Ok(Some(CompressedFileRange { -            format: CompressionFormat::Zlib, -            offset, -            compressed_size, -            uncompressed_size, -        })) -    } -} - -impl<'data, 'file, Elf, R> read::private::Sealed for ElfSection<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Elf, R> ObjectSection<'data> for ElfSection<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    type RelocationIterator = ElfSectionRelocationIterator<'data, 'file, Elf, R>; - -    #[inline] -    fn index(&self) -> SectionIndex { -        self.index -    } - -    #[inline] -    fn address(&self) -> u64 { -        self.section.sh_addr(self.file.endian).into() -    } - -    #[inline] -    fn size(&self) -> u64 { -        self.section.sh_size(self.file.endian).into() -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.section.sh_addralign(self.file.endian).into() -    } - -    #[inline] -    fn file_range(&self) -> Option<(u64, u64)> { -        self.section.file_range(self.file.endian) -    } - -    #[inline] -    fn data(&self) -> read::Result<&'data [u8]> { -        self.bytes() -    } - -    fn data_range(&self, address: u64, size: u64) -> read::Result<Option<&'data [u8]>> { -        Ok(read::util::data_range( -            self.bytes()?, -            self.address(), -            address, -            size, -        )) -    } - -    fn compressed_file_range(&self) -> read::Result<CompressedFileRange> { -        Ok(if let Some(data) = self.maybe_compressed()? { -            data -        } else if let Some(data) = self.maybe_compressed_gnu()? { -            data -        } else { -            CompressedFileRange::none(self.file_range()) -        }) -    } - -    fn compressed_data(&self) -> read::Result<CompressedData<'data>> { -        self.compressed_file_range()?.data(self.file.data) -    } - -    fn name_bytes(&self) -> read::Result<&[u8]> { -        self.file -            .sections -            .section_name(self.file.endian, self.section) -    } - -    fn name(&self) -> read::Result<&str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 ELF section name") -    } - -    #[inline] -    fn segment_name_bytes(&self) -> read::Result<Option<&[u8]>> { -        Ok(None) -    } - -    #[inline] -    fn segment_name(&self) -> read::Result<Option<&str>> { -        Ok(None) -    } - -    fn kind(&self) -> SectionKind { -        let flags = self.section.sh_flags(self.file.endian).into(); -        let sh_type = self.section.sh_type(self.file.endian); -        match sh_type { -            elf::SHT_PROGBITS => { -                if flags & u64::from(elf::SHF_ALLOC) != 0 { -                    if flags & u64::from(elf::SHF_EXECINSTR) != 0 { -                        SectionKind::Text -                    } else if flags & u64::from(elf::SHF_TLS) != 0 { -                        SectionKind::Tls -                    } else if flags & u64::from(elf::SHF_WRITE) != 0 { -                        SectionKind::Data -                    } else if flags & u64::from(elf::SHF_STRINGS) != 0 { -                        SectionKind::ReadOnlyString -                    } else { -                        SectionKind::ReadOnlyData -                    } -                } else if flags & u64::from(elf::SHF_STRINGS) != 0 { -                    SectionKind::OtherString -                } else { -                    SectionKind::Other -                } -            } -            elf::SHT_NOBITS => { -                if flags & u64::from(elf::SHF_TLS) != 0 { -                    SectionKind::UninitializedTls -                } else { -                    SectionKind::UninitializedData -                } -            } -            elf::SHT_NOTE => SectionKind::Note, -            elf::SHT_NULL -            | elf::SHT_SYMTAB -            | elf::SHT_STRTAB -            | elf::SHT_RELA -            | elf::SHT_HASH -            | elf::SHT_DYNAMIC -            | elf::SHT_REL -            | elf::SHT_DYNSYM -            | elf::SHT_GROUP => SectionKind::Metadata, -            _ => SectionKind::Elf(sh_type), -        } -    } - -    fn relocations(&self) -> ElfSectionRelocationIterator<'data, 'file, Elf, R> { -        ElfSectionRelocationIterator { -            section_index: self.index, -            file: self.file, -            relocations: None, -        } -    } - -    fn flags(&self) -> SectionFlags { -        SectionFlags::Elf { -            sh_flags: self.section.sh_flags(self.file.endian).into(), -        } -    } -} - -/// A trait for generic access to [`elf::SectionHeader32`] and [`elf::SectionHeader64`]. -#[allow(missing_docs)] -pub trait SectionHeader: Debug + Pod { -    type Elf: FileHeader<SectionHeader = Self, Endian = Self::Endian, Word = Self::Word>; -    type Word: Into<u64>; -    type Endian: endian::Endian; - -    fn sh_name(&self, endian: Self::Endian) -> u32; -    fn sh_type(&self, endian: Self::Endian) -> u32; -    fn sh_flags(&self, endian: Self::Endian) -> Self::Word; -    fn sh_addr(&self, endian: Self::Endian) -> Self::Word; -    fn sh_offset(&self, endian: Self::Endian) -> Self::Word; -    fn sh_size(&self, endian: Self::Endian) -> Self::Word; -    fn sh_link(&self, endian: Self::Endian) -> u32; -    fn sh_info(&self, endian: Self::Endian) -> u32; -    fn sh_addralign(&self, endian: Self::Endian) -> Self::Word; -    fn sh_entsize(&self, endian: Self::Endian) -> Self::Word; - -    /// 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") -    } - -    /// 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)> { -        if self.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]> { -        if let 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]> { -        let mut data = self.data(endian, data).map(Bytes)?; -        data.read_slice(data.len() / mem::size_of::<T>()) -            .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>>> { -        if self.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)>> { -        if self.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")?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((rel, link))) -    } - -    /// 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)>> { -        if self.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")?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((rela, link))) -    } - -    /// 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)>> { -        if self.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")?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((dynamic, link))) -    } - -    /// 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>>> { -        if self.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>])>> { -        if self.sh_type(endian) != elf::SHT_GROUP { -            return Ok(None); -        } -        let mut data = self -            .data(endian, data) -            .read_error("Invalid ELF group section offset or size") -            .map(Bytes)?; -        let flag = data -            .read::<U32Bytes<_>>() -            .read_error("Invalid ELF group section offset or size")? -            .get(endian); -        let count = data.len() / mem::size_of::<U32Bytes<Self::Endian>>(); -        let sections = data -            .read_slice(count) -            .read_error("Invalid ELF group section offset or size")?; -        Ok(Some((flag, 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>>> { -        if self.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)>> { -        if self.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)?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((hash, link))) -    } - -    /// 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>>> { -        if self.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)>> { -        if self.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)?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((hash, link))) -    } - -    /// 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)>> { -        if self.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")?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((versym, link))) -    } - -    /// 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)>> { -        if self.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")?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((VerdefIterator::new(endian, verdef), link))) -    } - -    /// 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)>> { -        if self.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")?; -        let link = SectionIndex(self.sh_link(endian) as usize); -        Ok(Some((VerneedIterator::new(endian, verneed), link))) -    } - -    /// 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>>> { -        if self.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")?; -        let mut 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; - -    #[inline] -    fn sh_name(&self, endian: Self::Endian) -> u32 { -        self.sh_name.get(endian) -    } - -    #[inline] -    fn sh_type(&self, endian: Self::Endian) -> u32 { -        self.sh_type.get(endian) -    } - -    #[inline] -    fn sh_flags(&self, endian: Self::Endian) -> Self::Word { -        self.sh_flags.get(endian) -    } - -    #[inline] -    fn sh_addr(&self, endian: Self::Endian) -> Self::Word { -        self.sh_addr.get(endian) -    } - -    #[inline] -    fn sh_offset(&self, endian: Self::Endian) -> Self::Word { -        self.sh_offset.get(endian) -    } - -    #[inline] -    fn sh_size(&self, endian: Self::Endian) -> Self::Word { -        self.sh_size.get(endian) -    } - -    #[inline] -    fn sh_link(&self, endian: Self::Endian) -> u32 { -        self.sh_link.get(endian) -    } - -    #[inline] -    fn sh_info(&self, endian: Self::Endian) -> u32 { -        self.sh_info.get(endian) -    } - -    #[inline] -    fn sh_addralign(&self, endian: Self::Endian) -> Self::Word { -        self.sh_addralign.get(endian) -    } - -    #[inline] -    fn sh_entsize(&self, endian: Self::Endian) -> Self::Word { -        self.sh_entsize.get(endian) -    } -} - -impl<Endian: endian::Endian> SectionHeader for elf::SectionHeader64<Endian> { -    type Word = u64; -    type Endian = Endian; -    type Elf = elf::FileHeader64<Endian>; - -    #[inline] -    fn sh_name(&self, endian: Self::Endian) -> u32 { -        self.sh_name.get(endian) -    } - -    #[inline] -    fn sh_type(&self, endian: Self::Endian) -> u32 { -        self.sh_type.get(endian) -    } - -    #[inline] -    fn sh_flags(&self, endian: Self::Endian) -> Self::Word { -        self.sh_flags.get(endian) -    } - -    #[inline] -    fn sh_addr(&self, endian: Self::Endian) -> Self::Word { -        self.sh_addr.get(endian) -    } - -    #[inline] -    fn sh_offset(&self, endian: Self::Endian) -> Self::Word { -        self.sh_offset.get(endian) -    } - -    #[inline] -    fn sh_size(&self, endian: Self::Endian) -> Self::Word { -        self.sh_size.get(endian) -    } - -    #[inline] -    fn sh_link(&self, endian: Self::Endian) -> u32 { -        self.sh_link.get(endian) -    } - -    #[inline] -    fn sh_info(&self, endian: Self::Endian) -> u32 { -        self.sh_info.get(endian) -    } - -    #[inline] -    fn sh_addralign(&self, endian: Self::Endian) -> Self::Word { -        self.sh_addralign.get(endian) -    } - -    #[inline] -    fn sh_entsize(&self, endian: Self::Endian) -> Self::Word { -        self.sh_entsize.get(endian) -    } -} diff --git a/vendor/object/src/read/elf/segment.rs b/vendor/object/src/read/elf/segment.rs deleted file mode 100644 index 957117a..0000000 --- a/vendor/object/src/read/elf/segment.rs +++ /dev/null @@ -1,334 +0,0 @@ -use core::fmt::Debug; -use core::{mem, slice, str}; - -use crate::elf; -use crate::endian::{self, Endianness}; -use crate::pod::Pod; -use crate::read::{self, Bytes, ObjectSegment, ReadError, ReadRef, SegmentFlags}; - -use super::{ElfFile, FileHeader, NoteIterator}; - -/// An iterator for the segments in an [`ElfFile32`](super::ElfFile32). -pub type ElfSegmentIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSegmentIterator<'data, 'file, elf::FileHeader32<Endian>, R>; -/// An iterator for the segments in an [`ElfFile64`](super::ElfFile64). -pub type ElfSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSegmentIterator<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// An iterator for the segments in an [`ElfFile`]. -#[derive(Debug)] -pub struct ElfSegmentIterator<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file ElfFile<'data, Elf, R>, -    pub(super) iter: slice::Iter<'data, Elf::ProgramHeader>, -} - -impl<'data, 'file, Elf, R> Iterator for ElfSegmentIterator<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    type Item = ElfSegment<'data, 'file, Elf, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        for segment in self.iter.by_ref() { -            if segment.p_type(self.file.endian) == elf::PT_LOAD { -                return Some(ElfSegment { -                    file: self.file, -                    segment, -                }); -            } -        } -        None -    } -} - -/// A segment in an [`ElfFile32`](super::ElfFile32). -pub type ElfSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSegment<'data, 'file, elf::FileHeader32<Endian>, R>; -/// A segment in an [`ElfFile64`](super::ElfFile64). -pub type ElfSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSegment<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// A segment in an [`ElfFile`]. -/// -/// Most functionality is provided by the [`ObjectSegment`] trait implementation. -#[derive(Debug)] -pub struct ElfSegment<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file ElfFile<'data, Elf, R>, -    pub(super) segment: &'data Elf::ProgramHeader, -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSegment<'data, 'file, Elf, R> { -    fn bytes(&self) -> read::Result<&'data [u8]> { -        self.segment -            .data(self.file.endian, self.file.data) -            .read_error("Invalid ELF segment size or offset") -    } -} - -impl<'data, 'file, Elf, R> read::private::Sealed for ElfSegment<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Elf, R> ObjectSegment<'data> for ElfSegment<'data, 'file, Elf, R> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    #[inline] -    fn address(&self) -> u64 { -        self.segment.p_vaddr(self.file.endian).into() -    } - -    #[inline] -    fn size(&self) -> u64 { -        self.segment.p_memsz(self.file.endian).into() -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.segment.p_align(self.file.endian).into() -    } - -    #[inline] -    fn file_range(&self) -> (u64, u64) { -        self.segment.file_range(self.file.endian) -    } - -    #[inline] -    fn data(&self) -> read::Result<&'data [u8]> { -        self.bytes() -    } - -    fn data_range(&self, address: u64, size: u64) -> read::Result<Option<&'data [u8]>> { -        Ok(read::util::data_range( -            self.bytes()?, -            self.address(), -            address, -            size, -        )) -    } - -    #[inline] -    fn name_bytes(&self) -> read::Result<Option<&[u8]>> { -        Ok(None) -    } - -    #[inline] -    fn name(&self) -> read::Result<Option<&str>> { -        Ok(None) -    } - -    #[inline] -    fn flags(&self) -> SegmentFlags { -        let p_flags = self.segment.p_flags(self.file.endian); -        SegmentFlags::Elf { p_flags } -    } -} - -/// A trait for generic access to [`elf::ProgramHeader32`] and [`elf::ProgramHeader64`]. -#[allow(missing_docs)] -pub trait ProgramHeader: Debug + Pod { -    type Elf: FileHeader<ProgramHeader = Self, Endian = Self::Endian, Word = Self::Word>; -    type Word: Into<u64>; -    type Endian: endian::Endian; - -    fn p_type(&self, endian: Self::Endian) -> u32; -    fn p_flags(&self, endian: Self::Endian) -> u32; -    fn p_offset(&self, endian: Self::Endian) -> Self::Word; -    fn p_vaddr(&self, endian: Self::Endian) -> Self::Word; -    fn p_paddr(&self, endian: Self::Endian) -> Self::Word; -    fn p_filesz(&self, endian: Self::Endian) -> Self::Word; -    fn p_memsz(&self, endian: Self::Endian) -> Self::Word; -    fn p_align(&self, endian: Self::Endian) -> Self::Word; - -    /// Return the offset and size of the segment in the file. -    fn file_range(&self, endian: Self::Endian) -> (u64, u64) { -        (self.p_offset(endian).into(), self.p_filesz(endian).into()) -    } - -    /// Return the segment data. -    /// -    /// Returns `Err` for invalid values. -    fn data<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> Result<&'data [u8], ()> { -        let (offset, size) = self.file_range(endian); -        data.read_bytes_at(offset, size) -    } - -    /// Return the segment data as a slice of the given type. -    /// -    /// Allows padding at the end of the data. -    /// Returns `Ok(&[])` if the segment 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, -    ) -> Result<&'data [T], ()> { -        let mut data = self.data(endian, data).map(Bytes)?; -        data.read_slice(data.len() / mem::size_of::<T>()) -    } - -    /// Return the segment data in the given virtual address range -    /// -    /// Returns `Ok(None)` if the segment does not contain the address. -    /// Returns `Err` for invalid values. -    fn data_range<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -        address: u64, -        size: u64, -    ) -> Result<Option<&'data [u8]>, ()> { -        Ok(read::util::data_range( -            self.data(endian, data)?, -            self.p_vaddr(endian).into(), -            address, -            size, -        )) -    } - -    /// Return entries in a dynamic segment. -    /// -    /// Returns `Ok(None)` if the segment is not `PT_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]>> { -        if self.p_type(endian) != elf::PT_DYNAMIC { -            return Ok(None); -        } -        let dynamic = self -            .data_as_array(endian, data) -            .read_error("Invalid ELF dynamic segment offset or size")?; -        Ok(Some(dynamic)) -    } - -    /// Return a note iterator for the segment data. -    /// -    /// Returns `Ok(None)` if the segment 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>>> { -        if self.p_type(endian) != elf::PT_NOTE { -            return Ok(None); -        } -        let data = self -            .data(endian, data) -            .read_error("Invalid ELF note segment offset or size")?; -        let notes = NoteIterator::new(endian, self.p_align(endian), data)?; -        Ok(Some(notes)) -    } -} - -impl<Endian: endian::Endian> ProgramHeader for elf::ProgramHeader32<Endian> { -    type Word = u32; -    type Endian = Endian; -    type Elf = elf::FileHeader32<Endian>; - -    #[inline] -    fn p_type(&self, endian: Self::Endian) -> u32 { -        self.p_type.get(endian) -    } - -    #[inline] -    fn p_flags(&self, endian: Self::Endian) -> u32 { -        self.p_flags.get(endian) -    } - -    #[inline] -    fn p_offset(&self, endian: Self::Endian) -> Self::Word { -        self.p_offset.get(endian) -    } - -    #[inline] -    fn p_vaddr(&self, endian: Self::Endian) -> Self::Word { -        self.p_vaddr.get(endian) -    } - -    #[inline] -    fn p_paddr(&self, endian: Self::Endian) -> Self::Word { -        self.p_paddr.get(endian) -    } - -    #[inline] -    fn p_filesz(&self, endian: Self::Endian) -> Self::Word { -        self.p_filesz.get(endian) -    } - -    #[inline] -    fn p_memsz(&self, endian: Self::Endian) -> Self::Word { -        self.p_memsz.get(endian) -    } - -    #[inline] -    fn p_align(&self, endian: Self::Endian) -> Self::Word { -        self.p_align.get(endian) -    } -} - -impl<Endian: endian::Endian> ProgramHeader for elf::ProgramHeader64<Endian> { -    type Word = u64; -    type Endian = Endian; -    type Elf = elf::FileHeader64<Endian>; - -    #[inline] -    fn p_type(&self, endian: Self::Endian) -> u32 { -        self.p_type.get(endian) -    } - -    #[inline] -    fn p_flags(&self, endian: Self::Endian) -> u32 { -        self.p_flags.get(endian) -    } - -    #[inline] -    fn p_offset(&self, endian: Self::Endian) -> Self::Word { -        self.p_offset.get(endian) -    } - -    #[inline] -    fn p_vaddr(&self, endian: Self::Endian) -> Self::Word { -        self.p_vaddr.get(endian) -    } - -    #[inline] -    fn p_paddr(&self, endian: Self::Endian) -> Self::Word { -        self.p_paddr.get(endian) -    } - -    #[inline] -    fn p_filesz(&self, endian: Self::Endian) -> Self::Word { -        self.p_filesz.get(endian) -    } - -    #[inline] -    fn p_memsz(&self, endian: Self::Endian) -> Self::Word { -        self.p_memsz.get(endian) -    } - -    #[inline] -    fn p_align(&self, endian: Self::Endian) -> Self::Word { -        self.p_align.get(endian) -    } -} diff --git a/vendor/object/src/read/elf/symbol.rs b/vendor/object/src/read/elf/symbol.rs deleted file mode 100644 index 8ba707f..0000000 --- a/vendor/object/src/read/elf/symbol.rs +++ /dev/null @@ -1,595 +0,0 @@ -use alloc::fmt; -use alloc::vec::Vec; -use core::fmt::Debug; -use core::slice; -use core::str; - -use crate::endian::{self, Endianness}; -use crate::pod::Pod; -use crate::read::util::StringTable; -use crate::read::{ -    self, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, SectionIndex, SymbolFlags, -    SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry, SymbolScope, SymbolSection, -}; -use crate::{elf, U32}; - -use super::{FileHeader, SectionHeader, SectionTable}; - -/// A table of symbol entries in an ELF file. -/// -/// Also includes the string table used for the symbol names. -/// -/// Returned by [`SectionTable::symbols`]. -#[derive(Debug, Clone, Copy)] -pub struct SymbolTable<'data, Elf: FileHeader, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    section: SectionIndex, -    string_section: SectionIndex, -    shndx_section: SectionIndex, -    symbols: &'data [Elf::Sym], -    strings: StringTable<'data, R>, -    shndx: &'data [U32<Elf::Endian>], -} - -impl<'data, Elf: FileHeader, R: ReadRef<'data>> Default for SymbolTable<'data, Elf, R> { -    fn default() -> Self { -        SymbolTable { -            section: SectionIndex(0), -            string_section: SectionIndex(0), -            shndx_section: SectionIndex(0), -            symbols: &[], -            strings: Default::default(), -            shndx: &[], -        } -    } -} - -impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> { -    /// Parse the given symbol table section. -    pub fn parse( -        endian: Elf::Endian, -        data: R, -        sections: &SectionTable<'data, Elf, R>, -        section_index: SectionIndex, -        section: &Elf::SectionHeader, -    ) -> read::Result<SymbolTable<'data, Elf, R>> { -        debug_assert!( -            section.sh_type(endian) == elf::SHT_DYNSYM -                || section.sh_type(endian) == elf::SHT_SYMTAB -        ); - -        let symbols = section -            .data_as_array(endian, data) -            .read_error("Invalid ELF symbol table data")?; - -        let link = SectionIndex(section.sh_link(endian) as usize); -        let strings = sections.strings(endian, data, link)?; - -        let mut shndx_section = SectionIndex(0); -        let mut shndx = &[][..]; -        for (i, s) in sections.iter().enumerate() { -            if s.sh_type(endian) == elf::SHT_SYMTAB_SHNDX -                && s.sh_link(endian) as usize == section_index.0 -            { -                shndx_section = SectionIndex(i); -                shndx = s -                    .data_as_array(endian, data) -                    .read_error("Invalid ELF symtab_shndx data")?; -            } -        } - -        Ok(SymbolTable { -            section: section_index, -            string_section: link, -            symbols, -            strings, -            shndx, -            shndx_section, -        }) -    } - -    /// Return the section index of this symbol table. -    #[inline] -    pub fn section(&self) -> SectionIndex { -        self.section -    } - -    /// Return the section index of the shndx table. -    #[inline] -    pub fn shndx_section(&self) -> SectionIndex { -        self.shndx_section -    } - -    /// Return the section index of the linked string table. -    #[inline] -    pub fn string_section(&self) -> SectionIndex { -        self.string_section -    } - -    /// Return the string table used for the symbol names. -    #[inline] -    pub fn strings(&self) -> StringTable<'data, R> { -        self.strings -    } - -    /// Return the symbol table. -    #[inline] -    pub fn symbols(&self) -> &'data [Elf::Sym] { -        self.symbols -    } - -    /// Iterate over the symbols. -    #[inline] -    pub fn iter(&self) -> slice::Iter<'data, Elf::Sym> { -        self.symbols.iter() -    } - -    /// Return true if the symbol table is empty. -    #[inline] -    pub fn is_empty(&self) -> bool { -        self.symbols.is_empty() -    } - -    /// The number of symbols. -    #[inline] -    pub fn len(&self) -> usize { -        self.symbols.len() -    } - -    /// Return the symbol at the given index. -    pub fn symbol(&self, index: usize) -> read::Result<&'data Elf::Sym> { -        self.symbols -            .get(index) -            .read_error("Invalid ELF symbol index") -    } - -    /// Return the extended section index for the given symbol if present. -    #[inline] -    pub fn shndx(&self, endian: Elf::Endian, index: usize) -> Option<u32> { -        self.shndx.get(index).map(|x| x.get(endian)) -    } - -    /// Return the section index for the given symbol. -    /// -    /// This uses the extended section index if present. -    pub fn symbol_section( -        &self, -        endian: Elf::Endian, -        symbol: &'data Elf::Sym, -        index: usize, -    ) -> read::Result<Option<SectionIndex>> { -        match symbol.st_shndx(endian) { -            elf::SHN_UNDEF => Ok(None), -            elf::SHN_XINDEX => self -                .shndx(endian, index) -                .read_error("Missing ELF symbol extended index") -                .map(|index| Some(SectionIndex(index as usize))), -            shndx if shndx < elf::SHN_LORESERVE => Ok(Some(SectionIndex(shndx.into()))), -            _ => Ok(None), -        } -    } - -    /// Return the symbol name for the given symbol. -    pub fn symbol_name( -        &self, -        endian: Elf::Endian, -        symbol: &'data Elf::Sym, -    ) -> read::Result<&'data [u8]> { -        symbol.name(endian, self.strings) -    } - -    /// Construct a map from addresses to a user-defined map entry. -    pub fn map<Entry: SymbolMapEntry, F: Fn(&'data Elf::Sym) -> Option<Entry>>( -        &self, -        endian: Elf::Endian, -        f: F, -    ) -> SymbolMap<Entry> { -        let mut symbols = Vec::with_capacity(self.symbols.len()); -        for symbol in self.symbols { -            if !symbol.is_definition(endian) { -                continue; -            } -            if let Some(entry) = f(symbol) { -                symbols.push(entry); -            } -        } -        SymbolMap::new(symbols) -    } -} - -/// A symbol table in an [`ElfFile32`](super::ElfFile32). -pub type ElfSymbolTable32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSymbolTable<'data, 'file, elf::FileHeader32<Endian>, R>; -/// A symbol table in an [`ElfFile32`](super::ElfFile32). -pub type ElfSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSymbolTable<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// A symbol table in an [`ElfFile`](super::ElfFile). -#[derive(Debug, Clone, Copy)] -pub struct ElfSymbolTable<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) endian: Elf::Endian, -    pub(super) symbols: &'file SymbolTable<'data, Elf, R>, -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> read::private::Sealed -    for ElfSymbolTable<'data, 'file, Elf, R> -{ -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data> -    for ElfSymbolTable<'data, 'file, Elf, R> -{ -    type Symbol = ElfSymbol<'data, 'file, Elf, R>; -    type SymbolIterator = ElfSymbolIterator<'data, 'file, Elf, R>; - -    fn symbols(&self) -> Self::SymbolIterator { -        ElfSymbolIterator { -            endian: self.endian, -            symbols: self.symbols, -            index: 0, -        } -    } - -    fn symbol_by_index(&self, index: SymbolIndex) -> read::Result<Self::Symbol> { -        let symbol = self.symbols.symbol(index.0)?; -        Ok(ElfSymbol { -            endian: self.endian, -            symbols: self.symbols, -            index, -            symbol, -        }) -    } -} - -/// An iterator for the symbols in an [`ElfFile32`](super::ElfFile32). -pub type ElfSymbolIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSymbolIterator<'data, 'file, elf::FileHeader32<Endian>, R>; -/// An iterator for the symbols in an [`ElfFile64`](super::ElfFile64). -pub type ElfSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSymbolIterator<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// An iterator for the symbols in an [`ElfFile`](super::ElfFile). -pub struct ElfSymbolIterator<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) endian: Elf::Endian, -    pub(super) symbols: &'file SymbolTable<'data, Elf, R>, -    pub(super) index: usize, -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> fmt::Debug -    for ElfSymbolIterator<'data, 'file, Elf, R> -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("ElfSymbolIterator").finish() -    } -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> Iterator -    for ElfSymbolIterator<'data, 'file, Elf, R> -{ -    type Item = ElfSymbol<'data, 'file, Elf, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        let index = self.index; -        let symbol = self.symbols.symbols.get(index)?; -        self.index += 1; -        Some(ElfSymbol { -            endian: self.endian, -            symbols: self.symbols, -            index: SymbolIndex(index), -            symbol, -        }) -    } -} - -/// A symbol in an [`ElfFile32`](super::ElfFile32). -pub type ElfSymbol32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSymbol<'data, 'file, elf::FileHeader32<Endian>, R>; -/// A symbol in an [`ElfFile64`](super::ElfFile64). -pub type ElfSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    ElfSymbol<'data, 'file, elf::FileHeader64<Endian>, R>; - -/// A symbol in an [`ElfFile`](super::ElfFile). -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -#[derive(Debug, Clone, Copy)] -pub struct ElfSymbol<'data, 'file, Elf, R = &'data [u8]> -where -    Elf: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) endian: Elf::Endian, -    pub(super) symbols: &'file SymbolTable<'data, Elf, R>, -    pub(super) index: SymbolIndex, -    pub(super) symbol: &'data Elf::Sym, -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSymbol<'data, 'file, Elf, R> { -    /// Return a reference to the raw symbol structure. -    #[inline] -    pub fn raw_symbol(&self) -> &'data Elf::Sym { -        self.symbol -    } -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> read::private::Sealed -    for ElfSymbol<'data, 'file, Elf, R> -{ -} - -impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> -    for ElfSymbol<'data, 'file, Elf, R> -{ -    #[inline] -    fn index(&self) -> SymbolIndex { -        self.index -    } - -    fn name_bytes(&self) -> read::Result<&'data [u8]> { -        self.symbol.name(self.endian, self.symbols.strings()) -    } - -    fn name(&self) -> read::Result<&'data str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 ELF symbol name") -    } - -    #[inline] -    fn address(&self) -> u64 { -        self.symbol.st_value(self.endian).into() -    } - -    #[inline] -    fn size(&self) -> u64 { -        self.symbol.st_size(self.endian).into() -    } - -    fn kind(&self) -> SymbolKind { -        match self.symbol.st_type() { -            elf::STT_NOTYPE if self.index.0 == 0 => SymbolKind::Null, -            elf::STT_NOTYPE => SymbolKind::Unknown, -            elf::STT_OBJECT | elf::STT_COMMON => SymbolKind::Data, -            elf::STT_FUNC | elf::STT_GNU_IFUNC => SymbolKind::Text, -            elf::STT_SECTION => SymbolKind::Section, -            elf::STT_FILE => SymbolKind::File, -            elf::STT_TLS => SymbolKind::Tls, -            _ => SymbolKind::Unknown, -        } -    } - -    fn section(&self) -> SymbolSection { -        match self.symbol.st_shndx(self.endian) { -            elf::SHN_UNDEF => SymbolSection::Undefined, -            elf::SHN_ABS => { -                if self.symbol.st_type() == elf::STT_FILE { -                    SymbolSection::None -                } else { -                    SymbolSection::Absolute -                } -            } -            elf::SHN_COMMON => SymbolSection::Common, -            elf::SHN_XINDEX => match self.symbols.shndx(self.endian, self.index.0) { -                Some(index) => SymbolSection::Section(SectionIndex(index as usize)), -                None => SymbolSection::Unknown, -            }, -            index if index < elf::SHN_LORESERVE => { -                SymbolSection::Section(SectionIndex(index as usize)) -            } -            _ => SymbolSection::Unknown, -        } -    } - -    #[inline] -    fn is_undefined(&self) -> bool { -        self.symbol.st_shndx(self.endian) == elf::SHN_UNDEF -    } - -    #[inline] -    fn is_definition(&self) -> bool { -        self.symbol.is_definition(self.endian) -    } - -    #[inline] -    fn is_common(&self) -> bool { -        self.symbol.st_shndx(self.endian) == elf::SHN_COMMON -    } - -    #[inline] -    fn is_weak(&self) -> bool { -        self.symbol.st_bind() == elf::STB_WEAK -    } - -    fn scope(&self) -> SymbolScope { -        if self.symbol.st_shndx(self.endian) == elf::SHN_UNDEF { -            SymbolScope::Unknown -        } else { -            match self.symbol.st_bind() { -                elf::STB_LOCAL => SymbolScope::Compilation, -                elf::STB_GLOBAL | elf::STB_WEAK => { -                    if self.symbol.st_visibility() == elf::STV_HIDDEN { -                        SymbolScope::Linkage -                    } else { -                        SymbolScope::Dynamic -                    } -                } -                _ => SymbolScope::Unknown, -            } -        } -    } - -    #[inline] -    fn is_global(&self) -> bool { -        self.symbol.st_bind() != elf::STB_LOCAL -    } - -    #[inline] -    fn is_local(&self) -> bool { -        self.symbol.st_bind() == elf::STB_LOCAL -    } - -    #[inline] -    fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> { -        SymbolFlags::Elf { -            st_info: self.symbol.st_info(), -            st_other: self.symbol.st_other(), -        } -    } -} - -/// A trait for generic access to [`elf::Sym32`] and [`elf::Sym64`]. -#[allow(missing_docs)] -pub trait Sym: Debug + Pod { -    type Word: Into<u64>; -    type Endian: endian::Endian; - -    fn st_name(&self, endian: Self::Endian) -> u32; -    fn st_info(&self) -> u8; -    fn st_bind(&self) -> u8; -    fn st_type(&self) -> u8; -    fn st_other(&self) -> u8; -    fn st_visibility(&self) -> u8; -    fn st_shndx(&self, endian: Self::Endian) -> u16; -    fn st_value(&self, endian: Self::Endian) -> Self::Word; -    fn st_size(&self, endian: Self::Endian) -> Self::Word; - -    /// Parse the symbol 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.st_name(endian)) -            .read_error("Invalid ELF symbol name offset") -    } - -    /// Return true if the symbol is undefined. -    #[inline] -    fn is_undefined(&self, endian: Self::Endian) -> bool { -        self.st_shndx(endian) == elf::SHN_UNDEF -    } - -    /// Return true if the symbol is a definition of a function or data object. -    fn is_definition(&self, endian: Self::Endian) -> bool { -        let shndx = self.st_shndx(endian); -        if shndx == elf::SHN_UNDEF || (shndx >= elf::SHN_LORESERVE && shndx != elf::SHN_XINDEX) { -            return false; -        } -        match self.st_type() { -            elf::STT_NOTYPE => self.st_size(endian).into() != 0, -            elf::STT_FUNC | elf::STT_OBJECT => true, -            _ => false, -        } -    } -} - -impl<Endian: endian::Endian> Sym for elf::Sym32<Endian> { -    type Word = u32; -    type Endian = Endian; - -    #[inline] -    fn st_name(&self, endian: Self::Endian) -> u32 { -        self.st_name.get(endian) -    } - -    #[inline] -    fn st_info(&self) -> u8 { -        self.st_info -    } - -    #[inline] -    fn st_bind(&self) -> u8 { -        self.st_bind() -    } - -    #[inline] -    fn st_type(&self) -> u8 { -        self.st_type() -    } - -    #[inline] -    fn st_other(&self) -> u8 { -        self.st_other -    } - -    #[inline] -    fn st_visibility(&self) -> u8 { -        self.st_visibility() -    } - -    #[inline] -    fn st_shndx(&self, endian: Self::Endian) -> u16 { -        self.st_shndx.get(endian) -    } - -    #[inline] -    fn st_value(&self, endian: Self::Endian) -> Self::Word { -        self.st_value.get(endian) -    } - -    #[inline] -    fn st_size(&self, endian: Self::Endian) -> Self::Word { -        self.st_size.get(endian) -    } -} - -impl<Endian: endian::Endian> Sym for elf::Sym64<Endian> { -    type Word = u64; -    type Endian = Endian; - -    #[inline] -    fn st_name(&self, endian: Self::Endian) -> u32 { -        self.st_name.get(endian) -    } - -    #[inline] -    fn st_info(&self) -> u8 { -        self.st_info -    } - -    #[inline] -    fn st_bind(&self) -> u8 { -        self.st_bind() -    } - -    #[inline] -    fn st_type(&self) -> u8 { -        self.st_type() -    } - -    #[inline] -    fn st_other(&self) -> u8 { -        self.st_other -    } - -    #[inline] -    fn st_visibility(&self) -> u8 { -        self.st_visibility() -    } - -    #[inline] -    fn st_shndx(&self, endian: Self::Endian) -> u16 { -        self.st_shndx.get(endian) -    } - -    #[inline] -    fn st_value(&self, endian: Self::Endian) -> Self::Word { -        self.st_value.get(endian) -    } - -    #[inline] -    fn st_size(&self, endian: Self::Endian) -> Self::Word { -        self.st_size.get(endian) -    } -} diff --git a/vendor/object/src/read/elf/version.rs b/vendor/object/src/read/elf/version.rs deleted file mode 100644 index 28eeed0..0000000 --- a/vendor/object/src/read/elf/version.rs +++ /dev/null @@ -1,424 +0,0 @@ -use alloc::vec::Vec; - -use crate::read::{Bytes, ReadError, ReadRef, Result, StringTable}; -use crate::{elf, endian}; - -use super::FileHeader; - -/// A version index. -#[derive(Debug, Default, Clone, Copy)] -pub struct VersionIndex(pub u16); - -impl VersionIndex { -    /// Return the version index. -    pub fn index(&self) -> u16 { -        self.0 & elf::VERSYM_VERSION -    } - -    /// Return true if it is the local index. -    pub fn is_local(&self) -> bool { -        self.index() == elf::VER_NDX_LOCAL -    } - -    /// Return true if it is the global index. -    pub fn is_global(&self) -> bool { -        self.index() == elf::VER_NDX_GLOBAL -    } - -    /// Return the hidden flag. -    pub fn is_hidden(&self) -> bool { -        self.0 & elf::VERSYM_HIDDEN != 0 -    } -} - -/// A version definition or requirement. -/// -/// This is derived from entries in the [`elf::SHT_GNU_VERDEF`] and [`elf::SHT_GNU_VERNEED`] sections. -#[derive(Debug, Default, Clone, Copy)] -pub struct Version<'data> { -    name: &'data [u8], -    hash: u32, -    // Used to keep track of valid indices in `VersionTable`. -    valid: bool, -} - -impl<'data> Version<'data> { -    /// Return the version name. -    pub fn name(&self) -> &'data [u8] { -        self.name -    } - -    /// Return hash of the version name. -    pub fn hash(&self) -> u32 { -        self.hash -    } -} - -/// A table of version definitions and requirements. -/// -/// It allows looking up the version information for a given symbol index. -/// -/// This is derived from entries in the [`elf::SHT_GNU_VERSYM`], [`elf::SHT_GNU_VERDEF`] -/// and [`elf::SHT_GNU_VERNEED`] sections. -/// -/// Returned by [`SectionTable::versions`](super::SectionTable::versions). -#[derive(Debug, Clone)] -pub struct VersionTable<'data, Elf: FileHeader> { -    symbols: &'data [elf::Versym<Elf::Endian>], -    versions: Vec<Version<'data>>, -} - -impl<'data, Elf: FileHeader> Default for VersionTable<'data, Elf> { -    fn default() -> Self { -        VersionTable { -            symbols: &[], -            versions: Vec::new(), -        } -    } -} - -impl<'data, Elf: FileHeader> VersionTable<'data, Elf> { -    /// Parse the version sections. -    pub fn parse<R: ReadRef<'data>>( -        endian: Elf::Endian, -        versyms: &'data [elf::Versym<Elf::Endian>], -        verdefs: Option<VerdefIterator<'data, Elf>>, -        verneeds: Option<VerneedIterator<'data, Elf>>, -        strings: StringTable<'data, R>, -    ) -> Result<Self> { -        let mut max_index = 0; -        if let Some(mut verdefs) = verdefs.clone() { -            while let Some((verdef, _)) = verdefs.next()? { -                if verdef.vd_flags.get(endian) & elf::VER_FLG_BASE != 0 { -                    continue; -                } -                let index = verdef.vd_ndx.get(endian) & elf::VERSYM_VERSION; -                if max_index < index { -                    max_index = index; -                } -            } -        } -        if let Some(mut verneeds) = verneeds.clone() { -            while let Some((_, mut vernauxs)) = verneeds.next()? { -                while let Some(vernaux) = vernauxs.next()? { -                    let index = vernaux.vna_other.get(endian) & elf::VERSYM_VERSION; -                    if max_index < index { -                        max_index = index; -                    } -                } -            } -        } - -        // Indices should be sequential, but this could be up to -        // 32k * size_of::<Version>() if max_index is bad. -        let mut versions = vec![Version::default(); max_index as usize + 1]; - -        if let Some(mut verdefs) = verdefs { -            while let Some((verdef, mut verdauxs)) = verdefs.next()? { -                if verdef.vd_flags.get(endian) & elf::VER_FLG_BASE != 0 { -                    continue; -                } -                let index = verdef.vd_ndx.get(endian) & elf::VERSYM_VERSION; -                if index <= elf::VER_NDX_GLOBAL { -                    // TODO: return error? -                    continue; -                } -                if let Some(verdaux) = verdauxs.next()? { -                    versions[usize::from(index)] = Version { -                        name: verdaux.name(endian, strings)?, -                        hash: verdef.vd_hash.get(endian), -                        valid: true, -                    }; -                } -            } -        } -        if let Some(mut verneeds) = verneeds { -            while let Some((_, mut vernauxs)) = verneeds.next()? { -                while let Some(vernaux) = vernauxs.next()? { -                    let index = vernaux.vna_other.get(endian) & elf::VERSYM_VERSION; -                    if index <= elf::VER_NDX_GLOBAL { -                        // TODO: return error? -                        continue; -                    } -                    versions[usize::from(index)] = Version { -                        name: vernaux.name(endian, strings)?, -                        hash: vernaux.vna_hash.get(endian), -                        valid: true, -                    }; -                } -            } -        } - -        Ok(VersionTable { -            symbols: versyms, -            versions, -        }) -    } - -    /// Return true if the version table is empty. -    pub fn is_empty(&self) -> bool { -        self.symbols.is_empty() -    } - -    /// Return version index for a given symbol index. -    pub fn version_index(&self, endian: Elf::Endian, index: usize) -> VersionIndex { -        let version_index = match self.symbols.get(index) { -            Some(x) => x.0.get(endian), -            // Ideally this would be VER_NDX_LOCAL for undefined symbols, -            // but currently there are no checks that need this distinction. -            None => elf::VER_NDX_GLOBAL, -        }; -        VersionIndex(version_index) -    } - -    /// Return version information for a given symbol version index. -    /// -    /// Returns `Ok(None)` for local and global versions. -    /// Returns `Err(_)` if index is invalid. -    pub fn version(&self, index: VersionIndex) -> Result<Option<&Version<'data>>> { -        if index.index() <= elf::VER_NDX_GLOBAL { -            return Ok(None); -        } -        self.versions -            .get(usize::from(index.index())) -            .filter(|version| version.valid) -            .read_error("Invalid ELF symbol version index") -            .map(Some) -    } - -    /// Return true if the given symbol index satisfies the requirements of `need`. -    /// -    /// Returns false for any error. -    /// -    /// Note: this function hasn't been fully tested and is likely to be incomplete. -    pub fn matches(&self, endian: Elf::Endian, index: usize, need: Option<&Version<'_>>) -> bool { -        let version_index = self.version_index(endian, index); -        let def = match self.version(version_index) { -            Ok(def) => def, -            Err(_) => return false, -        }; -        match (def, need) { -            (Some(def), Some(need)) => need.hash == def.hash && need.name == def.name, -            (None, Some(_need)) => { -                // Version must be present if needed. -                false -            } -            (Some(_def), None) => { -                // For a dlsym call, use the newest version. -                // TODO: if not a dlsym call, then use the oldest version. -                !version_index.is_hidden() -            } -            (None, None) => true, -        } -    } -} - -/// An iterator for the entries in an ELF [`elf::SHT_GNU_VERDEF`] section. -#[derive(Debug, Clone)] -pub struct VerdefIterator<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> VerdefIterator<'data, Elf> { -    pub(super) fn new(endian: Elf::Endian, data: &'data [u8]) -> Self { -        VerdefIterator { -            endian, -            data: Bytes(data), -        } -    } - -    /// Return the next `Verdef` entry. -    pub fn next( -        &mut self, -    ) -> Result<Option<(&'data elf::Verdef<Elf::Endian>, VerdauxIterator<'data, Elf>)>> { -        if self.data.is_empty() { -            return Ok(None); -        } - -        let verdef = self -            .data -            .read_at::<elf::Verdef<_>>(0) -            .read_error("ELF verdef is too short")?; - -        let mut verdaux_data = self.data; -        verdaux_data -            .skip(verdef.vd_aux.get(self.endian) as usize) -            .read_error("Invalid ELF vd_aux")?; -        let verdaux = -            VerdauxIterator::new(self.endian, verdaux_data.0, verdef.vd_cnt.get(self.endian)); - -        let next = verdef.vd_next.get(self.endian); -        if next != 0 { -            self.data -                .skip(next as usize) -                .read_error("Invalid ELF vd_next")?; -        } else { -            self.data = Bytes(&[]); -        } -        Ok(Some((verdef, verdaux))) -    } -} - -/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERDEF`] section. -#[derive(Debug, Clone)] -pub struct VerdauxIterator<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    data: Bytes<'data>, -    count: u16, -} - -impl<'data, Elf: FileHeader> VerdauxIterator<'data, Elf> { -    pub(super) fn new(endian: Elf::Endian, data: &'data [u8], count: u16) -> Self { -        VerdauxIterator { -            endian, -            data: Bytes(data), -            count, -        } -    } - -    /// Return the next `Verdaux` entry. -    pub fn next(&mut self) -> Result<Option<&'data elf::Verdaux<Elf::Endian>>> { -        if self.count == 0 { -            return Ok(None); -        } - -        let verdaux = self -            .data -            .read_at::<elf::Verdaux<_>>(0) -            .read_error("ELF verdaux is too short")?; - -        self.data -            .skip(verdaux.vda_next.get(self.endian) as usize) -            .read_error("Invalid ELF vda_next")?; -        self.count -= 1; -        Ok(Some(verdaux)) -    } -} - -/// An iterator for the entries in an ELF [`elf::SHT_GNU_VERNEED`] section. -#[derive(Debug, Clone)] -pub struct VerneedIterator<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    data: Bytes<'data>, -} - -impl<'data, Elf: FileHeader> VerneedIterator<'data, Elf> { -    pub(super) fn new(endian: Elf::Endian, data: &'data [u8]) -> Self { -        VerneedIterator { -            endian, -            data: Bytes(data), -        } -    } - -    /// Return the next `Verneed` entry. -    pub fn next( -        &mut self, -    ) -> Result< -        Option<( -            &'data elf::Verneed<Elf::Endian>, -            VernauxIterator<'data, Elf>, -        )>, -    > { -        if self.data.is_empty() { -            return Ok(None); -        } - -        let verneed = self -            .data -            .read_at::<elf::Verneed<_>>(0) -            .read_error("ELF verneed is too short")?; - -        let mut vernaux_data = self.data; -        vernaux_data -            .skip(verneed.vn_aux.get(self.endian) as usize) -            .read_error("Invalid ELF vn_aux")?; -        let vernaux = -            VernauxIterator::new(self.endian, vernaux_data.0, verneed.vn_cnt.get(self.endian)); - -        let next = verneed.vn_next.get(self.endian); -        if next != 0 { -            self.data -                .skip(next as usize) -                .read_error("Invalid ELF vn_next")?; -        } else { -            self.data = Bytes(&[]); -        } -        Ok(Some((verneed, vernaux))) -    } -} - -/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERNEED`] section. -#[derive(Debug, Clone)] -pub struct VernauxIterator<'data, Elf: FileHeader> { -    endian: Elf::Endian, -    data: Bytes<'data>, -    count: u16, -} - -impl<'data, Elf: FileHeader> VernauxIterator<'data, Elf> { -    pub(super) fn new(endian: Elf::Endian, data: &'data [u8], count: u16) -> Self { -        VernauxIterator { -            endian, -            data: Bytes(data), -            count, -        } -    } - -    /// Return the next `Vernaux` entry. -    pub fn next(&mut self) -> Result<Option<&'data elf::Vernaux<Elf::Endian>>> { -        if self.count == 0 { -            return Ok(None); -        } - -        let vernaux = self -            .data -            .read_at::<elf::Vernaux<_>>(0) -            .read_error("ELF vernaux is too short")?; - -        self.data -            .skip(vernaux.vna_next.get(self.endian) as usize) -            .read_error("Invalid ELF vna_next")?; -        self.count -= 1; -        Ok(Some(vernaux)) -    } -} - -impl<Endian: endian::Endian> elf::Verdaux<Endian> { -    /// Parse the version name from the string table. -    pub fn name<'data, R: ReadRef<'data>>( -        &self, -        endian: Endian, -        strings: StringTable<'data, R>, -    ) -> Result<&'data [u8]> { -        strings -            .get(self.vda_name.get(endian)) -            .read_error("Invalid ELF vda_name") -    } -} - -impl<Endian: endian::Endian> elf::Verneed<Endian> { -    /// Parse the file from the string table. -    pub fn file<'data, R: ReadRef<'data>>( -        &self, -        endian: Endian, -        strings: StringTable<'data, R>, -    ) -> Result<&'data [u8]> { -        strings -            .get(self.vn_file.get(endian)) -            .read_error("Invalid ELF vn_file") -    } -} - -impl<Endian: endian::Endian> elf::Vernaux<Endian> { -    /// Parse the version name from the string table. -    pub fn name<'data, R: ReadRef<'data>>( -        &self, -        endian: Endian, -        strings: StringTable<'data, R>, -    ) -> Result<&'data [u8]> { -        strings -            .get(self.vna_name.get(endian)) -            .read_error("Invalid ELF vna_name") -    } -} diff --git a/vendor/object/src/read/macho/dyld_cache.rs b/vendor/object/src/read/macho/dyld_cache.rs deleted file mode 100644 index 0f5dfc5..0000000 --- a/vendor/object/src/read/macho/dyld_cache.rs +++ /dev/null @@ -1,344 +0,0 @@ -use alloc::vec::Vec; -use core::slice; - -use crate::read::{Error, File, ReadError, ReadRef, Result}; -use crate::{macho, Architecture, Endian, Endianness}; - -/// A parsed representation of the dyld shared cache. -#[derive(Debug)] -pub struct DyldCache<'data, E = Endianness, R = &'data [u8]> -where -    E: Endian, -    R: ReadRef<'data>, -{ -    endian: E, -    data: R, -    subcaches: Vec<DyldSubCache<'data, E, R>>, -    mappings: &'data [macho::DyldCacheMappingInfo<E>], -    images: &'data [macho::DyldCacheImageInfo<E>], -    arch: Architecture, -} - -/// Information about a subcache. -#[derive(Debug)] -pub struct DyldSubCache<'data, E = Endianness, R = &'data [u8]> -where -    E: Endian, -    R: ReadRef<'data>, -{ -    data: R, -    mappings: &'data [macho::DyldCacheMappingInfo<E>], -} - -// This is the offset of the images_across_all_subcaches_count field. -const MIN_HEADER_SIZE_SUBCACHES: u32 = 0x1c4; - -impl<'data, E, R> DyldCache<'data, E, R> -where -    E: Endian, -    R: ReadRef<'data>, -{ -    /// Parse the raw dyld shared cache data. -    /// -    /// For shared caches from macOS 12 / iOS 15 and above, the subcache files need to be -    /// supplied as well, in the correct order, with the `.symbols` subcache last (if present). -    /// For example, `data` would be the data for `dyld_shared_cache_x86_64`, -    /// and `subcache_data` would be the data for `[dyld_shared_cache_x86_64.1, dyld_shared_cache_x86_64.2, ...]`. -    pub fn parse(data: R, subcache_data: &[R]) -> Result<Self> { -        let header = macho::DyldCacheHeader::parse(data)?; -        let (arch, endian) = header.parse_magic()?; -        let mappings = header.mappings(endian, data)?; - -        let symbols_subcache_uuid = header.symbols_subcache_uuid(endian); -        let subcaches_info = header.subcaches(endian, data)?.unwrap_or(&[]); - -        if subcache_data.len() != subcaches_info.len() + symbols_subcache_uuid.is_some() as usize { -            return Err(Error("Incorrect number of SubCaches")); -        } - -        // Split out the .symbols subcache data from the other subcaches. -        let (symbols_subcache_data_and_uuid, subcache_data) = -            if let Some(symbols_uuid) = symbols_subcache_uuid { -                let (sym_data, rest_data) = subcache_data.split_last().unwrap(); -                (Some((*sym_data, symbols_uuid)), rest_data) -            } else { -                (None, subcache_data) -            }; - -        // Read the regular SubCaches (.1, .2, ...), if present. -        let mut subcaches = Vec::new(); -        for (&data, info) in subcache_data.iter().zip(subcaches_info.iter()) { -            let sc_header = macho::DyldCacheHeader::<E>::parse(data)?; -            if sc_header.uuid != info.uuid { -                return Err(Error("Unexpected SubCache UUID")); -            } -            let mappings = sc_header.mappings(endian, data)?; -            subcaches.push(DyldSubCache { data, mappings }); -        } - -        // Read the .symbols SubCache, if present. -        // Other than the UUID verification, the symbols SubCache is currently unused. -        let _symbols_subcache = match symbols_subcache_data_and_uuid { -            Some((data, uuid)) => { -                let sc_header = macho::DyldCacheHeader::<E>::parse(data)?; -                if sc_header.uuid != uuid { -                    return Err(Error("Unexpected .symbols SubCache UUID")); -                } -                let mappings = sc_header.mappings(endian, data)?; -                Some(DyldSubCache { data, mappings }) -            } -            None => None, -        }; - -        let images = header.images(endian, data)?; -        Ok(DyldCache { -            endian, -            data, -            subcaches, -            mappings, -            images, -            arch, -        }) -    } - -    /// Get the architecture type of the file. -    pub fn architecture(&self) -> Architecture { -        self.arch -    } - -    /// Get the endianness of the file. -    #[inline] -    pub fn endianness(&self) -> Endianness { -        if self.is_little_endian() { -            Endianness::Little -        } else { -            Endianness::Big -        } -    } - -    /// Return true if the file is little endian, false if it is big endian. -    pub fn is_little_endian(&self) -> bool { -        self.endian.is_little_endian() -    } - -    /// Iterate over the images in this cache. -    pub fn images<'cache>(&'cache self) -> DyldCacheImageIterator<'data, 'cache, E, R> { -        DyldCacheImageIterator { -            cache: self, -            iter: self.images.iter(), -        } -    } - -    /// Find the address in a mapping and return the cache or subcache data it was found in, -    /// together with the translated file offset. -    pub fn data_and_offset_for_address(&self, address: u64) -> Option<(R, u64)> { -        if let Some(file_offset) = address_to_file_offset(address, self.endian, self.mappings) { -            return Some((self.data, file_offset)); -        } -        for subcache in &self.subcaches { -            if let Some(file_offset) = -                address_to_file_offset(address, self.endian, subcache.mappings) -            { -                return Some((subcache.data, file_offset)); -            } -        } -        None -    } -} - -/// An iterator over all the images (dylibs) in the dyld shared cache. -#[derive(Debug)] -pub struct DyldCacheImageIterator<'data, 'cache, E = Endianness, R = &'data [u8]> -where -    E: Endian, -    R: ReadRef<'data>, -{ -    cache: &'cache DyldCache<'data, E, R>, -    iter: slice::Iter<'data, macho::DyldCacheImageInfo<E>>, -} - -impl<'data, 'cache, E, R> Iterator for DyldCacheImageIterator<'data, 'cache, E, R> -where -    E: Endian, -    R: ReadRef<'data>, -{ -    type Item = DyldCacheImage<'data, 'cache, E, R>; - -    fn next(&mut self) -> Option<DyldCacheImage<'data, 'cache, E, R>> { -        let image_info = self.iter.next()?; -        Some(DyldCacheImage { -            cache: self.cache, -            image_info, -        }) -    } -} - -/// One image (dylib) from inside the dyld shared cache. -#[derive(Debug)] -pub struct DyldCacheImage<'data, 'cache, E = Endianness, R = &'data [u8]> -where -    E: Endian, -    R: ReadRef<'data>, -{ -    pub(crate) cache: &'cache DyldCache<'data, E, R>, -    image_info: &'data macho::DyldCacheImageInfo<E>, -} - -impl<'data, 'cache, E, R> DyldCacheImage<'data, 'cache, E, R> -where -    E: Endian, -    R: ReadRef<'data>, -{ -    /// The file system path of this image. -    pub fn path(&self) -> Result<&'data str> { -        let path = self.image_info.path(self.cache.endian, self.cache.data)?; -        // The path should always be ascii, so from_utf8 should always succeed. -        let path = core::str::from_utf8(path).map_err(|_| Error("Path string not valid utf-8"))?; -        Ok(path) -    } - -    /// The subcache data which contains the Mach-O header for this image, -    /// together with the file offset at which this image starts. -    pub fn image_data_and_offset(&self) -> Result<(R, u64)> { -        let address = self.image_info.address.get(self.cache.endian); -        self.cache -            .data_and_offset_for_address(address) -            .ok_or(Error("Address not found in any mapping")) -    } - -    /// Parse this image into an Object. -    pub fn parse_object(&self) -> Result<File<'data, R>> { -        File::parse_dyld_cache_image(self) -    } -} - -impl<E: Endian> macho::DyldCacheHeader<E> { -    /// Read the dyld cache header. -    pub fn parse<'data, R: ReadRef<'data>>(data: R) -> Result<&'data Self> { -        data.read_at::<macho::DyldCacheHeader<E>>(0) -            .read_error("Invalid dyld cache header size or alignment") -    } - -    /// Returns (arch, endian) based on the magic string. -    pub fn parse_magic(&self) -> Result<(Architecture, E)> { -        let (arch, is_big_endian) = match &self.magic { -            b"dyld_v1    i386\0" => (Architecture::I386, false), -            b"dyld_v1  x86_64\0" => (Architecture::X86_64, false), -            b"dyld_v1 x86_64h\0" => (Architecture::X86_64, false), -            b"dyld_v1     ppc\0" => (Architecture::PowerPc, true), -            b"dyld_v1   armv6\0" => (Architecture::Arm, false), -            b"dyld_v1   armv7\0" => (Architecture::Arm, false), -            b"dyld_v1  armv7f\0" => (Architecture::Arm, false), -            b"dyld_v1  armv7s\0" => (Architecture::Arm, false), -            b"dyld_v1  armv7k\0" => (Architecture::Arm, false), -            b"dyld_v1   arm64\0" => (Architecture::Aarch64, false), -            b"dyld_v1  arm64e\0" => (Architecture::Aarch64, false), -            _ => return Err(Error("Unrecognized dyld cache magic")), -        }; -        let endian = -            E::from_big_endian(is_big_endian).read_error("Unsupported dyld cache endian")?; -        Ok((arch, endian)) -    } - -    /// Return the mapping information table. -    pub fn mappings<'data, R: ReadRef<'data>>( -        &self, -        endian: E, -        data: R, -    ) -> Result<&'data [macho::DyldCacheMappingInfo<E>]> { -        data.read_slice_at::<macho::DyldCacheMappingInfo<E>>( -            self.mapping_offset.get(endian).into(), -            self.mapping_count.get(endian) as usize, -        ) -        .read_error("Invalid dyld cache mapping size or alignment") -    } - -    /// Return the information about subcaches, if present. -    pub fn subcaches<'data, R: ReadRef<'data>>( -        &self, -        endian: E, -        data: R, -    ) -> Result<Option<&'data [macho::DyldSubCacheInfo<E>]>> { -        if self.mapping_offset.get(endian) >= MIN_HEADER_SIZE_SUBCACHES { -            let subcaches = data -                .read_slice_at::<macho::DyldSubCacheInfo<E>>( -                    self.subcaches_offset.get(endian).into(), -                    self.subcaches_count.get(endian) as usize, -                ) -                .read_error("Invalid dyld subcaches size or alignment")?; -            Ok(Some(subcaches)) -        } else { -            Ok(None) -        } -    } - -    /// Return the UUID for the .symbols subcache, if present. -    pub fn symbols_subcache_uuid(&self, endian: E) -> Option<[u8; 16]> { -        if self.mapping_offset.get(endian) >= MIN_HEADER_SIZE_SUBCACHES { -            let uuid = self.symbols_subcache_uuid; -            if uuid != [0; 16] { -                return Some(uuid); -            } -        } -        None -    } - -    /// Return the image information table. -    pub fn images<'data, R: ReadRef<'data>>( -        &self, -        endian: E, -        data: R, -    ) -> Result<&'data [macho::DyldCacheImageInfo<E>]> { -        if self.mapping_offset.get(endian) >= MIN_HEADER_SIZE_SUBCACHES { -            data.read_slice_at::<macho::DyldCacheImageInfo<E>>( -                self.images_across_all_subcaches_offset.get(endian).into(), -                self.images_across_all_subcaches_count.get(endian) as usize, -            ) -            .read_error("Invalid dyld cache image size or alignment") -        } else { -            data.read_slice_at::<macho::DyldCacheImageInfo<E>>( -                self.images_offset.get(endian).into(), -                self.images_count.get(endian) as usize, -            ) -            .read_error("Invalid dyld cache image size or alignment") -        } -    } -} - -impl<E: Endian> macho::DyldCacheImageInfo<E> { -    /// The file system path of this image. -    pub fn path<'data, R: ReadRef<'data>>(&self, endian: E, data: R) -> Result<&'data [u8]> { -        let r_start = self.path_file_offset.get(endian).into(); -        let r_end = data.len().read_error("Couldn't get data len()")?; -        data.read_bytes_at_until(r_start..r_end, 0) -            .read_error("Couldn't read dyld cache image path") -    } - -    /// Find the file offset of the image by looking up its address in the mappings. -    pub fn file_offset( -        &self, -        endian: E, -        mappings: &[macho::DyldCacheMappingInfo<E>], -    ) -> Result<u64> { -        let address = self.address.get(endian); -        address_to_file_offset(address, endian, mappings) -            .read_error("Invalid dyld cache image address") -    } -} - -/// Find the file offset of the image by looking up its address in the mappings. -pub fn address_to_file_offset<E: Endian>( -    address: u64, -    endian: E, -    mappings: &[macho::DyldCacheMappingInfo<E>], -) -> Option<u64> { -    for mapping in mappings { -        let mapping_address = mapping.address.get(endian); -        if address >= mapping_address -            && address < mapping_address.wrapping_add(mapping.size.get(endian)) -        { -            return Some(address - mapping_address + mapping.file_offset.get(endian)); -        } -    } -    None -} diff --git a/vendor/object/src/read/macho/fat.rs b/vendor/object/src/read/macho/fat.rs deleted file mode 100644 index a481351..0000000 --- a/vendor/object/src/read/macho/fat.rs +++ /dev/null @@ -1,122 +0,0 @@ -use crate::read::{Architecture, Error, ReadError, ReadRef, Result}; -use crate::{macho, BigEndian, Pod}; - -pub use macho::{FatArch32, FatArch64, FatHeader}; - -impl FatHeader { -    /// Attempt to parse a fat header. -    /// -    /// Does not validate the magic value. -    pub fn parse<'data, R: ReadRef<'data>>(file: R) -> Result<&'data FatHeader> { -        file.read_at::<FatHeader>(0) -            .read_error("Invalid fat header size or alignment") -    } - -    /// Attempt to parse a fat header and 32-bit fat arches. -    pub fn parse_arch32<'data, R: ReadRef<'data>>(file: R) -> Result<&'data [FatArch32]> { -        let mut offset = 0; -        let header = file -            .read::<FatHeader>(&mut offset) -            .read_error("Invalid fat header size or alignment")?; -        if header.magic.get(BigEndian) != macho::FAT_MAGIC { -            return Err(Error("Invalid 32-bit fat magic")); -        } -        file.read_slice::<FatArch32>(&mut offset, header.nfat_arch.get(BigEndian) as usize) -            .read_error("Invalid nfat_arch") -    } - -    /// Attempt to parse a fat header and 64-bit fat arches. -    pub fn parse_arch64<'data, R: ReadRef<'data>>(file: R) -> Result<&'data [FatArch64]> { -        let mut offset = 0; -        let header = file -            .read::<FatHeader>(&mut offset) -            .read_error("Invalid fat header size or alignment")?; -        if header.magic.get(BigEndian) != macho::FAT_MAGIC_64 { -            return Err(Error("Invalid 64-bit fat magic")); -        } -        file.read_slice::<FatArch64>(&mut offset, header.nfat_arch.get(BigEndian) as usize) -            .read_error("Invalid nfat_arch") -    } -} - -/// A trait for generic access to [`macho::FatArch32`] and [`macho::FatArch64`]. -#[allow(missing_docs)] -pub trait FatArch: Pod { -    type Word: Into<u64>; - -    fn cputype(&self) -> u32; -    fn cpusubtype(&self) -> u32; -    fn offset(&self) -> Self::Word; -    fn size(&self) -> Self::Word; -    fn align(&self) -> u32; - -    fn architecture(&self) -> Architecture { -        match self.cputype() { -            macho::CPU_TYPE_ARM => Architecture::Arm, -            macho::CPU_TYPE_ARM64 => Architecture::Aarch64, -            macho::CPU_TYPE_X86 => Architecture::I386, -            macho::CPU_TYPE_X86_64 => Architecture::X86_64, -            macho::CPU_TYPE_MIPS => Architecture::Mips, -            macho::CPU_TYPE_POWERPC => Architecture::PowerPc, -            macho::CPU_TYPE_POWERPC64 => Architecture::PowerPc64, -            _ => Architecture::Unknown, -        } -    } - -    fn file_range(&self) -> (u64, u64) { -        (self.offset().into(), self.size().into()) -    } - -    fn data<'data, R: ReadRef<'data>>(&self, file: R) -> Result<&'data [u8]> { -        file.read_bytes_at(self.offset().into(), self.size().into()) -            .read_error("Invalid fat arch offset or size") -    } -} - -impl FatArch for FatArch32 { -    type Word = u32; - -    fn cputype(&self) -> u32 { -        self.cputype.get(BigEndian) -    } - -    fn cpusubtype(&self) -> u32 { -        self.cpusubtype.get(BigEndian) -    } - -    fn offset(&self) -> Self::Word { -        self.offset.get(BigEndian) -    } - -    fn size(&self) -> Self::Word { -        self.size.get(BigEndian) -    } - -    fn align(&self) -> u32 { -        self.align.get(BigEndian) -    } -} - -impl FatArch for FatArch64 { -    type Word = u64; - -    fn cputype(&self) -> u32 { -        self.cputype.get(BigEndian) -    } - -    fn cpusubtype(&self) -> u32 { -        self.cpusubtype.get(BigEndian) -    } - -    fn offset(&self) -> Self::Word { -        self.offset.get(BigEndian) -    } - -    fn size(&self) -> Self::Word { -        self.size.get(BigEndian) -    } - -    fn align(&self) -> u32 { -        self.align.get(BigEndian) -    } -} diff --git a/vendor/object/src/read/macho/file.rs b/vendor/object/src/read/macho/file.rs deleted file mode 100644 index 0e04477..0000000 --- a/vendor/object/src/read/macho/file.rs +++ /dev/null @@ -1,781 +0,0 @@ -use alloc::vec::Vec; -use core::fmt::Debug; -use core::{mem, str}; - -use crate::read::{ -    self, Architecture, ComdatKind, Error, Export, FileFlags, Import, NoDynamicRelocationIterator, -    Object, ObjectComdat, ObjectKind, ObjectMap, ObjectSection, ReadError, ReadRef, Result, -    SectionIndex, SubArchitecture, SymbolIndex, -}; -use crate::{endian, macho, BigEndian, ByteString, Endian, Endianness, Pod}; - -use super::{ -    DyldCacheImage, LoadCommandIterator, MachOSection, MachOSectionInternal, MachOSectionIterator, -    MachOSegment, MachOSegmentInternal, MachOSegmentIterator, MachOSymbol, MachOSymbolIterator, -    MachOSymbolTable, Nlist, Section, Segment, SymbolTable, -}; - -/// A 32-bit Mach-O object file. -/// -/// This is a file that starts with [`macho::MachHeader32`], and corresponds -/// to [`crate::FileKind::MachO32`]. -pub type MachOFile32<'data, Endian = Endianness, R = &'data [u8]> = -    MachOFile<'data, macho::MachHeader32<Endian>, R>; -/// A 64-bit Mach-O object file. -/// -/// This is a file that starts with [`macho::MachHeader64`], and corresponds -/// to [`crate::FileKind::MachO64`]. -pub type MachOFile64<'data, Endian = Endianness, R = &'data [u8]> = -    MachOFile<'data, macho::MachHeader64<Endian>, R>; - -/// A partially parsed Mach-O file. -/// -/// Most of the functionality of this type is provided by the [`Object`] trait implementation. -#[derive(Debug)] -pub struct MachOFile<'data, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) endian: Mach::Endian, -    pub(super) data: R, -    pub(super) header_offset: u64, -    pub(super) header: &'data Mach, -    pub(super) segments: Vec<MachOSegmentInternal<'data, Mach, R>>, -    pub(super) sections: Vec<MachOSectionInternal<'data, Mach>>, -    pub(super) symbols: SymbolTable<'data, Mach, R>, -} - -impl<'data, Mach, R> MachOFile<'data, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    /// Parse the raw Mach-O file data. -    pub fn parse(data: R) -> Result<Self> { -        let header = Mach::parse(data, 0)?; -        let endian = header.endian()?; - -        // Build a list of segments and sections to make some operations more efficient. -        let mut segments = Vec::new(); -        let mut sections = Vec::new(); -        let mut symbols = SymbolTable::default(); -        if let Ok(mut commands) = header.load_commands(endian, data, 0) { -            while let Ok(Some(command)) = commands.next() { -                if let Some((segment, section_data)) = Mach::Segment::from_command(command)? { -                    let segment_index = segments.len(); -                    segments.push(MachOSegmentInternal { segment, data }); -                    for section in segment.sections(endian, section_data)? { -                        let index = SectionIndex(sections.len() + 1); -                        sections.push(MachOSectionInternal::parse(index, segment_index, section)); -                    } -                } else if let Some(symtab) = command.symtab()? { -                    symbols = symtab.symbols(endian, data)?; -                } -            } -        } - -        Ok(MachOFile { -            endian, -            data, -            header_offset: 0, -            header, -            segments, -            sections, -            symbols, -        }) -    } - -    /// Parse the Mach-O file for the given image from the dyld shared cache. -    /// This will read different sections from different subcaches, if necessary. -    pub fn parse_dyld_cache_image<'cache, E: Endian>( -        image: &DyldCacheImage<'data, 'cache, E, R>, -    ) -> Result<Self> { -        let (data, header_offset) = image.image_data_and_offset()?; -        let header = Mach::parse(data, header_offset)?; -        let endian = header.endian()?; - -        // Build a list of sections to make some operations more efficient. -        // Also build a list of segments, because we need to remember which ReadRef -        // to read each section's data from. Only the DyldCache knows this information, -        // and we won't have access to it once we've exited this function. -        let mut segments = Vec::new(); -        let mut sections = Vec::new(); -        let mut linkedit_data: Option<R> = None; -        let mut symtab = None; -        if let Ok(mut commands) = header.load_commands(endian, data, header_offset) { -            while let Ok(Some(command)) = commands.next() { -                if let Some((segment, section_data)) = Mach::Segment::from_command(command)? { -                    // Each segment can be stored in a different subcache. Get the segment's -                    // address and look it up in the cache mappings, to find the correct cache data. -                    let addr = segment.vmaddr(endian).into(); -                    let (data, _offset) = image -                        .cache -                        .data_and_offset_for_address(addr) -                        .read_error("Could not find segment data in dyld shared cache")?; -                    if segment.name() == macho::SEG_LINKEDIT.as_bytes() { -                        linkedit_data = Some(data); -                    } -                    let segment_index = segments.len(); -                    segments.push(MachOSegmentInternal { segment, data }); - -                    for section in segment.sections(endian, section_data)? { -                        let index = SectionIndex(sections.len() + 1); -                        sections.push(MachOSectionInternal::parse(index, segment_index, section)); -                    } -                } else if let Some(st) = command.symtab()? { -                    symtab = Some(st); -                } -            } -        } - -        // The symbols are found in the __LINKEDIT segment, so make sure to read them from the -        // correct subcache. -        let symbols = match (symtab, linkedit_data) { -            (Some(symtab), Some(linkedit_data)) => symtab.symbols(endian, linkedit_data)?, -            _ => SymbolTable::default(), -        }; - -        Ok(MachOFile { -            endian, -            data, -            header_offset, -            header, -            segments, -            sections, -            symbols, -        }) -    } - -    /// Return the section at the given index. -    #[inline] -    pub(super) fn section_internal( -        &self, -        index: SectionIndex, -    ) -> Result<&MachOSectionInternal<'data, Mach>> { -        index -            .0 -            .checked_sub(1) -            .and_then(|index| self.sections.get(index)) -            .read_error("Invalid Mach-O section index") -    } - -    pub(super) fn segment_internal( -        &self, -        index: usize, -    ) -> Result<&MachOSegmentInternal<'data, Mach, R>> { -        self.segments -            .get(index) -            .read_error("Invalid Mach-O segment index") -    } - -    /// Returns the endianness. -    pub fn endian(&self) -> Mach::Endian { -        self.endian -    } - -    /// Returns the raw data. -    pub fn data(&self) -> R { -        self.data -    } - -    /// Returns the raw Mach-O file header. -    pub fn raw_header(&self) -> &'data Mach { -        self.header -    } - -    /// Return the `LC_BUILD_VERSION` load command if present. -    pub fn build_version(&self) -> Result<Option<&'data macho::BuildVersionCommand<Mach::Endian>>> { -        let mut commands = self -            .header -            .load_commands(self.endian, self.data, self.header_offset)?; -        while let Some(command) = commands.next()? { -            if let Some(build_version) = command.build_version()? { -                return Ok(Some(build_version)); -            } -        } -        Ok(None) -    } -} - -impl<'data, Mach, R> read::private::Sealed for MachOFile<'data, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Mach, R> Object<'data, 'file> for MachOFile<'data, Mach, R> -where -    'data: 'file, -    Mach: MachHeader, -    R: 'file + ReadRef<'data>, -{ -    type Segment = MachOSegment<'data, 'file, Mach, R>; -    type SegmentIterator = MachOSegmentIterator<'data, 'file, Mach, R>; -    type Section = MachOSection<'data, 'file, Mach, R>; -    type SectionIterator = MachOSectionIterator<'data, 'file, Mach, R>; -    type Comdat = MachOComdat<'data, 'file, Mach, R>; -    type ComdatIterator = MachOComdatIterator<'data, 'file, Mach, R>; -    type Symbol = MachOSymbol<'data, 'file, Mach, R>; -    type SymbolIterator = MachOSymbolIterator<'data, 'file, Mach, R>; -    type SymbolTable = MachOSymbolTable<'data, 'file, Mach, R>; -    type DynamicRelocationIterator = NoDynamicRelocationIterator; - -    fn architecture(&self) -> Architecture { -        match self.header.cputype(self.endian) { -            macho::CPU_TYPE_ARM => Architecture::Arm, -            macho::CPU_TYPE_ARM64 => Architecture::Aarch64, -            macho::CPU_TYPE_ARM64_32 => Architecture::Aarch64_Ilp32, -            macho::CPU_TYPE_X86 => Architecture::I386, -            macho::CPU_TYPE_X86_64 => Architecture::X86_64, -            macho::CPU_TYPE_MIPS => Architecture::Mips, -            macho::CPU_TYPE_POWERPC => Architecture::PowerPc, -            macho::CPU_TYPE_POWERPC64 => Architecture::PowerPc64, -            _ => Architecture::Unknown, -        } -    } - -    fn sub_architecture(&self) -> Option<SubArchitecture> { -        match ( -            self.header.cputype(self.endian), -            self.header.cpusubtype(self.endian), -        ) { -            (macho::CPU_TYPE_ARM64, macho::CPU_SUBTYPE_ARM64E) => Some(SubArchitecture::Arm64E), -            _ => None, -        } -    } - -    #[inline] -    fn is_little_endian(&self) -> bool { -        self.header.is_little_endian() -    } - -    #[inline] -    fn is_64(&self) -> bool { -        self.header.is_type_64() -    } - -    fn kind(&self) -> ObjectKind { -        match self.header.filetype(self.endian) { -            macho::MH_OBJECT => ObjectKind::Relocatable, -            macho::MH_EXECUTE => ObjectKind::Executable, -            macho::MH_CORE => ObjectKind::Core, -            macho::MH_DYLIB => ObjectKind::Dynamic, -            _ => ObjectKind::Unknown, -        } -    } - -    fn segments(&'file self) -> MachOSegmentIterator<'data, 'file, Mach, R> { -        MachOSegmentIterator { -            file: self, -            iter: self.segments.iter(), -        } -    } - -    fn section_by_name_bytes( -        &'file self, -        section_name: &[u8], -    ) -> Option<MachOSection<'data, 'file, Mach, R>> { -        // Translate the "." prefix to the "__" prefix used by OSX/Mach-O, eg -        // ".debug_info" to "__debug_info", and limit to 16 bytes total. -        let system_name = if section_name.starts_with(b".") { -            if section_name.len() > 15 { -                Some(§ion_name[1..15]) -            } else { -                Some(§ion_name[1..]) -            } -        } else { -            None -        }; -        let cmp_section_name = |section: &MachOSection<'data, 'file, Mach, R>| { -            section -                .name_bytes() -                .map(|name| { -                    section_name == name -                        || system_name -                            .filter(|system_name| { -                                name.starts_with(b"__") && name[2..] == **system_name -                            }) -                            .is_some() -                }) -                .unwrap_or(false) -        }; - -        self.sections().find(cmp_section_name) -    } - -    fn section_by_index( -        &'file self, -        index: SectionIndex, -    ) -> Result<MachOSection<'data, 'file, Mach, R>> { -        let internal = *self.section_internal(index)?; -        Ok(MachOSection { -            file: self, -            internal, -        }) -    } - -    fn sections(&'file self) -> MachOSectionIterator<'data, 'file, Mach, R> { -        MachOSectionIterator { -            file: self, -            iter: self.sections.iter(), -        } -    } - -    fn comdats(&'file self) -> MachOComdatIterator<'data, 'file, Mach, R> { -        MachOComdatIterator { file: self } -    } - -    fn symbol_by_index( -        &'file self, -        index: SymbolIndex, -    ) -> Result<MachOSymbol<'data, 'file, Mach, R>> { -        let nlist = self.symbols.symbol(index.0)?; -        MachOSymbol::new(self, index, nlist).read_error("Unsupported Mach-O symbol index") -    } - -    fn symbols(&'file self) -> MachOSymbolIterator<'data, 'file, Mach, R> { -        MachOSymbolIterator { -            file: self, -            index: 0, -        } -    } - -    #[inline] -    fn symbol_table(&'file self) -> Option<MachOSymbolTable<'data, 'file, Mach, R>> { -        Some(MachOSymbolTable { file: self }) -    } - -    fn dynamic_symbols(&'file self) -> MachOSymbolIterator<'data, 'file, Mach, R> { -        MachOSymbolIterator { -            file: self, -            index: self.symbols.len(), -        } -    } - -    #[inline] -    fn dynamic_symbol_table(&'file self) -> Option<MachOSymbolTable<'data, 'file, Mach, R>> { -        None -    } - -    fn object_map(&'file self) -> ObjectMap<'data> { -        self.symbols.object_map(self.endian) -    } - -    fn imports(&self) -> Result<Vec<Import<'data>>> { -        let mut dysymtab = None; -        let mut libraries = Vec::new(); -        let twolevel = self.header.flags(self.endian) & macho::MH_TWOLEVEL != 0; -        if twolevel { -            libraries.push(&[][..]); -        } -        let mut commands = self -            .header -            .load_commands(self.endian, self.data, self.header_offset)?; -        while let Some(command) = commands.next()? { -            if let Some(command) = command.dysymtab()? { -                dysymtab = Some(command); -            } -            if twolevel { -                if let Some(dylib) = command.dylib()? { -                    libraries.push(command.string(self.endian, dylib.dylib.name)?); -                } -            } -        } - -        let mut imports = Vec::new(); -        if let Some(dysymtab) = dysymtab { -            let index = dysymtab.iundefsym.get(self.endian) as usize; -            let number = dysymtab.nundefsym.get(self.endian) as usize; -            for i in index..(index.wrapping_add(number)) { -                let symbol = self.symbols.symbol(i)?; -                let name = symbol.name(self.endian, self.symbols.strings())?; -                let library = if twolevel { -                    libraries -                        .get(symbol.library_ordinal(self.endian) as usize) -                        .copied() -                        .read_error("Invalid Mach-O symbol library ordinal")? -                } else { -                    &[] -                }; -                imports.push(Import { -                    name: ByteString(name), -                    library: ByteString(library), -                }); -            } -        } -        Ok(imports) -    } - -    fn exports(&self) -> Result<Vec<Export<'data>>> { -        let mut dysymtab = None; -        let mut commands = self -            .header -            .load_commands(self.endian, self.data, self.header_offset)?; -        while let Some(command) = commands.next()? { -            if let Some(command) = command.dysymtab()? { -                dysymtab = Some(command); -                break; -            } -        } - -        let mut exports = Vec::new(); -        if let Some(dysymtab) = dysymtab { -            let index = dysymtab.iextdefsym.get(self.endian) as usize; -            let number = dysymtab.nextdefsym.get(self.endian) as usize; -            for i in index..(index.wrapping_add(number)) { -                let symbol = self.symbols.symbol(i)?; -                let name = symbol.name(self.endian, self.symbols.strings())?; -                let address = symbol.n_value(self.endian).into(); -                exports.push(Export { -                    name: ByteString(name), -                    address, -                }); -            } -        } -        Ok(exports) -    } - -    #[inline] -    fn dynamic_relocations(&'file self) -> Option<NoDynamicRelocationIterator> { -        None -    } - -    fn has_debug_symbols(&self) -> bool { -        self.section_by_name(".debug_info").is_some() -    } - -    fn mach_uuid(&self) -> Result<Option<[u8; 16]>> { -        self.header.uuid(self.endian, self.data, self.header_offset) -    } - -    fn relative_address_base(&self) -> u64 { -        0 -    } - -    fn entry(&self) -> u64 { -        if let Ok(mut commands) = -            self.header -                .load_commands(self.endian, self.data, self.header_offset) -        { -            while let Ok(Some(command)) = commands.next() { -                if let Ok(Some(command)) = command.entry_point() { -                    return command.entryoff.get(self.endian); -                } -            } -        } -        0 -    } - -    fn flags(&self) -> FileFlags { -        FileFlags::MachO { -            flags: self.header.flags(self.endian), -        } -    } -} - -/// An iterator for the COMDAT section groups in a [`MachOFile64`]. -pub type MachOComdatIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOComdatIterator<'data, 'file, macho::MachHeader32<Endian>, R>; -/// An iterator for the COMDAT section groups in a [`MachOFile64`]. -pub type MachOComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOComdatIterator<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// An iterator for the COMDAT section groups in a [`MachOFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct MachOComdatIterator<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file MachOFile<'data, Mach, R>, -} - -impl<'data, 'file, Mach, R> Iterator for MachOComdatIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type Item = MachOComdat<'data, 'file, Mach, R>; - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -/// A COMDAT section group in a [`MachOFile32`]. -pub type MachOComdat32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOComdat<'data, 'file, macho::MachHeader32<Endian>, R>; - -/// A COMDAT section group in a [`MachOFile64`]. -pub type MachOComdat64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOComdat<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// A COMDAT section group in a [`MachOFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct MachOComdat<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file MachOFile<'data, Mach, R>, -} - -impl<'data, 'file, Mach, R> read::private::Sealed for MachOComdat<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Mach, R> ObjectComdat<'data> for MachOComdat<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type SectionIterator = MachOComdatSectionIterator<'data, 'file, Mach, 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 for the sections in a COMDAT section group in a [`MachOFile32`]. -pub type MachOComdatSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOComdatSectionIterator<'data, 'file, macho::MachHeader32<Endian>, R>; -/// An iterator for the sections in a COMDAT section group in a [`MachOFile64`]. -pub type MachOComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOComdatSectionIterator<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// An iterator for the sections in a COMDAT section group in a [`MachOFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct MachOComdatSectionIterator<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file MachOFile<'data, Mach, R>, -} - -impl<'data, 'file, Mach, R> Iterator for MachOComdatSectionIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type Item = SectionIndex; - -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -/// A trait for generic access to [`macho::MachHeader32`] and [`macho::MachHeader64`]. -#[allow(missing_docs)] -pub trait MachHeader: Debug + Pod { -    type Word: Into<u64>; -    type Endian: endian::Endian; -    type Segment: Segment<Endian = Self::Endian, Section = Self::Section>; -    type Section: Section<Endian = Self::Endian>; -    type Nlist: Nlist<Endian = Self::Endian>; - -    /// Return true if this type is a 64-bit header. -    /// -    /// This is a property of the type, not a value in the header data. -    fn is_type_64(&self) -> bool; - -    /// Return true if the `magic` field signifies big-endian. -    fn is_big_endian(&self) -> bool; - -    /// Return true if the `magic` field signifies little-endian. -    fn is_little_endian(&self) -> bool; - -    fn magic(&self) -> u32; -    fn cputype(&self, endian: Self::Endian) -> u32; -    fn cpusubtype(&self, endian: Self::Endian) -> u32; -    fn filetype(&self, endian: Self::Endian) -> u32; -    fn ncmds(&self, endian: Self::Endian) -> u32; -    fn sizeofcmds(&self, endian: Self::Endian) -> u32; -    fn flags(&self, endian: Self::Endian) -> u32; - -    // 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: u64) -> read::Result<&'data Self> { -        let header = data -            .read_at::<Self>(offset) -            .read_error("Invalid Mach-O header size or alignment")?; -        if !header.is_supported() { -            return Err(Error("Unsupported Mach-O header")); -        } -        Ok(header) -    } - -    fn is_supported(&self) -> bool { -        self.is_little_endian() || self.is_big_endian() -    } - -    fn endian(&self) -> Result<Self::Endian> { -        Self::Endian::from_big_endian(self.is_big_endian()).read_error("Unsupported Mach-O endian") -    } - -    fn load_commands<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -        header_offset: u64, -    ) -> Result<LoadCommandIterator<'data, Self::Endian>> { -        let data = data -            .read_bytes_at( -                header_offset + mem::size_of::<Self>() as u64, -                self.sizeofcmds(endian).into(), -            ) -            .read_error("Invalid Mach-O load command table size")?; -        Ok(LoadCommandIterator::new(endian, data, self.ncmds(endian))) -    } - -    /// Return the UUID from the `LC_UUID` load command, if one is present. -    fn uuid<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -        header_offset: u64, -    ) -> Result<Option<[u8; 16]>> { -        let mut commands = self.load_commands(endian, data, header_offset)?; -        while let Some(command) = commands.next()? { -            if let Ok(Some(uuid)) = command.uuid() { -                return Ok(Some(uuid.uuid)); -            } -        } -        Ok(None) -    } -} - -impl<Endian: endian::Endian> MachHeader for macho::MachHeader32<Endian> { -    type Word = u32; -    type Endian = Endian; -    type Segment = macho::SegmentCommand32<Endian>; -    type Section = macho::Section32<Endian>; -    type Nlist = macho::Nlist32<Endian>; - -    fn is_type_64(&self) -> bool { -        false -    } - -    fn is_big_endian(&self) -> bool { -        self.magic() == macho::MH_MAGIC -    } - -    fn is_little_endian(&self) -> bool { -        self.magic() == macho::MH_CIGAM -    } - -    fn magic(&self) -> u32 { -        self.magic.get(BigEndian) -    } - -    fn cputype(&self, endian: Self::Endian) -> u32 { -        self.cputype.get(endian) -    } - -    fn cpusubtype(&self, endian: Self::Endian) -> u32 { -        self.cpusubtype.get(endian) -    } - -    fn filetype(&self, endian: Self::Endian) -> u32 { -        self.filetype.get(endian) -    } - -    fn ncmds(&self, endian: Self::Endian) -> u32 { -        self.ncmds.get(endian) -    } - -    fn sizeofcmds(&self, endian: Self::Endian) -> u32 { -        self.sizeofcmds.get(endian) -    } - -    fn flags(&self, endian: Self::Endian) -> u32 { -        self.flags.get(endian) -    } -} - -impl<Endian: endian::Endian> MachHeader for macho::MachHeader64<Endian> { -    type Word = u64; -    type Endian = Endian; -    type Segment = macho::SegmentCommand64<Endian>; -    type Section = macho::Section64<Endian>; -    type Nlist = macho::Nlist64<Endian>; - -    fn is_type_64(&self) -> bool { -        true -    } - -    fn is_big_endian(&self) -> bool { -        self.magic() == macho::MH_MAGIC_64 -    } - -    fn is_little_endian(&self) -> bool { -        self.magic() == macho::MH_CIGAM_64 -    } - -    fn magic(&self) -> u32 { -        self.magic.get(BigEndian) -    } - -    fn cputype(&self, endian: Self::Endian) -> u32 { -        self.cputype.get(endian) -    } - -    fn cpusubtype(&self, endian: Self::Endian) -> u32 { -        self.cpusubtype.get(endian) -    } - -    fn filetype(&self, endian: Self::Endian) -> u32 { -        self.filetype.get(endian) -    } - -    fn ncmds(&self, endian: Self::Endian) -> u32 { -        self.ncmds.get(endian) -    } - -    fn sizeofcmds(&self, endian: Self::Endian) -> u32 { -        self.sizeofcmds.get(endian) -    } - -    fn flags(&self, endian: Self::Endian) -> u32 { -        self.flags.get(endian) -    } -} diff --git a/vendor/object/src/read/macho/load_command.rs b/vendor/object/src/read/macho/load_command.rs deleted file mode 100644 index 7225fbd..0000000 --- a/vendor/object/src/read/macho/load_command.rs +++ /dev/null @@ -1,382 +0,0 @@ -use core::marker::PhantomData; -use core::mem; - -use crate::endian::Endian; -use crate::macho; -use crate::pod::Pod; -use crate::read::macho::{MachHeader, SymbolTable}; -use crate::read::{Bytes, Error, ReadError, ReadRef, Result, StringTable}; - -/// An iterator for the load commands from a [`MachHeader`]. -#[derive(Debug, Default, Clone, Copy)] -pub struct LoadCommandIterator<'data, E: Endian> { -    endian: E, -    data: Bytes<'data>, -    ncmds: u32, -} - -impl<'data, E: Endian> LoadCommandIterator<'data, E> { -    pub(super) fn new(endian: E, data: &'data [u8], ncmds: u32) -> Self { -        LoadCommandIterator { -            endian, -            data: Bytes(data), -            ncmds, -        } -    } - -    /// Return the next load command. -    pub fn next(&mut self) -> Result<Option<LoadCommandData<'data, E>>> { -        if self.ncmds == 0 { -            return Ok(None); -        } -        let header = self -            .data -            .read_at::<macho::LoadCommand<E>>(0) -            .read_error("Invalid Mach-O load command header")?; -        let cmd = header.cmd.get(self.endian); -        let cmdsize = header.cmdsize.get(self.endian) as usize; -        if cmdsize < mem::size_of::<macho::LoadCommand<E>>() { -            return Err(Error("Invalid Mach-O load command size")); -        } -        let data = self -            .data -            .read_bytes(cmdsize) -            .read_error("Invalid Mach-O load command size")?; -        self.ncmds -= 1; -        Ok(Some(LoadCommandData { -            cmd, -            data, -            marker: Default::default(), -        })) -    } -} - -/// The data for a [`macho::LoadCommand`]. -#[derive(Debug, Clone, Copy)] -pub struct LoadCommandData<'data, E: Endian> { -    cmd: u32, -    // Includes the header. -    data: Bytes<'data>, -    marker: PhantomData<E>, -} - -impl<'data, E: Endian> LoadCommandData<'data, E> { -    /// Return the `cmd` field of the [`macho::LoadCommand`]. -    /// -    /// This is one of the `LC_` constants. -    pub fn cmd(&self) -> u32 { -        self.cmd -    } - -    /// Return the `cmdsize` field of the [`macho::LoadCommand`]. -    pub fn cmdsize(&self) -> u32 { -        self.data.len() as u32 -    } - -    /// Parse the data as the given type. -    #[inline] -    pub fn data<T: Pod>(&self) -> Result<&'data T> { -        self.data -            .read_at(0) -            .read_error("Invalid Mach-O command size") -    } - -    /// Raw bytes of this [`macho::LoadCommand`] structure. -    pub fn raw_data(&self) -> &'data [u8] { -        self.data.0 -    } - -    /// Parse a load command string value. -    /// -    /// Strings used by load commands are specified by offsets that are -    /// relative to the load command header. -    pub fn string(&self, endian: E, s: macho::LcStr<E>) -> Result<&'data [u8]> { -        self.data -            .read_string_at(s.offset.get(endian) as usize) -            .read_error("Invalid load command string offset") -    } - -    /// Parse the command data according to the `cmd` field. -    pub fn variant(&self) -> Result<LoadCommandVariant<'data, E>> { -        Ok(match self.cmd { -            macho::LC_SEGMENT => { -                let mut data = self.data; -                let segment = data.read().read_error("Invalid Mach-O command size")?; -                LoadCommandVariant::Segment32(segment, data.0) -            } -            macho::LC_SYMTAB => LoadCommandVariant::Symtab(self.data()?), -            macho::LC_THREAD | macho::LC_UNIXTHREAD => { -                let mut data = self.data; -                let thread = data.read().read_error("Invalid Mach-O command size")?; -                LoadCommandVariant::Thread(thread, data.0) -            } -            macho::LC_DYSYMTAB => LoadCommandVariant::Dysymtab(self.data()?), -            macho::LC_LOAD_DYLIB -            | macho::LC_LOAD_WEAK_DYLIB -            | macho::LC_REEXPORT_DYLIB -            | macho::LC_LAZY_LOAD_DYLIB -            | macho::LC_LOAD_UPWARD_DYLIB => LoadCommandVariant::Dylib(self.data()?), -            macho::LC_ID_DYLIB => LoadCommandVariant::IdDylib(self.data()?), -            macho::LC_LOAD_DYLINKER => LoadCommandVariant::LoadDylinker(self.data()?), -            macho::LC_ID_DYLINKER => LoadCommandVariant::IdDylinker(self.data()?), -            macho::LC_PREBOUND_DYLIB => LoadCommandVariant::PreboundDylib(self.data()?), -            macho::LC_ROUTINES => LoadCommandVariant::Routines32(self.data()?), -            macho::LC_SUB_FRAMEWORK => LoadCommandVariant::SubFramework(self.data()?), -            macho::LC_SUB_UMBRELLA => LoadCommandVariant::SubUmbrella(self.data()?), -            macho::LC_SUB_CLIENT => LoadCommandVariant::SubClient(self.data()?), -            macho::LC_SUB_LIBRARY => LoadCommandVariant::SubLibrary(self.data()?), -            macho::LC_TWOLEVEL_HINTS => LoadCommandVariant::TwolevelHints(self.data()?), -            macho::LC_PREBIND_CKSUM => LoadCommandVariant::PrebindCksum(self.data()?), -            macho::LC_SEGMENT_64 => { -                let mut data = self.data; -                let segment = data.read().read_error("Invalid Mach-O command size")?; -                LoadCommandVariant::Segment64(segment, data.0) -            } -            macho::LC_ROUTINES_64 => LoadCommandVariant::Routines64(self.data()?), -            macho::LC_UUID => LoadCommandVariant::Uuid(self.data()?), -            macho::LC_RPATH => LoadCommandVariant::Rpath(self.data()?), -            macho::LC_CODE_SIGNATURE -            | macho::LC_SEGMENT_SPLIT_INFO -            | macho::LC_FUNCTION_STARTS -            | macho::LC_DATA_IN_CODE -            | macho::LC_DYLIB_CODE_SIGN_DRS -            | macho::LC_LINKER_OPTIMIZATION_HINT -            | macho::LC_DYLD_EXPORTS_TRIE -            | macho::LC_DYLD_CHAINED_FIXUPS => LoadCommandVariant::LinkeditData(self.data()?), -            macho::LC_ENCRYPTION_INFO => LoadCommandVariant::EncryptionInfo32(self.data()?), -            macho::LC_DYLD_INFO | macho::LC_DYLD_INFO_ONLY => { -                LoadCommandVariant::DyldInfo(self.data()?) -            } -            macho::LC_VERSION_MIN_MACOSX -            | macho::LC_VERSION_MIN_IPHONEOS -            | macho::LC_VERSION_MIN_TVOS -            | macho::LC_VERSION_MIN_WATCHOS => LoadCommandVariant::VersionMin(self.data()?), -            macho::LC_DYLD_ENVIRONMENT => LoadCommandVariant::DyldEnvironment(self.data()?), -            macho::LC_MAIN => LoadCommandVariant::EntryPoint(self.data()?), -            macho::LC_SOURCE_VERSION => LoadCommandVariant::SourceVersion(self.data()?), -            macho::LC_ENCRYPTION_INFO_64 => LoadCommandVariant::EncryptionInfo64(self.data()?), -            macho::LC_LINKER_OPTION => LoadCommandVariant::LinkerOption(self.data()?), -            macho::LC_NOTE => LoadCommandVariant::Note(self.data()?), -            macho::LC_BUILD_VERSION => LoadCommandVariant::BuildVersion(self.data()?), -            macho::LC_FILESET_ENTRY => LoadCommandVariant::FilesetEntry(self.data()?), -            _ => LoadCommandVariant::Other, -        }) -    } - -    /// Try to parse this command as a [`macho::SegmentCommand32`]. -    /// -    /// Returns the segment command and the data containing the sections. -    pub fn segment_32(self) -> Result<Option<(&'data macho::SegmentCommand32<E>, &'data [u8])>> { -        if self.cmd == macho::LC_SEGMENT { -            let mut data = self.data; -            let segment = data.read().read_error("Invalid Mach-O command size")?; -            Ok(Some((segment, data.0))) -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as a [`macho::SymtabCommand`]. -    /// -    /// Returns the segment command and the data containing the sections. -    pub fn symtab(self) -> Result<Option<&'data macho::SymtabCommand<E>>> { -        if self.cmd == macho::LC_SYMTAB { -            Some(self.data()).transpose() -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as a [`macho::DysymtabCommand`]. -    pub fn dysymtab(self) -> Result<Option<&'data macho::DysymtabCommand<E>>> { -        if self.cmd == macho::LC_DYSYMTAB { -            Some(self.data()).transpose() -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as a [`macho::DylibCommand`]. -    pub fn dylib(self) -> Result<Option<&'data macho::DylibCommand<E>>> { -        if self.cmd == macho::LC_LOAD_DYLIB -            || self.cmd == macho::LC_LOAD_WEAK_DYLIB -            || self.cmd == macho::LC_REEXPORT_DYLIB -            || self.cmd == macho::LC_LAZY_LOAD_DYLIB -            || self.cmd == macho::LC_LOAD_UPWARD_DYLIB -        { -            Some(self.data()).transpose() -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as a [`macho::UuidCommand`]. -    pub fn uuid(self) -> Result<Option<&'data macho::UuidCommand<E>>> { -        if self.cmd == macho::LC_UUID { -            Some(self.data()).transpose() -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as a [`macho::SegmentCommand64`]. -    pub fn segment_64(self) -> Result<Option<(&'data macho::SegmentCommand64<E>, &'data [u8])>> { -        if self.cmd == macho::LC_SEGMENT_64 { -            let mut data = self.data; -            let command = data.read().read_error("Invalid Mach-O command size")?; -            Ok(Some((command, data.0))) -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as a [`macho::DyldInfoCommand`]. -    pub fn dyld_info(self) -> Result<Option<&'data macho::DyldInfoCommand<E>>> { -        if self.cmd == macho::LC_DYLD_INFO || self.cmd == macho::LC_DYLD_INFO_ONLY { -            Some(self.data()).transpose() -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as an [`macho::EntryPointCommand`]. -    pub fn entry_point(self) -> Result<Option<&'data macho::EntryPointCommand<E>>> { -        if self.cmd == macho::LC_MAIN { -            Some(self.data()).transpose() -        } else { -            Ok(None) -        } -    } - -    /// Try to parse this command as a [`macho::BuildVersionCommand`]. -    pub fn build_version(self) -> Result<Option<&'data macho::BuildVersionCommand<E>>> { -        if self.cmd == macho::LC_BUILD_VERSION { -            Some(self.data()).transpose() -        } else { -            Ok(None) -        } -    } -} - -/// A [`macho::LoadCommand`] that has been interpreted according to its `cmd` field. -#[derive(Debug, Clone, Copy)] -#[non_exhaustive] -pub enum LoadCommandVariant<'data, E: Endian> { -    /// `LC_SEGMENT` -    Segment32(&'data macho::SegmentCommand32<E>, &'data [u8]), -    /// `LC_SYMTAB` -    Symtab(&'data macho::SymtabCommand<E>), -    // obsolete: `LC_SYMSEG` -    //Symseg(&'data macho::SymsegCommand<E>), -    /// `LC_THREAD` or `LC_UNIXTHREAD` -    Thread(&'data macho::ThreadCommand<E>, &'data [u8]), -    // obsolete: `LC_IDFVMLIB` or `LC_LOADFVMLIB` -    //Fvmlib(&'data macho::FvmlibCommand<E>), -    // obsolete: `LC_IDENT` -    //Ident(&'data macho::IdentCommand<E>), -    // internal: `LC_FVMFILE` -    //Fvmfile(&'data macho::FvmfileCommand<E>), -    // internal: `LC_PREPAGE` -    /// `LC_DYSYMTAB` -    Dysymtab(&'data macho::DysymtabCommand<E>), -    /// `LC_LOAD_DYLIB`, `LC_LOAD_WEAK_DYLIB`, `LC_REEXPORT_DYLIB`, -    /// `LC_LAZY_LOAD_DYLIB`, or `LC_LOAD_UPWARD_DYLIB` -    Dylib(&'data macho::DylibCommand<E>), -    /// `LC_ID_DYLIB` -    IdDylib(&'data macho::DylibCommand<E>), -    /// `LC_LOAD_DYLINKER` -    LoadDylinker(&'data macho::DylinkerCommand<E>), -    /// `LC_ID_DYLINKER` -    IdDylinker(&'data macho::DylinkerCommand<E>), -    /// `LC_PREBOUND_DYLIB` -    PreboundDylib(&'data macho::PreboundDylibCommand<E>), -    /// `LC_ROUTINES` -    Routines32(&'data macho::RoutinesCommand32<E>), -    /// `LC_SUB_FRAMEWORK` -    SubFramework(&'data macho::SubFrameworkCommand<E>), -    /// `LC_SUB_UMBRELLA` -    SubUmbrella(&'data macho::SubUmbrellaCommand<E>), -    /// `LC_SUB_CLIENT` -    SubClient(&'data macho::SubClientCommand<E>), -    /// `LC_SUB_LIBRARY` -    SubLibrary(&'data macho::SubLibraryCommand<E>), -    /// `LC_TWOLEVEL_HINTS` -    TwolevelHints(&'data macho::TwolevelHintsCommand<E>), -    /// `LC_PREBIND_CKSUM` -    PrebindCksum(&'data macho::PrebindCksumCommand<E>), -    /// `LC_SEGMENT_64` -    Segment64(&'data macho::SegmentCommand64<E>, &'data [u8]), -    /// `LC_ROUTINES_64` -    Routines64(&'data macho::RoutinesCommand64<E>), -    /// `LC_UUID` -    Uuid(&'data macho::UuidCommand<E>), -    /// `LC_RPATH` -    Rpath(&'data macho::RpathCommand<E>), -    /// `LC_CODE_SIGNATURE`, `LC_SEGMENT_SPLIT_INFO`, `LC_FUNCTION_STARTS`, -    /// `LC_DATA_IN_CODE`, `LC_DYLIB_CODE_SIGN_DRS`, `LC_LINKER_OPTIMIZATION_HINT`, -    /// `LC_DYLD_EXPORTS_TRIE`, or `LC_DYLD_CHAINED_FIXUPS`. -    LinkeditData(&'data macho::LinkeditDataCommand<E>), -    /// `LC_ENCRYPTION_INFO` -    EncryptionInfo32(&'data macho::EncryptionInfoCommand32<E>), -    /// `LC_DYLD_INFO` or `LC_DYLD_INFO_ONLY` -    DyldInfo(&'data macho::DyldInfoCommand<E>), -    /// `LC_VERSION_MIN_MACOSX`, `LC_VERSION_MIN_IPHONEOS`, `LC_VERSION_MIN_WATCHOS`, -    /// or `LC_VERSION_MIN_TVOS` -    VersionMin(&'data macho::VersionMinCommand<E>), -    /// `LC_DYLD_ENVIRONMENT` -    DyldEnvironment(&'data macho::DylinkerCommand<E>), -    /// `LC_MAIN` -    EntryPoint(&'data macho::EntryPointCommand<E>), -    /// `LC_SOURCE_VERSION` -    SourceVersion(&'data macho::SourceVersionCommand<E>), -    /// `LC_ENCRYPTION_INFO_64` -    EncryptionInfo64(&'data macho::EncryptionInfoCommand64<E>), -    /// `LC_LINKER_OPTION` -    LinkerOption(&'data macho::LinkerOptionCommand<E>), -    /// `LC_NOTE` -    Note(&'data macho::NoteCommand<E>), -    /// `LC_BUILD_VERSION` -    BuildVersion(&'data macho::BuildVersionCommand<E>), -    /// `LC_FILESET_ENTRY` -    FilesetEntry(&'data macho::FilesetEntryCommand<E>), -    /// An unrecognized or obsolete load command. -    Other, -} - -impl<E: Endian> macho::SymtabCommand<E> { -    /// Return the symbol table that this command references. -    pub fn symbols<'data, Mach: MachHeader<Endian = E>, R: ReadRef<'data>>( -        &self, -        endian: E, -        data: R, -    ) -> Result<SymbolTable<'data, Mach, R>> { -        let symbols = data -            .read_slice_at( -                self.symoff.get(endian).into(), -                self.nsyms.get(endian) as usize, -            ) -            .read_error("Invalid Mach-O symbol table offset or size")?; -        let str_start: u64 = self.stroff.get(endian).into(); -        let str_end = str_start -            .checked_add(self.strsize.get(endian).into()) -            .read_error("Invalid Mach-O string table length")?; -        let strings = StringTable::new(data, str_start, str_end); -        Ok(SymbolTable::new(symbols, strings)) -    } -} - -#[cfg(test)] -mod tests { -    use super::*; -    use crate::LittleEndian; - -    #[test] -    fn cmd_size_invalid() { -        let mut commands = LoadCommandIterator::new(LittleEndian, &[0; 8], 10); -        assert!(commands.next().is_err()); -        let mut commands = LoadCommandIterator::new(LittleEndian, &[0, 0, 0, 0, 7, 0, 0, 0, 0], 10); -        assert!(commands.next().is_err()); -        let mut commands = LoadCommandIterator::new(LittleEndian, &[0, 0, 0, 0, 8, 0, 0, 0, 0], 10); -        assert!(commands.next().is_ok()); -    } -} diff --git a/vendor/object/src/read/macho/mod.rs b/vendor/object/src/read/macho/mod.rs deleted file mode 100644 index ab51ff3..0000000 --- a/vendor/object/src/read/macho/mod.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! Support for reading Mach-O files. -//! -//! Traits are used to abstract over the difference between 32-bit and 64-bit Mach-O -//! files. The primary trait for this is [`MachHeader`]. -//! -//! ## High level API -//! -//! [`MachOFile`] implements the [`Object`](crate::read::Object) trait for Mach-O files. -//! [`MachOFile`] is parameterised by [`MachHeader`] to allow reading both 32-bit and -//! 64-bit Mach-O files. There are type aliases for these parameters ([`MachOFile32`] and -//! [`MachOFile64`]). -//! -//! ## Low level API -//! -//! The [`MachHeader`] trait can be directly used to parse both [`macho::MachHeader32`] -//! and [`macho::MachHeader64`]. Additionally, [`FatHeader`] and the [`FatArch`] trait -//! can be used to iterate images in multi-architecture binaries, and [`DyldCache`] can -//! be used to locate images in a dyld shared cache. -//! -//! ### Example for low level API -//!  ```no_run -//! use object::macho; -//! use object::read::macho::{MachHeader, Nlist}; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads a file and displays the name of each symbol. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let header = macho::MachHeader64::<object::Endianness>::parse(&*data, 0)?; -//!     let endian = header.endian()?; -//!     let mut commands = header.load_commands(endian, &*data, 0)?; -//!     while let Some(command) = commands.next()? { -//!         if let Some(symtab_command) = command.symtab()? { -//!             let symbols = symtab_command.symbols::<macho::MachHeader64<_>, _>(endian, &*data)?; -//!             for symbol in symbols.iter() { -//!                 let name = symbol.name(endian, symbols.strings())?; -//!                 println!("{}", String::from_utf8_lossy(name)); -//!             } -//!         } -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` -#[cfg(doc)] -use crate::macho; - -mod dyld_cache; -pub use dyld_cache::*; - -mod fat; -pub use fat::*; - -mod file; -pub use file::*; - -mod load_command; -pub use load_command::*; - -mod segment; -pub use segment::*; - -mod section; -pub use section::*; - -mod symbol; -pub use symbol::*; - -mod relocation; -pub use relocation::*; diff --git a/vendor/object/src/read/macho/relocation.rs b/vendor/object/src/read/macho/relocation.rs deleted file mode 100644 index 709f1a4..0000000 --- a/vendor/object/src/read/macho/relocation.rs +++ /dev/null @@ -1,158 +0,0 @@ -use core::{fmt, slice}; - -use crate::endian::Endianness; -use crate::macho; -use crate::read::{ -    ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, SectionIndex, -    SymbolIndex, -}; - -use super::{MachHeader, MachOFile}; - -/// An iterator for the relocations in a [`MachOSection32`](super::MachOSection32). -pub type MachORelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachORelocationIterator<'data, 'file, macho::MachHeader32<Endian>, R>; -/// An iterator for the relocations in a [`MachOSection64`](super::MachOSection64). -pub type MachORelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachORelocationIterator<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// An iterator for the relocations in a [`MachOSection`](super::MachOSection). -pub struct MachORelocationIterator<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file MachOFile<'data, Mach, R>, -    pub(super) relocations: slice::Iter<'data, macho::Relocation<Mach::Endian>>, -} - -impl<'data, 'file, Mach, R> Iterator for MachORelocationIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type Item = (u64, Relocation); - -    fn next(&mut self) -> Option<Self::Item> { -        let mut paired_addend = 0; -        loop { -            let reloc = self.relocations.next()?; -            let endian = self.file.endian; -            let cputype = self.file.header.cputype(endian); -            if reloc.r_scattered(endian, cputype) { -                // FIXME: handle scattered relocations -                // We need to add `RelocationTarget::Address` for this. -                continue; -            } -            let reloc = reloc.info(self.file.endian); -            let mut encoding = RelocationEncoding::Generic; -            let kind = match cputype { -                macho::CPU_TYPE_ARM => match (reloc.r_type, reloc.r_pcrel) { -                    (macho::ARM_RELOC_VANILLA, false) => RelocationKind::Absolute, -                    _ => RelocationKind::MachO { -                        value: reloc.r_type, -                        relative: reloc.r_pcrel, -                    }, -                }, -                macho::CPU_TYPE_ARM64 | macho::CPU_TYPE_ARM64_32 => { -                    match (reloc.r_type, reloc.r_pcrel) { -                        (macho::ARM64_RELOC_UNSIGNED, false) => RelocationKind::Absolute, -                        (macho::ARM64_RELOC_ADDEND, _) => { -                            paired_addend = i64::from(reloc.r_symbolnum) -                                .wrapping_shl(64 - 24) -                                .wrapping_shr(64 - 24); -                            continue; -                        } -                        _ => RelocationKind::MachO { -                            value: reloc.r_type, -                            relative: reloc.r_pcrel, -                        }, -                    } -                } -                macho::CPU_TYPE_X86 => match (reloc.r_type, reloc.r_pcrel) { -                    (macho::GENERIC_RELOC_VANILLA, false) => RelocationKind::Absolute, -                    _ => RelocationKind::MachO { -                        value: reloc.r_type, -                        relative: reloc.r_pcrel, -                    }, -                }, -                macho::CPU_TYPE_X86_64 => match (reloc.r_type, reloc.r_pcrel) { -                    (macho::X86_64_RELOC_UNSIGNED, false) => RelocationKind::Absolute, -                    (macho::X86_64_RELOC_SIGNED, true) => { -                        encoding = RelocationEncoding::X86RipRelative; -                        RelocationKind::Relative -                    } -                    (macho::X86_64_RELOC_BRANCH, true) => { -                        encoding = RelocationEncoding::X86Branch; -                        RelocationKind::Relative -                    } -                    (macho::X86_64_RELOC_GOT, true) => RelocationKind::GotRelative, -                    (macho::X86_64_RELOC_GOT_LOAD, true) => { -                        encoding = RelocationEncoding::X86RipRelativeMovq; -                        RelocationKind::GotRelative -                    } -                    _ => RelocationKind::MachO { -                        value: reloc.r_type, -                        relative: reloc.r_pcrel, -                    }, -                }, -                _ => RelocationKind::MachO { -                    value: reloc.r_type, -                    relative: reloc.r_pcrel, -                }, -            }; -            let size = 8 << reloc.r_length; -            let target = if reloc.r_extern { -                RelocationTarget::Symbol(SymbolIndex(reloc.r_symbolnum as usize)) -            } else { -                RelocationTarget::Section(SectionIndex(reloc.r_symbolnum as usize)) -            }; -            let implicit_addend = paired_addend == 0; -            let mut addend = paired_addend; -            if reloc.r_pcrel { -                // For PC relative relocations on some architectures, the -                // addend does not include the offset required due to the -                // PC being different from the place of the relocation. -                // This differs from other file formats, so adjust the -                // addend here to account for this. -                match cputype { -                    macho::CPU_TYPE_X86 => { -                        addend -= 1 << reloc.r_length; -                    } -                    macho::CPU_TYPE_X86_64 => { -                        addend -= 1 << reloc.r_length; -                        match reloc.r_type { -                            macho::X86_64_RELOC_SIGNED_1 => addend -= 1, -                            macho::X86_64_RELOC_SIGNED_2 => addend -= 2, -                            macho::X86_64_RELOC_SIGNED_4 => addend -= 4, -                            _ => {} -                        } -                    } -                    // TODO: maybe missing support for some architectures and relocations -                    _ => {} -                } -            } -            return Some(( -                reloc.r_address as u64, -                Relocation { -                    kind, -                    encoding, -                    size, -                    target, -                    addend, -                    implicit_addend, -                }, -            )); -        } -    } -} - -impl<'data, 'file, Mach, R> fmt::Debug for MachORelocationIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("MachORelocationIterator").finish() -    } -} diff --git a/vendor/object/src/read/macho/section.rs b/vendor/object/src/read/macho/section.rs deleted file mode 100644 index 7c79123..0000000 --- a/vendor/object/src/read/macho/section.rs +++ /dev/null @@ -1,389 +0,0 @@ -use core::fmt::Debug; -use core::{fmt, result, slice, str}; - -use crate::endian::{self, Endianness}; -use crate::macho; -use crate::pod::Pod; -use crate::read::{ -    self, CompressedData, CompressedFileRange, ObjectSection, ReadError, ReadRef, Result, -    SectionFlags, SectionIndex, SectionKind, -}; - -use super::{MachHeader, MachOFile, MachORelocationIterator}; - -/// An iterator for the sections in a [`MachOFile32`](super::MachOFile32). -pub type MachOSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSectionIterator<'data, 'file, macho::MachHeader32<Endian>, R>; -/// An iterator for the sections in a [`MachOFile64`](super::MachOFile64). -pub type MachOSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSectionIterator<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// An iterator for the sections in a [`MachOFile`]. -pub struct MachOSectionIterator<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file MachOFile<'data, Mach, R>, -    pub(super) iter: slice::Iter<'file, MachOSectionInternal<'data, Mach>>, -} - -impl<'data, 'file, Mach, R> fmt::Debug for MachOSectionIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        // It's painful to do much better than this -        f.debug_struct("MachOSectionIterator").finish() -    } -} - -impl<'data, 'file, Mach, R> Iterator for MachOSectionIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type Item = MachOSection<'data, 'file, Mach, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|&internal| MachOSection { -            file: self.file, -            internal, -        }) -    } -} - -/// A section in a [`MachOFile32`](super::MachOFile32). -pub type MachOSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSection<'data, 'file, macho::MachHeader32<Endian>, R>; -/// A section in a [`MachOFile64`](super::MachOFile64). -pub type MachOSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSection<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// A section in a [`MachOFile`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -#[derive(Debug)] -pub struct MachOSection<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file MachOFile<'data, Mach, R>, -    pub(super) internal: MachOSectionInternal<'data, Mach>, -} - -impl<'data, 'file, Mach, R> MachOSection<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    fn bytes(&self) -> Result<&'data [u8]> { -        let segment_index = self.internal.segment_index; -        let segment = self.file.segment_internal(segment_index)?; -        self.internal -            .section -            .data(self.file.endian, segment.data) -            .read_error("Invalid Mach-O section size or offset") -    } -} - -impl<'data, 'file, Mach, R> read::private::Sealed for MachOSection<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Mach, R> ObjectSection<'data> for MachOSection<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type RelocationIterator = MachORelocationIterator<'data, 'file, Mach, R>; - -    #[inline] -    fn index(&self) -> SectionIndex { -        self.internal.index -    } - -    #[inline] -    fn address(&self) -> u64 { -        self.internal.section.addr(self.file.endian).into() -    } - -    #[inline] -    fn size(&self) -> u64 { -        self.internal.section.size(self.file.endian).into() -    } - -    #[inline] -    fn align(&self) -> u64 { -        let align = self.internal.section.align(self.file.endian); -        if align < 64 { -            1 << align -        } else { -            0 -        } -    } - -    #[inline] -    fn file_range(&self) -> Option<(u64, u64)> { -        self.internal.section.file_range(self.file.endian) -    } - -    #[inline] -    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, -        )) -    } - -    #[inline] -    fn compressed_file_range(&self) -> Result<CompressedFileRange> { -        Ok(CompressedFileRange::none(self.file_range())) -    } - -    #[inline] -    fn compressed_data(&self) -> Result<CompressedData<'data>> { -        self.data().map(CompressedData::none) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<&[u8]> { -        Ok(self.internal.section.name()) -    } - -    #[inline] -    fn name(&self) -> Result<&str> { -        str::from_utf8(self.internal.section.name()) -            .ok() -            .read_error("Non UTF-8 Mach-O section name") -    } - -    #[inline] -    fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { -        Ok(Some(self.internal.section.segment_name())) -    } - -    #[inline] -    fn segment_name(&self) -> Result<Option<&str>> { -        Ok(Some( -            str::from_utf8(self.internal.section.segment_name()) -                .ok() -                .read_error("Non UTF-8 Mach-O segment name")?, -        )) -    } - -    fn kind(&self) -> SectionKind { -        self.internal.kind -    } - -    fn relocations(&self) -> MachORelocationIterator<'data, 'file, Mach, R> { -        MachORelocationIterator { -            file: self.file, -            relocations: self -                .internal -                .section -                .relocations(self.file.endian, self.file.data) -                .unwrap_or(&[]) -                .iter(), -        } -    } - -    fn flags(&self) -> SectionFlags { -        SectionFlags::MachO { -            flags: self.internal.section.flags(self.file.endian), -        } -    } -} - -#[derive(Debug, Clone, Copy)] -pub(super) struct MachOSectionInternal<'data, Mach: MachHeader> { -    pub index: SectionIndex, -    pub segment_index: usize, -    pub kind: SectionKind, -    pub section: &'data Mach::Section, -} - -impl<'data, Mach: MachHeader> MachOSectionInternal<'data, Mach> { -    pub(super) fn parse( -        index: SectionIndex, -        segment_index: usize, -        section: &'data Mach::Section, -    ) -> Self { -        // TODO: we don't validate flags, should we? -        let kind = match (section.segment_name(), section.name()) { -            (b"__TEXT", b"__text") => SectionKind::Text, -            (b"__TEXT", b"__const") => SectionKind::ReadOnlyData, -            (b"__TEXT", b"__cstring") => SectionKind::ReadOnlyString, -            (b"__TEXT", b"__literal4") => SectionKind::ReadOnlyData, -            (b"__TEXT", b"__literal8") => SectionKind::ReadOnlyData, -            (b"__TEXT", b"__literal16") => SectionKind::ReadOnlyData, -            (b"__TEXT", b"__eh_frame") => SectionKind::ReadOnlyData, -            (b"__TEXT", b"__gcc_except_tab") => SectionKind::ReadOnlyData, -            (b"__DATA", b"__data") => SectionKind::Data, -            (b"__DATA", b"__const") => SectionKind::ReadOnlyData, -            (b"__DATA", b"__bss") => SectionKind::UninitializedData, -            (b"__DATA", b"__common") => SectionKind::Common, -            (b"__DATA", b"__thread_data") => SectionKind::Tls, -            (b"__DATA", b"__thread_bss") => SectionKind::UninitializedTls, -            (b"__DATA", b"__thread_vars") => SectionKind::TlsVariables, -            (b"__DWARF", _) => SectionKind::Debug, -            _ => SectionKind::Unknown, -        }; -        MachOSectionInternal { -            index, -            segment_index, -            kind, -            section, -        } -    } -} - -/// A trait for generic access to [`macho::Section32`] and [`macho::Section64`]. -#[allow(missing_docs)] -pub trait Section: Debug + Pod { -    type Word: Into<u64>; -    type Endian: endian::Endian; - -    fn sectname(&self) -> &[u8; 16]; -    fn segname(&self) -> &[u8; 16]; -    fn addr(&self, endian: Self::Endian) -> Self::Word; -    fn size(&self, endian: Self::Endian) -> Self::Word; -    fn offset(&self, endian: Self::Endian) -> u32; -    fn align(&self, endian: Self::Endian) -> u32; -    fn reloff(&self, endian: Self::Endian) -> u32; -    fn nreloc(&self, endian: Self::Endian) -> u32; -    fn flags(&self, endian: Self::Endian) -> u32; - -    /// Return the `sectname` bytes up until the null terminator. -    fn name(&self) -> &[u8] { -        let sectname = &self.sectname()[..]; -        match memchr::memchr(b'\0', sectname) { -            Some(end) => §name[..end], -            None => sectname, -        } -    } - -    /// Return the `segname` bytes up until the null terminator. -    fn segment_name(&self) -> &[u8] { -        let segname = &self.segname()[..]; -        match memchr::memchr(b'\0', segname) { -            Some(end) => &segname[..end], -            None => segname, -        } -    } - -    /// 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)> { -        match self.flags(endian) & macho::SECTION_TYPE { -            macho::S_ZEROFILL | macho::S_GB_ZEROFILL | macho::S_THREAD_LOCAL_ZEROFILL => None, -            _ => Some((self.offset(endian).into(), self.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, -    ) -> result::Result<&'data [u8], ()> { -        if let Some((offset, size)) = self.file_range(endian) { -            data.read_bytes_at(offset, size) -        } else { -            Ok(&[]) -        } -    } - -    /// Return the relocation array. -    /// -    /// Returns `Err` for invalid values. -    fn relocations<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> Result<&'data [macho::Relocation<Self::Endian>]> { -        data.read_slice_at(self.reloff(endian).into(), self.nreloc(endian) as usize) -            .read_error("Invalid Mach-O relocations offset or number") -    } -} - -impl<Endian: endian::Endian> Section for macho::Section32<Endian> { -    type Word = u32; -    type Endian = Endian; - -    fn sectname(&self) -> &[u8; 16] { -        &self.sectname -    } -    fn segname(&self) -> &[u8; 16] { -        &self.segname -    } -    fn addr(&self, endian: Self::Endian) -> Self::Word { -        self.addr.get(endian) -    } -    fn size(&self, endian: Self::Endian) -> Self::Word { -        self.size.get(endian) -    } -    fn offset(&self, endian: Self::Endian) -> u32 { -        self.offset.get(endian) -    } -    fn align(&self, endian: Self::Endian) -> u32 { -        self.align.get(endian) -    } -    fn reloff(&self, endian: Self::Endian) -> u32 { -        self.reloff.get(endian) -    } -    fn nreloc(&self, endian: Self::Endian) -> u32 { -        self.nreloc.get(endian) -    } -    fn flags(&self, endian: Self::Endian) -> u32 { -        self.flags.get(endian) -    } -} - -impl<Endian: endian::Endian> Section for macho::Section64<Endian> { -    type Word = u64; -    type Endian = Endian; - -    fn sectname(&self) -> &[u8; 16] { -        &self.sectname -    } -    fn segname(&self) -> &[u8; 16] { -        &self.segname -    } -    fn addr(&self, endian: Self::Endian) -> Self::Word { -        self.addr.get(endian) -    } -    fn size(&self, endian: Self::Endian) -> Self::Word { -        self.size.get(endian) -    } -    fn offset(&self, endian: Self::Endian) -> u32 { -        self.offset.get(endian) -    } -    fn align(&self, endian: Self::Endian) -> u32 { -        self.align.get(endian) -    } -    fn reloff(&self, endian: Self::Endian) -> u32 { -        self.reloff.get(endian) -    } -    fn nreloc(&self, endian: Self::Endian) -> u32 { -        self.nreloc.get(endian) -    } -    fn flags(&self, endian: Self::Endian) -> u32 { -        self.flags.get(endian) -    } -} diff --git a/vendor/object/src/read/macho/segment.rs b/vendor/object/src/read/macho/segment.rs deleted file mode 100644 index c889ad2..0000000 --- a/vendor/object/src/read/macho/segment.rs +++ /dev/null @@ -1,303 +0,0 @@ -use core::fmt::Debug; -use core::{result, slice, str}; - -use crate::endian::{self, Endianness}; -use crate::macho; -use crate::pod::Pod; -use crate::read::{self, ObjectSegment, ReadError, ReadRef, Result, SegmentFlags}; - -use super::{LoadCommandData, MachHeader, MachOFile, Section}; - -/// An iterator for the segments in a [`MachOFile32`](super::MachOFile32). -pub type MachOSegmentIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSegmentIterator<'data, 'file, macho::MachHeader32<Endian>, R>; -/// An iterator for the segments in a [`MachOFile64`](super::MachOFile64). -pub type MachOSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSegmentIterator<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// An iterator for the segments in a [`MachOFile`]. -#[derive(Debug)] -pub struct MachOSegmentIterator<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file MachOFile<'data, Mach, R>, -    pub(super) iter: slice::Iter<'file, MachOSegmentInternal<'data, Mach, R>>, -} - -impl<'data, 'file, Mach, R> Iterator for MachOSegmentIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type Item = MachOSegment<'data, 'file, Mach, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|internal| MachOSegment { -            file: self.file, -            internal, -        }) -    } -} - -/// A segment in a [`MachOFile32`](super::MachOFile32). -pub type MachOSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSegment<'data, 'file, macho::MachHeader32<Endian>, R>; -/// A segment in a [`MachOFile64`](super::MachOFile64). -pub type MachOSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSegment<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// A segment in a [`MachOFile`]. -/// -/// Most functionality is provided by the [`ObjectSegment`] trait implementation. -#[derive(Debug)] -pub struct MachOSegment<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    file: &'file MachOFile<'data, Mach, R>, -    internal: &'file MachOSegmentInternal<'data, Mach, R>, -} - -impl<'data, 'file, Mach, R> MachOSegment<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    fn bytes(&self) -> Result<&'data [u8]> { -        self.internal -            .segment -            .data(self.file.endian, self.file.data) -            .read_error("Invalid Mach-O segment size or offset") -    } -} - -impl<'data, 'file, Mach, R> read::private::Sealed for MachOSegment<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Mach, R> ObjectSegment<'data> for MachOSegment<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    #[inline] -    fn address(&self) -> u64 { -        self.internal.segment.vmaddr(self.file.endian).into() -    } - -    #[inline] -    fn size(&self) -> u64 { -        self.internal.segment.vmsize(self.file.endian).into() -    } - -    #[inline] -    fn align(&self) -> u64 { -        // Page size. -        0x1000 -    } - -    #[inline] -    fn file_range(&self) -> (u64, u64) { -        self.internal.segment.file_range(self.file.endian) -    } - -    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, -        )) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<Option<&[u8]>> { -        Ok(Some(self.internal.segment.name())) -    } - -    #[inline] -    fn name(&self) -> Result<Option<&str>> { -        Ok(Some( -            str::from_utf8(self.internal.segment.name()) -                .ok() -                .read_error("Non UTF-8 Mach-O segment name")?, -        )) -    } - -    #[inline] -    fn flags(&self) -> SegmentFlags { -        let flags = self.internal.segment.flags(self.file.endian); -        let maxprot = self.internal.segment.maxprot(self.file.endian); -        let initprot = self.internal.segment.initprot(self.file.endian); -        SegmentFlags::MachO { -            flags, -            maxprot, -            initprot, -        } -    } -} - -#[derive(Debug, Clone, Copy)] -pub(super) struct MachOSegmentInternal<'data, Mach: MachHeader, R: ReadRef<'data>> { -    pub data: R, -    pub segment: &'data Mach::Segment, -} - -/// A trait for generic access to [`macho::SegmentCommand32`] and [`macho::SegmentCommand64`]. -#[allow(missing_docs)] -pub trait Segment: Debug + Pod { -    type Word: Into<u64>; -    type Endian: endian::Endian; -    type Section: Section<Endian = Self::Endian>; - -    fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result<Option<(&Self, &[u8])>>; - -    fn cmd(&self, endian: Self::Endian) -> u32; -    fn cmdsize(&self, endian: Self::Endian) -> u32; -    fn segname(&self) -> &[u8; 16]; -    fn vmaddr(&self, endian: Self::Endian) -> Self::Word; -    fn vmsize(&self, endian: Self::Endian) -> Self::Word; -    fn fileoff(&self, endian: Self::Endian) -> Self::Word; -    fn filesize(&self, endian: Self::Endian) -> Self::Word; -    fn maxprot(&self, endian: Self::Endian) -> u32; -    fn initprot(&self, endian: Self::Endian) -> u32; -    fn nsects(&self, endian: Self::Endian) -> u32; -    fn flags(&self, endian: Self::Endian) -> u32; - -    /// Return the `segname` bytes up until the null terminator. -    fn name(&self) -> &[u8] { -        let segname = &self.segname()[..]; -        match memchr::memchr(b'\0', segname) { -            Some(end) => &segname[..end], -            None => segname, -        } -    } - -    /// Return the offset and size of the segment in the file. -    fn file_range(&self, endian: Self::Endian) -> (u64, u64) { -        (self.fileoff(endian).into(), self.filesize(endian).into()) -    } - -    /// Get the segment data from the file data. -    /// -    /// Returns `Err` for invalid values. -    fn data<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        data: R, -    ) -> result::Result<&'data [u8], ()> { -        let (offset, size) = self.file_range(endian); -        data.read_bytes_at(offset, size) -    } - -    /// Get the array of sections from the data following the segment command. -    /// -    /// Returns `Err` for invalid values. -    fn sections<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        section_data: R, -    ) -> Result<&'data [Self::Section]> { -        section_data -            .read_slice_at(0, self.nsects(endian) as usize) -            .read_error("Invalid Mach-O number of sections") -    } -} - -impl<Endian: endian::Endian> Segment for macho::SegmentCommand32<Endian> { -    type Word = u32; -    type Endian = Endian; -    type Section = macho::Section32<Self::Endian>; - -    fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result<Option<(&Self, &[u8])>> { -        command.segment_32() -    } - -    fn cmd(&self, endian: Self::Endian) -> u32 { -        self.cmd.get(endian) -    } -    fn cmdsize(&self, endian: Self::Endian) -> u32 { -        self.cmdsize.get(endian) -    } -    fn segname(&self) -> &[u8; 16] { -        &self.segname -    } -    fn vmaddr(&self, endian: Self::Endian) -> Self::Word { -        self.vmaddr.get(endian) -    } -    fn vmsize(&self, endian: Self::Endian) -> Self::Word { -        self.vmsize.get(endian) -    } -    fn fileoff(&self, endian: Self::Endian) -> Self::Word { -        self.fileoff.get(endian) -    } -    fn filesize(&self, endian: Self::Endian) -> Self::Word { -        self.filesize.get(endian) -    } -    fn maxprot(&self, endian: Self::Endian) -> u32 { -        self.maxprot.get(endian) -    } -    fn initprot(&self, endian: Self::Endian) -> u32 { -        self.initprot.get(endian) -    } -    fn nsects(&self, endian: Self::Endian) -> u32 { -        self.nsects.get(endian) -    } -    fn flags(&self, endian: Self::Endian) -> u32 { -        self.flags.get(endian) -    } -} - -impl<Endian: endian::Endian> Segment for macho::SegmentCommand64<Endian> { -    type Word = u64; -    type Endian = Endian; -    type Section = macho::Section64<Self::Endian>; - -    fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result<Option<(&Self, &[u8])>> { -        command.segment_64() -    } - -    fn cmd(&self, endian: Self::Endian) -> u32 { -        self.cmd.get(endian) -    } -    fn cmdsize(&self, endian: Self::Endian) -> u32 { -        self.cmdsize.get(endian) -    } -    fn segname(&self) -> &[u8; 16] { -        &self.segname -    } -    fn vmaddr(&self, endian: Self::Endian) -> Self::Word { -        self.vmaddr.get(endian) -    } -    fn vmsize(&self, endian: Self::Endian) -> Self::Word { -        self.vmsize.get(endian) -    } -    fn fileoff(&self, endian: Self::Endian) -> Self::Word { -        self.fileoff.get(endian) -    } -    fn filesize(&self, endian: Self::Endian) -> Self::Word { -        self.filesize.get(endian) -    } -    fn maxprot(&self, endian: Self::Endian) -> u32 { -        self.maxprot.get(endian) -    } -    fn initprot(&self, endian: Self::Endian) -> u32 { -        self.initprot.get(endian) -    } -    fn nsects(&self, endian: Self::Endian) -> u32 { -        self.nsects.get(endian) -    } -    fn flags(&self, endian: Self::Endian) -> u32 { -        self.flags.get(endian) -    } -} diff --git a/vendor/object/src/read/macho/symbol.rs b/vendor/object/src/read/macho/symbol.rs deleted file mode 100644 index 434361f..0000000 --- a/vendor/object/src/read/macho/symbol.rs +++ /dev/null @@ -1,492 +0,0 @@ -use alloc::vec::Vec; -use core::fmt::Debug; -use core::{fmt, slice, str}; - -use crate::endian::{self, Endianness}; -use crate::macho; -use crate::pod::Pod; -use crate::read::util::StringTable; -use crate::read::{ -    self, ObjectMap, ObjectMapEntry, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, -    SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry, -    SymbolScope, SymbolSection, -}; - -use super::{MachHeader, MachOFile}; - -/// A table of symbol entries in a Mach-O file. -/// -/// Also includes the string table used for the symbol names. -/// -/// Returned by [`macho::SymtabCommand::symbols`]. -#[derive(Debug, Clone, Copy)] -pub struct SymbolTable<'data, Mach: MachHeader, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    symbols: &'data [Mach::Nlist], -    strings: StringTable<'data, R>, -} - -impl<'data, Mach: MachHeader, R: ReadRef<'data>> Default for SymbolTable<'data, Mach, R> { -    fn default() -> Self { -        SymbolTable { -            symbols: &[], -            strings: Default::default(), -        } -    } -} - -impl<'data, Mach: MachHeader, R: ReadRef<'data>> SymbolTable<'data, Mach, R> { -    #[inline] -    pub(super) fn new(symbols: &'data [Mach::Nlist], strings: StringTable<'data, R>) -> Self { -        SymbolTable { symbols, strings } -    } - -    /// Return the string table used for the symbol names. -    #[inline] -    pub fn strings(&self) -> StringTable<'data, R> { -        self.strings -    } - -    /// Iterate over the symbols. -    #[inline] -    pub fn iter(&self) -> slice::Iter<'data, Mach::Nlist> { -        self.symbols.iter() -    } - -    /// Return true if the symbol table is empty. -    #[inline] -    pub fn is_empty(&self) -> bool { -        self.symbols.is_empty() -    } - -    /// The number of symbols. -    #[inline] -    pub fn len(&self) -> usize { -        self.symbols.len() -    } - -    /// Return the symbol at the given index. -    pub fn symbol(&self, index: usize) -> Result<&'data Mach::Nlist> { -        self.symbols -            .get(index) -            .read_error("Invalid Mach-O symbol index") -    } - -    /// Construct a map from addresses to a user-defined map entry. -    pub fn map<Entry: SymbolMapEntry, F: Fn(&'data Mach::Nlist) -> Option<Entry>>( -        &self, -        f: F, -    ) -> SymbolMap<Entry> { -        let mut symbols = Vec::new(); -        for nlist in self.symbols { -            if !nlist.is_definition() { -                continue; -            } -            if let Some(entry) = f(nlist) { -                symbols.push(entry); -            } -        } -        SymbolMap::new(symbols) -    } - -    /// Construct a map from addresses to symbol names and object file names. -    pub fn object_map(&self, endian: Mach::Endian) -> ObjectMap<'data> { -        let mut symbols = Vec::new(); -        let mut objects = Vec::new(); -        let mut object = None; -        let mut current_function = None; -        // Each module starts with one or two N_SO symbols (path, or directory + filename) -        // and one N_OSO symbol. The module is terminated by an empty N_SO symbol. -        for nlist in self.symbols { -            let n_type = nlist.n_type(); -            if n_type & macho::N_STAB == 0 { -                continue; -            } -            // TODO: includes variables too (N_GSYM, N_STSYM). These may need to get their -            // address from regular symbols though. -            match n_type { -                macho::N_SO => { -                    object = None; -                } -                macho::N_OSO => { -                    object = None; -                    if let Ok(name) = nlist.name(endian, self.strings) { -                        if !name.is_empty() { -                            object = Some(objects.len()); -                            objects.push(name); -                        } -                    } -                } -                macho::N_FUN => { -                    if let Ok(name) = nlist.name(endian, self.strings) { -                        if !name.is_empty() { -                            current_function = Some((name, nlist.n_value(endian).into())) -                        } else if let Some((name, address)) = current_function.take() { -                            if let Some(object) = object { -                                symbols.push(ObjectMapEntry { -                                    address, -                                    size: nlist.n_value(endian).into(), -                                    name, -                                    object, -                                }); -                            } -                        } -                    } -                } -                _ => {} -            } -        } -        ObjectMap { -            symbols: SymbolMap::new(symbols), -            objects, -        } -    } -} - -/// A symbol table in a [`MachOFile32`](super::MachOFile32). -pub type MachOSymbolTable32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSymbolTable<'data, 'file, macho::MachHeader32<Endian>, R>; -/// A symbol table in a [`MachOFile64`](super::MachOFile64). -pub type MachOSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSymbolTable<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// A symbol table in a [`MachOFile`]. -#[derive(Debug, Clone, Copy)] -pub struct MachOSymbolTable<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file MachOFile<'data, Mach, R>, -} - -impl<'data, 'file, Mach, R> read::private::Sealed for MachOSymbolTable<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Mach, R> ObjectSymbolTable<'data> for MachOSymbolTable<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type Symbol = MachOSymbol<'data, 'file, Mach, R>; -    type SymbolIterator = MachOSymbolIterator<'data, 'file, Mach, R>; - -    fn symbols(&self) -> Self::SymbolIterator { -        MachOSymbolIterator { -            file: self.file, -            index: 0, -        } -    } - -    fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> { -        let nlist = self.file.symbols.symbol(index.0)?; -        MachOSymbol::new(self.file, index, nlist).read_error("Unsupported Mach-O symbol index") -    } -} - -/// An iterator for the symbols in a [`MachOFile32`](super::MachOFile32). -pub type MachOSymbolIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSymbolIterator<'data, 'file, macho::MachHeader32<Endian>, R>; -/// An iterator for the symbols in a [`MachOFile64`](super::MachOFile64). -pub type MachOSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSymbolIterator<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// An iterator for the symbols in a [`MachOFile`]. -pub struct MachOSymbolIterator<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file MachOFile<'data, Mach, R>, -    pub(super) index: usize, -} - -impl<'data, 'file, Mach, R> fmt::Debug for MachOSymbolIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.debug_struct("MachOSymbolIterator").finish() -    } -} - -impl<'data, 'file, Mach, R> Iterator for MachOSymbolIterator<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    type Item = MachOSymbol<'data, 'file, Mach, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        loop { -            let index = self.index; -            let nlist = self.file.symbols.symbols.get(index)?; -            self.index += 1; -            if let Some(symbol) = MachOSymbol::new(self.file, SymbolIndex(index), nlist) { -                return Some(symbol); -            } -        } -    } -} - -/// A symbol in a [`MachOFile32`](super::MachOFile32). -pub type MachOSymbol32<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSymbol<'data, 'file, macho::MachHeader32<Endian>, R>; -/// A symbol in a [`MachOFile64`](super::MachOFile64). -pub type MachOSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> = -    MachOSymbol<'data, 'file, macho::MachHeader64<Endian>, R>; - -/// A symbol in a [`MachOFile`]. -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -#[derive(Debug, Clone, Copy)] -pub struct MachOSymbol<'data, 'file, Mach, R = &'data [u8]> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    file: &'file MachOFile<'data, Mach, R>, -    index: SymbolIndex, -    nlist: &'data Mach::Nlist, -} - -impl<'data, 'file, Mach, R> MachOSymbol<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    pub(super) fn new( -        file: &'file MachOFile<'data, Mach, R>, -        index: SymbolIndex, -        nlist: &'data Mach::Nlist, -    ) -> Option<Self> { -        if nlist.n_type() & macho::N_STAB != 0 { -            return None; -        } -        Some(MachOSymbol { file, index, nlist }) -    } -} - -impl<'data, 'file, Mach, R> read::private::Sealed for MachOSymbol<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Mach, R> ObjectSymbol<'data> for MachOSymbol<'data, 'file, Mach, R> -where -    Mach: MachHeader, -    R: ReadRef<'data>, -{ -    #[inline] -    fn index(&self) -> SymbolIndex { -        self.index -    } - -    fn name_bytes(&self) -> Result<&'data [u8]> { -        self.nlist.name(self.file.endian, self.file.symbols.strings) -    } - -    fn name(&self) -> Result<&'data str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 Mach-O symbol name") -    } - -    #[inline] -    fn address(&self) -> u64 { -        self.nlist.n_value(self.file.endian).into() -    } - -    #[inline] -    fn size(&self) -> u64 { -        0 -    } - -    fn kind(&self) -> SymbolKind { -        self.section() -            .index() -            .and_then(|index| self.file.section_internal(index).ok()) -            .map(|section| match section.kind { -                SectionKind::Text => SymbolKind::Text, -                SectionKind::Data -                | SectionKind::ReadOnlyData -                | SectionKind::ReadOnlyString -                | SectionKind::UninitializedData -                | SectionKind::Common => SymbolKind::Data, -                SectionKind::Tls | SectionKind::UninitializedTls | SectionKind::TlsVariables => { -                    SymbolKind::Tls -                } -                _ => SymbolKind::Unknown, -            }) -            .unwrap_or(SymbolKind::Unknown) -    } - -    fn section(&self) -> SymbolSection { -        match self.nlist.n_type() & macho::N_TYPE { -            macho::N_UNDF => SymbolSection::Undefined, -            macho::N_ABS => SymbolSection::Absolute, -            macho::N_SECT => { -                let n_sect = self.nlist.n_sect(); -                if n_sect != 0 { -                    SymbolSection::Section(SectionIndex(n_sect as usize)) -                } else { -                    SymbolSection::Unknown -                } -            } -            _ => SymbolSection::Unknown, -        } -    } - -    #[inline] -    fn is_undefined(&self) -> bool { -        self.nlist.n_type() & macho::N_TYPE == macho::N_UNDF -    } - -    #[inline] -    fn is_definition(&self) -> bool { -        self.nlist.is_definition() -    } - -    #[inline] -    fn is_common(&self) -> bool { -        // Mach-O common symbols are based on section, not symbol -        false -    } - -    #[inline] -    fn is_weak(&self) -> bool { -        self.nlist.n_desc(self.file.endian) & (macho::N_WEAK_REF | macho::N_WEAK_DEF) != 0 -    } - -    fn scope(&self) -> SymbolScope { -        let n_type = self.nlist.n_type(); -        if n_type & macho::N_TYPE == macho::N_UNDF { -            SymbolScope::Unknown -        } else if n_type & macho::N_EXT == 0 { -            SymbolScope::Compilation -        } else if n_type & macho::N_PEXT != 0 { -            SymbolScope::Linkage -        } else { -            SymbolScope::Dynamic -        } -    } - -    #[inline] -    fn is_global(&self) -> bool { -        self.scope() != SymbolScope::Compilation -    } - -    #[inline] -    fn is_local(&self) -> bool { -        self.scope() == SymbolScope::Compilation -    } - -    #[inline] -    fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> { -        let n_desc = self.nlist.n_desc(self.file.endian); -        SymbolFlags::MachO { n_desc } -    } -} - -/// A trait for generic access to [`macho::Nlist32`] and [`macho::Nlist64`]. -#[allow(missing_docs)] -pub trait Nlist: Debug + Pod { -    type Word: Into<u64>; -    type Endian: endian::Endian; - -    fn n_strx(&self, endian: Self::Endian) -> u32; -    fn n_type(&self) -> u8; -    fn n_sect(&self) -> u8; -    fn n_desc(&self, endian: Self::Endian) -> u16; -    fn n_value(&self, endian: Self::Endian) -> Self::Word; - -    fn name<'data, R: ReadRef<'data>>( -        &self, -        endian: Self::Endian, -        strings: StringTable<'data, R>, -    ) -> Result<&'data [u8]> { -        strings -            .get(self.n_strx(endian)) -            .read_error("Invalid Mach-O symbol name offset") -    } - -    /// Return true if this is a STAB symbol. -    /// -    /// This determines the meaning of the `n_type` field. -    fn is_stab(&self) -> bool { -        self.n_type() & macho::N_STAB != 0 -    } - -    /// Return true if this is an undefined symbol. -    fn is_undefined(&self) -> bool { -        let n_type = self.n_type(); -        n_type & macho::N_STAB == 0 && n_type & macho::N_TYPE == macho::N_UNDF -    } - -    /// Return true if the symbol is a definition of a function or data object. -    fn is_definition(&self) -> bool { -        let n_type = self.n_type(); -        n_type & macho::N_STAB == 0 && n_type & macho::N_TYPE == macho::N_SECT -    } - -    /// Return the library ordinal. -    /// -    /// This is either a 1-based index into the dylib load commands, -    /// or a special ordinal. -    #[inline] -    fn library_ordinal(&self, endian: Self::Endian) -> u8 { -        (self.n_desc(endian) >> 8) as u8 -    } -} - -impl<Endian: endian::Endian> Nlist for macho::Nlist32<Endian> { -    type Word = u32; -    type Endian = Endian; - -    fn n_strx(&self, endian: Self::Endian) -> u32 { -        self.n_strx.get(endian) -    } -    fn n_type(&self) -> u8 { -        self.n_type -    } -    fn n_sect(&self) -> u8 { -        self.n_sect -    } -    fn n_desc(&self, endian: Self::Endian) -> u16 { -        self.n_desc.get(endian) -    } -    fn n_value(&self, endian: Self::Endian) -> Self::Word { -        self.n_value.get(endian) -    } -} - -impl<Endian: endian::Endian> Nlist for macho::Nlist64<Endian> { -    type Word = u64; -    type Endian = Endian; - -    fn n_strx(&self, endian: Self::Endian) -> u32 { -        self.n_strx.get(endian) -    } -    fn n_type(&self) -> u8 { -        self.n_type -    } -    fn n_sect(&self) -> u8 { -        self.n_sect -    } -    fn n_desc(&self, endian: Self::Endian) -> u16 { -        self.n_desc.get(endian) -    } -    fn n_value(&self, endian: Self::Endian) -> Self::Word { -        self.n_value.get(endian) -    } -} diff --git a/vendor/object/src/read/mod.rs b/vendor/object/src/read/mod.rs deleted file mode 100644 index c13e309..0000000 --- a/vendor/object/src/read/mod.rs +++ /dev/null @@ -1,860 +0,0 @@ -//! Interface for reading object files. -//! -//! ## Unified read API -//! -//! The [`Object`] trait provides a unified read API for accessing common features of -//! object files, such as sections and symbols. There is an implementation of this -//! trait for [`File`], which allows reading any file format, as well as implementations -//! for each file format: -//! [`ElfFile`](elf::ElfFile), [`MachOFile`](macho::MachOFile), [`CoffFile`](coff::CoffFile), -//! [`PeFile`](pe::PeFile), [`WasmFile`](wasm::WasmFile), [`XcoffFile`](xcoff::XcoffFile). -//! -//! ## Low level read API -//! -//! The submodules for each file format define helpers that operate on the raw structs. -//! These can be used instead of the unified API, or in conjunction with it to access -//! details that are not available via the unified API. -//! -//! See the [submodules](#modules) for examples of the low level read API. -//! -//! ## Naming Convention -//! -//! Types that form part of the unified API for a file format are prefixed with the -//! name of the file format. -//! -//! ## Example for unified read API -//!  ```no_run -//! use object::{Object, ObjectSection}; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads a file and displays the name of each section. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let file = object::File::parse(&*data)?; -//!     for section in file.sections() { -//!         println!("{}", section.name()?); -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` - -use alloc::borrow::Cow; -use alloc::vec::Vec; -use core::{fmt, result}; - -use crate::common::*; - -mod read_ref; -pub use read_ref::*; - -#[cfg(feature = "std")] -mod read_cache; -#[cfg(feature = "std")] -pub use read_cache::*; - -mod util; -pub use util::*; - -#[cfg(any( -    feature = "coff", -    feature = "elf", -    feature = "macho", -    feature = "pe", -    feature = "wasm", -    feature = "xcoff" -))] -mod any; -#[cfg(any( -    feature = "coff", -    feature = "elf", -    feature = "macho", -    feature = "pe", -    feature = "wasm", -    feature = "xcoff" -))] -pub use any::*; - -#[cfg(feature = "archive")] -pub mod archive; - -#[cfg(feature = "coff")] -pub mod coff; - -#[cfg(feature = "elf")] -pub mod elf; - -#[cfg(feature = "macho")] -pub mod macho; - -#[cfg(feature = "pe")] -pub mod pe; - -#[cfg(feature = "wasm")] -pub mod wasm; - -#[cfg(feature = "xcoff")] -pub mod xcoff; - -mod traits; -pub use traits::*; - -mod private { -    pub trait Sealed {} -} - -/// The error type used within the read module. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Error(&'static str); - -impl fmt::Display for Error { -    #[inline] -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.write_str(self.0) -    } -} - -#[cfg(feature = "std")] -impl std::error::Error for Error {} - -/// The result type used within the read module. -pub type Result<T> = result::Result<T, Error>; - -trait ReadError<T> { -    fn read_error(self, error: &'static str) -> Result<T>; -} - -impl<T> ReadError<T> for result::Result<T, ()> { -    fn read_error(self, error: &'static str) -> Result<T> { -        self.map_err(|()| Error(error)) -    } -} - -impl<T> ReadError<T> for result::Result<T, Error> { -    fn read_error(self, error: &'static str) -> Result<T> { -        self.map_err(|_| Error(error)) -    } -} - -impl<T> ReadError<T> for Option<T> { -    fn read_error(self, error: &'static str) -> Result<T> { -        self.ok_or(Error(error)) -    } -} - -/// The native executable file for the target platform. -#[cfg(all( -    unix, -    not(target_os = "macos"), -    target_pointer_width = "32", -    feature = "elf" -))] -pub type NativeFile<'data, R = &'data [u8]> = elf::ElfFile32<'data, crate::Endianness, R>; - -/// The native executable file for the target platform. -#[cfg(all( -    unix, -    not(target_os = "macos"), -    target_pointer_width = "64", -    feature = "elf" -))] -pub type NativeFile<'data, R = &'data [u8]> = elf::ElfFile64<'data, crate::Endianness, R>; - -/// The native executable file for the target platform. -#[cfg(all(target_os = "macos", target_pointer_width = "32", feature = "macho"))] -pub type NativeFile<'data, R = &'data [u8]> = macho::MachOFile32<'data, crate::Endianness, R>; - -/// The native executable file for the target platform. -#[cfg(all(target_os = "macos", target_pointer_width = "64", feature = "macho"))] -pub type NativeFile<'data, R = &'data [u8]> = macho::MachOFile64<'data, crate::Endianness, R>; - -/// The native executable file for the target platform. -#[cfg(all(target_os = "windows", target_pointer_width = "32", feature = "pe"))] -pub type NativeFile<'data, R = &'data [u8]> = pe::PeFile32<'data, R>; - -/// The native executable file for the target platform. -#[cfg(all(target_os = "windows", target_pointer_width = "64", feature = "pe"))] -pub type NativeFile<'data, R = &'data [u8]> = pe::PeFile64<'data, R>; - -/// The native executable file for the target platform. -#[cfg(all(feature = "wasm", target_arch = "wasm32", feature = "wasm"))] -pub type NativeFile<'data, R = &'data [u8]> = wasm::WasmFile<'data, R>; - -/// A file format kind. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum FileKind { -    /// A Unix archive. -    /// -    /// See [`archive::ArchiveFile`]. -    #[cfg(feature = "archive")] -    Archive, -    /// A COFF object file. -    /// -    /// See [`coff::CoffFile`]. -    #[cfg(feature = "coff")] -    Coff, -    /// A COFF bigobj object file. -    /// -    /// This supports a larger number of sections. -    /// -    /// See [`coff::CoffBigFile`]. -    #[cfg(feature = "coff")] -    CoffBig, -    /// A Windows short import file. -    /// -    /// See [`coff::ImportFile`]. -    #[cfg(feature = "coff")] -    CoffImport, -    /// A dyld cache file containing Mach-O images. -    /// -    /// See [`macho::DyldCache`] -    #[cfg(feature = "macho")] -    DyldCache, -    /// A 32-bit ELF file. -    /// -    /// See [`elf::ElfFile32`]. -    #[cfg(feature = "elf")] -    Elf32, -    /// A 64-bit ELF file. -    /// -    /// See [`elf::ElfFile64`]. -    #[cfg(feature = "elf")] -    Elf64, -    /// A 32-bit Mach-O file. -    /// -    /// See [`macho::MachOFile32`]. -    #[cfg(feature = "macho")] -    MachO32, -    /// A 64-bit Mach-O file. -    /// -    /// See [`macho::MachOFile64`]. -    #[cfg(feature = "macho")] -    MachO64, -    /// A 32-bit Mach-O fat binary. -    /// -    /// See [`macho::FatHeader::parse_arch32`]. -    #[cfg(feature = "macho")] -    MachOFat32, -    /// A 64-bit Mach-O fat binary. -    /// -    /// See [`macho::FatHeader::parse_arch64`]. -    #[cfg(feature = "macho")] -    MachOFat64, -    /// A 32-bit PE file. -    /// -    /// See [`pe::PeFile32`]. -    #[cfg(feature = "pe")] -    Pe32, -    /// A 64-bit PE file. -    /// -    /// See [`pe::PeFile64`]. -    #[cfg(feature = "pe")] -    Pe64, -    /// A Wasm file. -    /// -    /// See [`wasm::WasmFile`]. -    #[cfg(feature = "wasm")] -    Wasm, -    /// A 32-bit XCOFF file. -    /// -    /// See [`xcoff::XcoffFile32`]. -    #[cfg(feature = "xcoff")] -    Xcoff32, -    /// A 64-bit XCOFF file. -    /// -    /// See [`xcoff::XcoffFile64`]. -    #[cfg(feature = "xcoff")] -    Xcoff64, -} - -impl FileKind { -    /// Determine a file kind by parsing the start of the file. -    pub fn parse<'data, R: ReadRef<'data>>(data: R) -> Result<FileKind> { -        Self::parse_at(data, 0) -    } - -    /// Determine a file kind by parsing at the given offset. -    pub fn parse_at<'data, R: ReadRef<'data>>(data: R, offset: u64) -> Result<FileKind> { -        let magic = data -            .read_bytes_at(offset, 16) -            .read_error("Could not read file magic")?; -        if magic.len() < 16 { -            return Err(Error("File too short")); -        } - -        let kind = match [magic[0], magic[1], magic[2], magic[3], magic[4], magic[5], magic[6], magic[7]] { -            #[cfg(feature = "archive")] -            [b'!', b'<', b'a', b'r', b'c', b'h', b'>', b'\n'] => FileKind::Archive, -            #[cfg(feature = "macho")] -            [b'd', b'y', b'l', b'd', b'_', b'v', b'1', b' '] => FileKind::DyldCache, -            #[cfg(feature = "elf")] -            [0x7f, b'E', b'L', b'F', 1, ..] => FileKind::Elf32, -            #[cfg(feature = "elf")] -            [0x7f, b'E', b'L', b'F', 2, ..] => FileKind::Elf64, -            #[cfg(feature = "macho")] -            [0xfe, 0xed, 0xfa, 0xce, ..] -            | [0xce, 0xfa, 0xed, 0xfe, ..] => FileKind::MachO32, -            #[cfg(feature = "macho")] -            | [0xfe, 0xed, 0xfa, 0xcf, ..] -            | [0xcf, 0xfa, 0xed, 0xfe, ..] => FileKind::MachO64, -            #[cfg(feature = "macho")] -            [0xca, 0xfe, 0xba, 0xbe, ..] => FileKind::MachOFat32, -            #[cfg(feature = "macho")] -            [0xca, 0xfe, 0xba, 0xbf, ..] => FileKind::MachOFat64, -            #[cfg(feature = "wasm")] -            [0x00, b'a', b's', b'm', ..] => FileKind::Wasm, -            #[cfg(feature = "pe")] -            [b'M', b'Z', ..] if offset == 0 => { -                // offset == 0 restriction is because optional_header_magic only looks at offset 0 -                match pe::optional_header_magic(data) { -                    Ok(crate::pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC) => { -                        FileKind::Pe32 -                    } -                    Ok(crate::pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC) => { -                        FileKind::Pe64 -                    } -                    _ => return Err(Error("Unknown MS-DOS file")), -                } -            } -            // TODO: more COFF machines -            #[cfg(feature = "coff")] -            // COFF arm -            [0xc4, 0x01, ..] -            // COFF arm64 -            | [0x64, 0xaa, ..] -            // COFF arm64ec -            | [0x41, 0xa6, ..] -            // COFF x86 -            | [0x4c, 0x01, ..] -            // COFF x86-64 -            | [0x64, 0x86, ..] => FileKind::Coff, -            #[cfg(feature = "coff")] -            [0x00, 0x00, 0xff, 0xff, 0x00, 0x00, ..] => FileKind::CoffImport, -            #[cfg(feature = "coff")] -            [0x00, 0x00, 0xff, 0xff, 0x02, 0x00, ..] if offset == 0 => { -                // offset == 0 restriction is because anon_object_class_id only looks at offset 0 -                match coff::anon_object_class_id(data) { -                    Ok(crate::pe::ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID) => FileKind::CoffBig, -                    _ => return Err(Error("Unknown anon object file")), -                } -            } -            #[cfg(feature = "xcoff")] -            [0x01, 0xdf, ..] => FileKind::Xcoff32, -            #[cfg(feature = "xcoff")] -            [0x01, 0xf7, ..] => FileKind::Xcoff64, -            _ => return Err(Error("Unknown file magic")), -        }; -        Ok(kind) -    } -} - -/// An object kind. -/// -/// Returned by [`Object::kind`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum ObjectKind { -    /// The object kind is unknown. -    Unknown, -    /// Relocatable object. -    Relocatable, -    /// Executable. -    Executable, -    /// Dynamic shared object. -    Dynamic, -    /// Core. -    Core, -} - -/// The index used to identify a section in a file. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct SectionIndex(pub usize); - -/// The index used to identify a symbol in a symbol table. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct SymbolIndex(pub usize); - -/// The section where an [`ObjectSymbol`] is defined. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SymbolSection { -    /// The section is unknown. -    Unknown, -    /// The section is not applicable for this symbol (such as file symbols). -    None, -    /// The symbol is undefined. -    Undefined, -    /// The symbol has an absolute value. -    Absolute, -    /// The symbol is a zero-initialized symbol that will be combined with duplicate definitions. -    Common, -    /// The symbol is defined in the given section. -    Section(SectionIndex), -} - -impl SymbolSection { -    /// Returns the section index for the section where the symbol is defined. -    /// -    /// May return `None` if the symbol is not defined in a section. -    #[inline] -    pub fn index(self) -> Option<SectionIndex> { -        if let SymbolSection::Section(index) = self { -            Some(index) -        } else { -            None -        } -    } -} - -/// An entry in a [`SymbolMap`]. -pub trait SymbolMapEntry { -    /// The symbol address. -    fn address(&self) -> u64; -} - -/// A map from addresses to symbol information. -/// -/// The symbol information depends on the chosen entry type, such as [`SymbolMapName`]. -/// -/// Returned by [`Object::symbol_map`]. -#[derive(Debug, Default, Clone)] -pub struct SymbolMap<T: SymbolMapEntry> { -    symbols: Vec<T>, -} - -impl<T: SymbolMapEntry> SymbolMap<T> { -    /// Construct a new symbol map. -    /// -    /// This function will sort the symbols by address. -    pub fn new(mut symbols: Vec<T>) -> Self { -        symbols.sort_by_key(|s| s.address()); -        SymbolMap { symbols } -    } - -    /// Get the symbol before the given address. -    pub fn get(&self, address: u64) -> Option<&T> { -        let index = match self -            .symbols -            .binary_search_by_key(&address, |symbol| symbol.address()) -        { -            Ok(index) => index, -            Err(index) => index.checked_sub(1)?, -        }; -        self.symbols.get(index) -    } - -    /// Get all symbols in the map. -    #[inline] -    pub fn symbols(&self) -> &[T] { -        &self.symbols -    } -} - -/// The type used for entries in a [`SymbolMap`] that maps from addresses to names. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct SymbolMapName<'data> { -    address: u64, -    name: &'data str, -} - -impl<'data> SymbolMapName<'data> { -    /// Construct a `SymbolMapName`. -    pub fn new(address: u64, name: &'data str) -> Self { -        SymbolMapName { address, name } -    } - -    /// The symbol address. -    #[inline] -    pub fn address(&self) -> u64 { -        self.address -    } - -    /// The symbol name. -    #[inline] -    pub fn name(&self) -> &'data str { -        self.name -    } -} - -impl<'data> SymbolMapEntry for SymbolMapName<'data> { -    #[inline] -    fn address(&self) -> u64 { -        self.address -    } -} - -/// A map from addresses to symbol names and object files. -/// -/// This is derived from STAB entries in Mach-O files. -/// -/// Returned by [`Object::object_map`]. -#[derive(Debug, Default, Clone)] -pub struct ObjectMap<'data> { -    symbols: SymbolMap<ObjectMapEntry<'data>>, -    objects: Vec<&'data [u8]>, -} - -impl<'data> ObjectMap<'data> { -    /// Get the entry containing the given address. -    pub fn get(&self, address: u64) -> Option<&ObjectMapEntry<'data>> { -        self.symbols -            .get(address) -            .filter(|entry| entry.size == 0 || address.wrapping_sub(entry.address) < entry.size) -    } - -    /// Get all symbols in the map. -    #[inline] -    pub fn symbols(&self) -> &[ObjectMapEntry<'data>] { -        self.symbols.symbols() -    } - -    /// Get all objects in the map. -    #[inline] -    pub fn objects(&self) -> &[&'data [u8]] { -        &self.objects -    } -} - -/// An [`ObjectMap`] entry. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] -pub struct ObjectMapEntry<'data> { -    address: u64, -    size: u64, -    name: &'data [u8], -    object: usize, -} - -impl<'data> ObjectMapEntry<'data> { -    /// Get the symbol address. -    #[inline] -    pub fn address(&self) -> u64 { -        self.address -    } - -    /// Get the symbol size. -    /// -    /// This may be 0 if the size is unknown. -    #[inline] -    pub fn size(&self) -> u64 { -        self.size -    } - -    /// Get the symbol name. -    #[inline] -    pub fn name(&self) -> &'data [u8] { -        self.name -    } - -    /// Get the index of the object file name. -    #[inline] -    pub fn object_index(&self) -> usize { -        self.object -    } - -    /// Get the object file name. -    #[inline] -    pub fn object(&self, map: &ObjectMap<'data>) -> &'data [u8] { -        map.objects[self.object] -    } -} - -impl<'data> SymbolMapEntry for ObjectMapEntry<'data> { -    #[inline] -    fn address(&self) -> u64 { -        self.address -    } -} - -/// An imported symbol. -/// -/// Returned by [`Object::imports`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Import<'data> { -    library: ByteString<'data>, -    // TODO: or ordinal -    name: ByteString<'data>, -} - -impl<'data> Import<'data> { -    /// The symbol name. -    #[inline] -    pub fn name(&self) -> &'data [u8] { -        self.name.0 -    } - -    /// The name of the library to import the symbol from. -    #[inline] -    pub fn library(&self) -> &'data [u8] { -        self.library.0 -    } -} - -/// An exported symbol. -/// -/// Returned by [`Object::exports`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Export<'data> { -    // TODO: and ordinal? -    name: ByteString<'data>, -    address: u64, -} - -impl<'data> Export<'data> { -    /// The symbol name. -    #[inline] -    pub fn name(&self) -> &'data [u8] { -        self.name.0 -    } - -    /// The virtual address of the symbol. -    #[inline] -    pub fn address(&self) -> u64 { -        self.address -    } -} - -/// PDB information from the debug directory in a PE file. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct CodeView<'data> { -    guid: [u8; 16], -    path: ByteString<'data>, -    age: u32, -} - -impl<'data> CodeView<'data> { -    /// The path to the PDB as stored in CodeView. -    #[inline] -    pub fn path(&self) -> &'data [u8] { -        self.path.0 -    } - -    /// The age of the PDB. -    #[inline] -    pub fn age(&self) -> u32 { -        self.age -    } - -    /// The GUID of the PDB. -    #[inline] -    pub fn guid(&self) -> [u8; 16] { -        self.guid -    } -} - -/// The target referenced by a [`Relocation`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum RelocationTarget { -    /// The target is a symbol. -    Symbol(SymbolIndex), -    /// The target is a section. -    Section(SectionIndex), -    /// The offset is an absolute address. -    Absolute, -} - -/// A relocation entry. -/// -/// Returned by [`Object::dynamic_relocations`] or [`ObjectSection::relocations`]. -#[derive(Debug)] -pub struct Relocation { -    kind: RelocationKind, -    encoding: RelocationEncoding, -    size: u8, -    target: RelocationTarget, -    addend: i64, -    implicit_addend: bool, -} - -impl Relocation { -    /// The operation used to calculate the result of the relocation. -    #[inline] -    pub fn kind(&self) -> RelocationKind { -        self.kind -    } - -    /// Information about how the result of the relocation operation is encoded in the place. -    #[inline] -    pub fn encoding(&self) -> RelocationEncoding { -        self.encoding -    } - -    /// The size in bits of the place of the relocation. -    /// -    /// If 0, then the size is determined by the relocation kind. -    #[inline] -    pub fn size(&self) -> u8 { -        self.size -    } - -    /// The target of the relocation. -    #[inline] -    pub fn target(&self) -> RelocationTarget { -        self.target -    } - -    /// The addend to use in the relocation calculation. -    #[inline] -    pub fn addend(&self) -> i64 { -        self.addend -    } - -    /// Set the addend to use in the relocation calculation. -    #[inline] -    pub fn set_addend(&mut self, addend: i64) { -        self.addend = addend -    } - -    /// Returns true if there is an implicit addend stored in the data at the offset -    /// to be relocated. -    #[inline] -    pub fn has_implicit_addend(&self) -> bool { -        self.implicit_addend -    } -} - -/// A data compression format. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum CompressionFormat { -    /// The data is uncompressed. -    None, -    /// The data is compressed, but the compression format is unknown. -    Unknown, -    /// ZLIB/DEFLATE. -    /// -    /// Used for ELF compression and GNU compressed debug information. -    Zlib, -    /// Zstandard. -    /// -    /// Used for ELF compression. -    Zstandard, -} - -/// A range in a file that may be compressed. -/// -/// Returned by [`ObjectSection::compressed_file_range`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct CompressedFileRange { -    /// The data compression format. -    pub format: CompressionFormat, -    /// The file offset of the compressed data. -    pub offset: u64, -    /// The compressed data size. -    pub compressed_size: u64, -    /// The uncompressed data size. -    pub uncompressed_size: u64, -} - -impl CompressedFileRange { -    /// Data that is uncompressed. -    #[inline] -    pub fn none(range: Option<(u64, u64)>) -> Self { -        if let Some((offset, size)) = range { -            CompressedFileRange { -                format: CompressionFormat::None, -                offset, -                compressed_size: size, -                uncompressed_size: size, -            } -        } else { -            CompressedFileRange { -                format: CompressionFormat::None, -                offset: 0, -                compressed_size: 0, -                uncompressed_size: 0, -            } -        } -    } - -    /// Convert to [`CompressedData`] by reading from the file. -    pub fn data<'data, R: ReadRef<'data>>(self, file: R) -> Result<CompressedData<'data>> { -        let data = file -            .read_bytes_at(self.offset, self.compressed_size) -            .read_error("Invalid compressed data size or offset")?; -        Ok(CompressedData { -            format: self.format, -            data, -            uncompressed_size: self.uncompressed_size, -        }) -    } -} - -/// Data that may be compressed. -/// -/// Returned by [`ObjectSection::compressed_data`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct CompressedData<'data> { -    /// The data compression format. -    pub format: CompressionFormat, -    /// The compressed data. -    pub data: &'data [u8], -    /// The uncompressed data size. -    pub uncompressed_size: u64, -} - -impl<'data> CompressedData<'data> { -    /// Data that is uncompressed. -    #[inline] -    pub fn none(data: &'data [u8]) -> Self { -        CompressedData { -            format: CompressionFormat::None, -            data, -            uncompressed_size: data.len() as u64, -        } -    } - -    /// Return the uncompressed data. -    /// -    /// Returns an error for invalid data or unsupported compression. -    /// This includes if the data is compressed but the `compression` feature -    /// for this crate is disabled. -    pub fn decompress(self) -> Result<Cow<'data, [u8]>> { -        match self.format { -            CompressionFormat::None => Ok(Cow::Borrowed(self.data)), -            #[cfg(feature = "compression")] -            CompressionFormat::Zlib => { -                use core::convert::TryInto; -                let size = self -                    .uncompressed_size -                    .try_into() -                    .ok() -                    .read_error("Uncompressed data size is too large.")?; -                let mut decompressed = Vec::with_capacity(size); -                let mut decompress = flate2::Decompress::new(true); -                decompress -                    .decompress_vec( -                        self.data, -                        &mut decompressed, -                        flate2::FlushDecompress::Finish, -                    ) -                    .ok() -                    .read_error("Invalid zlib compressed data")?; -                Ok(Cow::Owned(decompressed)) -            } -            #[cfg(feature = "compression")] -            CompressionFormat::Zstandard => { -                use core::convert::TryInto; -                use std::io::Read; -                let size = self -                    .uncompressed_size -                    .try_into() -                    .ok() -                    .read_error("Uncompressed data size is too large.")?; -                let mut decompressed = Vec::with_capacity(size); -                let mut decoder = ruzstd::StreamingDecoder::new(self.data) -                    .ok() -                    .read_error("Invalid zstd compressed data")?; -                decoder -                    .read_to_end(&mut decompressed) -                    .ok() -                    .read_error("Invalid zstd compressed data")?; -                Ok(Cow::Owned(decompressed)) -            } -            _ => Err(Error("Unsupported compressed data.")), -        } -    } -} diff --git a/vendor/object/src/read/pe/data_directory.rs b/vendor/object/src/read/pe/data_directory.rs deleted file mode 100644 index a17179f..0000000 --- a/vendor/object/src/read/pe/data_directory.rs +++ /dev/null @@ -1,213 +0,0 @@ -use core::slice; - -use crate::read::{Error, ReadError, ReadRef, Result}; -use crate::{pe, LittleEndian as LE}; - -use super::{ -    DelayLoadImportTable, ExportTable, ImportTable, RelocationBlockIterator, ResourceDirectory, -    SectionTable, -}; - -/// The table of data directories in a PE file. -/// -/// Returned by [`ImageNtHeaders::parse`](super::ImageNtHeaders::parse). -#[derive(Debug, Clone, Copy)] -pub struct DataDirectories<'data> { -    entries: &'data [pe::ImageDataDirectory], -} - -impl<'data> DataDirectories<'data> { -    /// Parse the data directory table. -    /// -    /// `data` must be the remaining optional data following the -    /// [optional header](pe::ImageOptionalHeader64).  `number` must be from the -    /// [`number_of_rva_and_sizes`](pe::ImageOptionalHeader64::number_of_rva_and_sizes) -    /// field of the optional header. -    pub fn parse(data: &'data [u8], number: u32) -> Result<Self> { -        let entries = data -            .read_slice_at(0, number as usize) -            .read_error("Invalid PE number of RVA and sizes")?; -        Ok(DataDirectories { entries }) -    } - -    /// The number of data directories. -    #[allow(clippy::len_without_is_empty)] -    pub fn len(&self) -> usize { -        self.entries.len() -    } - -    /// Iterator over the data directories. -    pub fn iter(&self) -> slice::Iter<'data, pe::ImageDataDirectory> { -        self.entries.iter() -    } - -    /// Iterator which gives the directories as well as their index (one of the IMAGE_DIRECTORY_ENTRY_* constants). -    pub fn enumerate(&self) -> core::iter::Enumerate<slice::Iter<'data, pe::ImageDataDirectory>> { -        self.entries.iter().enumerate() -    } - -    /// Returns the data directory at the given index. -    /// -    /// Index should be one of the `IMAGE_DIRECTORY_ENTRY_*` constants. -    /// -    /// Returns `None` if the index is larger than the table size, -    /// or if the entry at the index has a zero virtual address. -    pub fn get(&self, index: usize) -> Option<&'data pe::ImageDataDirectory> { -        self.entries -            .get(index) -            .filter(|d| d.virtual_address.get(LE) != 0) -    } - -    /// Returns the unparsed export directory. -    /// -    /// `data` must be the entire file data. -    pub fn export_directory<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<&'data pe::ImageExportDirectory>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_EXPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let export_data = data_dir.data(data, sections)?; -        ExportTable::parse_directory(export_data).map(Some) -    } - -    /// Returns the partially parsed export directory. -    /// -    /// `data` must be the entire file data. -    pub fn export_table<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<ExportTable<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_EXPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let export_va = data_dir.virtual_address.get(LE); -        let export_data = data_dir.data(data, sections)?; -        ExportTable::parse(export_data, export_va).map(Some) -    } - -    /// Returns the partially parsed import directory. -    /// -    /// `data` must be the entire file data. -    pub fn import_table<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<ImportTable<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_IMPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let import_va = data_dir.virtual_address.get(LE); -        let (section_data, section_va) = sections -            .pe_data_containing(data, import_va) -            .read_error("Invalid import data dir virtual address")?; -        Ok(Some(ImportTable::new(section_data, section_va, import_va))) -    } - -    /// Returns the partially parsed delay-load import directory. -    /// -    /// `data` must be the entire file data. -    pub fn delay_load_import_table<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<DelayLoadImportTable<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let import_va = data_dir.virtual_address.get(LE); -        let (section_data, section_va) = sections -            .pe_data_containing(data, import_va) -            .read_error("Invalid import data dir virtual address")?; -        Ok(Some(DelayLoadImportTable::new( -            section_data, -            section_va, -            import_va, -        ))) -    } - -    /// Returns the blocks in the base relocation directory. -    /// -    /// `data` must be the entire file data. -    pub fn relocation_blocks<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<RelocationBlockIterator<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_BASERELOC) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let reloc_data = data_dir.data(data, sections)?; -        Ok(Some(RelocationBlockIterator::new(reloc_data))) -    } - -    /// Returns the resource directory. -    /// -    /// `data` must be the entire file data. -    pub fn resource_directory<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<ResourceDirectory<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_RESOURCE) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let rsrc_data = data_dir.data(data, sections)?; -        Ok(Some(ResourceDirectory::new(rsrc_data))) -    } -} - -impl pe::ImageDataDirectory { -    /// Return the virtual address range of this directory entry. -    pub fn address_range(&self) -> (u32, u32) { -        (self.virtual_address.get(LE), self.size.get(LE)) -    } - -    /// Return the file offset and size of this directory entry. -    /// -    /// This function has some limitations: -    /// - It requires that the data is contained in a single section. -    /// - It uses the size field of the directory entry, which is -    /// not desirable for all data directories. -    /// - It uses the `virtual_address` of the directory entry as an address, -    /// which is not valid for `IMAGE_DIRECTORY_ENTRY_SECURITY`. -    pub fn file_range(&self, sections: &SectionTable<'_>) -> Result<(u32, u32)> { -        let (offset, section_size) = sections -            .pe_file_range_at(self.virtual_address.get(LE)) -            .read_error("Invalid data dir virtual address")?; -        let size = self.size.get(LE); -        if size > section_size { -            return Err(Error("Invalid data dir size")); -        } -        Ok((offset, size)) -    } - -    /// Get the data referenced by this directory entry. -    /// -    /// This function has some limitations: -    /// - It requires that the data is contained in a single section. -    /// - It uses the size field of the directory entry, which is -    /// not desirable for all data directories. -    /// - It uses the `virtual_address` of the directory entry as an address, -    /// which is not valid for `IMAGE_DIRECTORY_ENTRY_SECURITY`. -    pub fn data<'data, R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<&'data [u8]> { -        sections -            .pe_data_at(data, self.virtual_address.get(LE)) -            .read_error("Invalid data dir virtual address")? -            .get(..self.size.get(LE) as usize) -            .read_error("Invalid data dir size") -    } -} diff --git a/vendor/object/src/read/pe/export.rs b/vendor/object/src/read/pe/export.rs deleted file mode 100644 index 1aba844..0000000 --- a/vendor/object/src/read/pe/export.rs +++ /dev/null @@ -1,333 +0,0 @@ -use alloc::vec::Vec; -use core::fmt::Debug; - -use crate::read::{ByteString, Bytes, Error, ReadError, ReadRef, Result}; -use crate::{pe, LittleEndian as LE, U16Bytes, U32Bytes}; - -/// Where an export is pointing to. -#[derive(Clone, Copy)] -pub enum ExportTarget<'data> { -    /// The address of the export, relative to the image base. -    Address(u32), -    /// Forwarded to an export ordinal in another DLL. -    /// -    /// This gives the name of the DLL, and the ordinal. -    ForwardByOrdinal(&'data [u8], u32), -    /// Forwarded to an export name in another DLL. -    /// -    /// This gives the name of the DLL, and the export name. -    ForwardByName(&'data [u8], &'data [u8]), -} - -impl<'data> ExportTarget<'data> { -    /// Returns true if the target is an address. -    pub fn is_address(&self) -> bool { -        match self { -            ExportTarget::Address(_) => true, -            _ => false, -        } -    } - -    /// Returns true if the export is forwarded to another DLL. -    pub fn is_forward(&self) -> bool { -        !self.is_address() -    } -} - -/// An export from a PE file. -/// -/// There are multiple kinds of PE exports (with or without a name, and local or forwarded). -#[derive(Clone, Copy)] -pub struct Export<'data> { -    /// The ordinal of the export. -    /// -    /// These are sequential, starting at a base specified in the DLL. -    pub ordinal: u32, -    /// The name of the export, if known. -    pub name: Option<&'data [u8]>, -    /// The target of this export. -    pub target: ExportTarget<'data>, -} - -impl<'a> Debug for Export<'a> { -    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> { -        f.debug_struct("Export") -            .field("ordinal", &self.ordinal) -            .field("name", &self.name.map(ByteString)) -            .field("target", &self.target) -            .finish() -    } -} - -impl<'a> Debug for ExportTarget<'a> { -    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> { -        match self { -            ExportTarget::Address(address) => write!(f, "Address({:#x})", address), -            ExportTarget::ForwardByOrdinal(library, ordinal) => write!( -                f, -                "ForwardByOrdinal({:?}.#{})", -                ByteString(library), -                ordinal -            ), -            ExportTarget::ForwardByName(library, name) => write!( -                f, -                "ForwardByName({:?}.{:?})", -                ByteString(library), -                ByteString(name) -            ), -        } -    } -} - -/// A partially parsed PE export table. -/// -/// Returned by [`DataDirectories::export_table`](super::DataDirectories::export_table). -#[derive(Debug, Clone)] -pub struct ExportTable<'data> { -    data: Bytes<'data>, -    virtual_address: u32, -    directory: &'data pe::ImageExportDirectory, -    addresses: &'data [U32Bytes<LE>], -    names: &'data [U32Bytes<LE>], -    name_ordinals: &'data [U16Bytes<LE>], -} - -impl<'data> ExportTable<'data> { -    /// Parse the export table given its section data and address. -    pub fn parse(data: &'data [u8], virtual_address: u32) -> Result<Self> { -        let directory = Self::parse_directory(data)?; -        let data = Bytes(data); - -        let mut addresses = &[][..]; -        let address_of_functions = directory.address_of_functions.get(LE); -        if address_of_functions != 0 { -            addresses = data -                .read_slice_at::<U32Bytes<_>>( -                    address_of_functions.wrapping_sub(virtual_address) as usize, -                    directory.number_of_functions.get(LE) as usize, -                ) -                .read_error("Invalid PE export address table")?; -        } - -        let mut names = &[][..]; -        let mut name_ordinals = &[][..]; -        let address_of_names = directory.address_of_names.get(LE); -        let address_of_name_ordinals = directory.address_of_name_ordinals.get(LE); -        if address_of_names != 0 { -            if address_of_name_ordinals == 0 { -                return Err(Error("Missing PE export ordinal table")); -            } - -            let number = directory.number_of_names.get(LE) as usize; -            names = data -                .read_slice_at::<U32Bytes<_>>( -                    address_of_names.wrapping_sub(virtual_address) as usize, -                    number, -                ) -                .read_error("Invalid PE export name pointer table")?; -            name_ordinals = data -                .read_slice_at::<U16Bytes<_>>( -                    address_of_name_ordinals.wrapping_sub(virtual_address) as usize, -                    number, -                ) -                .read_error("Invalid PE export ordinal table")?; -        } - -        Ok(ExportTable { -            data, -            virtual_address, -            directory, -            addresses, -            names, -            name_ordinals, -        }) -    } - -    /// Parse the export directory given its section data. -    pub fn parse_directory(data: &'data [u8]) -> Result<&'data pe::ImageExportDirectory> { -        data.read_at::<pe::ImageExportDirectory>(0) -            .read_error("Invalid PE export dir size") -    } - -    /// Returns the header of the export table. -    pub fn directory(&self) -> &'data pe::ImageExportDirectory { -        self.directory -    } - -    /// Returns the base value of ordinals. -    /// -    /// Adding this to an address index will give an ordinal. -    pub fn ordinal_base(&self) -> u32 { -        self.directory.base.get(LE) -    } - -    /// Returns the unparsed address table. -    /// -    /// An address table entry may be a local address, or the address of a forwarded export entry. -    /// See [`Self::is_forward`] and [`Self::target_from_address`]. -    pub fn addresses(&self) -> &'data [U32Bytes<LE>] { -        self.addresses -    } - -    /// Returns the unparsed name pointer table. -    /// -    /// A name pointer table entry can be used with [`Self::name_from_pointer`]. -    pub fn name_pointers(&self) -> &'data [U32Bytes<LE>] { -        self.names -    } - -    /// Returns the unparsed ordinal table. -    /// -    /// An ordinal table entry is a 0-based index into the address table. -    /// See [`Self::address_by_index`] and [`Self::target_by_index`]. -    pub fn name_ordinals(&self) -> &'data [U16Bytes<LE>] { -        self.name_ordinals -    } - -    /// Returns an iterator for the entries in the name pointer table and ordinal table. -    /// -    /// A name pointer table entry can be used with [`Self::name_from_pointer`]. -    /// -    /// An ordinal table entry is a 0-based index into the address table. -    /// See [`Self::address_by_index`] and [`Self::target_by_index`]. -    pub fn name_iter(&self) -> impl Iterator<Item = (u32, u16)> + 'data { -        self.names -            .iter() -            .map(|x| x.get(LE)) -            .zip(self.name_ordinals.iter().map(|x| x.get(LE))) -    } - -    /// Returns the export address table entry at the given address index. -    /// -    /// This may be a local address, or the address of a forwarded export entry. -    /// See [`Self::is_forward`] and [`Self::target_from_address`]. -    /// -    /// `index` is a 0-based index into the export address table. -    pub fn address_by_index(&self, index: u32) -> Result<u32> { -        Ok(self -            .addresses -            .get(index as usize) -            .read_error("Invalid PE export address index")? -            .get(LE)) -    } - -    /// Returns the export address table entry at the given ordinal. -    /// -    /// This may be a local address, or the address of a forwarded export entry. -    /// See [`Self::is_forward`] and [`Self::target_from_address`]. -    pub fn address_by_ordinal(&self, ordinal: u32) -> Result<u32> { -        self.address_by_index(ordinal.wrapping_sub(self.ordinal_base())) -    } - -    /// Returns the target of the export at the given address index. -    /// -    /// `index` is a 0-based index into the export address table. -    pub fn target_by_index(&self, index: u32) -> Result<ExportTarget<'data>> { -        self.target_from_address(self.address_by_index(index)?) -    } - -    /// Returns the target of the export at the given ordinal. -    pub fn target_by_ordinal(&self, ordinal: u32) -> Result<ExportTarget<'data>> { -        self.target_from_address(self.address_by_ordinal(ordinal)?) -    } - -    /// Convert an export address table entry into a target. -    pub fn target_from_address(&self, address: u32) -> Result<ExportTarget<'data>> { -        Ok(if let Some(forward) = self.forward_string(address)? { -            let i = forward -                .iter() -                .position(|x| *x == b'.') -                .read_error("Missing PE forwarded export separator")?; -            let library = &forward[..i]; -            match &forward[i + 1..] { -                [b'#', digits @ ..] => { -                    let ordinal = -                        parse_ordinal(digits).read_error("Invalid PE forwarded export ordinal")?; -                    ExportTarget::ForwardByOrdinal(library, ordinal) -                } -                [] => { -                    return Err(Error("Missing PE forwarded export name")); -                } -                name => ExportTarget::ForwardByName(library, name), -            } -        } else { -            ExportTarget::Address(address) -        }) -    } - -    fn forward_offset(&self, address: u32) -> Option<usize> { -        let offset = address.wrapping_sub(self.virtual_address) as usize; -        if offset < self.data.len() { -            Some(offset) -        } else { -            None -        } -    } - -    /// Return true if the export address table entry is a forward. -    pub fn is_forward(&self, address: u32) -> bool { -        self.forward_offset(address).is_some() -    } - -    /// Return the forward string if the export address table entry is a forward. -    pub fn forward_string(&self, address: u32) -> Result<Option<&'data [u8]>> { -        if let Some(offset) = self.forward_offset(address) { -            self.data -                .read_string_at(offset) -                .read_error("Invalid PE forwarded export address") -                .map(Some) -        } else { -            Ok(None) -        } -    } - -    /// Convert an export name pointer table entry into a name. -    pub fn name_from_pointer(&self, name_pointer: u32) -> Result<&'data [u8]> { -        let offset = name_pointer.wrapping_sub(self.virtual_address); -        self.data -            .read_string_at(offset as usize) -            .read_error("Invalid PE export name pointer") -    } - -    /// Returns the parsed exports in this table. -    pub fn exports(&self) -> Result<Vec<Export<'data>>> { -        // First, let's list all exports. -        let mut exports = Vec::new(); -        let ordinal_base = self.ordinal_base(); -        for (i, address) in self.addresses.iter().enumerate() { -            // Convert from an array index to an ordinal. -            let ordinal = ordinal_base.wrapping_add(i as u32); -            let target = self.target_from_address(address.get(LE))?; -            exports.push(Export { -                ordinal, -                target, -                // Might be populated later. -                name: None, -            }); -        } - -        // Now, check whether some (or all) of them have an associated name. -        // `ordinal_index` is a 0-based index into `addresses`. -        for (name_pointer, ordinal_index) in self.name_iter() { -            let name = self.name_from_pointer(name_pointer)?; -            exports -                .get_mut(ordinal_index as usize) -                .read_error("Invalid PE export ordinal")? -                .name = Some(name); -        } - -        Ok(exports) -    } -} - -fn parse_ordinal(digits: &[u8]) -> Option<u32> { -    if digits.is_empty() { -        return None; -    } -    let mut result: u32 = 0; -    for &c in digits { -        let x = (c as char).to_digit(10)?; -        result = result.checked_mul(10)?.checked_add(x)?; -    } -    Some(result) -} diff --git a/vendor/object/src/read/pe/file.rs b/vendor/object/src/read/pe/file.rs deleted file mode 100644 index 5372bdd..0000000 --- a/vendor/object/src/read/pe/file.rs +++ /dev/null @@ -1,1050 +0,0 @@ -use alloc::vec::Vec; -use core::fmt::Debug; -use core::{mem, str}; - -use core::convert::TryInto; - -use crate::read::coff::{CoffCommon, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, SymbolTable}; -use crate::read::{ -    self, Architecture, ComdatKind, Error, Export, FileFlags, Import, NoDynamicRelocationIterator, -    Object, ObjectComdat, ObjectKind, ReadError, ReadRef, Result, SectionIndex, SymbolIndex, -}; -use crate::{pe, ByteString, Bytes, CodeView, LittleEndian as LE, Pod, SubArchitecture, U32}; - -use super::{ -    DataDirectories, ExportTable, ImageThunkData, ImportTable, PeSection, PeSectionIterator, -    PeSegment, PeSegmentIterator, RichHeaderInfo, SectionTable, -}; - -/// A PE32 (32-bit) image file. -/// -/// This is a file that starts with [`pe::ImageNtHeaders32`], and corresponds -/// to [`crate::FileKind::Pe32`]. -pub type PeFile32<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders32, R>; -/// A PE32+ (64-bit) image file. -/// -/// This is a file that starts with [`pe::ImageNtHeaders64`], and corresponds -/// to [`crate::FileKind::Pe64`]. -pub type PeFile64<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders64, R>; - -/// A PE image file. -/// -/// Most functionality is provided by the [`Object`] trait implementation. -#[derive(Debug)] -pub struct PeFile<'data, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) dos_header: &'data pe::ImageDosHeader, -    pub(super) nt_headers: &'data Pe, -    pub(super) data_directories: DataDirectories<'data>, -    pub(super) common: CoffCommon<'data, R>, -    pub(super) data: R, -} - -impl<'data, Pe, R> PeFile<'data, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    /// Parse the raw PE file data. -    pub fn parse(data: R) -> Result<Self> { -        let dos_header = pe::ImageDosHeader::parse(data)?; -        let mut offset = dos_header.nt_headers_offset().into(); -        let (nt_headers, data_directories) = Pe::parse(data, &mut offset)?; -        let sections = nt_headers.sections(data, offset)?; -        let coff_symbols = nt_headers.symbols(data); -        let image_base = nt_headers.optional_header().image_base(); - -        Ok(PeFile { -            dos_header, -            nt_headers, -            data_directories, -            common: CoffCommon { -                sections, -                // The PE file format deprecates the COFF symbol table (https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#coff-file-header-object-and-image) -                // We do not want to prevent parsing the rest of the PE file for a corrupt COFF header, but rather return an empty symbol table -                symbols: coff_symbols.unwrap_or_default(), -                image_base, -            }, -            data, -        }) -    } - -    /// Returns this binary data. -    pub fn data(&self) -> R { -        self.data -    } - -    /// Return the DOS header of this file. -    pub fn dos_header(&self) -> &'data pe::ImageDosHeader { -        self.dos_header -    } - -    /// Return the NT Headers of this file. -    pub fn nt_headers(&self) -> &'data Pe { -        self.nt_headers -    } - -    /// Returns information about the rich header of this file (if any). -    pub fn rich_header_info(&self) -> Option<RichHeaderInfo<'_>> { -        RichHeaderInfo::parse(self.data, self.dos_header.nt_headers_offset().into()) -    } - -    /// Returns the section table of this binary. -    pub fn section_table(&self) -> SectionTable<'data> { -        self.common.sections -    } - -    /// Returns the data directories of this file. -    pub fn data_directories(&self) -> DataDirectories<'data> { -        self.data_directories -    } - -    /// Returns the data directory at the given index. -    pub fn data_directory(&self, id: usize) -> Option<&'data pe::ImageDataDirectory> { -        self.data_directories.get(id) -    } - -    /// Returns the export table of this file. -    /// -    /// The export table is located using the data directory. -    pub fn export_table(&self) -> Result<Option<ExportTable<'data>>> { -        self.data_directories -            .export_table(self.data, &self.common.sections) -    } - -    /// Returns the import table of this file. -    /// -    /// The import table is located using the data directory. -    pub fn import_table(&self) -> Result<Option<ImportTable<'data>>> { -        self.data_directories -            .import_table(self.data, &self.common.sections) -    } - -    pub(super) fn section_alignment(&self) -> u64 { -        u64::from(self.nt_headers.optional_header().section_alignment()) -    } -} - -impl<'data, Pe, R> read::private::Sealed for PeFile<'data, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> Object<'data, 'file> for PeFile<'data, Pe, R> -where -    'data: 'file, -    Pe: ImageNtHeaders, -    R: 'file + ReadRef<'data>, -{ -    type Segment = PeSegment<'data, 'file, Pe, R>; -    type SegmentIterator = PeSegmentIterator<'data, 'file, Pe, R>; -    type Section = PeSection<'data, 'file, Pe, R>; -    type SectionIterator = PeSectionIterator<'data, 'file, Pe, R>; -    type Comdat = PeComdat<'data, 'file, Pe, R>; -    type ComdatIterator = PeComdatIterator<'data, 'file, Pe, R>; -    type Symbol = CoffSymbol<'data, 'file, R>; -    type SymbolIterator = CoffSymbolIterator<'data, 'file, R>; -    type SymbolTable = CoffSymbolTable<'data, 'file, R>; -    type DynamicRelocationIterator = NoDynamicRelocationIterator; - -    fn architecture(&self) -> Architecture { -        match self.nt_headers.file_header().machine.get(LE) { -            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.nt_headers.file_header().machine.get(LE) { -            pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC), -            _ => None, -        } -    } - -    #[inline] -    fn is_little_endian(&self) -> bool { -        // Only little endian is supported. -        true -    } - -    #[inline] -    fn is_64(&self) -> bool { -        self.nt_headers.is_type_64() -    } - -    fn kind(&self) -> ObjectKind { -        let characteristics = self.nt_headers.file_header().characteristics.get(LE); -        if characteristics & pe::IMAGE_FILE_DLL != 0 { -            ObjectKind::Dynamic -        } else if characteristics & pe::IMAGE_FILE_SYSTEM != 0 { -            ObjectKind::Unknown -        } else { -            ObjectKind::Executable -        } -    } - -    fn segments(&'file self) -> PeSegmentIterator<'data, 'file, Pe, R> { -        PeSegmentIterator { -            file: self, -            iter: self.common.sections.iter(), -        } -    } - -    fn section_by_name_bytes( -        &'file self, -        section_name: &[u8], -    ) -> Option<PeSection<'data, 'file, Pe, R>> { -        self.common -            .sections -            .section_by_name(self.common.symbols.strings(), section_name) -            .map(|(index, section)| PeSection { -                file: self, -                index: SectionIndex(index), -                section, -            }) -    } - -    fn section_by_index( -        &'file self, -        index: SectionIndex, -    ) -> Result<PeSection<'data, 'file, Pe, R>> { -        let section = self.common.sections.section(index.0)?; -        Ok(PeSection { -            file: self, -            index, -            section, -        }) -    } - -    fn sections(&'file self) -> PeSectionIterator<'data, 'file, Pe, R> { -        PeSectionIterator { -            file: self, -            iter: self.common.sections.iter().enumerate(), -        } -    } - -    fn comdats(&'file self) -> PeComdatIterator<'data, 'file, Pe, R> { -        PeComdatIterator { file: self } -    } - -    fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<CoffSymbol<'data, 'file, R>> { -        let symbol = self.common.symbols.symbol(index.0)?; -        Ok(CoffSymbol { -            file: &self.common, -            index, -            symbol, -        }) -    } - -    fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> { -        CoffSymbolIterator { -            file: &self.common, -            index: 0, -        } -    } - -    fn symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> { -        Some(CoffSymbolTable { file: &self.common }) -    } - -    fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> { -        CoffSymbolIterator { -            file: &self.common, -            // Hack: don't return any. -            index: self.common.symbols.len(), -        } -    } - -    fn dynamic_symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> { -        None -    } - -    fn dynamic_relocations(&'file self) -> Option<NoDynamicRelocationIterator> { -        None -    } - -    fn imports(&self) -> Result<Vec<Import<'data>>> { -        let mut imports = Vec::new(); -        if let Some(import_table) = self.import_table()? { -            let mut import_descs = import_table.descriptors()?; -            while let Some(import_desc) = import_descs.next()? { -                let library = import_table.name(import_desc.name.get(LE))?; -                let mut first_thunk = import_desc.original_first_thunk.get(LE); -                if first_thunk == 0 { -                    first_thunk = import_desc.first_thunk.get(LE); -                } -                let mut thunks = import_table.thunks(first_thunk)?; -                while let Some(thunk) = thunks.next::<Pe>()? { -                    if !thunk.is_ordinal() { -                        let (_hint, name) = import_table.hint_name(thunk.address())?; -                        imports.push(Import { -                            library: ByteString(library), -                            name: ByteString(name), -                        }); -                    } -                } -            } -        } -        Ok(imports) -    } - -    fn exports(&self) -> Result<Vec<Export<'data>>> { -        let mut exports = Vec::new(); -        if let Some(export_table) = self.export_table()? { -            for (name_pointer, address_index) in export_table.name_iter() { -                let name = export_table.name_from_pointer(name_pointer)?; -                let address = export_table.address_by_index(address_index.into())?; -                if !export_table.is_forward(address) { -                    exports.push(Export { -                        name: ByteString(name), -                        address: self.common.image_base.wrapping_add(address.into()), -                    }) -                } -            } -        } -        Ok(exports) -    } - -    fn pdb_info(&self) -> Result<Option<CodeView<'_>>> { -        let data_dir = match self.data_directory(pe::IMAGE_DIRECTORY_ENTRY_DEBUG) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let debug_data = data_dir.data(self.data, &self.common.sections).map(Bytes)?; -        let debug_data_size = data_dir.size.get(LE) as usize; - -        let count = debug_data_size / mem::size_of::<pe::ImageDebugDirectory>(); -        let rem = debug_data_size % mem::size_of::<pe::ImageDebugDirectory>(); -        if rem != 0 || count < 1 { -            return Err(Error("Invalid PE debug dir size")); -        } - -        let debug_dirs = debug_data -            .read_slice_at::<pe::ImageDebugDirectory>(0, count) -            .read_error("Invalid PE debug dir size")?; - -        for debug_dir in debug_dirs { -            if debug_dir.typ.get(LE) != pe::IMAGE_DEBUG_TYPE_CODEVIEW { -                continue; -            } - -            let info = self -                .data -                .read_slice_at::<u8>( -                    debug_dir.pointer_to_raw_data.get(LE) as u64, -                    debug_dir.size_of_data.get(LE) as usize, -                ) -                .read_error("Invalid CodeView Info address")?; - -            let mut info = Bytes(info); - -            let sig = info -                .read_bytes(4) -                .read_error("Invalid CodeView signature")?; -            if sig.0 != b"RSDS" { -                continue; -            } - -            let guid: [u8; 16] = info -                .read_bytes(16) -                .read_error("Invalid CodeView GUID")? -                .0 -                .try_into() -                .unwrap(); - -            let age = info.read::<U32<LE>>().read_error("Invalid CodeView Age")?; - -            let path = info -                .read_string() -                .read_error("Invalid CodeView file path")?; - -            return Ok(Some(CodeView { -                path: ByteString(path), -                guid, -                age: age.get(LE), -            })); -        } -        Ok(None) -    } - -    fn has_debug_symbols(&self) -> bool { -        self.section_by_name(".debug_info").is_some() -    } - -    fn relative_address_base(&self) -> u64 { -        self.common.image_base -    } - -    fn entry(&self) -> u64 { -        u64::from(self.nt_headers.optional_header().address_of_entry_point()) -            .wrapping_add(self.common.image_base) -    } - -    fn flags(&self) -> FileFlags { -        FileFlags::Coff { -            characteristics: self.nt_headers.file_header().characteristics.get(LE), -        } -    } -} - -/// An iterator for the COMDAT section groups in a [`PeFile32`]. -pub type PeComdatIterator32<'data, 'file, R = &'data [u8]> = -    PeComdatIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the COMDAT section groups in a [`PeFile64`]. -pub type PeComdatIterator64<'data, 'file, R = &'data [u8]> = -    PeComdatIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the COMDAT section groups in a [`PeFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeComdatIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file PeFile<'data, Pe, R>, -} - -impl<'data, 'file, Pe, R> Iterator for PeComdatIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = PeComdat<'data, 'file, Pe, R>; - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -/// A COMDAT section group in a [`PeFile32`]. -pub type PeComdat32<'data, 'file, R = &'data [u8]> = -    PeComdat<'data, 'file, pe::ImageNtHeaders32, R>; -/// A COMDAT section group in a [`PeFile64`]. -pub type PeComdat64<'data, 'file, R = &'data [u8]> = -    PeComdat<'data, 'file, pe::ImageNtHeaders64, R>; - -/// A COMDAT section group in a [`PeFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeComdat<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file PeFile<'data, Pe, R>, -} - -impl<'data, 'file, Pe, R> read::private::Sealed for PeComdat<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> ObjectComdat<'data> for PeComdat<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type SectionIterator = PeComdatSectionIterator<'data, 'file, Pe, 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 for the sections in a COMDAT section group in a [`PeFile32`]. -pub type PeComdatSectionIterator32<'data, 'file, R = &'data [u8]> = -    PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the sections in a COMDAT section group in a [`PeFile64`]. -pub type PeComdatSectionIterator64<'data, 'file, R = &'data [u8]> = -    PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the sections in a COMDAT section group in a [`PeFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeComdatSectionIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file PeFile<'data, Pe, R>, -} - -impl<'data, 'file, Pe, R> Iterator for PeComdatSectionIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = SectionIndex; - -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -impl pe::ImageDosHeader { -    /// Read the DOS header. -    /// -    /// Also checks that the `e_magic` field in the header is valid. -    pub fn parse<'data, R: ReadRef<'data>>(data: R) -> read::Result<&'data Self> { -        // DOS header comes first. -        let dos_header = data -            .read_at::<pe::ImageDosHeader>(0) -            .read_error("Invalid DOS header size or alignment")?; -        if dos_header.e_magic.get(LE) != pe::IMAGE_DOS_SIGNATURE { -            return Err(Error("Invalid DOS magic")); -        } -        Ok(dos_header) -    } - -    /// Return the file offset of the nt_headers. -    #[inline] -    pub fn nt_headers_offset(&self) -> u32 { -        self.e_lfanew.get(LE) -    } -} - -/// Find the optional header and read its `magic` field. -/// -/// It can be useful to know this magic value before trying to -/// fully parse the NT headers. -pub fn optional_header_magic<'data, R: ReadRef<'data>>(data: R) -> Result<u16> { -    let dos_header = pe::ImageDosHeader::parse(data)?; -    // NT headers are at an offset specified in the DOS header. -    let offset = dos_header.nt_headers_offset().into(); -    // It doesn't matter which NT header type is used for the purpose -    // of reading the optional header magic. -    let nt_headers = data -        .read_at::<pe::ImageNtHeaders32>(offset) -        .read_error("Invalid NT headers offset, size, or alignment")?; -    if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE { -        return Err(Error("Invalid PE magic")); -    } -    Ok(nt_headers.optional_header().magic()) -} - -/// A trait for generic access to [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`]. -#[allow(missing_docs)] -pub trait ImageNtHeaders: Debug + Pod { -    type ImageOptionalHeader: ImageOptionalHeader; -    type ImageThunkData: ImageThunkData; - -    /// Return true if this type is a 64-bit header. -    /// -    /// This is a property of the type, not a value in the header data. -    fn is_type_64(&self) -> bool; - -    /// Return true if the magic field in the optional header is valid. -    fn is_valid_optional_magic(&self) -> bool; - -    /// Return the signature -    fn signature(&self) -> u32; - -    /// Return the file header. -    fn file_header(&self) -> &pe::ImageFileHeader; - -    /// Return the optional header. -    fn optional_header(&self) -> &Self::ImageOptionalHeader; - -    // Provided methods. - -    /// Read the NT headers, including the data directories. -    /// -    /// `data` must be for the entire file. -    /// -    /// `offset` must be headers offset, which can be obtained from [`pe::ImageDosHeader::nt_headers_offset`]. -    /// It is updated to point after the optional header, which is where the section headers are located. -    /// -    /// Also checks that the `signature` and `magic` fields in the headers are valid. -    fn parse<'data, R: ReadRef<'data>>( -        data: R, -        offset: &mut u64, -    ) -> read::Result<(&'data Self, DataDirectories<'data>)> { -        // Note that this does not include the data directories in the optional header. -        let nt_headers = data -            .read::<Self>(offset) -            .read_error("Invalid PE headers offset or size")?; -        if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE { -            return Err(Error("Invalid PE magic")); -        } -        if !nt_headers.is_valid_optional_magic() { -            return Err(Error("Invalid PE optional header magic")); -        } - -        // Read the rest of the optional header, and then read the data directories from that. -        let optional_data_size = -            u64::from(nt_headers.file_header().size_of_optional_header.get(LE)) -                .checked_sub(mem::size_of::<Self::ImageOptionalHeader>() as u64) -                .read_error("PE optional header size is too small")?; -        let optional_data = data -            .read_bytes(offset, optional_data_size) -            .read_error("Invalid PE optional header size")?; -        let data_directories = DataDirectories::parse( -            optional_data, -            nt_headers.optional_header().number_of_rva_and_sizes(), -        )?; - -        Ok((nt_headers, data_directories)) -    } - -    /// Read the section table. -    /// -    /// `data` must be for the entire file. -    /// `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.file_header(), data, offset) -    } - -    /// Read the COFF 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>> { -        SymbolTable::parse(self.file_header(), data) -    } -} - -/// A trait for generic access to [`pe::ImageOptionalHeader32`] and [`pe::ImageOptionalHeader64`]. -#[allow(missing_docs)] -pub trait ImageOptionalHeader: Debug + Pod { -    // Standard fields. -    fn magic(&self) -> u16; -    fn major_linker_version(&self) -> u8; -    fn minor_linker_version(&self) -> u8; -    fn size_of_code(&self) -> u32; -    fn size_of_initialized_data(&self) -> u32; -    fn size_of_uninitialized_data(&self) -> u32; -    fn address_of_entry_point(&self) -> u32; -    fn base_of_code(&self) -> u32; -    fn base_of_data(&self) -> Option<u32>; - -    // NT additional fields. -    fn image_base(&self) -> u64; -    fn section_alignment(&self) -> u32; -    fn file_alignment(&self) -> u32; -    fn major_operating_system_version(&self) -> u16; -    fn minor_operating_system_version(&self) -> u16; -    fn major_image_version(&self) -> u16; -    fn minor_image_version(&self) -> u16; -    fn major_subsystem_version(&self) -> u16; -    fn minor_subsystem_version(&self) -> u16; -    fn win32_version_value(&self) -> u32; -    fn size_of_image(&self) -> u32; -    fn size_of_headers(&self) -> u32; -    fn check_sum(&self) -> u32; -    fn subsystem(&self) -> u16; -    fn dll_characteristics(&self) -> u16; -    fn size_of_stack_reserve(&self) -> u64; -    fn size_of_stack_commit(&self) -> u64; -    fn size_of_heap_reserve(&self) -> u64; -    fn size_of_heap_commit(&self) -> u64; -    fn loader_flags(&self) -> u32; -    fn number_of_rva_and_sizes(&self) -> u32; -} - -impl ImageNtHeaders for pe::ImageNtHeaders32 { -    type ImageOptionalHeader = pe::ImageOptionalHeader32; -    type ImageThunkData = pe::ImageThunkData32; - -    #[inline] -    fn is_type_64(&self) -> bool { -        false -    } - -    #[inline] -    fn is_valid_optional_magic(&self) -> bool { -        self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC -    } - -    #[inline] -    fn signature(&self) -> u32 { -        self.signature.get(LE) -    } - -    #[inline] -    fn file_header(&self) -> &pe::ImageFileHeader { -        &self.file_header -    } - -    #[inline] -    fn optional_header(&self) -> &Self::ImageOptionalHeader { -        &self.optional_header -    } -} - -impl ImageOptionalHeader for pe::ImageOptionalHeader32 { -    #[inline] -    fn magic(&self) -> u16 { -        self.magic.get(LE) -    } - -    #[inline] -    fn major_linker_version(&self) -> u8 { -        self.major_linker_version -    } - -    #[inline] -    fn minor_linker_version(&self) -> u8 { -        self.minor_linker_version -    } - -    #[inline] -    fn size_of_code(&self) -> u32 { -        self.size_of_code.get(LE) -    } - -    #[inline] -    fn size_of_initialized_data(&self) -> u32 { -        self.size_of_initialized_data.get(LE) -    } - -    #[inline] -    fn size_of_uninitialized_data(&self) -> u32 { -        self.size_of_uninitialized_data.get(LE) -    } - -    #[inline] -    fn address_of_entry_point(&self) -> u32 { -        self.address_of_entry_point.get(LE) -    } - -    #[inline] -    fn base_of_code(&self) -> u32 { -        self.base_of_code.get(LE) -    } - -    #[inline] -    fn base_of_data(&self) -> Option<u32> { -        Some(self.base_of_data.get(LE)) -    } - -    #[inline] -    fn image_base(&self) -> u64 { -        self.image_base.get(LE).into() -    } - -    #[inline] -    fn section_alignment(&self) -> u32 { -        self.section_alignment.get(LE) -    } - -    #[inline] -    fn file_alignment(&self) -> u32 { -        self.file_alignment.get(LE) -    } - -    #[inline] -    fn major_operating_system_version(&self) -> u16 { -        self.major_operating_system_version.get(LE) -    } - -    #[inline] -    fn minor_operating_system_version(&self) -> u16 { -        self.minor_operating_system_version.get(LE) -    } - -    #[inline] -    fn major_image_version(&self) -> u16 { -        self.major_image_version.get(LE) -    } - -    #[inline] -    fn minor_image_version(&self) -> u16 { -        self.minor_image_version.get(LE) -    } - -    #[inline] -    fn major_subsystem_version(&self) -> u16 { -        self.major_subsystem_version.get(LE) -    } - -    #[inline] -    fn minor_subsystem_version(&self) -> u16 { -        self.minor_subsystem_version.get(LE) -    } - -    #[inline] -    fn win32_version_value(&self) -> u32 { -        self.win32_version_value.get(LE) -    } - -    #[inline] -    fn size_of_image(&self) -> u32 { -        self.size_of_image.get(LE) -    } - -    #[inline] -    fn size_of_headers(&self) -> u32 { -        self.size_of_headers.get(LE) -    } - -    #[inline] -    fn check_sum(&self) -> u32 { -        self.check_sum.get(LE) -    } - -    #[inline] -    fn subsystem(&self) -> u16 { -        self.subsystem.get(LE) -    } - -    #[inline] -    fn dll_characteristics(&self) -> u16 { -        self.dll_characteristics.get(LE) -    } - -    #[inline] -    fn size_of_stack_reserve(&self) -> u64 { -        self.size_of_stack_reserve.get(LE).into() -    } - -    #[inline] -    fn size_of_stack_commit(&self) -> u64 { -        self.size_of_stack_commit.get(LE).into() -    } - -    #[inline] -    fn size_of_heap_reserve(&self) -> u64 { -        self.size_of_heap_reserve.get(LE).into() -    } - -    #[inline] -    fn size_of_heap_commit(&self) -> u64 { -        self.size_of_heap_commit.get(LE).into() -    } - -    #[inline] -    fn loader_flags(&self) -> u32 { -        self.loader_flags.get(LE) -    } - -    #[inline] -    fn number_of_rva_and_sizes(&self) -> u32 { -        self.number_of_rva_and_sizes.get(LE) -    } -} - -impl ImageNtHeaders for pe::ImageNtHeaders64 { -    type ImageOptionalHeader = pe::ImageOptionalHeader64; -    type ImageThunkData = pe::ImageThunkData64; - -    #[inline] -    fn is_type_64(&self) -> bool { -        true -    } - -    #[inline] -    fn is_valid_optional_magic(&self) -> bool { -        self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC -    } - -    #[inline] -    fn signature(&self) -> u32 { -        self.signature.get(LE) -    } - -    #[inline] -    fn file_header(&self) -> &pe::ImageFileHeader { -        &self.file_header -    } - -    #[inline] -    fn optional_header(&self) -> &Self::ImageOptionalHeader { -        &self.optional_header -    } -} - -impl ImageOptionalHeader for pe::ImageOptionalHeader64 { -    #[inline] -    fn magic(&self) -> u16 { -        self.magic.get(LE) -    } - -    #[inline] -    fn major_linker_version(&self) -> u8 { -        self.major_linker_version -    } - -    #[inline] -    fn minor_linker_version(&self) -> u8 { -        self.minor_linker_version -    } - -    #[inline] -    fn size_of_code(&self) -> u32 { -        self.size_of_code.get(LE) -    } - -    #[inline] -    fn size_of_initialized_data(&self) -> u32 { -        self.size_of_initialized_data.get(LE) -    } - -    #[inline] -    fn size_of_uninitialized_data(&self) -> u32 { -        self.size_of_uninitialized_data.get(LE) -    } - -    #[inline] -    fn address_of_entry_point(&self) -> u32 { -        self.address_of_entry_point.get(LE) -    } - -    #[inline] -    fn base_of_code(&self) -> u32 { -        self.base_of_code.get(LE) -    } - -    #[inline] -    fn base_of_data(&self) -> Option<u32> { -        None -    } - -    #[inline] -    fn image_base(&self) -> u64 { -        self.image_base.get(LE) -    } - -    #[inline] -    fn section_alignment(&self) -> u32 { -        self.section_alignment.get(LE) -    } - -    #[inline] -    fn file_alignment(&self) -> u32 { -        self.file_alignment.get(LE) -    } - -    #[inline] -    fn major_operating_system_version(&self) -> u16 { -        self.major_operating_system_version.get(LE) -    } - -    #[inline] -    fn minor_operating_system_version(&self) -> u16 { -        self.minor_operating_system_version.get(LE) -    } - -    #[inline] -    fn major_image_version(&self) -> u16 { -        self.major_image_version.get(LE) -    } - -    #[inline] -    fn minor_image_version(&self) -> u16 { -        self.minor_image_version.get(LE) -    } - -    #[inline] -    fn major_subsystem_version(&self) -> u16 { -        self.major_subsystem_version.get(LE) -    } - -    #[inline] -    fn minor_subsystem_version(&self) -> u16 { -        self.minor_subsystem_version.get(LE) -    } - -    #[inline] -    fn win32_version_value(&self) -> u32 { -        self.win32_version_value.get(LE) -    } - -    #[inline] -    fn size_of_image(&self) -> u32 { -        self.size_of_image.get(LE) -    } - -    #[inline] -    fn size_of_headers(&self) -> u32 { -        self.size_of_headers.get(LE) -    } - -    #[inline] -    fn check_sum(&self) -> u32 { -        self.check_sum.get(LE) -    } - -    #[inline] -    fn subsystem(&self) -> u16 { -        self.subsystem.get(LE) -    } - -    #[inline] -    fn dll_characteristics(&self) -> u16 { -        self.dll_characteristics.get(LE) -    } - -    #[inline] -    fn size_of_stack_reserve(&self) -> u64 { -        self.size_of_stack_reserve.get(LE) -    } - -    #[inline] -    fn size_of_stack_commit(&self) -> u64 { -        self.size_of_stack_commit.get(LE) -    } - -    #[inline] -    fn size_of_heap_reserve(&self) -> u64 { -        self.size_of_heap_reserve.get(LE) -    } - -    #[inline] -    fn size_of_heap_commit(&self) -> u64 { -        self.size_of_heap_commit.get(LE) -    } - -    #[inline] -    fn loader_flags(&self) -> u32 { -        self.loader_flags.get(LE) -    } - -    #[inline] -    fn number_of_rva_and_sizes(&self) -> u32 { -        self.number_of_rva_and_sizes.get(LE) -    } -} diff --git a/vendor/object/src/read/pe/import.rs b/vendor/object/src/read/pe/import.rs deleted file mode 100644 index 8e9a9a9..0000000 --- a/vendor/object/src/read/pe/import.rs +++ /dev/null @@ -1,337 +0,0 @@ -use core::fmt::Debug; -use core::mem; - -use crate::read::{Bytes, ReadError, Result}; -use crate::{pe, LittleEndian as LE, Pod, U16Bytes}; - -use super::ImageNtHeaders; - -/// Information for parsing a PE import table. -/// -/// Returned by [`DataDirectories::import_table`](super::DataDirectories::import_table). -#[derive(Debug, Clone)] -pub struct ImportTable<'data> { -    section_data: Bytes<'data>, -    section_address: u32, -    import_address: u32, -} - -impl<'data> ImportTable<'data> { -    /// Create a new import table parser. -    /// -    /// The import descriptors start at `import_address`. -    /// The size declared in the `IMAGE_DIRECTORY_ENTRY_IMPORT` data directory is -    /// ignored by the Windows loader, and so descriptors will be parsed until a null entry. -    /// -    /// `section_data` should be from the section containing `import_address`, and -    /// `section_address` should be the address of that section. Pointers within the -    /// descriptors and thunks may point to anywhere within the section data. -    pub fn new(section_data: &'data [u8], section_address: u32, import_address: u32) -> Self { -        ImportTable { -            section_data: Bytes(section_data), -            section_address, -            import_address, -        } -    } - -    /// Return an iterator for the import descriptors. -    pub fn descriptors(&self) -> Result<ImportDescriptorIterator<'data>> { -        let offset = self.import_address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE import descriptor address")?; -        Ok(ImportDescriptorIterator { data }) -    } - -    /// Return a library name given its address. -    /// -    /// This address may be from [`pe::ImageImportDescriptor::name`]. -    pub fn name(&self, address: u32) -> Result<&'data [u8]> { -        self.section_data -            .read_string_at(address.wrapping_sub(self.section_address) as usize) -            .read_error("Invalid PE import descriptor name") -    } - -    /// Return a list of thunks given its address. -    /// -    /// This address may be from [`pe::ImageImportDescriptor::original_first_thunk`] -    /// or [`pe::ImageImportDescriptor::first_thunk`]. -    pub fn thunks(&self, address: u32) -> Result<ImportThunkList<'data>> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE import thunk table address")?; -        Ok(ImportThunkList { data }) -    } - -    /// Parse a thunk. -    pub fn import<Pe: ImageNtHeaders>(&self, thunk: Pe::ImageThunkData) -> Result<Import<'data>> { -        if thunk.is_ordinal() { -            Ok(Import::Ordinal(thunk.ordinal())) -        } else { -            let (hint, name) = self.hint_name(thunk.address())?; -            Ok(Import::Name(hint, name)) -        } -    } - -    /// Return the hint and name at the given address. -    /// -    /// This address may be from [`pe::ImageThunkData32`] or [`pe::ImageThunkData64`]. -    /// -    /// The hint is an index into the export name pointer table in the target library. -    pub fn hint_name(&self, address: u32) -> Result<(u16, &'data [u8])> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE import thunk address")?; -        let hint = data -            .read::<U16Bytes<LE>>() -            .read_error("Missing PE import thunk hint")? -            .get(LE); -        let name = data -            .read_string() -            .read_error("Missing PE import thunk name")?; -        Ok((hint, name)) -    } -} - -/// A fallible iterator for the descriptors in the import data directory. -#[derive(Debug, Clone)] -pub struct ImportDescriptorIterator<'data> { -    data: Bytes<'data>, -} - -impl<'data> ImportDescriptorIterator<'data> { -    /// Return the next descriptor. -    /// -    /// Returns `Ok(None)` when a null descriptor is found. -    pub fn next(&mut self) -> Result<Option<&'data pe::ImageImportDescriptor>> { -        let import_desc = self -            .data -            .read::<pe::ImageImportDescriptor>() -            .read_error("Missing PE null import descriptor")?; -        if import_desc.is_null() { -            Ok(None) -        } else { -            Ok(Some(import_desc)) -        } -    } -} - -/// A list of import thunks. -/// -/// These may be in the import lookup table, or the import address table. -#[derive(Debug, Clone)] -pub struct ImportThunkList<'data> { -    data: Bytes<'data>, -} - -impl<'data> ImportThunkList<'data> { -    /// Get the thunk at the given index. -    pub fn get<Pe: ImageNtHeaders>(&self, index: usize) -> Result<Pe::ImageThunkData> { -        let thunk = self -            .data -            .read_at(index * mem::size_of::<Pe::ImageThunkData>()) -            .read_error("Invalid PE import thunk index")?; -        Ok(*thunk) -    } - -    /// Return the first thunk in the list, and update `self` to point after it. -    /// -    /// Returns `Ok(None)` when a null thunk is found. -    pub fn next<Pe: ImageNtHeaders>(&mut self) -> Result<Option<Pe::ImageThunkData>> { -        let thunk = self -            .data -            .read::<Pe::ImageThunkData>() -            .read_error("Missing PE null import thunk")?; -        if thunk.address() == 0 { -            Ok(None) -        } else { -            Ok(Some(*thunk)) -        } -    } -} - -/// A parsed import thunk. -#[derive(Debug, Clone, Copy)] -pub enum Import<'data> { -    /// Import by ordinal. -    Ordinal(u16), -    /// Import by name. -    /// -    /// Includes a hint for the index into the export name pointer table in the target library. -    Name(u16, &'data [u8]), -} - -/// A trait for generic access to [`pe::ImageThunkData32`] and [`pe::ImageThunkData64`]. -#[allow(missing_docs)] -pub trait ImageThunkData: Debug + Pod { -    /// Return the raw thunk value. -    fn raw(self) -> u64; - -    /// Returns true if the ordinal flag is set. -    fn is_ordinal(self) -> bool; - -    /// Return the ordinal portion of the thunk. -    /// -    /// Does not check the ordinal flag. -    fn ordinal(self) -> u16; - -    /// Return the RVA portion of the thunk. -    /// -    /// Does not check the ordinal flag. -    fn address(self) -> u32; -} - -impl ImageThunkData for pe::ImageThunkData64 { -    fn raw(self) -> u64 { -        self.0.get(LE) -    } - -    fn is_ordinal(self) -> bool { -        self.0.get(LE) & pe::IMAGE_ORDINAL_FLAG64 != 0 -    } - -    fn ordinal(self) -> u16 { -        self.0.get(LE) as u16 -    } - -    fn address(self) -> u32 { -        self.0.get(LE) as u32 & 0x7fff_ffff -    } -} - -impl ImageThunkData for pe::ImageThunkData32 { -    fn raw(self) -> u64 { -        self.0.get(LE).into() -    } - -    fn is_ordinal(self) -> bool { -        self.0.get(LE) & pe::IMAGE_ORDINAL_FLAG32 != 0 -    } - -    fn ordinal(self) -> u16 { -        self.0.get(LE) as u16 -    } - -    fn address(self) -> u32 { -        self.0.get(LE) & 0x7fff_ffff -    } -} - -/// Information for parsing a PE delay-load import table. -/// -/// Returned by -/// [`DataDirectories::delay_load_import_table`](super::DataDirectories::delay_load_import_table). -#[derive(Debug, Clone)] -pub struct DelayLoadImportTable<'data> { -    section_data: Bytes<'data>, -    section_address: u32, -    import_address: u32, -} - -impl<'data> DelayLoadImportTable<'data> { -    /// Create a new delay load import table parser. -    /// -    /// The import descriptors start at `import_address`. -    /// This table works in the same way the import table does: descriptors will be -    /// parsed until a null entry. -    /// -    /// `section_data` should be from the section containing `import_address`, and -    /// `section_address` should be the address of that section. Pointers within the -    /// descriptors and thunks may point to anywhere within the section data. -    pub fn new(section_data: &'data [u8], section_address: u32, import_address: u32) -> Self { -        DelayLoadImportTable { -            section_data: Bytes(section_data), -            section_address, -            import_address, -        } -    } - -    /// Return an iterator for the import descriptors. -    pub fn descriptors(&self) -> Result<DelayLoadDescriptorIterator<'data>> { -        let offset = self.import_address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE delay-load import descriptor address")?; -        Ok(DelayLoadDescriptorIterator { data }) -    } - -    /// Return a library name given its address. -    /// -    /// This address may be from [`pe::ImageDelayloadDescriptor::dll_name_rva`]. -    pub fn name(&self, address: u32) -> Result<&'data [u8]> { -        self.section_data -            .read_string_at(address.wrapping_sub(self.section_address) as usize) -            .read_error("Invalid PE import descriptor name") -    } - -    /// Return a list of thunks given its address. -    /// -    /// This address may be from the INT, i.e. from -    /// [`pe::ImageDelayloadDescriptor::import_name_table_rva`]. -    /// -    /// Please note that others RVA values from [`pe::ImageDelayloadDescriptor`] are used -    /// by the delay loader at runtime to store values, and thus do not point inside the same -    /// section as the INT. Calling this function on those addresses will fail. -    pub fn thunks(&self, address: u32) -> Result<ImportThunkList<'data>> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE delay load import thunk table address")?; -        Ok(ImportThunkList { data }) -    } - -    /// Parse a thunk. -    pub fn import<Pe: ImageNtHeaders>(&self, thunk: Pe::ImageThunkData) -> Result<Import<'data>> { -        if thunk.is_ordinal() { -            Ok(Import::Ordinal(thunk.ordinal())) -        } else { -            let (hint, name) = self.hint_name(thunk.address())?; -            Ok(Import::Name(hint, name)) -        } -    } - -    /// Return the hint and name at the given address. -    /// -    /// This address may be from [`pe::ImageThunkData32`] or [`pe::ImageThunkData64`]. -    /// -    /// The hint is an index into the export name pointer table in the target library. -    pub fn hint_name(&self, address: u32) -> Result<(u16, &'data [u8])> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE delay load import thunk address")?; -        let hint = data -            .read::<U16Bytes<LE>>() -            .read_error("Missing PE delay load import thunk hint")? -            .get(LE); -        let name = data -            .read_string() -            .read_error("Missing PE delay load import thunk name")?; -        Ok((hint, name)) -    } -} - -/// A fallible iterator for the descriptors in the delay-load data directory. -#[derive(Debug, Clone)] -pub struct DelayLoadDescriptorIterator<'data> { -    data: Bytes<'data>, -} - -impl<'data> DelayLoadDescriptorIterator<'data> { -    /// Return the next descriptor. -    /// -    /// Returns `Ok(None)` when a null descriptor is found. -    pub fn next(&mut self) -> Result<Option<&'data pe::ImageDelayloadDescriptor>> { -        let import_desc = self -            .data -            .read::<pe::ImageDelayloadDescriptor>() -            .read_error("Missing PE null delay-load import descriptor")?; -        if import_desc.is_null() { -            Ok(None) -        } else { -            Ok(Some(import_desc)) -        } -    } -} diff --git a/vendor/object/src/read/pe/mod.rs b/vendor/object/src/read/pe/mod.rs deleted file mode 100644 index ab6011c..0000000 --- a/vendor/object/src/read/pe/mod.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Support for reading PE files. -//! -//! Traits are used to abstract over the difference between PE32 and PE32+. -//! The primary trait for this is [`ImageNtHeaders`]. -//! -//! ## High level API -//! -//! [`PeFile`] implements the [`Object`](crate::read::Object) trait for -//! PE files. [`PeFile`] is parameterised by [`ImageNtHeaders`] to allow -//! reading both PE32 and PE32+. There are type aliases for these parameters -//! ([`PeFile32`] and [`PeFile64`]). -//! -//! ## Low level API -//! -//! The [`ImageNtHeaders`] trait can be directly used to parse both -//! [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`]. -//! -//! ### Example for low level API -//!  ```no_run -//! use object::pe; -//! use object::read::pe::ImageNtHeaders; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads a file and displays the name of each section. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let dos_header = pe::ImageDosHeader::parse(&*data)?; -//!     let mut offset = dos_header.nt_headers_offset().into(); -//!     let (nt_headers, data_directories) = pe::ImageNtHeaders64::parse(&*data, &mut offset)?; -//!     let sections = nt_headers.sections(&*data, offset)?; -//!     let symbols = nt_headers.symbols(&*data)?; -//!     for section in sections.iter() { -//!         println!("{}", String::from_utf8_lossy(section.name(symbols.strings())?)); -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` -#[cfg(doc)] -use crate::pe; - -mod file; -pub use file::*; - -mod section; -pub use section::*; - -mod data_directory; -pub use data_directory::*; - -mod export; -pub use export::*; - -mod import; -pub use import::*; - -mod relocation; -pub use relocation::*; - -mod resource; -pub use resource::*; - -mod rich; -pub use rich::*; - -pub use super::coff::{SectionTable, SymbolTable}; diff --git a/vendor/object/src/read/pe/relocation.rs b/vendor/object/src/read/pe/relocation.rs deleted file mode 100644 index 77421b7..0000000 --- a/vendor/object/src/read/pe/relocation.rs +++ /dev/null @@ -1,92 +0,0 @@ -use core::slice; - -use crate::endian::{LittleEndian as LE, U16}; -use crate::pe; -use crate::read::{Bytes, Error, ReadError, Result}; - -/// An iterator over the relocation blocks in the `.reloc` section of a PE file. -/// -/// Returned by [`DataDirectories::relocation_blocks`](super::DataDirectories::relocation_blocks). -#[derive(Debug, Default, Clone, Copy)] -pub struct RelocationBlockIterator<'data> { -    data: Bytes<'data>, -} - -impl<'data> RelocationBlockIterator<'data> { -    /// Construct a new iterator from the data of the `.reloc` section. -    pub fn new(data: &'data [u8]) -> Self { -        RelocationBlockIterator { data: Bytes(data) } -    } - -    /// Read the next relocation page. -    pub fn next(&mut self) -> Result<Option<RelocationIterator<'data>>> { -        if self.data.is_empty() { -            return Ok(None); -        } -        let header = self -            .data -            .read::<pe::ImageBaseRelocation>() -            .read_error("Invalid PE reloc section size")?; -        let virtual_address = header.virtual_address.get(LE); -        let size = header.size_of_block.get(LE); -        if size <= 8 || size & 3 != 0 { -            return Err(Error("Invalid PE reloc block size")); -        } -        let count = (size - 8) / 2; -        let relocs = self -            .data -            .read_slice::<U16<LE>>(count as usize) -            .read_error("Invalid PE reloc block size")? -            .iter(); -        Ok(Some(RelocationIterator { -            virtual_address, -            size, -            relocs, -        })) -    } -} - -/// An iterator of the relocations in a block in the `.reloc` section of a PE file. -#[derive(Debug, Clone)] -pub struct RelocationIterator<'data> { -    virtual_address: u32, -    size: u32, -    relocs: slice::Iter<'data, U16<LE>>, -} - -impl<'data> RelocationIterator<'data> { -    /// Return the virtual address of the page that this block of relocations applies to. -    pub fn virtual_address(&self) -> u32 { -        self.virtual_address -    } - -    /// Return the size in bytes of this block of relocations. -    pub fn size(&self) -> u32 { -        self.size -    } -} - -impl<'data> Iterator for RelocationIterator<'data> { -    type Item = Relocation; - -    fn next(&mut self) -> Option<Relocation> { -        loop { -            let reloc = self.relocs.next()?.get(LE); -            if reloc != 0 { -                return Some(Relocation { -                    virtual_address: self.virtual_address.wrapping_add((reloc & 0xfff) as u32), -                    typ: reloc >> 12, -                }); -            } -        } -    } -} - -/// A relocation in the `.reloc` section of a PE file. -#[derive(Debug, Default, Clone, Copy)] -pub struct Relocation { -    /// The virtual address of the relocation. -    pub virtual_address: u32, -    /// One of the `pe::IMAGE_REL_BASED_*` constants. -    pub typ: u16, -} diff --git a/vendor/object/src/read/pe/resource.rs b/vendor/object/src/read/pe/resource.rs deleted file mode 100644 index 331da3f..0000000 --- a/vendor/object/src/read/pe/resource.rs +++ /dev/null @@ -1,209 +0,0 @@ -use alloc::string::String; -use core::char; - -use crate::read::{ReadError, ReadRef, Result}; -use crate::{pe, LittleEndian as LE, U16Bytes}; - -/// The `.rsrc` section of a PE file. -/// -/// Returned by [`DataDirectories::resource_directory`](super::DataDirectories::resource_directory). -#[derive(Debug, Clone, Copy)] -pub struct ResourceDirectory<'data> { -    data: &'data [u8], -} - -impl<'data> ResourceDirectory<'data> { -    /// Construct from the data of the `.rsrc` section. -    pub fn new(data: &'data [u8]) -> Self { -        ResourceDirectory { data } -    } - -    /// Parses the root resource directory. -    pub fn root(&self) -> Result<ResourceDirectoryTable<'data>> { -        ResourceDirectoryTable::parse(self.data, 0) -    } -} - -/// A table of resource entries. -#[derive(Debug, Clone)] -pub struct ResourceDirectoryTable<'data> { -    /// The table header. -    pub header: &'data pe::ImageResourceDirectory, -    /// The table entries. -    pub entries: &'data [pe::ImageResourceDirectoryEntry], -} - -impl<'data> ResourceDirectoryTable<'data> { -    fn parse(data: &'data [u8], offset: u32) -> Result<Self> { -        let mut offset = u64::from(offset); -        let header = data -            .read::<pe::ImageResourceDirectory>(&mut offset) -            .read_error("Invalid resource table header")?; -        let entries_count = header.number_of_id_entries.get(LE) as usize -            + header.number_of_named_entries.get(LE) as usize; -        let entries = data -            .read_slice::<pe::ImageResourceDirectoryEntry>(&mut offset, entries_count) -            .read_error("Invalid resource table entries")?; -        Ok(Self { header, entries }) -    } -} - -impl pe::ImageResourceDirectoryEntry { -    /// Returns true if the entry has a name, rather than an ID. -    pub fn has_name(&self) -> bool { -        self.name_or_id.get(LE) & pe::IMAGE_RESOURCE_NAME_IS_STRING != 0 -    } - -    /// Returns the section offset of the name. -    /// -    /// Valid if `has_name()` returns true. -    fn name(&self) -> ResourceName { -        let offset = self.name_or_id.get(LE) & !pe::IMAGE_RESOURCE_NAME_IS_STRING; -        ResourceName { offset } -    } - -    /// Returns the ID. -    /// -    /// Valid if `has_string_name()` returns false. -    fn id(&self) -> u16 { -        (self.name_or_id.get(LE) & 0x0000_FFFF) as u16 -    } - -    /// Returns the entry name -    pub fn name_or_id(&self) -> ResourceNameOrId { -        if self.has_name() { -            ResourceNameOrId::Name(self.name()) -        } else { -            ResourceNameOrId::Id(self.id()) -        } -    } - -    /// Returns true if the entry is a subtable. -    pub fn is_table(&self) -> bool { -        self.offset_to_data_or_directory.get(LE) & pe::IMAGE_RESOURCE_DATA_IS_DIRECTORY != 0 -    } - -    /// Returns the section offset of the associated table or data. -    pub fn data_offset(&self) -> u32 { -        self.offset_to_data_or_directory.get(LE) & !pe::IMAGE_RESOURCE_DATA_IS_DIRECTORY -    } - -    /// Returns the data associated to this directory entry. -    pub fn data<'data>( -        &self, -        section: ResourceDirectory<'data>, -    ) -> Result<ResourceDirectoryEntryData<'data>> { -        if self.is_table() { -            ResourceDirectoryTable::parse(section.data, self.data_offset()) -                .map(ResourceDirectoryEntryData::Table) -        } else { -            section -                .data -                .read_at::<pe::ImageResourceDataEntry>(self.data_offset().into()) -                .read_error("Invalid resource entry") -                .map(ResourceDirectoryEntryData::Data) -        } -    } -} - -/// Data associated with a resource directory entry. -#[derive(Debug, Clone)] -pub enum ResourceDirectoryEntryData<'data> { -    /// A subtable entry. -    Table(ResourceDirectoryTable<'data>), -    /// A resource data entry. -    Data(&'data pe::ImageResourceDataEntry), -} - -impl<'data> ResourceDirectoryEntryData<'data> { -    /// Converts to an option of table. -    /// -    /// Helper for iterator filtering. -    pub fn table(self) -> Option<ResourceDirectoryTable<'data>> { -        match self { -            Self::Table(dir) => Some(dir), -            _ => None, -        } -    } - -    /// Converts to an option of data entry. -    /// -    /// Helper for iterator filtering. -    pub fn data(self) -> Option<&'data pe::ImageResourceDataEntry> { -        match self { -            Self::Data(rsc) => Some(rsc), -            _ => None, -        } -    } -} - -/// A resource name. -#[derive(Debug, Clone, Copy)] -pub struct ResourceName { -    offset: u32, -} - -impl ResourceName { -    /// Converts to a `String`. -    pub fn to_string_lossy(&self, directory: ResourceDirectory<'_>) -> Result<String> { -        let d = self.data(directory)?.iter().map(|c| c.get(LE)); - -        Ok(char::decode_utf16(d) -            .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER)) -            .collect::<String>()) -    } - -    /// Returns the string unicode buffer. -    pub fn data<'data>( -        &self, -        directory: ResourceDirectory<'data>, -    ) -> Result<&'data [U16Bytes<LE>]> { -        let mut offset = u64::from(self.offset); -        let len = directory -            .data -            .read::<U16Bytes<LE>>(&mut offset) -            .read_error("Invalid resource name offset")?; -        directory -            .data -            .read_slice::<U16Bytes<LE>>(&mut offset, len.get(LE).into()) -            .read_error("Invalid resource name length") -    } - -    /// Returns the string buffer as raw bytes. -    pub fn raw_data<'data>(&self, directory: ResourceDirectory<'data>) -> Result<&'data [u8]> { -        self.data(directory).map(crate::pod::bytes_of_slice) -    } -} - -/// A resource name or ID. -/// -/// Can be either a string or a numeric ID. -#[derive(Debug)] -pub enum ResourceNameOrId { -    /// A resource name. -    Name(ResourceName), -    /// A resource ID. -    Id(u16), -} - -impl ResourceNameOrId { -    /// Converts to an option of name. -    /// -    /// Helper for iterator filtering. -    pub fn name(self) -> Option<ResourceName> { -        match self { -            Self::Name(name) => Some(name), -            _ => None, -        } -    } - -    /// Converts to an option of ID. -    /// -    /// Helper for iterator filtering. -    pub fn id(self) -> Option<u16> { -        match self { -            Self::Id(id) => Some(id), -            _ => None, -        } -    } -} diff --git a/vendor/object/src/read/pe/rich.rs b/vendor/object/src/read/pe/rich.rs deleted file mode 100644 index 33dd039..0000000 --- a/vendor/object/src/read/pe/rich.rs +++ /dev/null @@ -1,91 +0,0 @@ -//! PE rich header handling - -use core::mem; - -use crate::pod::bytes_of_slice; -use crate::read::Bytes; -use crate::{pe, LittleEndian as LE, ReadRef, U32}; - -/// Parsed information about a Rich Header. -#[derive(Debug, Clone, Copy)] -pub struct RichHeaderInfo<'data> { -    /// The offset at which the rich header starts. -    pub offset: usize, -    /// The length (in bytes) of the rich header. -    /// -    /// This includes the payload, but also the 16-byte start sequence and the -    /// 8-byte final "Rich" and XOR key. -    pub length: usize, -    /// The XOR key used to mask the rich header. -    /// -    /// Unless the file has been tampered with, it should be equal to a checksum -    /// of the file header. -    pub xor_key: u32, -    masked_entries: &'data [pe::MaskedRichHeaderEntry], -} - -/// A PE rich header entry after it has been unmasked. -/// -/// See [`pe::MaskedRichHeaderEntry`]. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct RichHeaderEntry { -    /// ID of the component. -    pub comp_id: u32, -    /// Number of times this component has been used when building this PE. -    pub count: u32, -} - -impl<'data> RichHeaderInfo<'data> { -    /// Try to locate a rich header and its entries in the current PE file. -    pub fn parse<R: ReadRef<'data>>(data: R, nt_header_offset: u64) -> Option<Self> { -        // Locate the rich header, if any. -        // It ends with the "Rich" string and an XOR key, before the NT header. -        let data = data.read_bytes_at(0, nt_header_offset).map(Bytes).ok()?; -        let end_marker_offset = memmem(data.0, b"Rich", 4)?; -        let xor_key = *data.read_at::<U32<LE>>(end_marker_offset + 4).ok()?; - -        // It starts at the masked "DanS" string and 3 masked zeroes. -        let masked_start_marker = U32::new(LE, 0x536e_6144 ^ xor_key.get(LE)); -        let start_header = [masked_start_marker, xor_key, xor_key, xor_key]; -        let start_sequence = bytes_of_slice(&start_header); -        let start_marker_offset = memmem(&data.0[..end_marker_offset], start_sequence, 4)?; - -        // Extract the items between the markers. -        let items_offset = start_marker_offset + start_sequence.len(); -        let items_len = end_marker_offset - items_offset; -        let item_count = items_len / mem::size_of::<pe::MaskedRichHeaderEntry>(); -        let items = data.read_slice_at(items_offset, item_count).ok()?; -        Some(RichHeaderInfo { -            offset: start_marker_offset, -            // Includes "Rich" marker and the XOR key. -            length: end_marker_offset - start_marker_offset + 8, -            xor_key: xor_key.get(LE), -            masked_entries: items, -        }) -    } - -    /// Returns an iterator over the unmasked entries. -    pub fn unmasked_entries(&self) -> impl Iterator<Item = RichHeaderEntry> + 'data { -        let xor_key = self.xor_key; -        self.masked_entries -            .iter() -            .map(move |entry| RichHeaderEntry { -                comp_id: entry.masked_comp_id.get(LE) ^ xor_key, -                count: entry.masked_count.get(LE) ^ xor_key, -            }) -    } -} - -/// Find the offset of the first occurrence of needle in the data. -/// -/// The offset must have the given alignment. -fn memmem(data: &[u8], needle: &[u8], align: usize) -> Option<usize> { -    let mut offset = 0; -    loop { -        if data.get(offset..)?.get(..needle.len())? == needle { -            return Some(offset); -        } -        offset += align; -    } -} diff --git a/vendor/object/src/read/pe/section.rs b/vendor/object/src/read/pe/section.rs deleted file mode 100644 index 74c9d7f..0000000 --- a/vendor/object/src/read/pe/section.rs +++ /dev/null @@ -1,440 +0,0 @@ -use core::marker::PhantomData; -use core::{cmp, iter, slice, str}; - -use crate::endian::LittleEndian as LE; -use crate::pe; -use crate::pe::ImageSectionHeader; -use crate::read::{ -    self, CompressedData, CompressedFileRange, ObjectSection, ObjectSegment, ReadError, ReadRef, -    Relocation, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags, -}; - -use super::{ImageNtHeaders, PeFile, SectionTable}; - -/// An iterator for the loadable sections in a [`PeFile32`](super::PeFile32). -pub type PeSegmentIterator32<'data, 'file, R = &'data [u8]> = -    PeSegmentIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the loadable sections in a [`PeFile64`](super::PeFile64). -pub type PeSegmentIterator64<'data, 'file, R = &'data [u8]> = -    PeSegmentIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the loadable sections in a [`PeFile`]. -#[derive(Debug)] -pub struct PeSegmentIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file PeFile<'data, Pe, R>, -    pub(super) iter: slice::Iter<'data, pe::ImageSectionHeader>, -} - -impl<'data, 'file, Pe, R> Iterator for PeSegmentIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = PeSegment<'data, 'file, Pe, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|section| PeSegment { -            file: self.file, -            section, -        }) -    } -} - -/// A loadable section in a [`PeFile32`](super::PeFile32). -pub type PeSegment32<'data, 'file, R = &'data [u8]> = -    PeSegment<'data, 'file, pe::ImageNtHeaders32, R>; -/// A loadable section in a [`PeFile64`](super::PeFile64). -pub type PeSegment64<'data, 'file, R = &'data [u8]> = -    PeSegment<'data, 'file, pe::ImageNtHeaders64, R>; - -/// A loadable section in a [`PeFile`]. -/// -/// Most functionality is provided by the [`ObjectSegment`] trait implementation. -#[derive(Debug)] -pub struct PeSegment<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    file: &'file PeFile<'data, Pe, R>, -    section: &'data pe::ImageSectionHeader, -} - -impl<'data, 'file, Pe, R> read::private::Sealed for PeSegment<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> ObjectSegment<'data> for PeSegment<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[inline] -    fn address(&self) -> u64 { -        u64::from(self.section.virtual_address.get(LE)).wrapping_add(self.file.common.image_base) -    } - -    #[inline] -    fn size(&self) -> u64 { -        u64::from(self.section.virtual_size.get(LE)) -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.file.section_alignment() -    } - -    #[inline] -    fn file_range(&self) -> (u64, u64) { -        let (offset, size) = self.section.pe_file_range(); -        (u64::from(offset), u64::from(size)) -    } - -    fn data(&self) -> Result<&'data [u8]> { -        self.section.pe_data(self.file.data) -    } - -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> { -        Ok(read::util::data_range( -            self.data()?, -            self.address(), -            address, -            size, -        )) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<Option<&[u8]>> { -        self.section -            .name(self.file.common.symbols.strings()) -            .map(Some) -    } - -    #[inline] -    fn name(&self) -> Result<Option<&str>> { -        let name = self.section.name(self.file.common.symbols.strings())?; -        Ok(Some( -            str::from_utf8(name) -                .ok() -                .read_error("Non UTF-8 PE section name")?, -        )) -    } - -    #[inline] -    fn flags(&self) -> SegmentFlags { -        let characteristics = self.section.characteristics.get(LE); -        SegmentFlags::Coff { characteristics } -    } -} - -/// An iterator for the sections in a [`PeFile32`](super::PeFile32). -pub type PeSectionIterator32<'data, 'file, R = &'data [u8]> = -    PeSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the sections in a [`PeFile64`](super::PeFile64). -pub type PeSectionIterator64<'data, 'file, R = &'data [u8]> = -    PeSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the sections in a [`PeFile`]. -#[derive(Debug)] -pub struct PeSectionIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file PeFile<'data, Pe, R>, -    pub(super) iter: iter::Enumerate<slice::Iter<'data, pe::ImageSectionHeader>>, -} - -impl<'data, 'file, Pe, R> Iterator for PeSectionIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = PeSection<'data, 'file, Pe, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|(index, section)| PeSection { -            file: self.file, -            index: SectionIndex(index + 1), -            section, -        }) -    } -} - -/// A section in a [`PeFile32`](super::PeFile32). -pub type PeSection32<'data, 'file, R = &'data [u8]> = -    PeSection<'data, 'file, pe::ImageNtHeaders32, R>; -/// A section in a [`PeFile64`](super::PeFile64). -pub type PeSection64<'data, 'file, R = &'data [u8]> = -    PeSection<'data, 'file, pe::ImageNtHeaders64, R>; - -/// A section in a [`PeFile`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -#[derive(Debug)] -pub struct PeSection<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file PeFile<'data, Pe, R>, -    pub(super) index: SectionIndex, -    pub(super) section: &'data pe::ImageSectionHeader, -} - -impl<'data, 'file, Pe, R> read::private::Sealed for PeSection<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> ObjectSection<'data> for PeSection<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type RelocationIterator = PeRelocationIterator<'data, 'file, R>; - -    #[inline] -    fn index(&self) -> SectionIndex { -        self.index -    } - -    #[inline] -    fn address(&self) -> u64 { -        u64::from(self.section.virtual_address.get(LE)).wrapping_add(self.file.common.image_base) -    } - -    #[inline] -    fn size(&self) -> u64 { -        u64::from(self.section.virtual_size.get(LE)) -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.file.section_alignment() -    } - -    #[inline] -    fn file_range(&self) -> Option<(u64, u64)> { -        let (offset, size) = self.section.pe_file_range(); -        if size == 0 { -            None -        } else { -            Some((u64::from(offset), u64::from(size))) -        } -    } - -    fn data(&self) -> Result<&'data [u8]> { -        self.section.pe_data(self.file.data) -    } - -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> { -        Ok(read::util::data_range( -            self.data()?, -            self.address(), -            address, -            size, -        )) -    } - -    #[inline] -    fn compressed_file_range(&self) -> Result<CompressedFileRange> { -        Ok(CompressedFileRange::none(self.file_range())) -    } - -    #[inline] -    fn compressed_data(&self) -> Result<CompressedData<'data>> { -        self.data().map(CompressedData::none) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<&[u8]> { -        self.section.name(self.file.common.symbols.strings()) -    } - -    #[inline] -    fn name(&self) -> Result<&str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 PE section name") -    } - -    #[inline] -    fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { -        Ok(None) -    } - -    #[inline] -    fn segment_name(&self) -> Result<Option<&str>> { -        Ok(None) -    } - -    #[inline] -    fn kind(&self) -> SectionKind { -        self.section.kind() -    } - -    fn relocations(&self) -> PeRelocationIterator<'data, 'file, R> { -        PeRelocationIterator(PhantomData) -    } - -    fn flags(&self) -> SectionFlags { -        SectionFlags::Coff { -            characteristics: self.section.characteristics.get(LE), -        } -    } -} - -impl<'data> SectionTable<'data> { -    /// Return the file offset of the given virtual address, and the size up -    /// to the end of the section containing it. -    /// -    /// Returns `None` if no section contains the address. -    pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> { -        self.iter().find_map(|section| section.pe_file_range_at(va)) -    } - -    /// Return the data starting at the given virtual address, up to the end of the -    /// section containing it. -    /// -    /// Ignores sections with invalid data. -    /// -    /// Returns `None` if no section contains the address. -    pub fn pe_data_at<R: ReadRef<'data>>(&self, data: R, va: u32) -> Option<&'data [u8]> { -        self.iter().find_map(|section| section.pe_data_at(data, va)) -    } - -    /// Return the data of the section that contains the given virtual address in a PE file. -    /// -    /// Also returns the virtual address of that section. -    /// -    /// Ignores sections with invalid data. -    pub fn pe_data_containing<R: ReadRef<'data>>( -        &self, -        data: R, -        va: u32, -    ) -> Option<(&'data [u8], u32)> { -        self.iter() -            .find_map(|section| section.pe_data_containing(data, va)) -    } - -    /// Return the section that contains a given virtual address. -    pub fn section_containing(&self, va: u32) -> Option<&'data ImageSectionHeader> { -        self.iter().find(|section| section.contains_rva(va)) -    } -} - -impl pe::ImageSectionHeader { -    /// Return the offset and size of the section in a PE file. -    /// -    /// The size of the range will be the minimum of the file size and virtual size. -    pub fn pe_file_range(&self) -> (u32, u32) { -        // Pointer and size will be zero for uninitialized data; we don't need to validate this. -        let offset = self.pointer_to_raw_data.get(LE); -        let size = cmp::min(self.virtual_size.get(LE), self.size_of_raw_data.get(LE)); -        (offset, size) -    } - -    /// Return the file offset of the given virtual address, and the remaining size up -    /// to the end of the section. -    /// -    /// Returns `None` if the section does not contain the address. -    pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> { -        let section_va = self.virtual_address.get(LE); -        let offset = va.checked_sub(section_va)?; -        let (section_offset, section_size) = self.pe_file_range(); -        // Address must be within section (and not at its end). -        if offset < section_size { -            Some((section_offset.checked_add(offset)?, section_size - offset)) -        } else { -            None -        } -    } - -    /// Return the virtual address and size of the section. -    pub fn pe_address_range(&self) -> (u32, u32) { -        (self.virtual_address.get(LE), self.virtual_size.get(LE)) -    } - -    /// Return the section data in a PE file. -    /// -    /// The length of the data will be the minimum of the file size and virtual size. -    pub fn pe_data<'data, R: ReadRef<'data>>(&self, data: R) -> Result<&'data [u8]> { -        let (offset, size) = self.pe_file_range(); -        data.read_bytes_at(offset.into(), size.into()) -            .read_error("Invalid PE section offset or size") -    } - -    /// Return the data starting at the given virtual address, up to the end of the -    /// section. -    /// -    /// Ignores sections with invalid data. -    /// -    /// Returns `None` if the section does not contain the address. -    pub fn pe_data_at<'data, R: ReadRef<'data>>(&self, data: R, va: u32) -> Option<&'data [u8]> { -        let (offset, size) = self.pe_file_range_at(va)?; -        data.read_bytes_at(offset.into(), size.into()).ok() -    } - -    /// Tests whether a given RVA is part of this section -    pub fn contains_rva(&self, va: u32) -> bool { -        let section_va = self.virtual_address.get(LE); -        match va.checked_sub(section_va) { -            None => false, -            Some(offset) => { -                // Address must be within section (and not at its end). -                offset < self.virtual_size.get(LE) -            } -        } -    } - -    /// Return the section data if it contains the given virtual address. -    /// -    /// Also returns the virtual address of that section. -    /// -    /// Ignores sections with invalid data. -    pub fn pe_data_containing<'data, R: ReadRef<'data>>( -        &self, -        data: R, -        va: u32, -    ) -> Option<(&'data [u8], u32)> { -        let section_va = self.virtual_address.get(LE); -        let offset = va.checked_sub(section_va)?; -        let (section_offset, section_size) = self.pe_file_range(); -        // Address must be within section (and not at its end). -        if offset < section_size { -            let section_data = data -                .read_bytes_at(section_offset.into(), section_size.into()) -                .ok()?; -            Some((section_data, section_va)) -        } else { -            None -        } -    } -} - -/// An iterator for the relocations in an [`PeSection`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeRelocationIterator<'data, 'file, R = &'data [u8]>( -    PhantomData<(&'data (), &'file (), R)>, -); - -impl<'data, 'file, R> Iterator for PeRelocationIterator<'data, 'file, R> { -    type Item = (u64, Relocation); - -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} diff --git a/vendor/object/src/read/read_cache.rs b/vendor/object/src/read/read_cache.rs deleted file mode 100644 index d1377f1..0000000 --- a/vendor/object/src/read/read_cache.rs +++ /dev/null @@ -1,178 +0,0 @@ -use core::ops::Range; -use std::boxed::Box; -use std::cell::RefCell; -use std::collections::hash_map::Entry; -use std::collections::HashMap; -use std::convert::TryInto; -use std::io::{Read, Seek, SeekFrom}; -use std::mem; -use std::vec::Vec; - -use crate::read::ReadRef; - -/// An implementation of [`ReadRef`] for data in a stream that implements -/// `Read + Seek`. -/// -/// Contains a cache of read-only blocks of data, allowing references to -/// them to be returned. Entries in the cache are never removed. -/// Entries are keyed on the offset and size of the read. -/// Currently overlapping reads are considered separate reads. -#[derive(Debug)] -pub struct ReadCache<R: Read + Seek> { -    cache: RefCell<ReadCacheInternal<R>>, -} - -#[derive(Debug)] -struct ReadCacheInternal<R: Read + Seek> { -    read: R, -    bufs: HashMap<(u64, u64), Box<[u8]>>, -    strings: HashMap<(u64, u8), Box<[u8]>>, -} - -impl<R: Read + Seek> ReadCache<R> { -    /// Create an empty `ReadCache` for the given stream. -    pub fn new(read: R) -> Self { -        ReadCache { -            cache: RefCell::new(ReadCacheInternal { -                read, -                bufs: HashMap::new(), -                strings: HashMap::new(), -            }), -        } -    } - -    /// Return an implementation of `ReadRef` that restricts reads -    /// to the given range of the stream. -    pub fn range(&self, offset: u64, size: u64) -> ReadCacheRange<'_, R> { -        ReadCacheRange { -            r: self, -            offset, -            size, -        } -    } - -    /// Free buffers used by the cache. -    pub fn clear(&mut self) { -        self.cache.borrow_mut().bufs.clear(); -    } - -    /// Unwrap this `ReadCache<R>`, returning the underlying reader. -    pub fn into_inner(self) -> R { -        self.cache.into_inner().read -    } -} - -impl<'a, R: Read + Seek> ReadRef<'a> for &'a ReadCache<R> { -    fn len(self) -> Result<u64, ()> { -        let cache = &mut *self.cache.borrow_mut(); -        cache.read.seek(SeekFrom::End(0)).map_err(|_| ()) -    } - -    fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8], ()> { -        if size == 0 { -            return Ok(&[]); -        } -        let cache = &mut *self.cache.borrow_mut(); -        let buf = match cache.bufs.entry((offset, size)) { -            Entry::Occupied(entry) => entry.into_mut(), -            Entry::Vacant(entry) => { -                let size = size.try_into().map_err(|_| ())?; -                cache.read.seek(SeekFrom::Start(offset)).map_err(|_| ())?; -                let mut bytes = vec![0; size].into_boxed_slice(); -                cache.read.read_exact(&mut bytes).map_err(|_| ())?; -                entry.insert(bytes) -            } -        }; -        // Extend the lifetime to that of self. -        // This is OK because we never mutate or remove entries. -        Ok(unsafe { mem::transmute::<&[u8], &[u8]>(buf) }) -    } - -    fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8], ()> { -        let cache = &mut *self.cache.borrow_mut(); -        let buf = match cache.strings.entry((range.start, delimiter)) { -            Entry::Occupied(entry) => entry.into_mut(), -            Entry::Vacant(entry) => { -                cache -                    .read -                    .seek(SeekFrom::Start(range.start)) -                    .map_err(|_| ())?; - -                let max_check: usize = (range.end - range.start).try_into().map_err(|_| ())?; -                // Strings should be relatively small. -                // TODO: make this configurable? -                let max_check = max_check.min(4096); - -                let mut bytes = Vec::new(); -                let mut checked = 0; -                loop { -                    bytes.resize((checked + 256).min(max_check), 0); -                    let read = cache.read.read(&mut bytes[checked..]).map_err(|_| ())?; -                    if read == 0 { -                        return Err(()); -                    } -                    if let Some(len) = memchr::memchr(delimiter, &bytes[checked..][..read]) { -                        bytes.truncate(checked + len); -                        break entry.insert(bytes.into_boxed_slice()); -                    } -                    checked += read; -                    if checked >= max_check { -                        return Err(()); -                    } -                } -            } -        }; -        // Extend the lifetime to that of self. -        // This is OK because we never mutate or remove entries. -        Ok(unsafe { mem::transmute::<&[u8], &[u8]>(buf) }) -    } -} - -/// An implementation of [`ReadRef`] for a range of data in a stream that -/// implements `Read + Seek`. -/// -/// Shares an underlying `ReadCache` with a lifetime of `'a`. -#[derive(Debug)] -pub struct ReadCacheRange<'a, R: Read + Seek> { -    r: &'a ReadCache<R>, -    offset: u64, -    size: u64, -} - -impl<'a, R: Read + Seek> Clone for ReadCacheRange<'a, R> { -    fn clone(&self) -> Self { -        *self -    } -} - -impl<'a, R: Read + Seek> Copy for ReadCacheRange<'a, R> {} - -impl<'a, R: Read + Seek> ReadRef<'a> for ReadCacheRange<'a, R> { -    fn len(self) -> Result<u64, ()> { -        Ok(self.size) -    } - -    fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8], ()> { -        if size == 0 { -            return Ok(&[]); -        } -        let end = offset.checked_add(size).ok_or(())?; -        if end > self.size { -            return Err(()); -        } -        let r_offset = self.offset.checked_add(offset).ok_or(())?; -        self.r.read_bytes_at(r_offset, size) -    } - -    fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8], ()> { -        let r_start = self.offset.checked_add(range.start).ok_or(())?; -        let r_end = self.offset.checked_add(range.end).ok_or(())?; -        let bytes = self.r.read_bytes_at_until(r_start..r_end, delimiter)?; -        let size = bytes.len().try_into().map_err(|_| ())?; -        let end = range.start.checked_add(size).ok_or(())?; -        if end > self.size { -            return Err(()); -        } -        Ok(bytes) -    } -} diff --git a/vendor/object/src/read/read_ref.rs b/vendor/object/src/read/read_ref.rs deleted file mode 100644 index 8b87cba..0000000 --- a/vendor/object/src/read/read_ref.rs +++ /dev/null @@ -1,137 +0,0 @@ -#![allow(clippy::len_without_is_empty)] - -use core::convert::TryInto; -use core::ops::Range; -use core::{mem, result}; - -use crate::pod::{from_bytes, slice_from_bytes, Pod}; - -type Result<T> = result::Result<T, ()>; - -/// A trait for reading references to [`Pod`] types from a block of data. -/// -/// This allows parsers to handle both of these cases: -/// - the block of data exists in memory, and it is desirable -///   to use references to this block instead of copying it, -/// - the block of data exists in storage, and it is desirable -///   to read on demand to minimize I/O and memory usage. -/// -/// The methods accept `self` by value because `Self` is expected to behave -/// similar to a reference: it may be a reference with a lifetime of `'a`, -/// or it may be a wrapper of a reference. -/// -/// The `Clone` and `Copy` bounds are for convenience, and since `Self` is -/// expected to be similar to a reference, these are easily satisfied. -/// -/// Object file parsers typically use offsets to locate the structures -/// in the block, and will most commonly use the `*_at` methods to -/// read a structure at a known offset. -/// -/// Occasionally file parsers will need to treat the block as a stream, -/// and so convenience methods are provided that update an offset with -/// the size that was read. -// -// An alternative would be for methods to accept `&mut self` and use a -// `seek` method instead of the `offset` parameters, but this is less -// convenient for implementers. -pub trait ReadRef<'a>: Clone + Copy { -    /// The total size of the block of data. -    fn len(self) -> Result<u64>; - -    /// Get a reference to a `u8` slice at the given offset. -    /// -    /// Returns an error if offset or size are out of bounds. -    fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8]>; - -    /// Get a reference to a delimited `u8` slice which starts at range.start. -    /// -    /// Does not include the delimiter. -    /// -    /// Returns an error if the range is out of bounds or the delimiter is -    /// not found in the range. -    fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8]>; - -    /// Get a reference to a `u8` slice at the given offset, and update the offset. -    /// -    /// Returns an error if offset or size are out of bounds. -    fn read_bytes(self, offset: &mut u64, size: u64) -> Result<&'a [u8]> { -        let bytes = self.read_bytes_at(*offset, size)?; -        *offset = offset.wrapping_add(size); -        Ok(bytes) -    } - -    /// Get a reference to a `Pod` type at the given offset, and update the offset. -    /// -    /// Returns an error if offset or size are out of bounds. -    /// -    /// The default implementation uses `read_bytes`, and returns an error if -    /// `read_bytes` does not return bytes with the correct alignment for `T`. -    /// Implementors may want to provide their own implementation that ensures -    /// the alignment can be satisfied. Alternatively, only use this method with -    /// types that do not need alignment (see the `unaligned` feature of this crate). -    fn read<T: Pod>(self, offset: &mut u64) -> Result<&'a T> { -        let size = mem::size_of::<T>().try_into().map_err(|_| ())?; -        let bytes = self.read_bytes(offset, size)?; -        let (t, _) = from_bytes(bytes)?; -        Ok(t) -    } - -    /// Get a reference to a `Pod` type at the given offset. -    /// -    /// Returns an error if offset or size are out of bounds. -    /// -    /// Also see the `read` method for information regarding alignment of `T`. -    fn read_at<T: Pod>(self, mut offset: u64) -> Result<&'a T> { -        self.read(&mut offset) -    } - -    /// Get a reference to a slice of a `Pod` type at the given offset, and update the offset. -    /// -    /// Returns an error if offset or size are out of bounds. -    /// -    /// Also see the `read` method for information regarding alignment of `T`. -    fn read_slice<T: Pod>(self, offset: &mut u64, count: usize) -> Result<&'a [T]> { -        let size = count -            .checked_mul(mem::size_of::<T>()) -            .ok_or(())? -            .try_into() -            .map_err(|_| ())?; -        let bytes = self.read_bytes(offset, size)?; -        let (t, _) = slice_from_bytes(bytes, count)?; -        Ok(t) -    } - -    /// Get a reference to a slice of a `Pod` type at the given offset. -    /// -    /// Returns an error if offset or size are out of bounds. -    /// -    /// Also see the `read` method for information regarding alignment of `T`. -    fn read_slice_at<T: Pod>(self, mut offset: u64, count: usize) -> Result<&'a [T]> { -        self.read_slice(&mut offset, count) -    } -} - -impl<'a> ReadRef<'a> for &'a [u8] { -    fn len(self) -> Result<u64> { -        self.len().try_into().map_err(|_| ()) -    } - -    fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8]> { -        let offset: usize = offset.try_into().map_err(|_| ())?; -        let size: usize = size.try_into().map_err(|_| ())?; -        self.get(offset..).ok_or(())?.get(..size).ok_or(()) -    } - -    fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8]> { -        let start: usize = range.start.try_into().map_err(|_| ())?; -        let end: usize = range.end.try_into().map_err(|_| ())?; -        let bytes = self.get(start..end).ok_or(())?; -        match memchr::memchr(delimiter, bytes) { -            Some(len) => { -                // This will never fail. -                bytes.get(..len).ok_or(()) -            } -            None => Err(()), -        } -    } -} diff --git a/vendor/object/src/read/traits.rs b/vendor/object/src/read/traits.rs deleted file mode 100644 index 67105d3..0000000 --- a/vendor/object/src/read/traits.rs +++ /dev/null @@ -1,551 +0,0 @@ -use alloc::borrow::Cow; -use alloc::vec::Vec; - -use crate::read::{ -    self, Architecture, CodeView, ComdatKind, CompressedData, CompressedFileRange, Export, -    FileFlags, Import, ObjectKind, ObjectMap, Relocation, Result, SectionFlags, SectionIndex, -    SectionKind, SegmentFlags, SubArchitecture, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, -    SymbolMapName, SymbolScope, SymbolSection, -}; -use crate::Endianness; - -/// An object file. -/// -/// This is the primary trait for the unified read API. -pub trait Object<'data: 'file, 'file>: read::private::Sealed { -    /// A loadable segment in the object file. -    type Segment: ObjectSegment<'data>; - -    /// An iterator for the loadable segments in the object file. -    type SegmentIterator: Iterator<Item = Self::Segment>; - -    /// A section in the object file. -    type Section: ObjectSection<'data>; - -    /// An iterator for the sections in the object file. -    type SectionIterator: Iterator<Item = Self::Section>; - -    /// A COMDAT section group in the object file. -    type Comdat: ObjectComdat<'data>; - -    /// An iterator for the COMDAT section groups in the object file. -    type ComdatIterator: Iterator<Item = Self::Comdat>; - -    /// A symbol in the object file. -    type Symbol: ObjectSymbol<'data>; - -    /// An iterator for symbols in the object file. -    type SymbolIterator: Iterator<Item = Self::Symbol>; - -    /// A symbol table in the object file. -    type SymbolTable: ObjectSymbolTable< -        'data, -        Symbol = Self::Symbol, -        SymbolIterator = Self::SymbolIterator, -    >; - -    /// An iterator for the dynamic relocations in the file. -    /// -    /// The first field in the item tuple is the address -    /// that the relocation applies to. -    type DynamicRelocationIterator: Iterator<Item = (u64, Relocation)>; - -    /// Get the architecture type of the file. -    fn architecture(&self) -> Architecture; - -    /// Get the sub-architecture type of the file if known. -    /// -    /// A value of `None` has a range of meanings: the file supports all -    /// sub-architectures, the file does not explicitly specify a -    /// sub-architecture, or the sub-architecture is currently unrecognized. -    fn sub_architecture(&self) -> Option<SubArchitecture> { -        None -    } - -    /// Get the endianness of the file. -    #[inline] -    fn endianness(&self) -> Endianness { -        if self.is_little_endian() { -            Endianness::Little -        } else { -            Endianness::Big -        } -    } - -    /// Return true if the file is little endian, false if it is big endian. -    fn is_little_endian(&self) -> bool; - -    /// Return true if the file can contain 64-bit addresses. -    fn is_64(&self) -> bool; - -    /// Return the kind of this object. -    fn kind(&self) -> ObjectKind; - -    /// Get an iterator for the loadable segments in the file. -    /// -    /// For ELF, this is program headers with type [`PT_LOAD`](crate::elf::PT_LOAD). -    /// For Mach-O, this is load commands with type [`LC_SEGMENT`](crate::macho::LC_SEGMENT) -    /// or [`LC_SEGMENT_64`](crate::macho::LC_SEGMENT_64). -    /// For PE, this is all sections. -    fn segments(&'file self) -> Self::SegmentIterator; - -    /// Get the section named `section_name`, if such a section exists. -    /// -    /// If `section_name` starts with a '.' then it is treated as a system section name, -    /// and is compared using the conventions specific to the object file format. This -    /// includes: -    /// - if ".debug_str_offsets" is requested for a Mach-O object file, then the actual -    /// section name that is searched for is "__debug_str_offs". -    /// - if ".debug_info" is requested for an ELF object file, then -    /// ".zdebug_info" may be returned (and similarly for other debug sections). -    /// -    /// For some object files, multiple segments may contain sections with the same -    /// name. In this case, the first matching section will be used. -    /// -    /// This method skips over sections with invalid names. -    fn section_by_name(&'file self, section_name: &str) -> Option<Self::Section> { -        self.section_by_name_bytes(section_name.as_bytes()) -    } - -    /// Like [`Self::section_by_name`], but allows names that are not UTF-8. -    fn section_by_name_bytes(&'file self, section_name: &[u8]) -> Option<Self::Section>; - -    /// Get the section at the given index. -    /// -    /// The meaning of the index depends on the object file. -    /// -    /// For some object files, this requires iterating through all sections. -    /// -    /// Returns an error if the index is invalid. -    fn section_by_index(&'file self, index: SectionIndex) -> Result<Self::Section>; - -    /// Get an iterator for the sections in the file. -    fn sections(&'file self) -> Self::SectionIterator; - -    /// Get an iterator for the COMDAT section groups in the file. -    fn comdats(&'file self) -> Self::ComdatIterator; - -    /// Get the debugging symbol table, if any. -    fn symbol_table(&'file self) -> Option<Self::SymbolTable>; - -    /// Get the debugging symbol at the given index. -    /// -    /// The meaning of the index depends on the object file. -    /// -    /// Returns an error if the index is invalid. -    fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<Self::Symbol>; - -    /// Get an iterator for the debugging symbols in the file. -    /// -    /// This may skip over symbols that are malformed or unsupported. -    /// -    /// For Mach-O files, this does not include STAB entries. -    fn symbols(&'file self) -> Self::SymbolIterator; - -    /// Get the symbol named `symbol_name`, if the symbol exists. -    fn symbol_by_name(&'file self, symbol_name: &str) -> Option<Self::Symbol> { -        self.symbol_by_name_bytes(symbol_name.as_bytes()) -    } - -    /// Like [`Self::symbol_by_name`], but allows names that are not UTF-8. -    fn symbol_by_name_bytes(&'file self, symbol_name: &[u8]) -> Option<Self::Symbol> { -        self.symbols() -            .find(|sym| sym.name_bytes() == Ok(symbol_name)) -    } - -    /// Get the dynamic linking symbol table, if any. -    /// -    /// Only ELF has a separate dynamic linking symbol table. -    /// Consider using [`Self::exports`] or [`Self::imports`] instead. -    fn dynamic_symbol_table(&'file self) -> Option<Self::SymbolTable>; - -    /// Get an iterator for the dynamic linking symbols in the file. -    /// -    /// This may skip over symbols that are malformed or unsupported. -    /// -    /// Only ELF has dynamic linking symbols. -    /// Other file formats will return an empty iterator. -    /// Consider using [`Self::exports`] or [`Self::imports`] instead. -    fn dynamic_symbols(&'file self) -> Self::SymbolIterator; - -    /// Get the dynamic relocations for this file. -    /// -    /// Symbol indices in these relocations refer to the dynamic symbol table. -    /// -    /// Only ELF has dynamic relocations. -    fn dynamic_relocations(&'file self) -> Option<Self::DynamicRelocationIterator>; - -    /// Construct a map from addresses to symbol names. -    /// -    /// The map will only contain defined text and data symbols. -    /// The dynamic symbol table will only be used if there are no debugging symbols. -    fn symbol_map(&'file self) -> SymbolMap<SymbolMapName<'data>> { -        let mut symbols = Vec::new(); -        if let Some(table) = self.symbol_table().or_else(|| self.dynamic_symbol_table()) { -            // Sometimes symbols share addresses. Collect them all then choose the "best". -            let mut all_symbols = Vec::new(); -            for symbol in table.symbols() { -                // Must have an address. -                if !symbol.is_definition() { -                    continue; -                } -                // Must have a name. -                let name = match symbol.name() { -                    Ok(name) => name, -                    _ => continue, -                }; -                if name.is_empty() { -                    continue; -                } - -                // Lower is better. -                let mut priority = 0u32; - -                // Prefer known kind. -                match symbol.kind() { -                    SymbolKind::Text | SymbolKind::Data => {} -                    SymbolKind::Unknown => priority += 1, -                    _ => continue, -                } -                priority *= 2; - -                // Prefer global visibility. -                priority += match symbol.scope() { -                    SymbolScope::Unknown => 3, -                    SymbolScope::Compilation => 2, -                    SymbolScope::Linkage => 1, -                    SymbolScope::Dynamic => 0, -                }; -                priority *= 4; - -                // Prefer later entries (earlier symbol is likely to be less specific). -                let index = !0 - symbol.index().0; - -                // Tuple is ordered for sort. -                all_symbols.push((symbol.address(), priority, index, name)); -            } -            // Unstable sort is okay because tuple includes index. -            all_symbols.sort_unstable(); - -            let mut previous_address = !0; -            for (address, _priority, _index, name) in all_symbols { -                if address != previous_address { -                    symbols.push(SymbolMapName::new(address, name)); -                    previous_address = address; -                } -            } -        } -        SymbolMap::new(symbols) -    } - -    /// Construct a map from addresses to symbol names and object file names. -    /// -    /// This is derived from Mach-O STAB entries. -    fn object_map(&'file self) -> ObjectMap<'data> { -        ObjectMap::default() -    } - -    /// Get the imported symbols. -    fn imports(&self) -> Result<Vec<Import<'data>>>; - -    /// Get the exported symbols that expose both a name and an address. -    /// -    /// Some file formats may provide other kinds of symbols that can be retrieved using -    /// the low level API. -    fn exports(&self) -> Result<Vec<Export<'data>>>; - -    /// Return true if the file contains DWARF debug information sections, false if not. -    fn has_debug_symbols(&self) -> bool; - -    /// The UUID from a Mach-O [`LC_UUID`](crate::macho::LC_UUID) load command. -    #[inline] -    fn mach_uuid(&self) -> Result<Option<[u8; 16]>> { -        Ok(None) -    } - -    /// The build ID from an ELF [`NT_GNU_BUILD_ID`](crate::elf::NT_GNU_BUILD_ID) note. -    #[inline] -    fn build_id(&self) -> Result<Option<&'data [u8]>> { -        Ok(None) -    } - -    /// The filename and CRC from a `.gnu_debuglink` section. -    #[inline] -    fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> { -        Ok(None) -    } - -    /// The filename and build ID from a `.gnu_debugaltlink` section. -    #[inline] -    fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> { -        Ok(None) -    } - -    /// The filename and GUID from the PE CodeView section. -    #[inline] -    fn pdb_info(&self) -> Result<Option<CodeView<'_>>> { -        Ok(None) -    } - -    /// Get the base address used for relative virtual addresses. -    /// -    /// Currently this is only non-zero for PE. -    fn relative_address_base(&'file self) -> u64; - -    /// Get the virtual address of the entry point of the binary. -    fn entry(&'file self) -> u64; - -    /// File flags that are specific to each file format. -    fn flags(&self) -> FileFlags; -} - -/// A loadable segment in an [`Object`]. -/// -/// This trait is part of the unified read API. -pub trait ObjectSegment<'data>: read::private::Sealed { -    /// Returns the virtual address of the segment. -    fn address(&self) -> u64; - -    /// Returns the size of the segment in memory. -    fn size(&self) -> u64; - -    /// Returns the alignment of the segment in memory. -    fn align(&self) -> u64; - -    /// Returns the offset and size of the segment in the file. -    fn file_range(&self) -> (u64, u64); - -    /// Returns a reference to the file contents of the segment. -    /// -    /// The length of this data may be different from the size of the -    /// segment in memory. -    fn data(&self) -> Result<&'data [u8]>; - -    /// Return the segment data in the given range. -    /// -    /// Returns `Ok(None)` if the segment does not contain the given range. -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>; - -    /// Returns the name of the segment. -    fn name_bytes(&self) -> Result<Option<&[u8]>>; - -    /// Returns the name of the segment. -    /// -    /// Returns an error if the name is not UTF-8. -    fn name(&self) -> Result<Option<&str>>; - -    /// Return the flags of segment. -    fn flags(&self) -> SegmentFlags; -} - -/// A section in an [`Object`]. -/// -/// This trait is part of the unified read API. -pub trait ObjectSection<'data>: read::private::Sealed { -    /// An iterator for the relocations for a section. -    /// -    /// The first field in the item tuple is the section offset -    /// that the relocation applies to. -    type RelocationIterator: Iterator<Item = (u64, Relocation)>; - -    /// Returns the section index. -    fn index(&self) -> SectionIndex; - -    /// Returns the address of the section. -    fn address(&self) -> u64; - -    /// Returns the size of the section in memory. -    fn size(&self) -> u64; - -    /// Returns the alignment of the section in memory. -    fn align(&self) -> u64; - -    /// Returns offset and size of on-disk segment (if any). -    fn file_range(&self) -> Option<(u64, u64)>; - -    /// Returns the raw contents of the section. -    /// -    /// The length of this data may be different from the size of the -    /// section in memory. -    /// -    /// This does not do any decompression. -    fn data(&self) -> Result<&'data [u8]>; - -    /// Return the raw contents of the section data in the given range. -    /// -    /// This does not do any decompression. -    /// -    /// Returns `Ok(None)` if the section does not contain the given range. -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>; - -    /// Returns the potentially compressed file range of the section, -    /// along with information about the compression. -    fn compressed_file_range(&self) -> Result<CompressedFileRange>; - -    /// Returns the potentially compressed contents of the section, -    /// along with information about the compression. -    fn compressed_data(&self) -> Result<CompressedData<'data>>; - -    /// Returns the uncompressed contents of the section. -    /// -    /// The length of this data may be different from the size of the -    /// section in memory. -    /// -    /// If no compression is detected, then returns the data unchanged. -    /// Returns `Err` if decompression fails. -    fn uncompressed_data(&self) -> Result<Cow<'data, [u8]>> { -        self.compressed_data()?.decompress() -    } - -    /// Returns the name of the section. -    fn name_bytes(&self) -> Result<&[u8]>; - -    /// Returns the name of the section. -    /// -    /// Returns an error if the name is not UTF-8. -    fn name(&self) -> Result<&str>; - -    /// Returns the name of the segment for this section. -    fn segment_name_bytes(&self) -> Result<Option<&[u8]>>; - -    /// Returns the name of the segment for this section. -    /// -    /// Returns an error if the name is not UTF-8. -    fn segment_name(&self) -> Result<Option<&str>>; - -    /// Return the kind of this section. -    fn kind(&self) -> SectionKind; - -    /// Get the relocations for this section. -    fn relocations(&self) -> Self::RelocationIterator; - -    /// Section flags that are specific to each file format. -    fn flags(&self) -> SectionFlags; -} - -/// A COMDAT section group in an [`Object`]. -/// -/// This trait is part of the unified read API. -pub trait ObjectComdat<'data>: read::private::Sealed { -    /// An iterator for the sections in the section group. -    type SectionIterator: Iterator<Item = SectionIndex>; - -    /// Returns the COMDAT selection kind. -    fn kind(&self) -> ComdatKind; - -    /// Returns the index of the symbol used for the name of COMDAT section group. -    fn symbol(&self) -> SymbolIndex; - -    /// Returns the name of the COMDAT section group. -    fn name_bytes(&self) -> Result<&[u8]>; - -    /// Returns the name of the COMDAT section group. -    /// -    /// Returns an error if the name is not UTF-8. -    fn name(&self) -> Result<&str>; - -    /// Get the sections in this section group. -    fn sections(&self) -> Self::SectionIterator; -} - -/// A symbol table in an [`Object`]. -/// -/// This trait is part of the unified read API. -pub trait ObjectSymbolTable<'data>: read::private::Sealed { -    /// A symbol table entry. -    type Symbol: ObjectSymbol<'data>; - -    /// An iterator for the symbols in a symbol table. -    type SymbolIterator: Iterator<Item = Self::Symbol>; - -    /// Get an iterator for the symbols in the table. -    /// -    /// This may skip over symbols that are malformed or unsupported. -    fn symbols(&self) -> Self::SymbolIterator; - -    /// Get the symbol at the given index. -    /// -    /// The meaning of the index depends on the object file. -    /// -    /// Returns an error if the index is invalid. -    fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol>; -} - -/// A symbol table entry in an [`Object`]. -/// -/// This trait is part of the unified read API. -pub trait ObjectSymbol<'data>: read::private::Sealed { -    /// The index of the symbol. -    fn index(&self) -> SymbolIndex; - -    /// The name of the symbol. -    fn name_bytes(&self) -> Result<&'data [u8]>; - -    /// The name of the symbol. -    /// -    /// Returns an error if the name is not UTF-8. -    fn name(&self) -> Result<&'data str>; - -    /// The address of the symbol. May be zero if the address is unknown. -    fn address(&self) -> u64; - -    /// The size of the symbol. May be zero if the size is unknown. -    fn size(&self) -> u64; - -    /// Return the kind of this symbol. -    fn kind(&self) -> SymbolKind; - -    /// Returns the section where the symbol is defined. -    fn section(&self) -> SymbolSection; - -    /// Returns the section index for the section containing this symbol. -    /// -    /// May return `None` if the symbol is not defined in a section. -    fn section_index(&self) -> Option<SectionIndex> { -        self.section().index() -    } - -    /// Return true if the symbol is undefined. -    fn is_undefined(&self) -> bool; - -    /// Return true if the symbol is a definition of a function or data object -    /// that has a known address. -    /// -    /// This is primarily used to implement [`Object::symbol_map`]. -    fn is_definition(&self) -> bool; - -    /// Return true if the symbol is common data. -    /// -    /// Note: does not check for [`SymbolSection::Section`] with [`SectionKind::Common`]. -    fn is_common(&self) -> bool; - -    /// Return true if the symbol is weak. -    fn is_weak(&self) -> bool; - -    /// Returns the symbol scope. -    fn scope(&self) -> SymbolScope; - -    /// Return true if the symbol visible outside of the compilation unit. -    /// -    /// This treats [`SymbolScope::Unknown`] as global. -    fn is_global(&self) -> bool; - -    /// Return true if the symbol is only visible within the compilation unit. -    fn is_local(&self) -> bool; - -    /// Symbol flags that are specific to each file format. -    fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex>; -} - -/// An iterator for files that don't have dynamic relocations. -#[derive(Debug)] -pub struct NoDynamicRelocationIterator; - -impl Iterator for NoDynamicRelocationIterator { -    type Item = (u64, Relocation); - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} diff --git a/vendor/object/src/read/util.rs b/vendor/object/src/read/util.rs deleted file mode 100644 index 7d85b27..0000000 --- a/vendor/object/src/read/util.rs +++ /dev/null @@ -1,425 +0,0 @@ -use alloc::string::String; -use core::convert::TryInto; -use core::fmt; -use core::marker::PhantomData; - -use crate::pod::{from_bytes, slice_from_bytes, Pod}; -use crate::ReadRef; - -/// A newtype for byte slices. -/// -/// It has these important features: -/// - no methods that can panic, such as `Index` -/// - convenience methods for `Pod` types -/// - a useful `Debug` implementation -#[derive(Default, Clone, Copy, PartialEq, Eq)] -pub struct Bytes<'data>(pub &'data [u8]); - -impl<'data> fmt::Debug for Bytes<'data> { -    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { -        debug_list_bytes(self.0, fmt) -    } -} - -impl<'data> Bytes<'data> { -    /// Return the length of the byte slice. -    #[inline] -    pub fn len(&self) -> usize { -        self.0.len() -    } - -    /// Return true if the byte slice is empty. -    #[inline] -    pub fn is_empty(&self) -> bool { -        self.0.is_empty() -    } - -    /// Skip over the given number of bytes at the start of the byte slice. -    /// -    /// Modifies the byte slice to start after the bytes. -    /// -    /// Returns an error if there are too few bytes. -    #[inline] -    pub fn skip(&mut self, offset: usize) -> Result<(), ()> { -        match self.0.get(offset..) { -            Some(tail) => { -                self.0 = tail; -                Ok(()) -            } -            None => { -                self.0 = &[]; -                Err(()) -            } -        } -    } - -    /// Return a reference to the given number of bytes at the start of the byte slice. -    /// -    /// Modifies the byte slice to start after the bytes. -    /// -    /// Returns an error if there are too few bytes. -    #[inline] -    pub fn read_bytes(&mut self, count: usize) -> Result<Bytes<'data>, ()> { -        match (self.0.get(..count), self.0.get(count..)) { -            (Some(head), Some(tail)) => { -                self.0 = tail; -                Ok(Bytes(head)) -            } -            _ => { -                self.0 = &[]; -                Err(()) -            } -        } -    } - -    /// Return a reference to the given number of bytes at the given offset of the byte slice. -    /// -    /// Returns an error if the offset is invalid or there are too few bytes. -    #[inline] -    pub fn read_bytes_at(mut self, offset: usize, count: usize) -> Result<Bytes<'data>, ()> { -        self.skip(offset)?; -        self.read_bytes(count) -    } - -    /// Return a reference to a `Pod` struct at the start of the byte slice. -    /// -    /// Modifies the byte slice to start after the bytes. -    /// -    /// Returns an error if there are too few bytes or the slice is incorrectly aligned. -    #[inline] -    pub fn read<T: Pod>(&mut self) -> Result<&'data T, ()> { -        match from_bytes(self.0) { -            Ok((value, tail)) => { -                self.0 = tail; -                Ok(value) -            } -            Err(()) => { -                self.0 = &[]; -                Err(()) -            } -        } -    } - -    /// Return a reference to a `Pod` struct at the given offset of the byte slice. -    /// -    /// Returns an error if there are too few bytes or the offset is incorrectly aligned. -    #[inline] -    pub fn read_at<T: Pod>(mut self, offset: usize) -> Result<&'data T, ()> { -        self.skip(offset)?; -        self.read() -    } - -    /// Return a reference to a slice of `Pod` structs at the start of the byte slice. -    /// -    /// Modifies the byte slice to start after the bytes. -    /// -    /// Returns an error if there are too few bytes or the offset is incorrectly aligned. -    #[inline] -    pub fn read_slice<T: Pod>(&mut self, count: usize) -> Result<&'data [T], ()> { -        match slice_from_bytes(self.0, count) { -            Ok((value, tail)) => { -                self.0 = tail; -                Ok(value) -            } -            Err(()) => { -                self.0 = &[]; -                Err(()) -            } -        } -    } - -    /// Return a reference to a slice of `Pod` structs at the given offset of the byte slice. -    /// -    /// Returns an error if there are too few bytes or the offset is incorrectly aligned. -    #[inline] -    pub fn read_slice_at<T: Pod>(mut self, offset: usize, count: usize) -> Result<&'data [T], ()> { -        self.skip(offset)?; -        self.read_slice(count) -    } - -    /// Read a null terminated string. -    /// -    /// Does not assume any encoding. -    /// Reads past the null byte, but doesn't return it. -    #[inline] -    pub fn read_string(&mut self) -> Result<&'data [u8], ()> { -        match memchr::memchr(b'\0', self.0) { -            Some(null) => { -                // These will never fail. -                let bytes = self.read_bytes(null)?; -                self.skip(1)?; -                Ok(bytes.0) -            } -            None => { -                self.0 = &[]; -                Err(()) -            } -        } -    } - -    /// Read a null terminated string at an offset. -    /// -    /// Does not assume any encoding. Does not return the null byte. -    #[inline] -    pub fn read_string_at(mut self, offset: usize) -> Result<&'data [u8], ()> { -        self.skip(offset)?; -        self.read_string() -    } - -    /// Read an unsigned LEB128 number. -    pub fn read_uleb128(&mut self) -> Result<u64, ()> { -        let mut result = 0; -        let mut shift = 0; - -        loop { -            let byte = *self.read::<u8>()?; -            if shift == 63 && byte != 0x00 && byte != 0x01 { -                return Err(()); -            } -            result |= u64::from(byte & 0x7f) << shift; -            shift += 7; - -            if byte & 0x80 == 0 { -                return Ok(result); -            } -        } -    } - -    /// Read a signed LEB128 number. -    pub fn read_sleb128(&mut self) -> Result<i64, ()> { -        let mut result = 0; -        let mut shift = 0; - -        loop { -            let byte = *self.read::<u8>()?; -            if shift == 63 && byte != 0x00 && byte != 0x7f { -                return Err(()); -            } -            result |= i64::from(byte & 0x7f) << shift; -            shift += 7; - -            if byte & 0x80 == 0 { -                if shift < 64 && (byte & 0x40) != 0 { -                    // Sign extend the result. -                    result |= !0 << shift; -                } -                return Ok(result); -            } -        } -    } -} - -// Only for Debug impl of `Bytes`. -fn debug_list_bytes(bytes: &[u8], fmt: &mut fmt::Formatter<'_>) -> fmt::Result { -    let mut list = fmt.debug_list(); -    list.entries(bytes.iter().take(8).copied().map(DebugByte)); -    if bytes.len() > 8 { -        list.entry(&DebugLen(bytes.len())); -    } -    list.finish() -} - -struct DebugByte(u8); - -impl fmt::Debug for DebugByte { -    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!(fmt, "0x{:02x}", self.0) -    } -} - -struct DebugLen(usize); - -impl fmt::Debug for DebugLen { -    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!(fmt, "...; {}", self.0) -    } -} - -/// A newtype for byte strings. -/// -/// For byte slices that are strings of an unknown encoding. -/// -/// Provides a `Debug` implementation that interprets the bytes as UTF-8. -#[derive(Default, Clone, Copy, PartialEq, Eq)] -pub(crate) struct ByteString<'data>(pub &'data [u8]); - -impl<'data> fmt::Debug for ByteString<'data> { -    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { -        write!(fmt, "\"{}\"", String::from_utf8_lossy(self.0)) -    } -} - -#[allow(dead_code)] -#[inline] -pub(crate) fn align(offset: usize, size: usize) -> usize { -    (offset + (size - 1)) & !(size - 1) -} - -#[allow(dead_code)] -pub(crate) fn data_range( -    data: &[u8], -    data_address: u64, -    range_address: u64, -    size: u64, -) -> Option<&[u8]> { -    let offset = range_address.checked_sub(data_address)?; -    data.get(offset.try_into().ok()?..)? -        .get(..size.try_into().ok()?) -} - -/// A table of zero-terminated strings. -/// -/// This is used by most file formats for strings such as section names and symbol names. -#[derive(Debug, Clone, Copy)] -pub struct StringTable<'data, R = &'data [u8]> -where -    R: ReadRef<'data>, -{ -    data: Option<R>, -    start: u64, -    end: u64, -    marker: PhantomData<&'data ()>, -} - -impl<'data, R: ReadRef<'data>> StringTable<'data, R> { -    /// Interpret the given data as a string table. -    pub fn new(data: R, start: u64, end: u64) -> Self { -        StringTable { -            data: Some(data), -            start, -            end, -            marker: PhantomData, -        } -    } - -    /// Return the string at the given offset. -    pub fn get(&self, offset: u32) -> Result<&'data [u8], ()> { -        match self.data { -            Some(data) => { -                let r_start = self.start.checked_add(offset.into()).ok_or(())?; -                data.read_bytes_at_until(r_start..self.end, 0) -            } -            None => Err(()), -        } -    } -} - -impl<'data, R: ReadRef<'data>> Default for StringTable<'data, R> { -    fn default() -> Self { -        StringTable { -            data: None, -            start: 0, -            end: 0, -            marker: PhantomData, -        } -    } -} - -#[cfg(test)] -mod tests { -    use super::*; -    use crate::pod::bytes_of; - -    #[test] -    fn bytes() { -        let x = u32::to_be(0x0123_4567); -        let data = Bytes(bytes_of(&x)); - -        let mut bytes = data; -        assert_eq!(bytes.skip(0), Ok(())); -        assert_eq!(bytes, data); - -        let mut bytes = data; -        assert_eq!(bytes.skip(4), Ok(())); -        assert_eq!(bytes, Bytes(&[])); - -        let mut bytes = data; -        assert_eq!(bytes.skip(5), Err(())); -        assert_eq!(bytes, Bytes(&[])); - -        let mut bytes = data; -        assert_eq!(bytes.read_bytes(0), Ok(Bytes(&[]))); -        assert_eq!(bytes, data); - -        let mut bytes = data; -        assert_eq!(bytes.read_bytes(4), Ok(data)); -        assert_eq!(bytes, Bytes(&[])); - -        let mut bytes = data; -        assert_eq!(bytes.read_bytes(5), Err(())); -        assert_eq!(bytes, Bytes(&[])); - -        assert_eq!(data.read_bytes_at(0, 0), Ok(Bytes(&[]))); -        assert_eq!(data.read_bytes_at(4, 0), Ok(Bytes(&[]))); -        assert_eq!(data.read_bytes_at(0, 4), Ok(data)); -        assert_eq!(data.read_bytes_at(1, 4), Err(())); - -        let mut bytes = data; -        assert_eq!(bytes.read::<u16>(), Ok(&u16::to_be(0x0123))); -        assert_eq!(bytes, Bytes(&[0x45, 0x67])); -        assert_eq!(data.read_at::<u16>(2), Ok(&u16::to_be(0x4567))); -        assert_eq!(data.read_at::<u16>(3), Err(())); -        assert_eq!(data.read_at::<u16>(4), Err(())); - -        let mut bytes = data; -        assert_eq!(bytes.read::<u32>(), Ok(&x)); -        assert_eq!(bytes, Bytes(&[])); - -        let mut bytes = data; -        assert_eq!(bytes.read::<u64>(), Err(())); -        assert_eq!(bytes, Bytes(&[])); - -        let mut bytes = data; -        assert_eq!(bytes.read_slice::<u8>(0), Ok(&[][..])); -        assert_eq!(bytes, data); - -        let mut bytes = data; -        assert_eq!(bytes.read_slice::<u8>(4), Ok(data.0)); -        assert_eq!(bytes, Bytes(&[])); - -        let mut bytes = data; -        assert_eq!(bytes.read_slice::<u8>(5), Err(())); -        assert_eq!(bytes, Bytes(&[])); - -        assert_eq!(data.read_slice_at::<u8>(0, 0), Ok(&[][..])); -        assert_eq!(data.read_slice_at::<u8>(4, 0), Ok(&[][..])); -        assert_eq!(data.read_slice_at::<u8>(0, 4), Ok(data.0)); -        assert_eq!(data.read_slice_at::<u8>(1, 4), Err(())); - -        let data = Bytes(&[0x01, 0x02, 0x00, 0x04]); - -        let mut bytes = data; -        assert_eq!(bytes.read_string(), Ok(&data.0[..2])); -        assert_eq!(bytes.0, &data.0[3..]); - -        let mut bytes = data; -        bytes.skip(3).unwrap(); -        assert_eq!(bytes.read_string(), Err(())); -        assert_eq!(bytes.0, &[]); - -        assert_eq!(data.read_string_at(0), Ok(&data.0[..2])); -        assert_eq!(data.read_string_at(1), Ok(&data.0[1..2])); -        assert_eq!(data.read_string_at(2), Ok(&[][..])); -        assert_eq!(data.read_string_at(3), Err(())); -    } - -    #[test] -    fn bytes_debug() { -        assert_eq!(format!("{:?}", Bytes(&[])), "[]"); -        assert_eq!(format!("{:?}", Bytes(&[0x01])), "[0x01]"); -        assert_eq!( -            format!( -                "{:?}", -                Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]) -            ), -            "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]" -        ); -        assert_eq!( -            format!( -                "{:?}", -                Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]) -            ), -            "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, ...; 9]" -        ); -    } -} diff --git a/vendor/object/src/read/wasm.rs b/vendor/object/src/read/wasm.rs deleted file mode 100644 index 4d034bc..0000000 --- a/vendor/object/src/read/wasm.rs +++ /dev/null @@ -1,966 +0,0 @@ -//! Support for reading Wasm files. -//! -//! [`WasmFile`] implements the [`Object`] trait for Wasm files. -use alloc::boxed::Box; -use alloc::vec::Vec; -use core::marker::PhantomData; -use core::ops::Range; -use core::{slice, str}; -use wasmparser as wp; - -use crate::read::{ -    self, Architecture, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags, -    Import, NoDynamicRelocationIterator, Object, ObjectComdat, ObjectKind, ObjectSection, -    ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Relocation, Result, -    SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind, -    SymbolScope, SymbolSection, -}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(usize)] -enum SectionId { -    Custom = 0, -    Type = 1, -    Import = 2, -    Function = 3, -    Table = 4, -    Memory = 5, -    Global = 6, -    Export = 7, -    Start = 8, -    Element = 9, -    Code = 10, -    Data = 11, -    DataCount = 12, -} -// Update this constant when adding new section id: -const MAX_SECTION_ID: usize = SectionId::DataCount as usize; - -/// A WebAssembly object file. -#[derive(Debug)] -pub struct WasmFile<'data, R = &'data [u8]> { -    data: &'data [u8], -    has_memory64: bool, -    // All sections, including custom sections. -    sections: Vec<SectionHeader<'data>>, -    // Indices into `sections` of sections with a non-zero id. -    id_sections: Box<[Option<usize>; MAX_SECTION_ID + 1]>, -    // Whether the file has DWARF information. -    has_debug_symbols: bool, -    // Symbols collected from imports, exports, code and name sections. -    symbols: Vec<WasmSymbolInternal<'data>>, -    // Address of the function body for the entry point. -    entry: u64, -    marker: PhantomData<R>, -} - -#[derive(Debug)] -struct SectionHeader<'data> { -    id: SectionId, -    range: Range<usize>, -    name: &'data str, -} - -#[derive(Clone)] -enum LocalFunctionKind { -    Unknown, -    Exported { symbol_ids: Vec<u32> }, -    Local { symbol_id: u32 }, -} - -impl<T> ReadError<T> for wasmparser::Result<T> { -    fn read_error(self, error: &'static str) -> Result<T> { -        self.map_err(|_| Error(error)) -    } -} - -impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { -    /// Parse the raw wasm data. -    pub fn parse(data: R) -> Result<Self> { -        let len = data.len().read_error("Unknown Wasm file size")?; -        let data = data.read_bytes_at(0, len).read_error("Wasm read failed")?; -        let parser = wp::Parser::new(0).parse_all(data); - -        let mut file = WasmFile { -            data, -            has_memory64: false, -            sections: Vec::new(), -            id_sections: Default::default(), -            has_debug_symbols: false, -            symbols: Vec::new(), -            entry: 0, -            marker: PhantomData, -        }; - -        let mut main_file_symbol = Some(WasmSymbolInternal { -            name: "", -            address: 0, -            size: 0, -            kind: SymbolKind::File, -            section: SymbolSection::None, -            scope: SymbolScope::Compilation, -        }); - -        let mut imported_funcs_count = 0; -        let mut local_func_kinds = Vec::new(); -        let mut entry_func_id = None; -        let mut code_range_start = 0; -        let mut code_func_index = 0; -        // One-to-one mapping of globals to their value (if the global is a constant integer). -        let mut global_values = Vec::new(); - -        for payload in parser { -            let payload = payload.read_error("Invalid Wasm section header")?; - -            match payload { -                wp::Payload::TypeSection(section) => { -                    file.add_section(SectionId::Type, section.range(), ""); -                } -                wp::Payload::ImportSection(section) => { -                    file.add_section(SectionId::Import, section.range(), ""); -                    let mut last_module_name = None; - -                    for import in section { -                        let import = import.read_error("Couldn't read an import item")?; -                        let module_name = import.module; - -                        if last_module_name != Some(module_name) { -                            file.symbols.push(WasmSymbolInternal { -                                name: module_name, -                                address: 0, -                                size: 0, -                                kind: SymbolKind::File, -                                section: SymbolSection::None, -                                scope: SymbolScope::Dynamic, -                            }); -                            last_module_name = Some(module_name); -                        } - -                        let kind = match import.ty { -                            wp::TypeRef::Func(_) => { -                                imported_funcs_count += 1; -                                SymbolKind::Text -                            } -                            wp::TypeRef::Memory(memory) => { -                                file.has_memory64 |= memory.memory64; -                                SymbolKind::Data -                            } -                            wp::TypeRef::Table(_) | wp::TypeRef::Global(_) => SymbolKind::Data, -                            wp::TypeRef::Tag(_) => SymbolKind::Unknown, -                        }; - -                        file.symbols.push(WasmSymbolInternal { -                            name: import.name, -                            address: 0, -                            size: 0, -                            kind, -                            section: SymbolSection::Undefined, -                            scope: SymbolScope::Dynamic, -                        }); -                    } -                } -                wp::Payload::FunctionSection(section) => { -                    file.add_section(SectionId::Function, section.range(), ""); -                    local_func_kinds = -                        vec![LocalFunctionKind::Unknown; section.into_iter().count()]; -                } -                wp::Payload::TableSection(section) => { -                    file.add_section(SectionId::Table, section.range(), ""); -                } -                wp::Payload::MemorySection(section) => { -                    file.add_section(SectionId::Memory, section.range(), ""); -                    for memory in section { -                        let memory = memory.read_error("Couldn't read a memory item")?; -                        file.has_memory64 |= memory.memory64; -                    } -                } -                wp::Payload::GlobalSection(section) => { -                    file.add_section(SectionId::Global, section.range(), ""); -                    for global in section { -                        let global = global.read_error("Couldn't read a global item")?; -                        let mut address = None; -                        if !global.ty.mutable { -                            // There should be exactly one instruction. -                            let init = global.init_expr.get_operators_reader().read(); -                            address = match init.read_error("Couldn't read a global init expr")? { -                                wp::Operator::I32Const { value } => Some(value as u64), -                                wp::Operator::I64Const { value } => Some(value as u64), -                                _ => None, -                            }; -                        } -                        global_values.push(address); -                    } -                } -                wp::Payload::ExportSection(section) => { -                    file.add_section(SectionId::Export, section.range(), ""); -                    if let Some(main_file_symbol) = main_file_symbol.take() { -                        file.symbols.push(main_file_symbol); -                    } - -                    for export in section { -                        let export = export.read_error("Couldn't read an export item")?; - -                        let (kind, section_idx) = match export.kind { -                            wp::ExternalKind::Func => { -                                if let Some(local_func_id) = -                                    export.index.checked_sub(imported_funcs_count) -                                { -                                    let local_func_kind = -                                        &mut local_func_kinds[local_func_id as usize]; -                                    if let LocalFunctionKind::Unknown = local_func_kind { -                                        *local_func_kind = LocalFunctionKind::Exported { -                                            symbol_ids: Vec::new(), -                                        }; -                                    } -                                    let symbol_ids = match local_func_kind { -                                        LocalFunctionKind::Exported { symbol_ids } => symbol_ids, -                                        _ => unreachable!(), -                                    }; -                                    symbol_ids.push(file.symbols.len() as u32); -                                } -                                (SymbolKind::Text, SectionId::Code) -                            } -                            wp::ExternalKind::Table -                            | wp::ExternalKind::Memory -                            | wp::ExternalKind::Global => (SymbolKind::Data, SectionId::Data), -                            // TODO -                            wp::ExternalKind::Tag => continue, -                        }; - -                        // Try to guess the symbol address. Rust and C export a global containing -                        // the address in linear memory of the symbol. -                        let mut address = 0; -                        if export.kind == wp::ExternalKind::Global { -                            if let Some(&Some(x)) = global_values.get(export.index as usize) { -                                address = x; -                            } -                        } - -                        file.symbols.push(WasmSymbolInternal { -                            name: export.name, -                            address, -                            size: 0, -                            kind, -                            section: SymbolSection::Section(SectionIndex(section_idx as usize)), -                            scope: SymbolScope::Dynamic, -                        }); -                    } -                } -                wp::Payload::StartSection { func, range, .. } => { -                    file.add_section(SectionId::Start, range, ""); -                    entry_func_id = Some(func); -                } -                wp::Payload::ElementSection(section) => { -                    file.add_section(SectionId::Element, section.range(), ""); -                } -                wp::Payload::CodeSectionStart { range, .. } => { -                    code_range_start = range.start; -                    file.add_section(SectionId::Code, range, ""); -                    if let Some(main_file_symbol) = main_file_symbol.take() { -                        file.symbols.push(main_file_symbol); -                    } -                } -                wp::Payload::CodeSectionEntry(body) => { -                    let i = code_func_index; -                    code_func_index += 1; - -                    let range = body.range(); - -                    let address = range.start as u64 - code_range_start as u64; -                    let size = (range.end - range.start) as u64; - -                    if entry_func_id == Some(i as u32) { -                        file.entry = address; -                    } - -                    let local_func_kind = &mut local_func_kinds[i]; -                    match local_func_kind { -                        LocalFunctionKind::Unknown => { -                            *local_func_kind = LocalFunctionKind::Local { -                                symbol_id: file.symbols.len() as u32, -                            }; -                            file.symbols.push(WasmSymbolInternal { -                                name: "", -                                address, -                                size, -                                kind: SymbolKind::Text, -                                section: SymbolSection::Section(SectionIndex( -                                    SectionId::Code as usize, -                                )), -                                scope: SymbolScope::Compilation, -                            }); -                        } -                        LocalFunctionKind::Exported { symbol_ids } => { -                            for symbol_id in core::mem::take(symbol_ids) { -                                let export_symbol = &mut file.symbols[symbol_id as usize]; -                                export_symbol.address = address; -                                export_symbol.size = size; -                            } -                        } -                        _ => unreachable!(), -                    } -                } -                wp::Payload::DataSection(section) => { -                    file.add_section(SectionId::Data, section.range(), ""); -                } -                wp::Payload::DataCountSection { range, .. } => { -                    file.add_section(SectionId::DataCount, range, ""); -                } -                wp::Payload::CustomSection(section) => { -                    let name = section.name(); -                    let size = section.data().len(); -                    let mut range = section.range(); -                    range.start = range.end - size; -                    file.add_section(SectionId::Custom, range, name); -                    if name == "name" { -                        for name in -                            wp::NameSectionReader::new(section.data(), section.data_offset()) -                        { -                            // TODO: Right now, ill-formed name subsections -                            // are silently ignored in order to maintain -                            // compatibility with extended name sections, which -                            // are not yet supported by the version of -                            // `wasmparser` currently used. -                            // A better fix would be to update `wasmparser` to -                            // the newest version, but this requires -                            // a major rewrite of this file. -                            if let Ok(wp::Name::Function(name_map)) = name { -                                for naming in name_map { -                                    let naming = -                                        naming.read_error("Couldn't read a function name")?; -                                    if let Some(local_index) = -                                        naming.index.checked_sub(imported_funcs_count) -                                    { -                                        if let LocalFunctionKind::Local { symbol_id } = -                                            local_func_kinds[local_index as usize] -                                        { -                                            file.symbols[symbol_id as usize].name = naming.name; -                                        } -                                    } -                                } -                            } -                        } -                    } else if name.starts_with(".debug_") { -                        file.has_debug_symbols = true; -                    } -                } -                _ => {} -            } -        } - -        Ok(file) -    } - -    fn add_section(&mut self, id: SectionId, range: Range<usize>, name: &'data str) { -        let section = SectionHeader { id, range, name }; -        self.id_sections[id as usize] = Some(self.sections.len()); -        self.sections.push(section); -    } -} - -impl<'data, R> read::private::Sealed for WasmFile<'data, R> {} - -impl<'data, 'file, R: ReadRef<'data>> Object<'data, 'file> for WasmFile<'data, R> -where -    'data: 'file, -    R: 'file, -{ -    type Segment = WasmSegment<'data, 'file, R>; -    type SegmentIterator = WasmSegmentIterator<'data, 'file, R>; -    type Section = WasmSection<'data, 'file, R>; -    type SectionIterator = WasmSectionIterator<'data, 'file, R>; -    type Comdat = WasmComdat<'data, 'file, R>; -    type ComdatIterator = WasmComdatIterator<'data, 'file, R>; -    type Symbol = WasmSymbol<'data, 'file>; -    type SymbolIterator = WasmSymbolIterator<'data, 'file>; -    type SymbolTable = WasmSymbolTable<'data, 'file>; -    type DynamicRelocationIterator = NoDynamicRelocationIterator; - -    #[inline] -    fn architecture(&self) -> Architecture { -        if self.has_memory64 { -            Architecture::Wasm64 -        } else { -            Architecture::Wasm32 -        } -    } - -    #[inline] -    fn is_little_endian(&self) -> bool { -        true -    } - -    #[inline] -    fn is_64(&self) -> bool { -        self.has_memory64 -    } - -    fn kind(&self) -> ObjectKind { -        // TODO: check for `linking` custom section -        ObjectKind::Unknown -    } - -    fn segments(&'file self) -> Self::SegmentIterator { -        WasmSegmentIterator { file: self } -    } - -    fn section_by_name_bytes( -        &'file self, -        section_name: &[u8], -    ) -> Option<WasmSection<'data, 'file, R>> { -        self.sections() -            .find(|section| section.name_bytes() == Ok(section_name)) -    } - -    fn section_by_index(&'file self, index: SectionIndex) -> Result<WasmSection<'data, 'file, R>> { -        // TODO: Missing sections should return an empty section. -        let id_section = self -            .id_sections -            .get(index.0) -            .and_then(|x| *x) -            .read_error("Invalid Wasm section index")?; -        let section = self.sections.get(id_section).unwrap(); -        Ok(WasmSection { -            file: self, -            section, -        }) -    } - -    fn sections(&'file self) -> Self::SectionIterator { -        WasmSectionIterator { -            file: self, -            sections: self.sections.iter(), -        } -    } - -    fn comdats(&'file self) -> Self::ComdatIterator { -        WasmComdatIterator { file: self } -    } - -    #[inline] -    fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<WasmSymbol<'data, 'file>> { -        let symbol = self -            .symbols -            .get(index.0) -            .read_error("Invalid Wasm symbol index")?; -        Ok(WasmSymbol { index, symbol }) -    } - -    fn symbols(&'file self) -> Self::SymbolIterator { -        WasmSymbolIterator { -            symbols: self.symbols.iter().enumerate(), -        } -    } - -    fn symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> { -        Some(WasmSymbolTable { -            symbols: &self.symbols, -        }) -    } - -    fn dynamic_symbols(&'file self) -> Self::SymbolIterator { -        WasmSymbolIterator { -            symbols: [].iter().enumerate(), -        } -    } - -    #[inline] -    fn dynamic_symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> { -        None -    } - -    #[inline] -    fn dynamic_relocations(&self) -> Option<NoDynamicRelocationIterator> { -        None -    } - -    fn imports(&self) -> Result<Vec<Import<'data>>> { -        // TODO: return entries in the import section -        Ok(Vec::new()) -    } - -    fn exports(&self) -> Result<Vec<Export<'data>>> { -        // TODO: return entries in the export section -        Ok(Vec::new()) -    } - -    fn has_debug_symbols(&self) -> bool { -        self.has_debug_symbols -    } - -    fn relative_address_base(&self) -> u64 { -        0 -    } - -    #[inline] -    fn entry(&'file self) -> u64 { -        self.entry -    } - -    #[inline] -    fn flags(&self) -> FileFlags { -        FileFlags::None -    } -} - -/// An iterator for the segments in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmSegmentIterator<'data, 'file, R = &'data [u8]> { -    #[allow(unused)] -    file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> Iterator for WasmSegmentIterator<'data, 'file, R> { -    type Item = WasmSegment<'data, 'file, R>; - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -/// A segment in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmSegment<'data, 'file, R = &'data [u8]> { -    #[allow(unused)] -    file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> read::private::Sealed for WasmSegment<'data, 'file, R> {} - -impl<'data, 'file, R> ObjectSegment<'data> for WasmSegment<'data, 'file, R> { -    #[inline] -    fn address(&self) -> u64 { -        unreachable!() -    } - -    #[inline] -    fn size(&self) -> u64 { -        unreachable!() -    } - -    #[inline] -    fn align(&self) -> u64 { -        unreachable!() -    } - -    #[inline] -    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!() -    } - -    #[inline] -    fn name_bytes(&self) -> Result<Option<&[u8]>> { -        unreachable!() -    } - -    #[inline] -    fn name(&self) -> Result<Option<&str>> { -        unreachable!() -    } - -    #[inline] -    fn flags(&self) -> SegmentFlags { -        unreachable!() -    } -} - -/// An iterator for the sections in a [`WasmFile`]. -#[derive(Debug)] -pub struct WasmSectionIterator<'data, 'file, R = &'data [u8]> { -    file: &'file WasmFile<'data, R>, -    sections: slice::Iter<'file, SectionHeader<'data>>, -} - -impl<'data, 'file, R> Iterator for WasmSectionIterator<'data, 'file, R> { -    type Item = WasmSection<'data, 'file, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        let section = self.sections.next()?; -        Some(WasmSection { -            file: self.file, -            section, -        }) -    } -} - -/// A section in a [`WasmFile`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -#[derive(Debug)] -pub struct WasmSection<'data, 'file, R = &'data [u8]> { -    file: &'file WasmFile<'data, R>, -    section: &'file SectionHeader<'data>, -} - -impl<'data, 'file, R> read::private::Sealed for WasmSection<'data, 'file, R> {} - -impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for WasmSection<'data, 'file, R> { -    type RelocationIterator = WasmRelocationIterator<'data, 'file, R>; - -    #[inline] -    fn index(&self) -> SectionIndex { -        // Note that we treat all custom sections as index 0. -        // This is ok because they are never looked up by index. -        SectionIndex(self.section.id as usize) -    } - -    #[inline] -    fn address(&self) -> u64 { -        0 -    } - -    #[inline] -    fn size(&self) -> u64 { -        let range = &self.section.range; -        (range.end - range.start) as u64 -    } - -    #[inline] -    fn align(&self) -> u64 { -        1 -    } - -    #[inline] -    fn file_range(&self) -> Option<(u64, u64)> { -        let range = &self.section.range; -        Some((range.start as _, range.end as _)) -    } - -    #[inline] -    fn data(&self) -> Result<&'data [u8]> { -        let range = &self.section.range; -        self.file -            .data -            .read_bytes_at(range.start as u64, range.end as u64 - range.start as u64) -            .read_error("Invalid Wasm section size or offset") -    } - -    fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> { -        unimplemented!() -    } - -    #[inline] -    fn compressed_file_range(&self) -> Result<CompressedFileRange> { -        Ok(CompressedFileRange::none(self.file_range())) -    } - -    #[inline] -    fn compressed_data(&self) -> Result<CompressedData<'data>> { -        self.data().map(CompressedData::none) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<&[u8]> { -        self.name().map(str::as_bytes) -    } - -    #[inline] -    fn name(&self) -> Result<&str> { -        Ok(match self.section.id { -            SectionId::Custom => self.section.name, -            SectionId::Type => "<type>", -            SectionId::Import => "<import>", -            SectionId::Function => "<function>", -            SectionId::Table => "<table>", -            SectionId::Memory => "<memory>", -            SectionId::Global => "<global>", -            SectionId::Export => "<export>", -            SectionId::Start => "<start>", -            SectionId::Element => "<element>", -            SectionId::Code => "<code>", -            SectionId::Data => "<data>", -            SectionId::DataCount => "<data_count>", -        }) -    } - -    #[inline] -    fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { -        Ok(None) -    } - -    #[inline] -    fn segment_name(&self) -> Result<Option<&str>> { -        Ok(None) -    } - -    #[inline] -    fn kind(&self) -> SectionKind { -        match self.section.id { -            SectionId::Custom => match self.section.name { -                "reloc." | "linking" => SectionKind::Linker, -                _ => SectionKind::Other, -            }, -            SectionId::Type => SectionKind::Metadata, -            SectionId::Import => SectionKind::Linker, -            SectionId::Function => SectionKind::Metadata, -            SectionId::Table => SectionKind::UninitializedData, -            SectionId::Memory => SectionKind::UninitializedData, -            SectionId::Global => SectionKind::Data, -            SectionId::Export => SectionKind::Linker, -            SectionId::Start => SectionKind::Linker, -            SectionId::Element => SectionKind::Data, -            SectionId::Code => SectionKind::Text, -            SectionId::Data => SectionKind::Data, -            SectionId::DataCount => SectionKind::UninitializedData, -        } -    } - -    #[inline] -    fn relocations(&self) -> WasmRelocationIterator<'data, 'file, R> { -        WasmRelocationIterator(PhantomData) -    } - -    #[inline] -    fn flags(&self) -> SectionFlags { -        SectionFlags::None -    } -} - -/// An iterator for the COMDAT section groups in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmComdatIterator<'data, 'file, R = &'data [u8]> { -    #[allow(unused)] -    file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> Iterator for WasmComdatIterator<'data, 'file, R> { -    type Item = WasmComdat<'data, 'file, R>; - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -/// A COMDAT section group in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmComdat<'data, 'file, R = &'data [u8]> { -    #[allow(unused)] -    file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> read::private::Sealed for WasmComdat<'data, 'file, R> {} - -impl<'data, 'file, R> ObjectComdat<'data> for WasmComdat<'data, 'file, R> { -    type SectionIterator = WasmComdatSectionIterator<'data, 'file, 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 for the sections in a COMDAT section group in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmComdatSectionIterator<'data, 'file, R = &'data [u8]> { -    #[allow(unused)] -    file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> Iterator for WasmComdatSectionIterator<'data, 'file, R> { -    type Item = SectionIndex; - -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -/// A symbol table in a [`WasmFile`]. -#[derive(Debug)] -pub struct WasmSymbolTable<'data, 'file> { -    symbols: &'file [WasmSymbolInternal<'data>], -} - -impl<'data, 'file> read::private::Sealed for WasmSymbolTable<'data, 'file> {} - -impl<'data, 'file> ObjectSymbolTable<'data> for WasmSymbolTable<'data, 'file> { -    type Symbol = WasmSymbol<'data, 'file>; -    type SymbolIterator = WasmSymbolIterator<'data, 'file>; - -    fn symbols(&self) -> Self::SymbolIterator { -        WasmSymbolIterator { -            symbols: self.symbols.iter().enumerate(), -        } -    } - -    fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> { -        let symbol = self -            .symbols -            .get(index.0) -            .read_error("Invalid Wasm symbol index")?; -        Ok(WasmSymbol { index, symbol }) -    } -} - -/// An iterator for the symbols in a [`WasmFile`]. -#[derive(Debug)] -pub struct WasmSymbolIterator<'data, 'file> { -    symbols: core::iter::Enumerate<slice::Iter<'file, WasmSymbolInternal<'data>>>, -} - -impl<'data, 'file> Iterator for WasmSymbolIterator<'data, 'file> { -    type Item = WasmSymbol<'data, 'file>; - -    fn next(&mut self) -> Option<Self::Item> { -        let (index, symbol) = self.symbols.next()?; -        Some(WasmSymbol { -            index: SymbolIndex(index), -            symbol, -        }) -    } -} - -/// A symbol in a [`WasmFile`]. -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -#[derive(Clone, Copy, Debug)] -pub struct WasmSymbol<'data, 'file> { -    index: SymbolIndex, -    symbol: &'file WasmSymbolInternal<'data>, -} - -#[derive(Clone, Debug)] -struct WasmSymbolInternal<'data> { -    name: &'data str, -    address: u64, -    size: u64, -    kind: SymbolKind, -    section: SymbolSection, -    scope: SymbolScope, -} - -impl<'data, 'file> read::private::Sealed for WasmSymbol<'data, 'file> {} - -impl<'data, 'file> ObjectSymbol<'data> for WasmSymbol<'data, 'file> { -    #[inline] -    fn index(&self) -> SymbolIndex { -        self.index -    } - -    #[inline] -    fn name_bytes(&self) -> read::Result<&'data [u8]> { -        Ok(self.symbol.name.as_bytes()) -    } - -    #[inline] -    fn name(&self) -> read::Result<&'data str> { -        Ok(self.symbol.name) -    } - -    #[inline] -    fn address(&self) -> u64 { -        self.symbol.address -    } - -    #[inline] -    fn size(&self) -> u64 { -        self.symbol.size -    } - -    #[inline] -    fn kind(&self) -> SymbolKind { -        self.symbol.kind -    } - -    #[inline] -    fn section(&self) -> SymbolSection { -        self.symbol.section -    } - -    #[inline] -    fn is_undefined(&self) -> bool { -        self.symbol.section == SymbolSection::Undefined -    } - -    #[inline] -    fn is_definition(&self) -> bool { -        (self.symbol.kind == SymbolKind::Text || self.symbol.kind == SymbolKind::Data) -            && self.symbol.section != SymbolSection::Undefined -    } - -    #[inline] -    fn is_common(&self) -> bool { -        self.symbol.section == SymbolSection::Common -    } - -    #[inline] -    fn is_weak(&self) -> bool { -        false -    } - -    #[inline] -    fn scope(&self) -> SymbolScope { -        self.symbol.scope -    } - -    #[inline] -    fn is_global(&self) -> bool { -        self.symbol.scope != SymbolScope::Compilation -    } - -    #[inline] -    fn is_local(&self) -> bool { -        self.symbol.scope == SymbolScope::Compilation -    } - -    #[inline] -    fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> { -        SymbolFlags::None -    } -} - -/// An iterator for the relocations for a [`WasmSection`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmRelocationIterator<'data, 'file, R = &'data [u8]>( -    PhantomData<(&'data (), &'file (), R)>, -); - -impl<'data, 'file, R> Iterator for WasmRelocationIterator<'data, 'file, R> { -    type Item = (u64, Relocation); - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} diff --git a/vendor/object/src/read/xcoff/comdat.rs b/vendor/object/src/read/xcoff/comdat.rs deleted file mode 100644 index 03e52bf..0000000 --- a/vendor/object/src/read/xcoff/comdat.rs +++ /dev/null @@ -1,135 +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 for the COMDAT section groups in a [`XcoffFile32`](super::XcoffFile32). -pub type XcoffComdatIterator32<'data, 'file, R = &'data [u8]> = -    XcoffComdatIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator for the COMDAT section groups in a [`XcoffFile64`](super::XcoffFile64). -pub type XcoffComdatIterator64<'data, 'file, R = &'data [u8]> = -    XcoffComdatIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator for the COMDAT section groups in a [`XcoffFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[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 in a [`XcoffFile32`](super::XcoffFile32). -pub type XcoffComdat32<'data, 'file, R = &'data [u8]> = -    XcoffComdat<'data, 'file, xcoff::FileHeader32, R>; - -/// A COMDAT section group in a [`XcoffFile64`](super::XcoffFile64). -pub type XcoffComdat64<'data, 'file, R = &'data [u8]> = -    XcoffComdat<'data, 'file, xcoff::FileHeader64, R>; - -/// A COMDAT section group in a [`XcoffFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[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 for the sections in a COMDAT section group in a [`XcoffFile32`](super::XcoffFile32). -pub type XcoffComdatSectionIterator32<'data, 'file, R = &'data [u8]> = -    XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator for the sections in a COMDAT section group in a [`XcoffFile64`](super::XcoffFile64). -pub type XcoffComdatSectionIterator64<'data, 'file, R = &'data [u8]> = -    XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator for the sections in a COMDAT section group in a [`XcoffFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[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/src/read/xcoff/file.rs b/vendor/object/src/read/xcoff/file.rs deleted file mode 100644 index 70d980a..0000000 --- a/vendor/object/src/read/xcoff/file.rs +++ /dev/null @@ -1,696 +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. -/// -/// This is a file that starts with [`xcoff::FileHeader32`], and corresponds -/// to [`crate::FileKind::Xcoff32`]. -pub type XcoffFile32<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader32, R>; -/// A 64-bit XCOFF object file. -/// -/// This is a file that starts with [`xcoff::FileHeader64`], and corresponds -/// to [`crate::FileKind::Xcoff64`]. -pub type XcoffFile64<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader64, R>; - -/// A partially parsed XCOFF file. -/// -/// Most functionality 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 { -            file: self, -            symbols: self.symbols.iter(), -        } -    } - -    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.iter_none(), -        } -    } - -    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 [`xcoff::FileHeader32`] and [`xcoff::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) -    } -} - -/// A trait for generic access to [`xcoff::AuxHeader32`] and [`xcoff::AuxHeader64`]. -#[allow(missing_docs)] -pub trait AuxHeader: Debug + Pod { -    type Word: Into<u64>; - -    fn o_mflag(&self) -> u16; -    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_algntext(&self) -> u16; -    fn o_algndata(&self) -> u16; -    fn o_modtype(&self) -> u16; -    fn o_cpuflag(&self) -> u8; -    fn o_cputype(&self) -> u8; -    fn o_maxstack(&self) -> Self::Word; -    fn o_maxdata(&self) -> Self::Word; -    fn o_debugger(&self) -> u32; -    fn o_textpsize(&self) -> u8; -    fn o_datapsize(&self) -> u8; -    fn o_stackpsize(&self) -> u8; -    fn o_flags(&self) -> u8; -    fn o_sntdata(&self) -> u16; -    fn o_sntbss(&self) -> u16; -    fn o_x64flags(&self) -> Option<u16>; -} - -impl AuxHeader for xcoff::AuxHeader32 { -    type Word = u32; - -    fn o_mflag(&self) -> u16 { -        self.o_mflag.get(BE) -    } - -    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_algntext(&self) -> u16 { -        self.o_algntext.get(BE) -    } - -    fn o_algndata(&self) -> u16 { -        self.o_algndata.get(BE) -    } - -    fn o_modtype(&self) -> u16 { -        self.o_modtype.get(BE) -    } - -    fn o_cpuflag(&self) -> u8 { -        self.o_cpuflag -    } - -    fn o_cputype(&self) -> u8 { -        self.o_cputype -    } - -    fn o_maxstack(&self) -> Self::Word { -        self.o_maxstack.get(BE) -    } - -    fn o_maxdata(&self) -> Self::Word { -        self.o_maxdata.get(BE) -    } - -    fn o_debugger(&self) -> u32 { -        self.o_debugger.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 -    } - -    fn o_flags(&self) -> u8 { -        self.o_flags -    } - -    fn o_sntdata(&self) -> u16 { -        self.o_sntdata.get(BE) -    } - -    fn o_sntbss(&self) -> u16 { -        self.o_sntbss.get(BE) -    } - -    fn o_x64flags(&self) -> Option<u16> { -        None -    } -} - -impl AuxHeader for xcoff::AuxHeader64 { -    type Word = u64; - -    fn o_mflag(&self) -> u16 { -        self.o_mflag.get(BE) -    } - -    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_algntext(&self) -> u16 { -        self.o_algntext.get(BE) -    } - -    fn o_algndata(&self) -> u16 { -        self.o_algndata.get(BE) -    } - -    fn o_modtype(&self) -> u16 { -        self.o_modtype.get(BE) -    } - -    fn o_cpuflag(&self) -> u8 { -        self.o_cpuflag -    } - -    fn o_cputype(&self) -> u8 { -        self.o_cputype -    } - -    fn o_maxstack(&self) -> Self::Word { -        self.o_maxstack.get(BE) -    } - -    fn o_maxdata(&self) -> Self::Word { -        self.o_maxdata.get(BE) -    } - -    fn o_debugger(&self) -> u32 { -        self.o_debugger.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 -    } - -    fn o_flags(&self) -> u8 { -        self.o_flags -    } - -    fn o_sntdata(&self) -> u16 { -        self.o_sntdata.get(BE) -    } - -    fn o_sntbss(&self) -> u16 { -        self.o_sntbss.get(BE) -    } - -    fn o_x64flags(&self) -> Option<u16> { -        Some(self.o_x64flags.get(BE)) -    } -} diff --git a/vendor/object/src/read/xcoff/mod.rs b/vendor/object/src/read/xcoff/mod.rs deleted file mode 100644 index b75c4da..0000000 --- a/vendor/object/src/read/xcoff/mod.rs +++ /dev/null @@ -1,63 +0,0 @@ -//! Support for reading AIX XCOFF files. -//! -//! Traits are used to abstract over the difference between 32-bit and 64-bit XCOFF. -//! The primary trait for this is [`FileHeader`]. -//! -//! ## High level API -//! -//! [`XcoffFile`] implements the [`Object`](crate::read::Object) trait for XCOFF files. -//! [`XcoffFile`] is parameterised by [`FileHeader`] to allow reading both 32-bit and -//! 64-bit XCOFF. There are type aliases for these parameters ([`XcoffFile32`] and -//! [`XcoffFile64`]). -//! -//! ## Low level API -//! -//! The [`FileHeader`] trait can be directly used to parse both [`xcoff::FileHeader32`] -//! and [`xcoff::FileHeader64`]. -//! -//! ### Example for low level API -//!  ```no_run -//! use object::xcoff; -//! use object::read::xcoff::{FileHeader, SectionHeader, Symbol}; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads a file and displays the name of each section and symbol. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let mut offset = 0; -//!     let header = xcoff::FileHeader64::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)?; -//!     for section in sections.iter() { -//!         println!("{}", String::from_utf8_lossy(section.name())); -//!     } -//!     for (_index, symbol) in symbols.iter() { -//!         println!("{}", String::from_utf8_lossy(symbol.name(symbols.strings())?)); -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` -#[cfg(doc)] -use crate::xcoff; - -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/src/read/xcoff/relocation.rs b/vendor/object/src/read/xcoff/relocation.rs deleted file mode 100644 index a655ccc..0000000 --- a/vendor/object/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 for the relocations in an [`XcoffSection32`](super::XcoffSection32). -pub type XcoffRelocationIterator32<'data, 'file, R = &'data [u8]> = -    XcoffRelocationIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator for the relocations in an [`XcoffSection64`](super::XcoffSection64). -pub type XcoffRelocationIterator64<'data, 'file, R = &'data [u8]> = -    XcoffRelocationIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator for the relocations in an [`XcoffSection`](super::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 [`xcoff::Rel32`] and [`xcoff::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/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") -    } -} diff --git a/vendor/object/src/read/xcoff/segment.rs b/vendor/object/src/read/xcoff/segment.rs deleted file mode 100644 index d30d7d8..0000000 --- a/vendor/object/src/read/xcoff/segment.rs +++ /dev/null @@ -1,117 +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 for the segments in an [`XcoffFile32`](super::XcoffFile32). -pub type XcoffSegmentIterator32<'data, 'file, R = &'data [u8]> = -    XcoffSegmentIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator for the segments in an [`XcoffFile64`](super::XcoffFile64). -pub type XcoffSegmentIterator64<'data, 'file, R = &'data [u8]> = -    XcoffSegmentIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator for the segments in an [`XcoffFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[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 in an [`XcoffFile32`](super::XcoffFile32). -pub type XcoffSegment32<'data, 'file, R = &'data [u8]> = -    XcoffSegment<'data, 'file, xcoff::FileHeader32, R>; -/// A segment in an [`XcoffFile64`](super::XcoffFile64). -pub type XcoffSegment64<'data, 'file, R = &'data [u8]> = -    XcoffSegment<'data, 'file, xcoff::FileHeader64, R>; - -/// A loadable section in an [`XcoffFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[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/src/read/xcoff/symbol.rs b/vendor/object/src/read/xcoff/symbol.rs deleted file mode 100644 index 72651c3..0000000 --- a/vendor/object/src/read/xcoff/symbol.rs +++ /dev/null @@ -1,786 +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. -/// -/// Returned by [`FileHeader::symbols`]. -#[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 string table used for the symbol names. -    #[inline] -    pub fn strings(&self) -> StringTable<'data, R> { -        self.strings -    } - -    /// Iterate over the symbols. -    #[inline] -    pub fn iter<'table>(&'table self) -> SymbolIterator<'data, 'table, Xcoff, R> { -        SymbolIterator { -            symbols: self, -            index: 0, -        } -    } - -    /// Empty symbol iterator. -    #[inline] -    pub(super) fn iter_none<'table>(&'table self) -> SymbolIterator<'data, 'table, Xcoff, R> { -        SymbolIterator { -            symbols: self, -            index: self.symbols.len(), -        } -    } - -    /// 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() -    } -} - -/// An iterator for symbol entries in an XCOFF file. -/// -/// Yields the index and symbol structure for each symbol. -#[derive(Debug)] -pub struct SymbolIterator<'data, 'table, Xcoff, R = &'data [u8]> -where -    Xcoff: FileHeader, -    R: ReadRef<'data>, -{ -    symbols: &'table SymbolTable<'data, Xcoff, R>, -    index: usize, -} - -impl<'data, 'table, Xcoff: FileHeader, R: ReadRef<'data>> Iterator -    for SymbolIterator<'data, 'table, Xcoff, R> -{ -    type Item = (SymbolIndex, &'data Xcoff::Symbol); - -    fn next(&mut self) -> Option<Self::Item> { -        let index = self.index; -        let symbol = self.symbols.symbol(index).ok()?; -        self.index += 1 + symbol.n_numaux() as usize; -        Some((SymbolIndex(index), symbol)) -    } -} - -/// A symbol table in an [`XcoffFile32`](super::XcoffFile32). -pub type XcoffSymbolTable32<'data, 'file, R = &'data [u8]> = -    XcoffSymbolTable<'data, 'file, xcoff::FileHeader32, R>; -/// A symbol table in an [`XcoffFile64`](super::XcoffFile64). -pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> = -    XcoffSymbolTable<'data, 'file, xcoff::FileHeader64, R>; - -/// A symbol table in an [`XcoffFile`]. -#[derive(Debug, Clone, Copy)] -pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]> -where -    Xcoff: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) 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.iter(), -        } -    } - -    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 for the symbols in an [`XcoffFile32`](super::XcoffFile32). -pub type XcoffSymbolIterator32<'data, 'file, R = &'data [u8]> = -    XcoffSymbolIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator for the symbols in an [`XcoffFile64`](super::XcoffFile64). -pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> = -    XcoffSymbolIterator<'data, 'file, xcoff::FileHeader64, R>; - -/// An iterator for the symbols in an [`XcoffFile`]. -pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]> -where -    Xcoff: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file XcoffFile<'data, Xcoff, R>, -    pub(super) symbols: SymbolIterator<'data, 'file, Xcoff, R>, -} - -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, symbol) = self.symbols.next()?; -        Some(XcoffSymbol { -            file: self.file, -            symbols: self.symbols.symbols, -            index, -            symbol, -        }) -    } -} - -/// A symbol in an [`XcoffFile32`](super::XcoffFile32). -pub type XcoffSymbol32<'data, 'file, R = &'data [u8]> = -    XcoffSymbol<'data, 'file, xcoff::FileHeader32, R>; -/// A symbol in an [`XcoffFile64`](super::XcoffFile64). -pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> = -    XcoffSymbol<'data, 'file, xcoff::FileHeader64, R>; - -/// A symbol in an [`XcoffFile`]. -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -#[derive(Debug, Clone, Copy)] -pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]> -where -    Xcoff: FileHeader, -    R: ReadRef<'data>, -{ -    pub(super) 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(); -                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(); -                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.n_scnum() <= 0 { -            return false; -        } -        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 sym_type = aux_csect.sym_type(); -                sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_LD || sym_type == xcoff::XTY_CM -            } 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 => { -                    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 aux_csect.sym_type() == 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 [`xcoff::Symbol32`] and [`xcoff::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_offset(&self) -> Option<u32>; -    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 -    } - -    fn name_offset(&self) -> Option<u32> { -        Some(self.n_offset.get(BE)) -    } - -    /// 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 -    } - -    fn name_offset(&self) -> Option<u32> { -        if self.n_name[0] == 0 { -            let offset = u32::from_be_bytes(self.n_name[4..8].try_into().unwrap()); -            Some(offset) -        } else { -            None -        } -    } - -    /// Parse the symbol name for XCOFF32. -    fn name<'data, R: ReadRef<'data>>( -        &'data self, -        strings: StringTable<'data, R>, -    ) -> Result<&'data [u8]> { -        if let Some(offset) = self.name_offset() { -            // If the name starts with 0 then the last 4 bytes are a string table offset. -            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 [`xcoff::FileAux32`] and [`xcoff::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>; - -    fn name_offset(&self) -> Option<u32> { -        let x_fname = self.x_fname(); -        if x_fname[0] == 0 { -            Some(u32::from_be_bytes(x_fname[4..8].try_into().unwrap())) -        } else { -            None -        } -    } - -    /// 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]> { -        if let Some(offset) = self.name_offset() { -            // If the name starts with 0 then the last 4 bytes are a string table offset. -            strings -                .get(offset) -                .read_error("Invalid XCOFF symbol name offset") -        } else { -            // The name is inline and padded with nulls. -            let x_fname = self.x_fname(); -            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 [`xcoff::CsectAux32`] and [`xcoff::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_stab(&self) -> Option<u32>; -    fn x_snstab(&self) -> Option<u16>; -    fn x_auxtype(&self) -> Option<u8>; - -    fn alignment(&self) -> u8 { -        self.x_smtyp() >> 3 -    } -    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_stab(&self) -> Option<u32> { -        None -    } - -    fn x_snstab(&self) -> Option<u16> { -        None -    } - -    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_stab(&self) -> Option<u32> { -        Some(self.x_stab.get(BE)) -    } - -    fn x_snstab(&self) -> Option<u16> { -        Some(self.x_snstab.get(BE)) -    } - -    fn x_auxtype(&self) -> Option<u8> { -        None -    } -} diff --git a/vendor/object/src/write/coff/mod.rs b/vendor/object/src/write/coff/mod.rs deleted file mode 100644 index 6e0f5ed..0000000 --- a/vendor/object/src/write/coff/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Support for writing COFF files. -//! -//! Provides [`Writer`] for low level writing of COFF files. -//! This is also used to provide COFF support for [`write::Object`](crate::write::Object). - -mod object; -pub use self::object::*; - -mod writer; -pub use writer::*; diff --git a/vendor/object/src/write/coff/object.rs b/vendor/object/src/write/coff/object.rs deleted file mode 100644 index 5229665..0000000 --- a/vendor/object/src/write/coff/object.rs +++ /dev/null @@ -1,583 +0,0 @@ -use alloc::vec::Vec; - -use crate::pe as coff; -use crate::write::coff::writer; -use crate::write::util::*; -use crate::write::*; - -#[derive(Default, Clone, Copy)] -struct SectionOffsets { -    name: writer::Name, -    offset: u32, -    reloc_offset: u32, -    selection: u8, -    associative_section: u32, -} - -#[derive(Default, Clone, Copy)] -struct SymbolOffsets { -    name: writer::Name, -    index: u32, -    aux_count: u8, -} - -/// Internal format to use for the `.drectve` section containing linker -/// directives for symbol exports. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum CoffExportStyle { -    /// MSVC format supported by link.exe and LLD. -    Msvc, -    /// Gnu format supported by GNU LD and LLD. -    Gnu, -} - -impl<'a> Object<'a> { -    pub(crate) fn coff_section_info( -        &self, -        section: StandardSection, -    ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { -        match section { -            StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None), -            StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None), -            StandardSection::ReadOnlyData -            | StandardSection::ReadOnlyDataWithRel -            | StandardSection::ReadOnlyString => ( -                &[], -                &b".rdata"[..], -                SectionKind::ReadOnlyData, -                SectionFlags::None, -            ), -            StandardSection::UninitializedData => ( -                &[], -                &b".bss"[..], -                SectionKind::UninitializedData, -                SectionFlags::None, -            ), -            // TLS sections are data sections with a special name. -            StandardSection::Tls => (&[], &b".tls$"[..], SectionKind::Data, SectionFlags::None), -            StandardSection::UninitializedTls => { -                // Unsupported section. -                (&[], &[], SectionKind::UninitializedTls, SectionFlags::None) -            } -            StandardSection::TlsVariables => { -                // Unsupported section. -                (&[], &[], SectionKind::TlsVariables, SectionFlags::None) -            } -            StandardSection::Common => { -                // Unsupported section. -                (&[], &[], SectionKind::Common, SectionFlags::None) -            } -            StandardSection::GnuProperty => { -                // Unsupported section. -                (&[], &[], SectionKind::Note, SectionFlags::None) -            } -        } -    } - -    pub(crate) fn coff_subsection_name(&self, section: &[u8], value: &[u8]) -> Vec<u8> { -        let mut name = section.to_vec(); -        name.push(b'$'); -        name.extend_from_slice(value); -        name -    } - -    pub(crate) fn coff_fixup_relocation(&mut self, relocation: &mut Relocation) -> i64 { -        if relocation.kind == RelocationKind::GotRelative { -            // Use a stub symbol for the relocation instead. -            // This isn't really a GOT, but it's a similar purpose. -            // TODO: need to handle DLL imports differently? -            relocation.kind = RelocationKind::Relative; -            relocation.symbol = self.coff_add_stub_symbol(relocation.symbol); -        } else if relocation.kind == RelocationKind::PltRelative { -            // Windows doesn't need a separate relocation type for -            // references to functions in import libraries. -            // For convenience, treat this the same as Relative. -            relocation.kind = RelocationKind::Relative; -        } - -        let constant = match self.architecture { -            Architecture::I386 | Architecture::Arm | Architecture::Aarch64 => match relocation.kind -            { -                RelocationKind::Relative => { -                    // IMAGE_REL_I386_REL32, IMAGE_REL_ARM_REL32, IMAGE_REL_ARM64_REL32 -                    relocation.addend + 4 -                } -                _ => relocation.addend, -            }, -            Architecture::X86_64 => match relocation.kind { -                RelocationKind::Relative => { -                    // IMAGE_REL_AMD64_REL32 through to IMAGE_REL_AMD64_REL32_5 -                    if relocation.addend <= -4 && relocation.addend >= -9 { -                        0 -                    } else { -                        relocation.addend + 4 -                    } -                } -                _ => relocation.addend, -            }, -            _ => unimplemented!(), -        }; -        relocation.addend -= constant; -        constant -    } - -    fn coff_add_stub_symbol(&mut self, symbol_id: SymbolId) -> SymbolId { -        if let Some(stub_id) = self.stub_symbols.get(&symbol_id) { -            return *stub_id; -        } -        let stub_size = self.architecture.address_size().unwrap().bytes(); - -        let name = b".rdata$.refptr".to_vec(); -        let section_id = self.add_section(Vec::new(), name, SectionKind::ReadOnlyData); -        let section = self.section_mut(section_id); -        section.set_data(vec![0; stub_size as usize], u64::from(stub_size)); -        section.relocations = vec![Relocation { -            offset: 0, -            size: stub_size * 8, -            kind: RelocationKind::Absolute, -            encoding: RelocationEncoding::Generic, -            symbol: symbol_id, -            addend: 0, -        }]; - -        let mut name = b".refptr.".to_vec(); -        name.extend_from_slice(&self.symbol(symbol_id).name); -        let stub_id = self.add_raw_symbol(Symbol { -            name, -            value: 0, -            size: u64::from(stub_size), -            kind: SymbolKind::Data, -            scope: SymbolScope::Compilation, -            weak: false, -            section: SymbolSection::Section(section_id), -            flags: SymbolFlags::None, -        }); -        self.stub_symbols.insert(symbol_id, stub_id); - -        stub_id -    } - -    /// Appends linker directives to the `.drectve` section to tell the linker -    /// to export all symbols with `SymbolScope::Dynamic`. -    /// -    /// This must be called after all symbols have been defined. -    pub fn add_coff_exports(&mut self, style: CoffExportStyle) { -        assert_eq!(self.format, BinaryFormat::Coff); - -        let mut directives = vec![]; -        for symbol in &self.symbols { -            if symbol.scope == SymbolScope::Dynamic { -                match style { -                    CoffExportStyle::Msvc => directives.extend(b" /EXPORT:\""), -                    CoffExportStyle::Gnu => directives.extend(b" -export:\""), -                } -                directives.extend(&symbol.name); -                directives.extend(b"\""); -                if symbol.kind != SymbolKind::Text { -                    match style { -                        CoffExportStyle::Msvc => directives.extend(b",DATA"), -                        CoffExportStyle::Gnu => directives.extend(b",data"), -                    } -                } -            } -        } -        let drectve = self.add_section(vec![], b".drectve".to_vec(), SectionKind::Linker); -        self.append_section_data(drectve, &directives, 1); -    } - -    pub(crate) fn coff_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> { -        let mut writer = writer::Writer::new(buffer); - -        // Add section strings to strtab. -        let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()]; -        for (index, section) in self.sections.iter().enumerate() { -            section_offsets[index].name = writer.add_name(§ion.name); -        } - -        // Set COMDAT flags. -        for comdat in &self.comdats { -            let symbol = &self.symbols[comdat.symbol.0]; -            let comdat_section = match symbol.section { -                SymbolSection::Section(id) => id.0, -                _ => { -                    return Err(Error(format!( -                        "unsupported COMDAT symbol `{}` section {:?}", -                        symbol.name().unwrap_or(""), -                        symbol.section -                    ))); -                } -            }; -            section_offsets[comdat_section].selection = match comdat.kind { -                ComdatKind::NoDuplicates => coff::IMAGE_COMDAT_SELECT_NODUPLICATES, -                ComdatKind::Any => coff::IMAGE_COMDAT_SELECT_ANY, -                ComdatKind::SameSize => coff::IMAGE_COMDAT_SELECT_SAME_SIZE, -                ComdatKind::ExactMatch => coff::IMAGE_COMDAT_SELECT_EXACT_MATCH, -                ComdatKind::Largest => coff::IMAGE_COMDAT_SELECT_LARGEST, -                ComdatKind::Newest => coff::IMAGE_COMDAT_SELECT_NEWEST, -                ComdatKind::Unknown => { -                    return Err(Error(format!( -                        "unsupported COMDAT symbol `{}` kind {:?}", -                        symbol.name().unwrap_or(""), -                        comdat.kind -                    ))); -                } -            }; -            for id in &comdat.sections { -                let section = &self.sections[id.0]; -                if section.symbol.is_none() { -                    return Err(Error(format!( -                        "missing symbol for COMDAT section `{}`", -                        section.name().unwrap_or(""), -                    ))); -                } -                if id.0 != comdat_section { -                    section_offsets[id.0].selection = coff::IMAGE_COMDAT_SELECT_ASSOCIATIVE; -                    section_offsets[id.0].associative_section = comdat_section as u32 + 1; -                } -            } -        } - -        // Reserve symbol indices and add symbol strings to strtab. -        let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()]; -        for (index, symbol) in self.symbols.iter().enumerate() { -            symbol_offsets[index].index = writer.reserve_symbol_index(); -            let mut name = &*symbol.name; -            match symbol.kind { -                SymbolKind::File => { -                    // Name goes in auxiliary symbol records. -                    symbol_offsets[index].aux_count = writer.reserve_aux_file_name(&symbol.name); -                    name = b".file"; -                } -                SymbolKind::Section if symbol.section.id().is_some() => { -                    symbol_offsets[index].aux_count = writer.reserve_aux_section(); -                } -                _ => {} -            }; -            symbol_offsets[index].name = writer.add_name(name); -        } - -        // Reserve file ranges. -        writer.reserve_file_header(); -        writer.reserve_section_headers(self.sections.len() as u16); -        for (index, section) in self.sections.iter().enumerate() { -            section_offsets[index].offset = writer.reserve_section(section.data.len()); -            section_offsets[index].reloc_offset = -                writer.reserve_relocations(section.relocations.len()); -        } -        writer.reserve_symtab_strtab(); - -        // Start writing. -        writer.write_file_header(writer::FileHeader { -            machine: match (self.architecture, self.sub_architecture) { -                (Architecture::Arm, None) => coff::IMAGE_FILE_MACHINE_ARMNT, -                (Architecture::Aarch64, None) => coff::IMAGE_FILE_MACHINE_ARM64, -                (Architecture::Aarch64, Some(SubArchitecture::Arm64EC)) => { -                    coff::IMAGE_FILE_MACHINE_ARM64EC -                } -                (Architecture::I386, None) => coff::IMAGE_FILE_MACHINE_I386, -                (Architecture::X86_64, None) => coff::IMAGE_FILE_MACHINE_AMD64, -                _ => { -                    return Err(Error(format!( -                        "unimplemented architecture {:?} with sub-architecture {:?}", -                        self.architecture, self.sub_architecture -                    ))); -                } -            }, -            time_date_stamp: 0, -            characteristics: match self.flags { -                FileFlags::Coff { characteristics } => characteristics, -                _ => 0, -            }, -        })?; - -        // Write section headers. -        for (index, section) in self.sections.iter().enumerate() { -            let mut characteristics = if let SectionFlags::Coff { -                characteristics, .. -            } = section.flags -            { -                characteristics -            } else { -                match section.kind { -                    SectionKind::Text => { -                        coff::IMAGE_SCN_CNT_CODE -                            | coff::IMAGE_SCN_MEM_EXECUTE -                            | coff::IMAGE_SCN_MEM_READ -                    } -                    SectionKind::Data => { -                        coff::IMAGE_SCN_CNT_INITIALIZED_DATA -                            | coff::IMAGE_SCN_MEM_READ -                            | coff::IMAGE_SCN_MEM_WRITE -                    } -                    SectionKind::UninitializedData => { -                        coff::IMAGE_SCN_CNT_UNINITIALIZED_DATA -                            | coff::IMAGE_SCN_MEM_READ -                            | coff::IMAGE_SCN_MEM_WRITE -                    } -                    SectionKind::ReadOnlyData -                    | SectionKind::ReadOnlyDataWithRel -                    | SectionKind::ReadOnlyString => { -                        coff::IMAGE_SCN_CNT_INITIALIZED_DATA | coff::IMAGE_SCN_MEM_READ -                    } -                    SectionKind::Debug | SectionKind::Other | SectionKind::OtherString => { -                        coff::IMAGE_SCN_CNT_INITIALIZED_DATA -                            | coff::IMAGE_SCN_MEM_READ -                            | coff::IMAGE_SCN_MEM_DISCARDABLE -                    } -                    SectionKind::Linker => coff::IMAGE_SCN_LNK_INFO | coff::IMAGE_SCN_LNK_REMOVE, -                    SectionKind::Common -                    | SectionKind::Tls -                    | SectionKind::UninitializedTls -                    | SectionKind::TlsVariables -                    | SectionKind::Note -                    | SectionKind::Unknown -                    | SectionKind::Metadata -                    | SectionKind::Elf(_) => { -                        return Err(Error(format!( -                            "unimplemented section `{}` kind {:?}", -                            section.name().unwrap_or(""), -                            section.kind -                        ))); -                    } -                } -            }; -            if section_offsets[index].selection != 0 { -                characteristics |= coff::IMAGE_SCN_LNK_COMDAT; -            }; -            if section.relocations.len() > 0xffff { -                characteristics |= coff::IMAGE_SCN_LNK_NRELOC_OVFL; -            } -            characteristics |= match section.align { -                1 => coff::IMAGE_SCN_ALIGN_1BYTES, -                2 => coff::IMAGE_SCN_ALIGN_2BYTES, -                4 => coff::IMAGE_SCN_ALIGN_4BYTES, -                8 => coff::IMAGE_SCN_ALIGN_8BYTES, -                16 => coff::IMAGE_SCN_ALIGN_16BYTES, -                32 => coff::IMAGE_SCN_ALIGN_32BYTES, -                64 => coff::IMAGE_SCN_ALIGN_64BYTES, -                128 => coff::IMAGE_SCN_ALIGN_128BYTES, -                256 => coff::IMAGE_SCN_ALIGN_256BYTES, -                512 => coff::IMAGE_SCN_ALIGN_512BYTES, -                1024 => coff::IMAGE_SCN_ALIGN_1024BYTES, -                2048 => coff::IMAGE_SCN_ALIGN_2048BYTES, -                4096 => coff::IMAGE_SCN_ALIGN_4096BYTES, -                8192 => coff::IMAGE_SCN_ALIGN_8192BYTES, -                _ => { -                    return Err(Error(format!( -                        "unimplemented section `{}` align {}", -                        section.name().unwrap_or(""), -                        section.align -                    ))); -                } -            }; -            writer.write_section_header(writer::SectionHeader { -                name: section_offsets[index].name, -                size_of_raw_data: section.size as u32, -                pointer_to_raw_data: section_offsets[index].offset, -                pointer_to_relocations: section_offsets[index].reloc_offset, -                pointer_to_linenumbers: 0, -                number_of_relocations: section.relocations.len() as u32, -                number_of_linenumbers: 0, -                characteristics, -            }); -        } - -        // Write section data and relocations. -        for section in &self.sections { -            writer.write_section(§ion.data); - -            if !section.relocations.is_empty() { -                //debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len()); -                writer.write_relocations_count(section.relocations.len()); -                for reloc in §ion.relocations { -                    //assert!(reloc.implicit_addend); -                    let typ = match self.architecture { -                        Architecture::I386 => match (reloc.kind, reloc.size, reloc.addend) { -                            (RelocationKind::Absolute, 16, 0) => coff::IMAGE_REL_I386_DIR16, -                            (RelocationKind::Relative, 16, 0) => coff::IMAGE_REL_I386_REL16, -                            (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_I386_DIR32, -                            (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_I386_DIR32NB, -                            (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_I386_SECTION, -                            (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_I386_SECREL, -                            (RelocationKind::SectionOffset, 7, 0) => coff::IMAGE_REL_I386_SECREL7, -                            (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_I386_REL32, -                            (RelocationKind::Coff(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::X86_64 => match (reloc.kind, reloc.size, reloc.addend) { -                            (RelocationKind::Absolute, 64, 0) => coff::IMAGE_REL_AMD64_ADDR64, -                            (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_AMD64_ADDR32, -                            (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_AMD64_ADDR32NB, -                            (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_AMD64_REL32, -                            (RelocationKind::Relative, 32, -5) => coff::IMAGE_REL_AMD64_REL32_1, -                            (RelocationKind::Relative, 32, -6) => coff::IMAGE_REL_AMD64_REL32_2, -                            (RelocationKind::Relative, 32, -7) => coff::IMAGE_REL_AMD64_REL32_3, -                            (RelocationKind::Relative, 32, -8) => coff::IMAGE_REL_AMD64_REL32_4, -                            (RelocationKind::Relative, 32, -9) => coff::IMAGE_REL_AMD64_REL32_5, -                            (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_AMD64_SECTION, -                            (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_AMD64_SECREL, -                            (RelocationKind::SectionOffset, 7, 0) => coff::IMAGE_REL_AMD64_SECREL7, -                            (RelocationKind::Coff(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Arm => match (reloc.kind, reloc.size, reloc.addend) { -                            (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_ARM_ADDR32, -                            (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_ARM_ADDR32NB, -                            (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_ARM_REL32, -                            (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_ARM_SECTION, -                            (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_ARM_SECREL, -                            (RelocationKind::Coff(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Aarch64 => match (reloc.kind, reloc.size, reloc.addend) { -                            (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_ARM64_ADDR32, -                            (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_ARM64_ADDR32NB, -                            (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_ARM64_SECTION, -                            (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_ARM64_SECREL, -                            (RelocationKind::Absolute, 64, 0) => coff::IMAGE_REL_ARM64_ADDR64, -                            (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_ARM64_REL32, -                            (RelocationKind::Coff(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        _ => { -                            return Err(Error(format!( -                                "unimplemented architecture {:?}", -                                self.architecture -                            ))); -                        } -                    }; -                    writer.write_relocation(writer::Relocation { -                        virtual_address: reloc.offset as u32, -                        symbol: symbol_offsets[reloc.symbol.0].index, -                        typ, -                    }); -                } -            } -        } - -        // Write symbols. -        for (index, symbol) in self.symbols.iter().enumerate() { -            let section_number = match symbol.section { -                SymbolSection::None => { -                    debug_assert_eq!(symbol.kind, SymbolKind::File); -                    coff::IMAGE_SYM_DEBUG as u16 -                } -                SymbolSection::Undefined => coff::IMAGE_SYM_UNDEFINED as u16, -                SymbolSection::Absolute => coff::IMAGE_SYM_ABSOLUTE as u16, -                SymbolSection::Common => coff::IMAGE_SYM_UNDEFINED as u16, -                SymbolSection::Section(id) => id.0 as u16 + 1, -            }; -            let typ = if symbol.kind == SymbolKind::Text { -                coff::IMAGE_SYM_DTYPE_FUNCTION << coff::IMAGE_SYM_DTYPE_SHIFT -            } else { -                coff::IMAGE_SYM_TYPE_NULL -            }; -            let storage_class = match symbol.kind { -                SymbolKind::File => coff::IMAGE_SYM_CLASS_FILE, -                SymbolKind::Section => { -                    if symbol.section.id().is_some() { -                        coff::IMAGE_SYM_CLASS_STATIC -                    } else { -                        coff::IMAGE_SYM_CLASS_SECTION -                    } -                } -                SymbolKind::Label => coff::IMAGE_SYM_CLASS_LABEL, -                SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls => { -                    match symbol.section { -                        SymbolSection::None => { -                            return Err(Error(format!( -                                "missing section for symbol `{}`", -                                symbol.name().unwrap_or("") -                            ))); -                        } -                        SymbolSection::Undefined | SymbolSection::Common => { -                            coff::IMAGE_SYM_CLASS_EXTERNAL -                        } -                        SymbolSection::Absolute | SymbolSection::Section(_) => { -                            match symbol.scope { -                                // TODO: does this need aux symbol records too? -                                _ if symbol.weak => coff::IMAGE_SYM_CLASS_WEAK_EXTERNAL, -                                SymbolScope::Unknown => { -                                    return Err(Error(format!( -                                        "unimplemented symbol `{}` scope {:?}", -                                        symbol.name().unwrap_or(""), -                                        symbol.scope -                                    ))); -                                } -                                SymbolScope::Compilation => coff::IMAGE_SYM_CLASS_STATIC, -                                SymbolScope::Linkage | SymbolScope::Dynamic => { -                                    coff::IMAGE_SYM_CLASS_EXTERNAL -                                } -                            } -                        } -                    } -                } -                SymbolKind::Unknown | SymbolKind::Null => { -                    return Err(Error(format!( -                        "unimplemented symbol `{}` kind {:?}", -                        symbol.name().unwrap_or(""), -                        symbol.kind -                    ))); -                } -            }; -            let number_of_aux_symbols = symbol_offsets[index].aux_count; -            let value = if symbol.section == SymbolSection::Common { -                symbol.size as u32 -            } else { -                symbol.value as u32 -            }; -            writer.write_symbol(writer::Symbol { -                name: symbol_offsets[index].name, -                value, -                section_number, -                typ, -                storage_class, -                number_of_aux_symbols, -            }); - -            // Write auxiliary symbols. -            match symbol.kind { -                SymbolKind::File => { -                    writer.write_aux_file_name(&symbol.name, number_of_aux_symbols); -                } -                SymbolKind::Section if symbol.section.id().is_some() => { -                    debug_assert_eq!(number_of_aux_symbols, 1); -                    let section_index = symbol.section.id().unwrap().0; -                    let section = &self.sections[section_index]; -                    writer.write_aux_section(writer::AuxSymbolSection { -                        length: section.size as u32, -                        number_of_relocations: section.relocations.len() as u32, -                        number_of_linenumbers: 0, -                        check_sum: checksum(section.data()), -                        number: section_offsets[section_index].associative_section, -                        selection: section_offsets[section_index].selection, -                    }); -                } -                _ => { -                    debug_assert_eq!(number_of_aux_symbols, 0); -                } -            } -        } - -        writer.write_strtab(); - -        debug_assert_eq!(writer.reserved_len(), writer.len()); - -        Ok(()) -    } -} - -// JamCRC -fn checksum(data: &[u8]) -> u32 { -    let mut hasher = crc32fast::Hasher::new_with_initial(0xffff_ffff); -    hasher.update(data); -    !hasher.finalize() -} diff --git a/vendor/object/src/write/coff/writer.rs b/vendor/object/src/write/coff/writer.rs deleted file mode 100644 index 8c7ada3..0000000 --- a/vendor/object/src/write/coff/writer.rs +++ /dev/null @@ -1,518 +0,0 @@ -//! Helper for writing COFF files. -use alloc::string::String; -use alloc::vec::Vec; -use core::mem; - -use crate::endian::{LittleEndian as LE, U16Bytes, U32Bytes, U16, U32}; -use crate::pe; -use crate::write::string::{StringId, StringTable}; -use crate::write::util; -use crate::write::{Error, Result, WritableBuffer}; - -/// A helper for writing COFF files. -/// -/// Writing uses a two phase approach. The first phase builds up all of the information -/// that may need to be known ahead of time: -/// - build string table -/// - reserve section indices -/// - reserve symbol indices -/// - reserve file ranges for headers and sections -/// -/// Some of the information has ordering requirements. For example, strings must be added -/// to the string table before reserving the file range for the string table. There are debug -/// asserts to check some of these requirements. -/// -/// The second phase writes everything out in order. Thus the caller must ensure writing -/// is in the same order that file ranges were reserved. There are debug asserts to assist -/// with checking this. -#[allow(missing_debug_implementations)] -pub struct Writer<'a> { -    buffer: &'a mut dyn WritableBuffer, -    len: usize, - -    section_num: u16, - -    symtab_offset: u32, -    symtab_num: u32, - -    strtab: StringTable<'a>, -    strtab_len: usize, -    strtab_offset: u32, -    strtab_data: Vec<u8>, -} - -impl<'a> Writer<'a> { -    /// Create a new `Writer`. -    pub fn new(buffer: &'a mut dyn WritableBuffer) -> Self { -        Writer { -            buffer, -            len: 0, - -            section_num: 0, - -            symtab_offset: 0, -            symtab_num: 0, - -            strtab: StringTable::default(), -            strtab_len: 0, -            strtab_offset: 0, -            strtab_data: Vec::new(), -        } -    } - -    /// Return the current file length that has been reserved. -    pub fn reserved_len(&self) -> usize { -        self.len -    } - -    /// Return the current file length that has been written. -    #[allow(clippy::len_without_is_empty)] -    pub fn len(&self) -> usize { -        self.buffer.len() -    } - -    /// Reserve a file range with the given size and starting alignment. -    /// -    /// Returns the aligned offset of the start of the range. -    pub fn reserve(&mut self, len: usize, align_start: usize) -> u32 { -        if align_start > 1 { -            self.len = util::align(self.len, align_start); -        } -        let offset = self.len; -        self.len += len; -        offset as u32 -    } - -    /// Write alignment padding bytes. -    pub fn write_align(&mut self, align_start: usize) { -        if align_start > 1 { -            util::write_align(self.buffer, align_start); -        } -    } - -    /// Write data. -    pub fn write(&mut self, data: &[u8]) { -        self.buffer.write_bytes(data); -    } - -    /// Reserve the file range up to the given file offset. -    pub fn reserve_until(&mut self, offset: usize) { -        debug_assert!(self.len <= offset); -        self.len = offset; -    } - -    /// Write padding up to the given file offset. -    pub fn pad_until(&mut self, offset: usize) { -        debug_assert!(self.buffer.len() <= offset); -        self.buffer.resize(offset); -    } - -    /// Reserve the range for the file header. -    /// -    /// This must be at the start of the file. -    pub fn reserve_file_header(&mut self) { -        debug_assert_eq!(self.len, 0); -        self.reserve(mem::size_of::<pe::ImageFileHeader>(), 1); -    } - -    /// Write the file header. -    /// -    /// This must be at the start of the file. -    /// -    /// Fields that can be derived from known information are automatically set by this function. -    pub fn write_file_header(&mut self, header: FileHeader) -> Result<()> { -        debug_assert_eq!(self.buffer.len(), 0); - -        // Start writing. -        self.buffer -            .reserve(self.len) -            .map_err(|_| Error(String::from("Cannot allocate buffer")))?; - -        // Write file header. -        let header = pe::ImageFileHeader { -            machine: U16::new(LE, header.machine), -            number_of_sections: U16::new(LE, self.section_num), -            time_date_stamp: U32::new(LE, header.time_date_stamp), -            pointer_to_symbol_table: U32::new(LE, self.symtab_offset), -            number_of_symbols: U32::new(LE, self.symtab_num), -            size_of_optional_header: U16::default(), -            characteristics: U16::new(LE, header.characteristics), -        }; -        self.buffer.write(&header); - -        Ok(()) -    } - -    /// Reserve the range for the section headers. -    pub fn reserve_section_headers(&mut self, section_num: u16) { -        debug_assert_eq!(self.section_num, 0); -        self.section_num = section_num; -        self.reserve( -            section_num as usize * mem::size_of::<pe::ImageSectionHeader>(), -            1, -        ); -    } - -    /// Write a section header. -    pub fn write_section_header(&mut self, section: SectionHeader) { -        let mut coff_section = pe::ImageSectionHeader { -            name: [0; 8], -            virtual_size: U32::default(), -            virtual_address: U32::default(), -            size_of_raw_data: U32::new(LE, section.size_of_raw_data), -            pointer_to_raw_data: U32::new(LE, section.pointer_to_raw_data), -            pointer_to_relocations: U32::new(LE, section.pointer_to_relocations), -            pointer_to_linenumbers: U32::new(LE, section.pointer_to_linenumbers), -            number_of_relocations: if section.number_of_relocations > 0xffff { -                U16::new(LE, 0xffff) -            } else { -                U16::new(LE, section.number_of_relocations as u16) -            }, -            number_of_linenumbers: U16::default(), -            characteristics: U32::new(LE, section.characteristics), -        }; -        match section.name { -            Name::Short(name) => coff_section.name = name, -            Name::Long(str_id) => { -                let mut str_offset = self.strtab.get_offset(str_id); -                if str_offset <= 9_999_999 { -                    let mut name = [0; 7]; -                    let mut len = 0; -                    if str_offset == 0 { -                        name[6] = b'0'; -                        len = 1; -                    } else { -                        while str_offset != 0 { -                            let rem = (str_offset % 10) as u8; -                            str_offset /= 10; -                            name[6 - len] = b'0' + rem; -                            len += 1; -                        } -                    } -                    coff_section.name = [0; 8]; -                    coff_section.name[0] = b'/'; -                    coff_section.name[1..][..len].copy_from_slice(&name[7 - len..]); -                } else { -                    debug_assert!(str_offset as u64 <= 0xf_ffff_ffff); -                    coff_section.name[0] = b'/'; -                    coff_section.name[1] = b'/'; -                    for i in 0..6 { -                        let rem = (str_offset % 64) as u8; -                        str_offset /= 64; -                        let c = match rem { -                            0..=25 => b'A' + rem, -                            26..=51 => b'a' + rem - 26, -                            52..=61 => b'0' + rem - 52, -                            62 => b'+', -                            63 => b'/', -                            _ => unreachable!(), -                        }; -                        coff_section.name[7 - i] = c; -                    } -                } -            } -        } -        self.buffer.write(&coff_section); -    } - -    /// Reserve the range for the section data. -    /// -    /// Returns the aligned offset of the start of the range. -    /// Does nothing and returns 0 if the length is zero. -    pub fn reserve_section(&mut self, len: usize) -> u32 { -        if len == 0 { -            return 0; -        } -        // TODO: not sure what alignment is required here, but this seems to match LLVM -        self.reserve(len, 4) -    } - -    /// Write the alignment bytes prior to section data. -    /// -    /// This is unneeded if you are using `write_section` or `write_section_zeroes` -    /// for the data. -    pub fn write_section_align(&mut self) { -        util::write_align(self.buffer, 4); -    } - -    /// Write the section data. -    /// -    /// Writes alignment bytes prior to the data. -    /// Does nothing if the data is empty. -    pub fn write_section(&mut self, data: &[u8]) { -        if data.is_empty() { -            return; -        } -        self.write_section_align(); -        self.buffer.write_bytes(data); -    } - -    /// Write the section data using zero bytes. -    /// -    /// Writes alignment bytes prior to the data. -    /// Does nothing if the length is zero. -    pub fn write_section_zeroes(&mut self, len: usize) { -        if len == 0 { -            return; -        } -        self.write_section_align(); -        self.buffer.resize(self.buffer.len() + len); -    } - -    /// Reserve a file range for the given number of relocations. -    /// -    /// This will automatically reserve an extra relocation if there are more than 0xffff. -    /// -    /// Returns the offset of the range. -    /// Does nothing and returns 0 if the count is zero. -    pub fn reserve_relocations(&mut self, mut count: usize) -> u32 { -        if count == 0 { -            return 0; -        } -        if count > 0xffff { -            count += 1; -        } -        self.reserve(count * mem::size_of::<pe::ImageRelocation>(), 1) -    } - -    /// Write a relocation containing the count if required. -    /// -    /// This should be called before writing the first relocation for a section. -    pub fn write_relocations_count(&mut self, count: usize) { -        if count > 0xffff { -            let coff_relocation = pe::ImageRelocation { -                virtual_address: U32Bytes::new(LE, count as u32 + 1), -                symbol_table_index: U32Bytes::new(LE, 0), -                typ: U16Bytes::new(LE, 0), -            }; -            self.buffer.write(&coff_relocation); -        } -    } - -    /// Write a relocation. -    pub fn write_relocation(&mut self, reloc: Relocation) { -        let coff_relocation = pe::ImageRelocation { -            virtual_address: U32Bytes::new(LE, reloc.virtual_address), -            symbol_table_index: U32Bytes::new(LE, reloc.symbol), -            typ: U16Bytes::new(LE, reloc.typ), -        }; -        self.buffer.write(&coff_relocation); -    } - -    /// Reserve a symbol table entry. -    /// -    /// This must be called before [`Self::reserve_symtab_strtab`]. -    pub fn reserve_symbol_index(&mut self) -> u32 { -        debug_assert_eq!(self.symtab_offset, 0); -        let index = self.symtab_num; -        self.symtab_num += 1; -        index -    } - -    /// Reserve a number of symbol table entries. -    pub fn reserve_symbol_indices(&mut self, count: u32) { -        debug_assert_eq!(self.symtab_offset, 0); -        self.symtab_num += count; -    } - -    /// Write a symbol table entry. -    pub fn write_symbol(&mut self, symbol: Symbol) { -        let mut coff_symbol = pe::ImageSymbol { -            name: [0; 8], -            value: U32Bytes::new(LE, symbol.value), -            section_number: U16Bytes::new(LE, symbol.section_number), -            typ: U16Bytes::new(LE, symbol.typ), -            storage_class: symbol.storage_class, -            number_of_aux_symbols: symbol.number_of_aux_symbols, -        }; -        match symbol.name { -            Name::Short(name) => coff_symbol.name = name, -            Name::Long(str_id) => { -                let str_offset = self.strtab.get_offset(str_id); -                coff_symbol.name[4..8].copy_from_slice(&u32::to_le_bytes(str_offset as u32)); -            } -        } -        self.buffer.write(&coff_symbol); -    } - -    /// Reserve auxiliary symbols for a file name. -    /// -    /// Returns the number of auxiliary symbols required. -    /// -    /// This must be called before [`Self::reserve_symtab_strtab`]. -    pub fn reserve_aux_file_name(&mut self, name: &[u8]) -> u8 { -        debug_assert_eq!(self.symtab_offset, 0); -        let aux_count = (name.len() + pe::IMAGE_SIZEOF_SYMBOL - 1) / pe::IMAGE_SIZEOF_SYMBOL; -        self.symtab_num += aux_count as u32; -        aux_count as u8 -    } - -    /// Write auxiliary symbols for a file name. -    pub fn write_aux_file_name(&mut self, name: &[u8], aux_count: u8) { -        let aux_len = aux_count as usize * pe::IMAGE_SIZEOF_SYMBOL; -        debug_assert!(aux_len >= name.len()); -        let old_len = self.buffer.len(); -        self.buffer.write_bytes(name); -        self.buffer.resize(old_len + aux_len); -    } - -    /// Reserve an auxiliary symbol for a section. -    /// -    /// Returns the number of auxiliary symbols required. -    /// -    /// This must be called before [`Self::reserve_symtab_strtab`]. -    pub fn reserve_aux_section(&mut self) -> u8 { -        debug_assert_eq!(self.symtab_offset, 0); -        self.symtab_num += 1; -        1 -    } - -    /// Write an auxiliary symbol for a section. -    pub fn write_aux_section(&mut self, section: AuxSymbolSection) { -        let aux = pe::ImageAuxSymbolSection { -            length: U32Bytes::new(LE, section.length), -            number_of_relocations: if section.number_of_relocations > 0xffff { -                U16Bytes::new(LE, 0xffff) -            } else { -                U16Bytes::new(LE, section.number_of_relocations as u16) -            }, -            number_of_linenumbers: U16Bytes::new(LE, section.number_of_linenumbers), -            check_sum: U32Bytes::new(LE, section.check_sum), -            number: U16Bytes::new(LE, section.number as u16), -            selection: section.selection, -            reserved: 0, -            high_number: U16Bytes::new(LE, (section.number >> 16) as u16), -        }; -        self.buffer.write(&aux); -    } - -    /// Return the number of reserved symbol table entries. -    pub fn symbol_count(&self) -> u32 { -        self.symtab_num -    } - -    /// Add a string to the string table. -    /// -    /// This must be called before [`Self::reserve_symtab_strtab`]. -    pub fn add_string(&mut self, name: &'a [u8]) -> StringId { -        debug_assert_eq!(self.strtab_offset, 0); -        self.strtab.add(name) -    } - -    /// Add a section or symbol name to the string table if required. -    /// -    /// This must be called before [`Self::reserve_symtab_strtab`]. -    pub fn add_name(&mut self, name: &'a [u8]) -> Name { -        if name.len() > 8 { -            Name::Long(self.add_string(name)) -        } else { -            let mut short_name = [0; 8]; -            short_name[..name.len()].copy_from_slice(name); -            Name::Short(short_name) -        } -    } - -    /// Reserve the range for the symbol table and string table. -    /// -    /// This must be called after functions that reserve symbol -    /// indices or add strings. -    pub fn reserve_symtab_strtab(&mut self) { -        debug_assert_eq!(self.symtab_offset, 0); -        self.symtab_offset = self.reserve(self.symtab_num as usize * pe::IMAGE_SIZEOF_SYMBOL, 1); - -        debug_assert_eq!(self.strtab_offset, 0); -        // First 4 bytes of strtab are the length. -        self.strtab.write(4, &mut self.strtab_data); -        self.strtab_len = self.strtab_data.len() + 4; -        self.strtab_offset = self.reserve(self.strtab_len, 1); -    } - -    /// Write the string table. -    pub fn write_strtab(&mut self) { -        debug_assert_eq!(self.strtab_offset, self.buffer.len() as u32); -        self.buffer -            .write_bytes(&u32::to_le_bytes(self.strtab_len as u32)); -        self.buffer.write_bytes(&self.strtab_data); -    } -} - -/// Shortened and native endian version of [`pe::ImageFileHeader`]. -#[allow(missing_docs)] -#[derive(Debug, Default, Clone)] -pub struct FileHeader { -    pub machine: u16, -    pub time_date_stamp: u32, -    pub characteristics: u16, -} - -/// A section or symbol name. -#[derive(Debug, Clone, Copy)] -pub enum Name { -    /// An inline name. -    Short([u8; 8]), -    /// An id of a string table entry. -    Long(StringId), -} - -impl Default for Name { -    fn default() -> Name { -        Name::Short([0; 8]) -    } -} - -// From isn't useful. -#[allow(clippy::from_over_into)] -impl<'a> Into<Name> for &'a [u8; 8] { -    fn into(self) -> Name { -        Name::Short(*self) -    } -} - -/// Native endian version of [`pe::ImageSectionHeader`]. -#[allow(missing_docs)] -#[derive(Debug, Default, Clone)] -pub struct SectionHeader { -    pub name: Name, -    pub size_of_raw_data: u32, -    pub pointer_to_raw_data: u32, -    pub pointer_to_relocations: u32, -    pub pointer_to_linenumbers: u32, -    /// This will automatically be clamped if there are more than 0xffff. -    pub number_of_relocations: u32, -    pub number_of_linenumbers: u16, -    pub characteristics: u32, -} - -/// Native endian version of [`pe::ImageSymbol`]. -#[allow(missing_docs)] -#[derive(Debug, Default, Clone)] -pub struct Symbol { -    pub name: Name, -    pub value: u32, -    pub section_number: u16, -    pub typ: u16, -    pub storage_class: u8, -    pub number_of_aux_symbols: u8, -} - -/// Native endian version of [`pe::ImageAuxSymbolSection`]. -#[allow(missing_docs)] -#[derive(Debug, Default, Clone)] -pub struct AuxSymbolSection { -    pub length: u32, -    /// This will automatically be clamped if there are more than 0xffff. -    pub number_of_relocations: u32, -    pub number_of_linenumbers: u16, -    pub check_sum: u32, -    pub number: u32, -    pub selection: u8, -} - -/// Native endian version of [`pe::ImageRelocation`]. -#[allow(missing_docs)] -#[derive(Debug, Default, Clone)] -pub struct Relocation { -    pub virtual_address: u32, -    pub symbol: u32, -    pub typ: u16, -} diff --git a/vendor/object/src/write/elf/mod.rs b/vendor/object/src/write/elf/mod.rs deleted file mode 100644 index 3a4f371..0000000 --- a/vendor/object/src/write/elf/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Support for writing ELF files. -//! -//! Provides [`Writer`] for low level writing of ELF files. -//! This is also used to provide ELF support for [`write::Object`](crate::write::Object). - -mod object; - -mod writer; -pub use writer::*; diff --git a/vendor/object/src/write/elf/object.rs b/vendor/object/src/write/elf/object.rs deleted file mode 100644 index 5d7a93e..0000000 --- a/vendor/object/src/write/elf/object.rs +++ /dev/null @@ -1,907 +0,0 @@ -use alloc::vec::Vec; - -use crate::write::elf::writer::*; -use crate::write::string::StringId; -use crate::write::*; -use crate::AddressSize; -use crate::{elf, pod}; - -#[derive(Clone, Copy)] -struct ComdatOffsets { -    offset: usize, -    str_id: StringId, -} - -#[derive(Clone, Copy)] -struct SectionOffsets { -    index: SectionIndex, -    offset: usize, -    str_id: StringId, -    reloc_offset: usize, -    reloc_str_id: Option<StringId>, -} - -#[derive(Default, Clone, Copy)] -struct SymbolOffsets { -    index: SymbolIndex, -    str_id: Option<StringId>, -} - -// Public methods. -impl<'a> Object<'a> { -    /// Add a property with a u32 value to the ELF ".note.gnu.property" section. -    /// -    /// Requires `feature = "elf"`. -    pub fn add_elf_gnu_property_u32(&mut self, property: u32, value: u32) { -        if self.format != BinaryFormat::Elf { -            return; -        } - -        let align = if self.elf_is_64() { 8 } else { 4 }; -        let mut data = Vec::with_capacity(32); -        let n_name = b"GNU\0"; -        data.extend_from_slice(pod::bytes_of(&elf::NoteHeader32 { -            n_namesz: U32::new(self.endian, n_name.len() as u32), -            n_descsz: U32::new(self.endian, util::align(3 * 4, align) as u32), -            n_type: U32::new(self.endian, elf::NT_GNU_PROPERTY_TYPE_0), -        })); -        data.extend_from_slice(n_name); -        // This happens to already be aligned correctly. -        debug_assert_eq!(util::align(data.len(), align), data.len()); -        data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, property))); -        // Value size -        data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, 4))); -        data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, value))); -        util::write_align(&mut data, align); - -        let section = self.section_id(StandardSection::GnuProperty); -        self.append_section_data(section, &data, align as u64); -    } -} - -// Private methods. -impl<'a> Object<'a> { -    pub(crate) fn elf_section_info( -        &self, -        section: StandardSection, -    ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { -        match section { -            StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None), -            StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None), -            StandardSection::ReadOnlyData | StandardSection::ReadOnlyString => ( -                &[], -                &b".rodata"[..], -                SectionKind::ReadOnlyData, -                SectionFlags::None, -            ), -            StandardSection::ReadOnlyDataWithRel => ( -                &[], -                b".data.rel.ro", -                SectionKind::ReadOnlyDataWithRel, -                SectionFlags::None, -            ), -            StandardSection::UninitializedData => ( -                &[], -                &b".bss"[..], -                SectionKind::UninitializedData, -                SectionFlags::None, -            ), -            StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls, SectionFlags::None), -            StandardSection::UninitializedTls => ( -                &[], -                &b".tbss"[..], -                SectionKind::UninitializedTls, -                SectionFlags::None, -            ), -            StandardSection::TlsVariables => { -                // Unsupported section. -                (&[], &[], SectionKind::TlsVariables, SectionFlags::None) -            } -            StandardSection::Common => { -                // Unsupported section. -                (&[], &[], SectionKind::Common, SectionFlags::None) -            } -            StandardSection::GnuProperty => ( -                &[], -                &b".note.gnu.property"[..], -                SectionKind::Note, -                SectionFlags::Elf { -                    sh_flags: u64::from(elf::SHF_ALLOC), -                }, -            ), -        } -    } - -    pub(crate) fn elf_subsection_name(&self, section: &[u8], value: &[u8]) -> Vec<u8> { -        let mut name = section.to_vec(); -        name.push(b'.'); -        name.extend_from_slice(value); -        name -    } - -    fn elf_has_relocation_addend(&self) -> Result<bool> { -        Ok(match self.architecture { -            Architecture::Aarch64 => true, -            Architecture::Aarch64_Ilp32 => true, -            Architecture::Arm => false, -            Architecture::Avr => true, -            Architecture::Bpf => false, -            Architecture::Csky => true, -            Architecture::I386 => false, -            Architecture::X86_64 => true, -            Architecture::X86_64_X32 => true, -            Architecture::Hexagon => true, -            Architecture::LoongArch64 => true, -            Architecture::Mips => false, -            Architecture::Mips64 => true, -            Architecture::Msp430 => true, -            Architecture::PowerPc => true, -            Architecture::PowerPc64 => true, -            Architecture::Riscv64 => true, -            Architecture::Riscv32 => true, -            Architecture::S390x => true, -            Architecture::Sbf => false, -            Architecture::Sharc => true, -            Architecture::Sparc64 => true, -            Architecture::Xtensa => true, -            _ => { -                return Err(Error(format!( -                    "unimplemented architecture {:?}", -                    self.architecture -                ))); -            } -        }) -    } - -    pub(crate) fn elf_fixup_relocation(&mut self, relocation: &mut Relocation) -> Result<i64> { -        // Determine whether the addend is stored in the relocation or the data. -        if self.elf_has_relocation_addend()? { -            Ok(0) -        } else { -            let constant = relocation.addend; -            relocation.addend = 0; -            Ok(constant) -        } -    } - -    pub(crate) fn elf_is_64(&self) -> bool { -        match self.architecture.address_size().unwrap() { -            AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false, -            AddressSize::U64 => true, -        } -    } - -    pub(crate) fn elf_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> { -        // Create reloc section header names so we can reference them. -        let is_rela = self.elf_has_relocation_addend()?; -        let reloc_names: Vec<_> = self -            .sections -            .iter() -            .map(|section| { -                let mut reloc_name = Vec::with_capacity( -                    if is_rela { ".rela".len() } else { ".rel".len() } + section.name.len(), -                ); -                if !section.relocations.is_empty() { -                    reloc_name.extend_from_slice(if is_rela { -                        &b".rela"[..] -                    } else { -                        &b".rel"[..] -                    }); -                    reloc_name.extend_from_slice(§ion.name); -                } -                reloc_name -            }) -            .collect(); - -        // Start calculating offsets of everything. -        let mut writer = Writer::new(self.endian, self.elf_is_64(), buffer); -        writer.reserve_file_header(); - -        // Calculate size of section data. -        let mut comdat_offsets = Vec::with_capacity(self.comdats.len()); -        for comdat in &self.comdats { -            if comdat.kind != ComdatKind::Any { -                return Err(Error(format!( -                    "unsupported COMDAT symbol `{}` kind {:?}", -                    self.symbols[comdat.symbol.0].name().unwrap_or(""), -                    comdat.kind -                ))); -            } - -            writer.reserve_section_index(); -            let offset = writer.reserve_comdat(comdat.sections.len()); -            let str_id = writer.add_section_name(b".group"); -            comdat_offsets.push(ComdatOffsets { offset, str_id }); -        } -        let mut section_offsets = Vec::with_capacity(self.sections.len()); -        for (section, reloc_name) in self.sections.iter().zip(reloc_names.iter()) { -            let index = writer.reserve_section_index(); -            let offset = writer.reserve(section.data.len(), section.align as usize); -            let str_id = writer.add_section_name(§ion.name); -            let mut reloc_str_id = None; -            if !section.relocations.is_empty() { -                writer.reserve_section_index(); -                reloc_str_id = Some(writer.add_section_name(reloc_name)); -            } -            section_offsets.push(SectionOffsets { -                index, -                offset, -                str_id, -                // Relocation data is reserved later. -                reloc_offset: 0, -                reloc_str_id, -            }); -        } - -        // Calculate index of symbols and add symbol strings to strtab. -        let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()]; -        writer.reserve_null_symbol_index(); -        // Local symbols must come before global. -        for (index, symbol) in self.symbols.iter().enumerate() { -            if symbol.is_local() { -                let section_index = symbol.section.id().map(|s| section_offsets[s.0].index); -                symbol_offsets[index].index = writer.reserve_symbol_index(section_index); -            } -        } -        let symtab_num_local = writer.symbol_count(); -        for (index, symbol) in self.symbols.iter().enumerate() { -            if !symbol.is_local() { -                let section_index = symbol.section.id().map(|s| section_offsets[s.0].index); -                symbol_offsets[index].index = writer.reserve_symbol_index(section_index); -            } -        } -        for (index, symbol) in self.symbols.iter().enumerate() { -            if symbol.kind != SymbolKind::Section && !symbol.name.is_empty() { -                symbol_offsets[index].str_id = Some(writer.add_string(&symbol.name)); -            } -        } - -        // Calculate size of symbols. -        writer.reserve_symtab_section_index(); -        writer.reserve_symtab(); -        if writer.symtab_shndx_needed() { -            writer.reserve_symtab_shndx_section_index(); -        } -        writer.reserve_symtab_shndx(); -        writer.reserve_strtab_section_index(); -        writer.reserve_strtab(); - -        // Calculate size of relocations. -        for (index, section) in self.sections.iter().enumerate() { -            let count = section.relocations.len(); -            if count != 0 { -                section_offsets[index].reloc_offset = writer.reserve_relocations(count, is_rela); -            } -        } - -        // Calculate size of section headers. -        writer.reserve_shstrtab_section_index(); -        writer.reserve_shstrtab(); -        writer.reserve_section_headers(); - -        // Start writing. -        let e_type = elf::ET_REL; -        let e_machine = match (self.architecture, self.sub_architecture) { -            (Architecture::Aarch64, None) => elf::EM_AARCH64, -            (Architecture::Aarch64_Ilp32, None) => elf::EM_AARCH64, -            (Architecture::Arm, None) => elf::EM_ARM, -            (Architecture::Avr, None) => elf::EM_AVR, -            (Architecture::Bpf, None) => elf::EM_BPF, -            (Architecture::Csky, None) => elf::EM_CSKY, -            (Architecture::I386, None) => elf::EM_386, -            (Architecture::X86_64, None) => elf::EM_X86_64, -            (Architecture::X86_64_X32, None) => elf::EM_X86_64, -            (Architecture::Hexagon, None) => elf::EM_HEXAGON, -            (Architecture::LoongArch64, None) => elf::EM_LOONGARCH, -            (Architecture::Mips, None) => elf::EM_MIPS, -            (Architecture::Mips64, None) => elf::EM_MIPS, -            (Architecture::Msp430, None) => elf::EM_MSP430, -            (Architecture::PowerPc, None) => elf::EM_PPC, -            (Architecture::PowerPc64, None) => elf::EM_PPC64, -            (Architecture::Riscv32, None) => elf::EM_RISCV, -            (Architecture::Riscv64, None) => elf::EM_RISCV, -            (Architecture::S390x, None) => elf::EM_S390, -            (Architecture::Sbf, None) => elf::EM_SBF, -            (Architecture::Sharc, None) => elf::EM_SHARC, -            (Architecture::Sparc64, None) => elf::EM_SPARCV9, -            (Architecture::Xtensa, None) => elf::EM_XTENSA, -            _ => { -                return Err(Error(format!( -                    "unimplemented architecture {:?} with sub-architecture {:?}", -                    self.architecture, self.sub_architecture -                ))); -            } -        }; -        let (os_abi, abi_version, e_flags) = if let FileFlags::Elf { -            os_abi, -            abi_version, -            e_flags, -        } = self.flags -        { -            (os_abi, abi_version, e_flags) -        } else { -            (elf::ELFOSABI_NONE, 0, 0) -        }; -        writer.write_file_header(&FileHeader { -            os_abi, -            abi_version, -            e_type, -            e_machine, -            e_entry: 0, -            e_flags, -        })?; - -        // Write section data. -        for comdat in &self.comdats { -            writer.write_comdat_header(); -            for section in &comdat.sections { -                writer.write_comdat_entry(section_offsets[section.0].index); -            } -        } -        for (index, section) in self.sections.iter().enumerate() { -            writer.write_align(section.align as usize); -            debug_assert_eq!(section_offsets[index].offset, writer.len()); -            writer.write(§ion.data); -        } - -        // Write symbols. -        writer.write_null_symbol(); -        let mut write_symbol = |index: usize, symbol: &Symbol| -> Result<()> { -            let st_info = if let SymbolFlags::Elf { st_info, .. } = symbol.flags { -                st_info -            } else { -                let st_type = match symbol.kind { -                    SymbolKind::Null => elf::STT_NOTYPE, -                    SymbolKind::Text => { -                        if symbol.is_undefined() { -                            elf::STT_NOTYPE -                        } else { -                            elf::STT_FUNC -                        } -                    } -                    SymbolKind::Data => { -                        if symbol.is_undefined() { -                            elf::STT_NOTYPE -                        } else if symbol.is_common() { -                            elf::STT_COMMON -                        } else { -                            elf::STT_OBJECT -                        } -                    } -                    SymbolKind::Section => elf::STT_SECTION, -                    SymbolKind::File => elf::STT_FILE, -                    SymbolKind::Tls => elf::STT_TLS, -                    SymbolKind::Label => elf::STT_NOTYPE, -                    SymbolKind::Unknown => { -                        if symbol.is_undefined() { -                            elf::STT_NOTYPE -                        } else { -                            return Err(Error(format!( -                                "unimplemented symbol `{}` kind {:?}", -                                symbol.name().unwrap_or(""), -                                symbol.kind -                            ))); -                        } -                    } -                }; -                let st_bind = if symbol.weak { -                    elf::STB_WEAK -                } else if symbol.is_undefined() { -                    elf::STB_GLOBAL -                } else if symbol.is_local() { -                    elf::STB_LOCAL -                } else { -                    elf::STB_GLOBAL -                }; -                (st_bind << 4) + st_type -            }; -            let st_other = if let SymbolFlags::Elf { st_other, .. } = symbol.flags { -                st_other -            } else if symbol.scope == SymbolScope::Linkage { -                elf::STV_HIDDEN -            } else { -                elf::STV_DEFAULT -            }; -            let (st_shndx, section) = match symbol.section { -                SymbolSection::None => { -                    debug_assert_eq!(symbol.kind, SymbolKind::File); -                    (elf::SHN_ABS, None) -                } -                SymbolSection::Undefined => (elf::SHN_UNDEF, None), -                SymbolSection::Absolute => (elf::SHN_ABS, None), -                SymbolSection::Common => (elf::SHN_COMMON, None), -                SymbolSection::Section(id) => (0, Some(section_offsets[id.0].index)), -            }; -            writer.write_symbol(&Sym { -                name: symbol_offsets[index].str_id, -                section, -                st_info, -                st_other, -                st_shndx, -                st_value: symbol.value, -                st_size: symbol.size, -            }); -            Ok(()) -        }; -        for (index, symbol) in self.symbols.iter().enumerate() { -            if symbol.is_local() { -                write_symbol(index, symbol)?; -            } -        } -        for (index, symbol) in self.symbols.iter().enumerate() { -            if !symbol.is_local() { -                write_symbol(index, symbol)?; -            } -        } -        writer.write_symtab_shndx(); -        writer.write_strtab(); - -        // Write relocations. -        for (index, section) in self.sections.iter().enumerate() { -            if !section.relocations.is_empty() { -                writer.write_align_relocation(); -                debug_assert_eq!(section_offsets[index].reloc_offset, writer.len()); -                for reloc in §ion.relocations { -                    let r_type = match self.architecture { -                        Architecture::Aarch64 => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => { -                                elf::R_AARCH64_ABS64 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { -                                elf::R_AARCH64_ABS32 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => { -                                elf::R_AARCH64_ABS16 -                            } -                            (RelocationKind::Relative, RelocationEncoding::Generic, 64) => { -                                elf::R_AARCH64_PREL64 -                            } -                            (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { -                                elf::R_AARCH64_PREL32 -                            } -                            (RelocationKind::Relative, RelocationEncoding::Generic, 16) => { -                                elf::R_AARCH64_PREL16 -                            } -                            (RelocationKind::Relative, RelocationEncoding::AArch64Call, 26) -                            | (RelocationKind::PltRelative, RelocationEncoding::AArch64Call, 26) => { -                                elf::R_AARCH64_CALL26 -                            } -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Aarch64_Ilp32 => { -                            match (reloc.kind, reloc.encoding, reloc.size) { -                                (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { -                                    elf::R_AARCH64_P32_ABS32 -                                } -                                (RelocationKind::Elf(x), _, _) => x, -                                _ => { -                                    return Err(Error(format!( -                                        "unimplemented relocation {:?}", -                                        reloc -                                    ))); -                                } -                            } -                        } -                        Architecture::Arm => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_ARM_ABS32, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Avr => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_AVR_32, -                            (RelocationKind::Absolute, _, 16) => elf::R_AVR_16, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Bpf => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 64) => elf::R_BPF_64_64, -                            (RelocationKind::Absolute, _, 32) => elf::R_BPF_64_32, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Csky => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_CKCORE_ADDR32, -                            (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { -                                elf::R_CKCORE_PCREL32 -                            } -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::I386 => match (reloc.kind, reloc.size) { -                            (RelocationKind::Absolute, 32) => elf::R_386_32, -                            (RelocationKind::Relative, 32) => elf::R_386_PC32, -                            (RelocationKind::Got, 32) => elf::R_386_GOT32, -                            (RelocationKind::PltRelative, 32) => elf::R_386_PLT32, -                            (RelocationKind::GotBaseOffset, 32) => elf::R_386_GOTOFF, -                            (RelocationKind::GotBaseRelative, 32) => elf::R_386_GOTPC, -                            (RelocationKind::Absolute, 16) => elf::R_386_16, -                            (RelocationKind::Relative, 16) => elf::R_386_PC16, -                            (RelocationKind::Absolute, 8) => elf::R_386_8, -                            (RelocationKind::Relative, 8) => elf::R_386_PC8, -                            (RelocationKind::Elf(x), _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::X86_64 | Architecture::X86_64_X32 => { -                            match (reloc.kind, reloc.encoding, reloc.size) { -                                (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => { -                                    elf::R_X86_64_64 -                                } -                                (RelocationKind::Relative, RelocationEncoding::X86Branch, 32) => { -                                    elf::R_X86_64_PLT32 -                                } -                                (RelocationKind::Relative, _, 32) => elf::R_X86_64_PC32, -                                (RelocationKind::Got, _, 32) => elf::R_X86_64_GOT32, -                                (RelocationKind::PltRelative, _, 32) => elf::R_X86_64_PLT32, -                                (RelocationKind::GotRelative, _, 32) => elf::R_X86_64_GOTPCREL, -                                (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { -                                    elf::R_X86_64_32 -                                } -                                (RelocationKind::Absolute, RelocationEncoding::X86Signed, 32) => { -                                    elf::R_X86_64_32S -                                } -                                (RelocationKind::Absolute, _, 16) => elf::R_X86_64_16, -                                (RelocationKind::Relative, _, 16) => elf::R_X86_64_PC16, -                                (RelocationKind::Absolute, _, 8) => elf::R_X86_64_8, -                                (RelocationKind::Relative, _, 8) => elf::R_X86_64_PC8, -                                (RelocationKind::Elf(x), _, _) => x, -                                _ => { -                                    return Err(Error(format!( -                                        "unimplemented relocation {:?}", -                                        reloc -                                    ))); -                                } -                            } -                        } -                        Architecture::Hexagon => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_HEX_32, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::LoongArch64 => match (reloc.kind, reloc.encoding, reloc.size) -                        { -                            (RelocationKind::Absolute, _, 32) => elf::R_LARCH_32, -                            (RelocationKind::Absolute, _, 64) => elf::R_LARCH_64, -                            (RelocationKind::Relative, _, 32) => elf::R_LARCH_32_PCREL, -                            (RelocationKind::Relative, _, 64) => elf::R_LARCH_64_PCREL, -                            (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 16) -                            | ( -                                RelocationKind::PltRelative, -                                RelocationEncoding::LoongArchBranch, -                                16, -                            ) => elf::R_LARCH_B16, -                            (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 21) -                            | ( -                                RelocationKind::PltRelative, -                                RelocationEncoding::LoongArchBranch, -                                21, -                            ) => elf::R_LARCH_B21, -                            (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 26) -                            | ( -                                RelocationKind::PltRelative, -                                RelocationEncoding::LoongArchBranch, -                                26, -                            ) => elf::R_LARCH_B26, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Mips | Architecture::Mips64 => { -                            match (reloc.kind, reloc.encoding, reloc.size) { -                                (RelocationKind::Absolute, _, 16) => elf::R_MIPS_16, -                                (RelocationKind::Absolute, _, 32) => elf::R_MIPS_32, -                                (RelocationKind::Absolute, _, 64) => elf::R_MIPS_64, -                                (RelocationKind::Elf(x), _, _) => x, -                                _ => { -                                    return Err(Error(format!( -                                        "unimplemented relocation {:?}", -                                        reloc -                                    ))); -                                } -                            } -                        } -                        Architecture::Msp430 => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_MSP430_32, -                            (RelocationKind::Absolute, _, 16) => elf::R_MSP430_16_BYTE, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::PowerPc => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_PPC_ADDR32, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::PowerPc64 => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_PPC64_ADDR32, -                            (RelocationKind::Absolute, _, 64) => elf::R_PPC64_ADDR64, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Riscv32 | Architecture::Riscv64 => { -                            match (reloc.kind, reloc.encoding, reloc.size) { -                                (RelocationKind::Absolute, _, 32) => elf::R_RISCV_32, -                                (RelocationKind::Absolute, _, 64) => elf::R_RISCV_64, -                                (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { -                                    elf::R_RISCV_32_PCREL -                                } -                                (RelocationKind::Elf(x), _, _) => x, -                                _ => { -                                    return Err(Error(format!( -                                        "unimplemented relocation {:?}", -                                        reloc -                                    ))); -                                } -                            } -                        } -                        Architecture::S390x => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 8) => { -                                elf::R_390_8 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => { -                                elf::R_390_16 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { -                                elf::R_390_32 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => { -                                elf::R_390_64 -                            } -                            (RelocationKind::Relative, RelocationEncoding::Generic, 16) => { -                                elf::R_390_PC16 -                            } -                            (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { -                                elf::R_390_PC32 -                            } -                            (RelocationKind::Relative, RelocationEncoding::Generic, 64) => { -                                elf::R_390_PC64 -                            } -                            (RelocationKind::Relative, RelocationEncoding::S390xDbl, 16) => { -                                elf::R_390_PC16DBL -                            } -                            (RelocationKind::Relative, RelocationEncoding::S390xDbl, 32) => { -                                elf::R_390_PC32DBL -                            } -                            (RelocationKind::PltRelative, RelocationEncoding::S390xDbl, 16) => { -                                elf::R_390_PLT16DBL -                            } -                            (RelocationKind::PltRelative, RelocationEncoding::S390xDbl, 32) => { -                                elf::R_390_PLT32DBL -                            } -                            (RelocationKind::Got, RelocationEncoding::Generic, 16) => { -                                elf::R_390_GOT16 -                            } -                            (RelocationKind::Got, RelocationEncoding::Generic, 32) => { -                                elf::R_390_GOT32 -                            } -                            (RelocationKind::Got, RelocationEncoding::Generic, 64) => { -                                elf::R_390_GOT64 -                            } -                            (RelocationKind::GotRelative, RelocationEncoding::S390xDbl, 32) => { -                                elf::R_390_GOTENT -                            } -                            (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 16) => { -                                elf::R_390_GOTOFF16 -                            } -                            (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 32) => { -                                elf::R_390_GOTOFF32 -                            } -                            (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 64) => { -                                elf::R_390_GOTOFF64 -                            } -                            (RelocationKind::GotBaseRelative, RelocationEncoding::Generic, 64) => { -                                elf::R_390_GOTPC -                            } -                            (RelocationKind::GotBaseRelative, RelocationEncoding::S390xDbl, 32) => { -                                elf::R_390_GOTPCDBL -                            } -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Sbf => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 64) => elf::R_SBF_64_64, -                            (RelocationKind::Absolute, _, 32) => elf::R_SBF_64_32, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Sharc => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 32) => { -                                elf::R_SHARC_ADDR32_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { -                                elf::R_SHARC_ADDR_VAR_V3 -                            } -                            (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 24) => { -                                elf::R_SHARC_PCRLONG_V3 -                            } -                            (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 6) => { -                                elf::R_SHARC_PCRSHORT_V3 -                            } -                            (RelocationKind::Relative, RelocationEncoding::SharcTypeB, 6) => { -                                elf::R_SHARC_PCRSHORT_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => { -                                elf::R_SHARC_ADDR_VAR16_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 16) => { -                                elf::R_SHARC_DATA16_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 16) => { -                                elf::R_SHARC_DATA16_VISA_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 24) => { -                                elf::R_SHARC_ADDR24_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 6) => { -                                elf::R_SHARC_DATA6_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 6) => { -                                elf::R_SHARC_DATA6_VISA_V3 -                            } -                            (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 7) => { -                                elf::R_SHARC_DATA7_VISA_V3 -                            } -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Sparc64 => match (reloc.kind, reloc.encoding, reloc.size) { -                            // TODO: use R_SPARC_32/R_SPARC_64 if aligned. -                            (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32, -                            (RelocationKind::Absolute, _, 64) => elf::R_SPARC_UA64, -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Xtensa => match (reloc.kind, reloc.encoding, reloc.size) { -                            (RelocationKind::Absolute, _, 32) => elf::R_XTENSA_32, -                            (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { -                                elf::R_XTENSA_32_PCREL -                            } -                            (RelocationKind::Elf(x), _, _) => x, -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        _ => { -                            if let RelocationKind::Elf(x) = reloc.kind { -                                x -                            } else { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        } -                    }; -                    let r_sym = symbol_offsets[reloc.symbol.0].index.0; -                    writer.write_relocation( -                        is_rela, -                        &Rel { -                            r_offset: reloc.offset, -                            r_sym, -                            r_type, -                            r_addend: reloc.addend, -                        }, -                    ); -                } -            } -        } - -        writer.write_shstrtab(); - -        // Write section headers. -        writer.write_null_section_header(); - -        let symtab_index = writer.symtab_index(); -        for (comdat, comdat_offset) in self.comdats.iter().zip(comdat_offsets.iter()) { -            writer.write_comdat_section_header( -                comdat_offset.str_id, -                symtab_index, -                symbol_offsets[comdat.symbol.0].index, -                comdat_offset.offset, -                comdat.sections.len(), -            ); -        } -        for (index, section) in self.sections.iter().enumerate() { -            let sh_type = match section.kind { -                SectionKind::UninitializedData | SectionKind::UninitializedTls => elf::SHT_NOBITS, -                SectionKind::Note => elf::SHT_NOTE, -                SectionKind::Elf(sh_type) => sh_type, -                _ => elf::SHT_PROGBITS, -            }; -            let sh_flags = if let SectionFlags::Elf { sh_flags } = section.flags { -                sh_flags -            } else { -                match section.kind { -                    SectionKind::Text => elf::SHF_ALLOC | elf::SHF_EXECINSTR, -                    SectionKind::Data | SectionKind::ReadOnlyDataWithRel => { -                        elf::SHF_ALLOC | elf::SHF_WRITE -                    } -                    SectionKind::Tls => elf::SHF_ALLOC | elf::SHF_WRITE | elf::SHF_TLS, -                    SectionKind::UninitializedData => elf::SHF_ALLOC | elf::SHF_WRITE, -                    SectionKind::UninitializedTls => elf::SHF_ALLOC | elf::SHF_WRITE | elf::SHF_TLS, -                    SectionKind::ReadOnlyData => elf::SHF_ALLOC, -                    SectionKind::ReadOnlyString => { -                        elf::SHF_ALLOC | elf::SHF_STRINGS | elf::SHF_MERGE -                    } -                    SectionKind::OtherString => elf::SHF_STRINGS | elf::SHF_MERGE, -                    SectionKind::Other -                    | SectionKind::Debug -                    | SectionKind::Metadata -                    | SectionKind::Linker -                    | SectionKind::Note -                    | SectionKind::Elf(_) => 0, -                    SectionKind::Unknown | SectionKind::Common | SectionKind::TlsVariables => { -                        return Err(Error(format!( -                            "unimplemented section `{}` kind {:?}", -                            section.name().unwrap_or(""), -                            section.kind -                        ))); -                    } -                } -                .into() -            }; -            // TODO: not sure if this is correct, maybe user should determine this -            let sh_entsize = match section.kind { -                SectionKind::ReadOnlyString | SectionKind::OtherString => 1, -                _ => 0, -            }; -            writer.write_section_header(&SectionHeader { -                name: Some(section_offsets[index].str_id), -                sh_type, -                sh_flags, -                sh_addr: 0, -                sh_offset: section_offsets[index].offset as u64, -                sh_size: section.size, -                sh_link: 0, -                sh_info: 0, -                sh_addralign: section.align, -                sh_entsize, -            }); - -            if !section.relocations.is_empty() { -                writer.write_relocation_section_header( -                    section_offsets[index].reloc_str_id.unwrap(), -                    section_offsets[index].index, -                    symtab_index, -                    section_offsets[index].reloc_offset, -                    section.relocations.len(), -                    is_rela, -                ); -            } -        } - -        writer.write_symtab_section_header(symtab_num_local); -        writer.write_symtab_shndx_section_header(); -        writer.write_strtab_section_header(); -        writer.write_shstrtab_section_header(); - -        debug_assert_eq!(writer.reserved_len(), writer.len()); - -        Ok(()) -    } -} diff --git a/vendor/object/src/write/elf/writer.rs b/vendor/object/src/write/elf/writer.rs deleted file mode 100644 index 9750924..0000000 --- a/vendor/object/src/write/elf/writer.rs +++ /dev/null @@ -1,2143 +0,0 @@ -//! Helper for writing ELF files. -use alloc::string::String; -use alloc::vec::Vec; -use core::mem; - -use crate::elf; -use crate::endian::*; -use crate::pod; -use crate::write::string::{StringId, StringTable}; -use crate::write::util; -use crate::write::{Error, Result, WritableBuffer}; - -/// The index of an ELF section. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SectionIndex(pub u32); - -/// The index of an ELF symbol. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SymbolIndex(pub u32); - -/// A helper for writing ELF files. -/// -/// Writing uses a two phase approach. The first phase builds up all of the information -/// that may need to be known ahead of time: -/// - build string tables -/// - reserve section indices -/// - reserve symbol indices -/// - reserve file ranges for headers and sections -/// -/// Some of the information has ordering requirements. For example, strings must be added -/// to string tables before reserving the file range for the string table. Symbol indices -/// must be reserved after reserving the section indices they reference. There are debug -/// asserts to check some of these requirements. -/// -/// The second phase writes everything out in order. Thus the caller must ensure writing -/// is in the same order that file ranges were reserved. There are debug asserts to assist -/// with checking this. -#[allow(missing_debug_implementations)] -pub struct Writer<'a> { -    endian: Endianness, -    is_64: bool, -    is_mips64el: bool, -    elf_align: usize, - -    buffer: &'a mut dyn WritableBuffer, -    len: usize, - -    segment_offset: usize, -    segment_num: u32, - -    section_offset: usize, -    section_num: u32, - -    shstrtab: StringTable<'a>, -    shstrtab_str_id: Option<StringId>, -    shstrtab_index: SectionIndex, -    shstrtab_offset: usize, -    shstrtab_data: Vec<u8>, - -    need_strtab: bool, -    strtab: StringTable<'a>, -    strtab_str_id: Option<StringId>, -    strtab_index: SectionIndex, -    strtab_offset: usize, -    strtab_data: Vec<u8>, - -    symtab_str_id: Option<StringId>, -    symtab_index: SectionIndex, -    symtab_offset: usize, -    symtab_num: u32, - -    need_symtab_shndx: bool, -    symtab_shndx_str_id: Option<StringId>, -    symtab_shndx_offset: usize, -    symtab_shndx_data: Vec<u8>, - -    need_dynstr: bool, -    dynstr: StringTable<'a>, -    dynstr_str_id: Option<StringId>, -    dynstr_index: SectionIndex, -    dynstr_offset: usize, -    dynstr_data: Vec<u8>, - -    dynsym_str_id: Option<StringId>, -    dynsym_index: SectionIndex, -    dynsym_offset: usize, -    dynsym_num: u32, - -    dynamic_str_id: Option<StringId>, -    dynamic_offset: usize, -    dynamic_num: usize, - -    hash_str_id: Option<StringId>, -    hash_offset: usize, -    hash_size: usize, - -    gnu_hash_str_id: Option<StringId>, -    gnu_hash_offset: usize, -    gnu_hash_size: usize, - -    gnu_versym_str_id: Option<StringId>, -    gnu_versym_offset: usize, - -    gnu_verdef_str_id: Option<StringId>, -    gnu_verdef_offset: usize, -    gnu_verdef_size: usize, -    gnu_verdef_count: u16, -    gnu_verdef_remaining: u16, -    gnu_verdaux_remaining: u16, - -    gnu_verneed_str_id: Option<StringId>, -    gnu_verneed_offset: usize, -    gnu_verneed_size: usize, -    gnu_verneed_count: u16, -    gnu_verneed_remaining: u16, -    gnu_vernaux_remaining: u16, - -    gnu_attributes_str_id: Option<StringId>, -    gnu_attributes_offset: usize, -    gnu_attributes_size: usize, -} - -impl<'a> Writer<'a> { -    /// Create a new `Writer` for the given endianness and ELF class. -    pub fn new(endian: Endianness, is_64: bool, buffer: &'a mut dyn WritableBuffer) -> Self { -        let elf_align = if is_64 { 8 } else { 4 }; -        Writer { -            endian, -            is_64, -            // Determined later. -            is_mips64el: false, -            elf_align, - -            buffer, -            len: 0, - -            segment_offset: 0, -            segment_num: 0, - -            section_offset: 0, -            section_num: 0, - -            shstrtab: StringTable::default(), -            shstrtab_str_id: None, -            shstrtab_index: SectionIndex(0), -            shstrtab_offset: 0, -            shstrtab_data: Vec::new(), - -            need_strtab: false, -            strtab: StringTable::default(), -            strtab_str_id: None, -            strtab_index: SectionIndex(0), -            strtab_offset: 0, -            strtab_data: Vec::new(), - -            symtab_str_id: None, -            symtab_index: SectionIndex(0), -            symtab_offset: 0, -            symtab_num: 0, - -            need_symtab_shndx: false, -            symtab_shndx_str_id: None, -            symtab_shndx_offset: 0, -            symtab_shndx_data: Vec::new(), - -            need_dynstr: false, -            dynstr: StringTable::default(), -            dynstr_str_id: None, -            dynstr_index: SectionIndex(0), -            dynstr_offset: 0, -            dynstr_data: Vec::new(), - -            dynsym_str_id: None, -            dynsym_index: SectionIndex(0), -            dynsym_offset: 0, -            dynsym_num: 0, - -            dynamic_str_id: None, -            dynamic_offset: 0, -            dynamic_num: 0, - -            hash_str_id: None, -            hash_offset: 0, -            hash_size: 0, - -            gnu_hash_str_id: None, -            gnu_hash_offset: 0, -            gnu_hash_size: 0, - -            gnu_versym_str_id: None, -            gnu_versym_offset: 0, - -            gnu_verdef_str_id: None, -            gnu_verdef_offset: 0, -            gnu_verdef_size: 0, -            gnu_verdef_count: 0, -            gnu_verdef_remaining: 0, -            gnu_verdaux_remaining: 0, - -            gnu_verneed_str_id: None, -            gnu_verneed_offset: 0, -            gnu_verneed_size: 0, -            gnu_verneed_count: 0, -            gnu_verneed_remaining: 0, -            gnu_vernaux_remaining: 0, - -            gnu_attributes_str_id: None, -            gnu_attributes_offset: 0, -            gnu_attributes_size: 0, -        } -    } - -    /// Return the current file length that has been reserved. -    pub fn reserved_len(&self) -> usize { -        self.len -    } - -    /// Return the current file length that has been written. -    #[allow(clippy::len_without_is_empty)] -    pub fn len(&self) -> usize { -        self.buffer.len() -    } - -    /// Reserve a file range with the given size and starting alignment. -    /// -    /// Returns the aligned offset of the start of the range. -    pub fn reserve(&mut self, len: usize, align_start: usize) -> usize { -        if align_start > 1 { -            self.len = util::align(self.len, align_start); -        } -        let offset = self.len; -        self.len += len; -        offset -    } - -    /// Write alignment padding bytes. -    pub fn write_align(&mut self, align_start: usize) { -        if align_start > 1 { -            util::write_align(self.buffer, align_start); -        } -    } - -    /// Write data. -    /// -    /// This is typically used to write section data. -    pub fn write(&mut self, data: &[u8]) { -        self.buffer.write_bytes(data); -    } - -    /// Reserve the file range up to the given file offset. -    pub fn reserve_until(&mut self, offset: usize) { -        debug_assert!(self.len <= offset); -        self.len = offset; -    } - -    /// Write padding up to the given file offset. -    pub fn pad_until(&mut self, offset: usize) { -        debug_assert!(self.buffer.len() <= offset); -        self.buffer.resize(offset); -    } - -    fn file_header_size(&self) -> usize { -        if self.is_64 { -            mem::size_of::<elf::FileHeader64<Endianness>>() -        } else { -            mem::size_of::<elf::FileHeader32<Endianness>>() -        } -    } - -    /// Reserve the range for the file header. -    /// -    /// This must be at the start of the file. -    pub fn reserve_file_header(&mut self) { -        debug_assert_eq!(self.len, 0); -        self.reserve(self.file_header_size(), 1); -    } - -    /// Write the file header. -    /// -    /// This must be at the start of the file. -    /// -    /// Fields that can be derived from known information are automatically set by this function. -    pub fn write_file_header(&mut self, header: &FileHeader) -> Result<()> { -        debug_assert_eq!(self.buffer.len(), 0); - -        self.is_mips64el = -            self.is_64 && self.endian.is_little_endian() && header.e_machine == elf::EM_MIPS; - -        // Start writing. -        self.buffer -            .reserve(self.len) -            .map_err(|_| Error(String::from("Cannot allocate buffer")))?; - -        // Write file header. -        let e_ident = elf::Ident { -            magic: elf::ELFMAG, -            class: if self.is_64 { -                elf::ELFCLASS64 -            } else { -                elf::ELFCLASS32 -            }, -            data: if self.endian.is_little_endian() { -                elf::ELFDATA2LSB -            } else { -                elf::ELFDATA2MSB -            }, -            version: elf::EV_CURRENT, -            os_abi: header.os_abi, -            abi_version: header.abi_version, -            padding: [0; 7], -        }; - -        let e_ehsize = self.file_header_size() as u16; - -        let e_phoff = self.segment_offset as u64; -        let e_phentsize = if self.segment_num == 0 { -            0 -        } else { -            self.program_header_size() as u16 -        }; -        // TODO: overflow -        let e_phnum = self.segment_num as u16; - -        let e_shoff = self.section_offset as u64; -        let e_shentsize = if self.section_num == 0 { -            0 -        } else { -            self.section_header_size() as u16 -        }; -        let e_shnum = if self.section_num >= elf::SHN_LORESERVE.into() { -            0 -        } else { -            self.section_num as u16 -        }; -        let e_shstrndx = if self.shstrtab_index.0 >= elf::SHN_LORESERVE.into() { -            elf::SHN_XINDEX -        } else { -            self.shstrtab_index.0 as u16 -        }; - -        let endian = self.endian; -        if self.is_64 { -            let file = elf::FileHeader64 { -                e_ident, -                e_type: U16::new(endian, header.e_type), -                e_machine: U16::new(endian, header.e_machine), -                e_version: U32::new(endian, elf::EV_CURRENT.into()), -                e_entry: U64::new(endian, header.e_entry), -                e_phoff: U64::new(endian, e_phoff), -                e_shoff: U64::new(endian, e_shoff), -                e_flags: U32::new(endian, header.e_flags), -                e_ehsize: U16::new(endian, e_ehsize), -                e_phentsize: U16::new(endian, e_phentsize), -                e_phnum: U16::new(endian, e_phnum), -                e_shentsize: U16::new(endian, e_shentsize), -                e_shnum: U16::new(endian, e_shnum), -                e_shstrndx: U16::new(endian, e_shstrndx), -            }; -            self.buffer.write(&file) -        } else { -            let file = elf::FileHeader32 { -                e_ident, -                e_type: U16::new(endian, header.e_type), -                e_machine: U16::new(endian, header.e_machine), -                e_version: U32::new(endian, elf::EV_CURRENT.into()), -                e_entry: U32::new(endian, header.e_entry as u32), -                e_phoff: U32::new(endian, e_phoff as u32), -                e_shoff: U32::new(endian, e_shoff as u32), -                e_flags: U32::new(endian, header.e_flags), -                e_ehsize: U16::new(endian, e_ehsize), -                e_phentsize: U16::new(endian, e_phentsize), -                e_phnum: U16::new(endian, e_phnum), -                e_shentsize: U16::new(endian, e_shentsize), -                e_shnum: U16::new(endian, e_shnum), -                e_shstrndx: U16::new(endian, e_shstrndx), -            }; -            self.buffer.write(&file); -        } - -        Ok(()) -    } - -    fn program_header_size(&self) -> usize { -        if self.is_64 { -            mem::size_of::<elf::ProgramHeader64<Endianness>>() -        } else { -            mem::size_of::<elf::ProgramHeader32<Endianness>>() -        } -    } - -    /// Reserve the range for the program headers. -    pub fn reserve_program_headers(&mut self, num: u32) { -        debug_assert_eq!(self.segment_offset, 0); -        if num == 0 { -            return; -        } -        self.segment_num = num; -        self.segment_offset = -            self.reserve(num as usize * self.program_header_size(), self.elf_align); -    } - -    /// Write alignment padding bytes prior to the program headers. -    pub fn write_align_program_headers(&mut self) { -        if self.segment_offset == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.segment_offset, self.buffer.len()); -    } - -    /// Write a program header. -    pub fn write_program_header(&mut self, header: &ProgramHeader) { -        let endian = self.endian; -        if self.is_64 { -            let header = elf::ProgramHeader64 { -                p_type: U32::new(endian, header.p_type), -                p_flags: U32::new(endian, header.p_flags), -                p_offset: U64::new(endian, header.p_offset), -                p_vaddr: U64::new(endian, header.p_vaddr), -                p_paddr: U64::new(endian, header.p_paddr), -                p_filesz: U64::new(endian, header.p_filesz), -                p_memsz: U64::new(endian, header.p_memsz), -                p_align: U64::new(endian, header.p_align), -            }; -            self.buffer.write(&header); -        } else { -            let header = elf::ProgramHeader32 { -                p_type: U32::new(endian, header.p_type), -                p_offset: U32::new(endian, header.p_offset as u32), -                p_vaddr: U32::new(endian, header.p_vaddr as u32), -                p_paddr: U32::new(endian, header.p_paddr as u32), -                p_filesz: U32::new(endian, header.p_filesz as u32), -                p_memsz: U32::new(endian, header.p_memsz as u32), -                p_flags: U32::new(endian, header.p_flags), -                p_align: U32::new(endian, header.p_align as u32), -            }; -            self.buffer.write(&header); -        } -    } - -    /// Reserve the section index for the null section header. -    /// -    /// The null section header is usually automatically reserved, -    /// but this can be used to force an empty section table. -    /// -    /// This must be called before [`Self::reserve_section_headers`]. -    pub fn reserve_null_section_index(&mut self) -> SectionIndex { -        debug_assert_eq!(self.section_num, 0); -        if self.section_num == 0 { -            self.section_num = 1; -        } -        SectionIndex(0) -    } - -    /// Reserve a section table index. -    /// -    /// Automatically also reserves the null section header if required. -    /// -    /// This must be called before [`Self::reserve_section_headers`]. -    pub fn reserve_section_index(&mut self) -> SectionIndex { -        debug_assert_eq!(self.section_offset, 0); -        if self.section_num == 0 { -            self.section_num = 1; -        } -        let index = self.section_num; -        self.section_num += 1; -        SectionIndex(index) -    } - -    fn section_header_size(&self) -> usize { -        if self.is_64 { -            mem::size_of::<elf::SectionHeader64<Endianness>>() -        } else { -            mem::size_of::<elf::SectionHeader32<Endianness>>() -        } -    } - -    /// Reserve the range for the section headers. -    /// -    /// This function does nothing if no sections were reserved. -    /// This must be called after [`Self::reserve_section_index`] -    /// and other functions that reserve section indices. -    pub fn reserve_section_headers(&mut self) { -        debug_assert_eq!(self.section_offset, 0); -        if self.section_num == 0 { -            return; -        } -        self.section_offset = self.reserve( -            self.section_num as usize * self.section_header_size(), -            self.elf_align, -        ); -    } - -    /// Write the null section header. -    /// -    /// This must be the first section header that is written. -    /// This function does nothing if no sections were reserved. -    pub fn write_null_section_header(&mut self) { -        if self.section_num == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.section_offset, self.buffer.len()); -        self.write_section_header(&SectionHeader { -            name: None, -            sh_type: 0, -            sh_flags: 0, -            sh_addr: 0, -            sh_offset: 0, -            sh_size: if self.section_num >= elf::SHN_LORESERVE.into() { -                self.section_num.into() -            } else { -                0 -            }, -            sh_link: if self.shstrtab_index.0 >= elf::SHN_LORESERVE.into() { -                self.shstrtab_index.0 -            } else { -                0 -            }, -            // TODO: e_phnum overflow -            sh_info: 0, -            sh_addralign: 0, -            sh_entsize: 0, -        }); -    } - -    /// Write a section header. -    pub fn write_section_header(&mut self, section: &SectionHeader) { -        let sh_name = if let Some(name) = section.name { -            self.shstrtab.get_offset(name) as u32 -        } else { -            0 -        }; -        let endian = self.endian; -        if self.is_64 { -            let section = elf::SectionHeader64 { -                sh_name: U32::new(endian, sh_name), -                sh_type: U32::new(endian, section.sh_type), -                sh_flags: U64::new(endian, section.sh_flags), -                sh_addr: U64::new(endian, section.sh_addr), -                sh_offset: U64::new(endian, section.sh_offset), -                sh_size: U64::new(endian, section.sh_size), -                sh_link: U32::new(endian, section.sh_link), -                sh_info: U32::new(endian, section.sh_info), -                sh_addralign: U64::new(endian, section.sh_addralign), -                sh_entsize: U64::new(endian, section.sh_entsize), -            }; -            self.buffer.write(§ion); -        } else { -            let section = elf::SectionHeader32 { -                sh_name: U32::new(endian, sh_name), -                sh_type: U32::new(endian, section.sh_type), -                sh_flags: U32::new(endian, section.sh_flags as u32), -                sh_addr: U32::new(endian, section.sh_addr as u32), -                sh_offset: U32::new(endian, section.sh_offset as u32), -                sh_size: U32::new(endian, section.sh_size as u32), -                sh_link: U32::new(endian, section.sh_link), -                sh_info: U32::new(endian, section.sh_info), -                sh_addralign: U32::new(endian, section.sh_addralign as u32), -                sh_entsize: U32::new(endian, section.sh_entsize as u32), -            }; -            self.buffer.write(§ion); -        } -    } - -    /// Add a section name to the section header string table. -    /// -    /// This will be stored in the `.shstrtab` section. -    /// -    /// This must be called before [`Self::reserve_shstrtab`]. -    pub fn add_section_name(&mut self, name: &'a [u8]) -> StringId { -        debug_assert_eq!(self.shstrtab_offset, 0); -        self.shstrtab.add(name) -    } - -    /// Reserve the range for the section header string table. -    /// -    /// This range is used for a section named `.shstrtab`. -    /// -    /// This function does nothing if no sections were reserved. -    /// This must be called after [`Self::add_section_name`]. -    /// and other functions that reserve section names and indices. -    pub fn reserve_shstrtab(&mut self) { -        debug_assert_eq!(self.shstrtab_offset, 0); -        if self.section_num == 0 { -            return; -        } -        // Start with null section name. -        self.shstrtab_data = vec![0]; -        self.shstrtab.write(1, &mut self.shstrtab_data); -        self.shstrtab_offset = self.reserve(self.shstrtab_data.len(), 1); -    } - -    /// Write the section header string table. -    /// -    /// This function does nothing if the section was not reserved. -    pub fn write_shstrtab(&mut self) { -        if self.shstrtab_offset == 0 { -            return; -        } -        debug_assert_eq!(self.shstrtab_offset, self.buffer.len()); -        self.buffer.write_bytes(&self.shstrtab_data); -    } - -    /// Reserve the section index for the section header string table. -    /// -    /// This must be called before [`Self::reserve_shstrtab`] -    /// and [`Self::reserve_section_headers`]. -    pub fn reserve_shstrtab_section_index(&mut self) -> SectionIndex { -        debug_assert_eq!(self.shstrtab_index, SectionIndex(0)); -        self.shstrtab_str_id = Some(self.add_section_name(&b".shstrtab"[..])); -        self.shstrtab_index = self.reserve_section_index(); -        self.shstrtab_index -    } - -    /// Write the section header for the section header string table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_shstrtab_section_header(&mut self) { -        if self.shstrtab_index == SectionIndex(0) { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.shstrtab_str_id, -            sh_type: elf::SHT_STRTAB, -            sh_flags: 0, -            sh_addr: 0, -            sh_offset: self.shstrtab_offset as u64, -            sh_size: self.shstrtab_data.len() as u64, -            sh_link: 0, -            sh_info: 0, -            sh_addralign: 1, -            sh_entsize: 0, -        }); -    } - -    /// Add a string to the string table. -    /// -    /// This will be stored in the `.strtab` section. -    /// -    /// This must be called before [`Self::reserve_strtab`]. -    pub fn add_string(&mut self, name: &'a [u8]) -> StringId { -        debug_assert_eq!(self.strtab_offset, 0); -        self.need_strtab = true; -        self.strtab.add(name) -    } - -    /// Return true if `.strtab` is needed. -    pub fn strtab_needed(&self) -> bool { -        self.need_strtab -    } - -    /// Reserve the range for the string table. -    /// -    /// This range is used for a section named `.strtab`. -    /// -    /// This function does nothing if no strings or symbols were defined. -    /// This must be called after [`Self::add_string`]. -    pub fn reserve_strtab(&mut self) { -        debug_assert_eq!(self.strtab_offset, 0); -        if !self.need_strtab { -            return; -        } -        // Start with null string. -        self.strtab_data = vec![0]; -        self.strtab.write(1, &mut self.strtab_data); -        self.strtab_offset = self.reserve(self.strtab_data.len(), 1); -    } - -    /// Write the string table. -    /// -    /// This function does nothing if the section was not reserved. -    pub fn write_strtab(&mut self) { -        if self.strtab_offset == 0 { -            return; -        } -        debug_assert_eq!(self.strtab_offset, self.buffer.len()); -        self.buffer.write_bytes(&self.strtab_data); -    } - -    /// Reserve the section index for the string table. -    /// -    /// This must be called before [`Self::reserve_section_headers`]. -    pub fn reserve_strtab_section_index(&mut self) -> SectionIndex { -        debug_assert_eq!(self.strtab_index, SectionIndex(0)); -        self.strtab_str_id = Some(self.add_section_name(&b".strtab"[..])); -        self.strtab_index = self.reserve_section_index(); -        self.strtab_index -    } - -    /// Write the section header for the string table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_strtab_section_header(&mut self) { -        if self.strtab_index == SectionIndex(0) { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.strtab_str_id, -            sh_type: elf::SHT_STRTAB, -            sh_flags: 0, -            sh_addr: 0, -            sh_offset: self.strtab_offset as u64, -            sh_size: self.strtab_data.len() as u64, -            sh_link: 0, -            sh_info: 0, -            sh_addralign: 1, -            sh_entsize: 0, -        }); -    } - -    /// Reserve the null symbol table entry. -    /// -    /// This will be stored in the `.symtab` section. -    /// -    /// The null symbol table entry is usually automatically reserved, -    /// but this can be used to force an empty symbol table. -    /// -    /// This must be called before [`Self::reserve_symtab`]. -    pub fn reserve_null_symbol_index(&mut self) -> SymbolIndex { -        debug_assert_eq!(self.symtab_offset, 0); -        debug_assert_eq!(self.symtab_num, 0); -        self.symtab_num = 1; -        // The symtab must link to a strtab. -        self.need_strtab = true; -        SymbolIndex(0) -    } - -    /// Reserve a symbol table entry. -    /// -    /// This will be stored in the `.symtab` section. -    /// -    /// `section_index` is used to determine whether `.symtab_shndx` is required. -    /// -    /// Automatically also reserves the null symbol if required. -    /// Callers may assume that the returned indices will be sequential -    /// starting at 1. -    /// -    /// This must be called before [`Self::reserve_symtab`] and -    /// [`Self::reserve_symtab_shndx`]. -    pub fn reserve_symbol_index(&mut self, section_index: Option<SectionIndex>) -> SymbolIndex { -        debug_assert_eq!(self.symtab_offset, 0); -        debug_assert_eq!(self.symtab_shndx_offset, 0); -        if self.symtab_num == 0 { -            self.symtab_num = 1; -            // The symtab must link to a strtab. -            self.need_strtab = true; -        } -        let index = self.symtab_num; -        self.symtab_num += 1; -        if let Some(section_index) = section_index { -            if section_index.0 >= elf::SHN_LORESERVE.into() { -                self.need_symtab_shndx = true; -            } -        } -        SymbolIndex(index) -    } - -    /// Return the number of reserved symbol table entries. -    /// -    /// Includes the null symbol. -    pub fn symbol_count(&self) -> u32 { -        self.symtab_num -    } - -    fn symbol_size(&self) -> usize { -        if self.is_64 { -            mem::size_of::<elf::Sym64<Endianness>>() -        } else { -            mem::size_of::<elf::Sym32<Endianness>>() -        } -    } - -    /// Reserve the range for the symbol table. -    /// -    /// This range is used for a section named `.symtab`. -    /// This function does nothing if no symbols were reserved. -    /// This must be called after [`Self::reserve_symbol_index`]. -    pub fn reserve_symtab(&mut self) { -        debug_assert_eq!(self.symtab_offset, 0); -        if self.symtab_num == 0 { -            return; -        } -        self.symtab_offset = self.reserve( -            self.symtab_num as usize * self.symbol_size(), -            self.elf_align, -        ); -    } - -    /// Write the null symbol. -    /// -    /// This must be the first symbol that is written. -    /// This function does nothing if no symbols were reserved. -    pub fn write_null_symbol(&mut self) { -        if self.symtab_num == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.symtab_offset, self.buffer.len()); -        if self.is_64 { -            self.buffer.write(&elf::Sym64::<Endianness>::default()); -        } else { -            self.buffer.write(&elf::Sym32::<Endianness>::default()); -        } - -        if self.need_symtab_shndx { -            self.symtab_shndx_data.write_pod(&U32::new(self.endian, 0)); -        } -    } - -    /// Write a symbol. -    pub fn write_symbol(&mut self, sym: &Sym) { -        let st_name = if let Some(name) = sym.name { -            self.strtab.get_offset(name) as u32 -        } else { -            0 -        }; -        let st_shndx = if let Some(section) = sym.section { -            if section.0 >= elf::SHN_LORESERVE as u32 { -                elf::SHN_XINDEX -            } else { -                section.0 as u16 -            } -        } else { -            sym.st_shndx -        }; - -        let endian = self.endian; -        if self.is_64 { -            let sym = elf::Sym64 { -                st_name: U32::new(endian, st_name), -                st_info: sym.st_info, -                st_other: sym.st_other, -                st_shndx: U16::new(endian, st_shndx), -                st_value: U64::new(endian, sym.st_value), -                st_size: U64::new(endian, sym.st_size), -            }; -            self.buffer.write(&sym); -        } else { -            let sym = elf::Sym32 { -                st_name: U32::new(endian, st_name), -                st_info: sym.st_info, -                st_other: sym.st_other, -                st_shndx: U16::new(endian, st_shndx), -                st_value: U32::new(endian, sym.st_value as u32), -                st_size: U32::new(endian, sym.st_size as u32), -            }; -            self.buffer.write(&sym); -        } - -        if self.need_symtab_shndx { -            let section_index = sym.section.unwrap_or(SectionIndex(0)); -            self.symtab_shndx_data -                .write_pod(&U32::new(self.endian, section_index.0)); -        } -    } - -    /// Reserve the section index for the symbol table. -    /// -    /// This must be called before [`Self::reserve_section_headers`]. -    pub fn reserve_symtab_section_index(&mut self) -> SectionIndex { -        debug_assert_eq!(self.symtab_index, SectionIndex(0)); -        self.symtab_str_id = Some(self.add_section_name(&b".symtab"[..])); -        self.symtab_index = self.reserve_section_index(); -        self.symtab_index -    } - -    /// Return the section index of the symbol table. -    pub fn symtab_index(&mut self) -> SectionIndex { -        self.symtab_index -    } - -    /// Write the section header for the symbol table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_symtab_section_header(&mut self, num_local: u32) { -        if self.symtab_index == SectionIndex(0) { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.symtab_str_id, -            sh_type: elf::SHT_SYMTAB, -            sh_flags: 0, -            sh_addr: 0, -            sh_offset: self.symtab_offset as u64, -            sh_size: self.symtab_num as u64 * self.symbol_size() as u64, -            sh_link: self.strtab_index.0, -            sh_info: num_local, -            sh_addralign: self.elf_align as u64, -            sh_entsize: self.symbol_size() as u64, -        }); -    } - -    /// Return true if `.symtab_shndx` is needed. -    pub fn symtab_shndx_needed(&self) -> bool { -        self.need_symtab_shndx -    } - -    /// Reserve the range for the extended section indices for the symbol table. -    /// -    /// This range is used for a section named `.symtab_shndx`. -    /// This also reserves a section index. -    /// -    /// This function does nothing if extended section indices are not needed. -    /// This must be called after [`Self::reserve_symbol_index`]. -    pub fn reserve_symtab_shndx(&mut self) { -        debug_assert_eq!(self.symtab_shndx_offset, 0); -        if !self.need_symtab_shndx { -            return; -        } -        self.symtab_shndx_offset = self.reserve(self.symtab_num as usize * 4, 4); -        self.symtab_shndx_data.reserve(self.symtab_num as usize * 4); -    } - -    /// Write the extended section indices for the symbol table. -    /// -    /// This function does nothing if the section was not reserved. -    pub fn write_symtab_shndx(&mut self) { -        if self.symtab_shndx_offset == 0 { -            return; -        } -        debug_assert_eq!(self.symtab_shndx_offset, self.buffer.len()); -        debug_assert_eq!(self.symtab_num as usize * 4, self.symtab_shndx_data.len()); -        self.buffer.write_bytes(&self.symtab_shndx_data); -    } - -    /// Reserve the section index for the extended section indices symbol table. -    /// -    /// You should check [`Self::symtab_shndx_needed`] before calling this -    /// unless you have other means of knowing if this section is needed. -    /// -    /// This must be called before [`Self::reserve_section_headers`]. -    pub fn reserve_symtab_shndx_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.symtab_shndx_str_id.is_none()); -        self.symtab_shndx_str_id = Some(self.add_section_name(&b".symtab_shndx"[..])); -        self.reserve_section_index() -    } - -    /// Write the section header for the extended section indices for the symbol table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_symtab_shndx_section_header(&mut self) { -        if self.symtab_shndx_str_id.is_none() { -            return; -        } -        let sh_size = if self.symtab_shndx_offset == 0 { -            0 -        } else { -            (self.symtab_num * 4) as u64 -        }; -        self.write_section_header(&SectionHeader { -            name: self.symtab_shndx_str_id, -            sh_type: elf::SHT_SYMTAB_SHNDX, -            sh_flags: 0, -            sh_addr: 0, -            sh_offset: self.symtab_shndx_offset as u64, -            sh_size, -            sh_link: self.symtab_index.0, -            sh_info: 0, -            sh_addralign: 4, -            sh_entsize: 4, -        }); -    } - -    /// Add a string to the dynamic string table. -    /// -    /// This will be stored in the `.dynstr` section. -    /// -    /// This must be called before [`Self::reserve_dynstr`]. -    pub fn add_dynamic_string(&mut self, name: &'a [u8]) -> StringId { -        debug_assert_eq!(self.dynstr_offset, 0); -        self.need_dynstr = true; -        self.dynstr.add(name) -    } - -    /// Get a string that was previously added to the dynamic string table. -    /// -    /// Panics if the string was not added. -    pub fn get_dynamic_string(&self, name: &'a [u8]) -> StringId { -        self.dynstr.get_id(name) -    } - -    /// Return true if `.dynstr` is needed. -    pub fn dynstr_needed(&self) -> bool { -        self.need_dynstr -    } - -    /// Reserve the range for the dynamic string table. -    /// -    /// This range is used for a section named `.dynstr`. -    /// -    /// This function does nothing if no dynamic strings or symbols were defined. -    /// This must be called after [`Self::add_dynamic_string`]. -    pub fn reserve_dynstr(&mut self) { -        debug_assert_eq!(self.dynstr_offset, 0); -        if !self.need_dynstr { -            return; -        } -        // Start with null string. -        self.dynstr_data = vec![0]; -        self.dynstr.write(1, &mut self.dynstr_data); -        self.dynstr_offset = self.reserve(self.dynstr_data.len(), 1); -    } - -    /// Write the dynamic string table. -    /// -    /// This function does nothing if the section was not reserved. -    pub fn write_dynstr(&mut self) { -        if self.dynstr_offset == 0 { -            return; -        } -        debug_assert_eq!(self.dynstr_offset, self.buffer.len()); -        self.buffer.write_bytes(&self.dynstr_data); -    } - -    /// Reserve the section index for the dynamic string table. -    /// -    /// This must be called before [`Self::reserve_section_headers`]. -    pub fn reserve_dynstr_section_index(&mut self) -> SectionIndex { -        debug_assert_eq!(self.dynstr_index, SectionIndex(0)); -        self.dynstr_str_id = Some(self.add_section_name(&b".dynstr"[..])); -        self.dynstr_index = self.reserve_section_index(); -        self.dynstr_index -    } - -    /// Return the section index of the dynamic string table. -    pub fn dynstr_index(&mut self) -> SectionIndex { -        self.dynstr_index -    } - -    /// Write the section header for the dynamic string table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_dynstr_section_header(&mut self, sh_addr: u64) { -        if self.dynstr_index == SectionIndex(0) { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.dynstr_str_id, -            sh_type: elf::SHT_STRTAB, -            sh_flags: elf::SHF_ALLOC.into(), -            sh_addr, -            sh_offset: self.dynstr_offset as u64, -            sh_size: self.dynstr_data.len() as u64, -            sh_link: 0, -            sh_info: 0, -            sh_addralign: 1, -            sh_entsize: 0, -        }); -    } - -    /// Reserve the null dynamic symbol table entry. -    /// -    /// This will be stored in the `.dynsym` section. -    /// -    /// The null dynamic symbol table entry is usually automatically reserved, -    /// but this can be used to force an empty dynamic symbol table. -    /// -    /// This must be called before [`Self::reserve_dynsym`]. -    pub fn reserve_null_dynamic_symbol_index(&mut self) -> SymbolIndex { -        debug_assert_eq!(self.dynsym_offset, 0); -        debug_assert_eq!(self.dynsym_num, 0); -        self.dynsym_num = 1; -        // The symtab must link to a strtab. -        self.need_dynstr = true; -        SymbolIndex(0) -    } - -    /// Reserve a dynamic symbol table entry. -    /// -    /// This will be stored in the `.dynsym` section. -    /// -    /// Automatically also reserves the null symbol if required. -    /// Callers may assume that the returned indices will be sequential -    /// starting at 1. -    /// -    /// This must be called before [`Self::reserve_dynsym`]. -    pub fn reserve_dynamic_symbol_index(&mut self) -> SymbolIndex { -        debug_assert_eq!(self.dynsym_offset, 0); -        if self.dynsym_num == 0 { -            self.dynsym_num = 1; -            // The symtab must link to a strtab. -            self.need_dynstr = true; -        } -        let index = self.dynsym_num; -        self.dynsym_num += 1; -        SymbolIndex(index) -    } - -    /// Return the number of reserved dynamic symbols. -    /// -    /// Includes the null symbol. -    pub fn dynamic_symbol_count(&mut self) -> u32 { -        self.dynsym_num -    } - -    /// Reserve the range for the dynamic symbol table. -    /// -    /// This range is used for a section named `.dynsym`. -    /// -    /// This function does nothing if no dynamic symbols were reserved. -    /// This must be called after [`Self::reserve_dynamic_symbol_index`]. -    pub fn reserve_dynsym(&mut self) { -        debug_assert_eq!(self.dynsym_offset, 0); -        if self.dynsym_num == 0 { -            return; -        } -        self.dynsym_offset = self.reserve( -            self.dynsym_num as usize * self.symbol_size(), -            self.elf_align, -        ); -    } - -    /// Write the null dynamic symbol. -    /// -    /// This must be the first dynamic symbol that is written. -    /// This function does nothing if no dynamic symbols were reserved. -    pub fn write_null_dynamic_symbol(&mut self) { -        if self.dynsym_num == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.dynsym_offset, self.buffer.len()); -        if self.is_64 { -            self.buffer.write(&elf::Sym64::<Endianness>::default()); -        } else { -            self.buffer.write(&elf::Sym32::<Endianness>::default()); -        } -    } - -    /// Write a dynamic symbol. -    pub fn write_dynamic_symbol(&mut self, sym: &Sym) { -        let st_name = if let Some(name) = sym.name { -            self.dynstr.get_offset(name) as u32 -        } else { -            0 -        }; - -        let st_shndx = if let Some(section) = sym.section { -            if section.0 >= elf::SHN_LORESERVE as u32 { -                // TODO: we don't actually write out .dynsym_shndx yet. -                // This is unlikely to be needed though. -                elf::SHN_XINDEX -            } else { -                section.0 as u16 -            } -        } else { -            sym.st_shndx -        }; - -        let endian = self.endian; -        if self.is_64 { -            let sym = elf::Sym64 { -                st_name: U32::new(endian, st_name), -                st_info: sym.st_info, -                st_other: sym.st_other, -                st_shndx: U16::new(endian, st_shndx), -                st_value: U64::new(endian, sym.st_value), -                st_size: U64::new(endian, sym.st_size), -            }; -            self.buffer.write(&sym); -        } else { -            let sym = elf::Sym32 { -                st_name: U32::new(endian, st_name), -                st_info: sym.st_info, -                st_other: sym.st_other, -                st_shndx: U16::new(endian, st_shndx), -                st_value: U32::new(endian, sym.st_value as u32), -                st_size: U32::new(endian, sym.st_size as u32), -            }; -            self.buffer.write(&sym); -        } -    } - -    /// Reserve the section index for the dynamic symbol table. -    /// -    /// This must be called before [`Self::reserve_section_headers`]. -    pub fn reserve_dynsym_section_index(&mut self) -> SectionIndex { -        debug_assert_eq!(self.dynsym_index, SectionIndex(0)); -        self.dynsym_str_id = Some(self.add_section_name(&b".dynsym"[..])); -        self.dynsym_index = self.reserve_section_index(); -        self.dynsym_index -    } - -    /// Return the section index of the dynamic symbol table. -    pub fn dynsym_index(&mut self) -> SectionIndex { -        self.dynsym_index -    } - -    /// Write the section header for the dynamic symbol table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_dynsym_section_header(&mut self, sh_addr: u64, num_local: u32) { -        if self.dynsym_index == SectionIndex(0) { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.dynsym_str_id, -            sh_type: elf::SHT_DYNSYM, -            sh_flags: elf::SHF_ALLOC.into(), -            sh_addr, -            sh_offset: self.dynsym_offset as u64, -            sh_size: self.dynsym_num as u64 * self.symbol_size() as u64, -            sh_link: self.dynstr_index.0, -            sh_info: num_local, -            sh_addralign: self.elf_align as u64, -            sh_entsize: self.symbol_size() as u64, -        }); -    } - -    fn dyn_size(&self) -> usize { -        if self.is_64 { -            mem::size_of::<elf::Dyn64<Endianness>>() -        } else { -            mem::size_of::<elf::Dyn32<Endianness>>() -        } -    } - -    /// Reserve the range for the `.dynamic` section. -    /// -    /// This function does nothing if `dynamic_num` is zero. -    pub fn reserve_dynamic(&mut self, dynamic_num: usize) { -        debug_assert_eq!(self.dynamic_offset, 0); -        if dynamic_num == 0 { -            return; -        } -        self.dynamic_num = dynamic_num; -        self.dynamic_offset = self.reserve(dynamic_num * self.dyn_size(), self.elf_align); -    } - -    /// Write alignment padding bytes prior to the `.dynamic` section. -    /// -    /// This function does nothing if the section was not reserved. -    pub fn write_align_dynamic(&mut self) { -        if self.dynamic_offset == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.dynamic_offset, self.buffer.len()); -    } - -    /// Write a dynamic string entry. -    pub fn write_dynamic_string(&mut self, tag: u32, id: StringId) { -        self.write_dynamic(tag, self.dynstr.get_offset(id) as u64); -    } - -    /// Write a dynamic value entry. -    pub fn write_dynamic(&mut self, d_tag: u32, d_val: u64) { -        debug_assert!(self.dynamic_offset <= self.buffer.len()); -        let endian = self.endian; -        if self.is_64 { -            let d = elf::Dyn64 { -                d_tag: U64::new(endian, d_tag.into()), -                d_val: U64::new(endian, d_val), -            }; -            self.buffer.write(&d); -        } else { -            let d = elf::Dyn32 { -                d_tag: U32::new(endian, d_tag), -                d_val: U32::new(endian, d_val as u32), -            }; -            self.buffer.write(&d); -        } -        debug_assert!( -            self.dynamic_offset + self.dynamic_num * self.dyn_size() >= self.buffer.len() -        ); -    } - -    /// Reserve the section index for the dynamic table. -    pub fn reserve_dynamic_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.dynamic_str_id.is_none()); -        self.dynamic_str_id = Some(self.add_section_name(&b".dynamic"[..])); -        self.reserve_section_index() -    } - -    /// Write the section header for the dynamic table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_dynamic_section_header(&mut self, sh_addr: u64) { -        if self.dynamic_str_id.is_none() { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.dynamic_str_id, -            sh_type: elf::SHT_DYNAMIC, -            sh_flags: (elf::SHF_WRITE | elf::SHF_ALLOC).into(), -            sh_addr, -            sh_offset: self.dynamic_offset as u64, -            sh_size: (self.dynamic_num * self.dyn_size()) as u64, -            sh_link: self.dynstr_index.0, -            sh_info: 0, -            sh_addralign: self.elf_align as u64, -            sh_entsize: self.dyn_size() as u64, -        }); -    } - -    fn rel_size(&self, is_rela: bool) -> usize { -        if self.is_64 { -            if is_rela { -                mem::size_of::<elf::Rela64<Endianness>>() -            } else { -                mem::size_of::<elf::Rel64<Endianness>>() -            } -        } else { -            if is_rela { -                mem::size_of::<elf::Rela32<Endianness>>() -            } else { -                mem::size_of::<elf::Rel32<Endianness>>() -            } -        } -    } - -    /// Reserve a file range for a SysV hash section. -    /// -    /// `symbol_count` is the number of symbols in the hash, -    /// not the total number of symbols. -    pub fn reserve_hash(&mut self, bucket_count: u32, chain_count: u32) { -        self.hash_size = mem::size_of::<elf::HashHeader<Endianness>>() -            + bucket_count as usize * 4 -            + chain_count as usize * 4; -        self.hash_offset = self.reserve(self.hash_size, self.elf_align); -    } - -    /// Write a SysV hash section. -    /// -    /// `chain_count` is the number of symbols in the hash. -    /// The argument to `hash` will be in the range `0..chain_count`. -    pub fn write_hash<F>(&mut self, bucket_count: u32, chain_count: u32, hash: F) -    where -        F: Fn(u32) -> Option<u32>, -    { -        let mut buckets = vec![U32::new(self.endian, 0); bucket_count as usize]; -        let mut chains = vec![U32::new(self.endian, 0); chain_count as usize]; -        for i in 0..chain_count { -            if let Some(hash) = hash(i) { -                let bucket = hash % bucket_count; -                chains[i as usize] = buckets[bucket as usize]; -                buckets[bucket as usize] = U32::new(self.endian, i); -            } -        } - -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.hash_offset, self.buffer.len()); -        self.buffer.write(&elf::HashHeader { -            bucket_count: U32::new(self.endian, bucket_count), -            chain_count: U32::new(self.endian, chain_count), -        }); -        self.buffer.write_slice(&buckets); -        self.buffer.write_slice(&chains); -    } - -    /// Reserve the section index for the SysV hash table. -    pub fn reserve_hash_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.hash_str_id.is_none()); -        self.hash_str_id = Some(self.add_section_name(&b".hash"[..])); -        self.reserve_section_index() -    } - -    /// Write the section header for the SysV hash table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_hash_section_header(&mut self, sh_addr: u64) { -        if self.hash_str_id.is_none() { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.hash_str_id, -            sh_type: elf::SHT_HASH, -            sh_flags: elf::SHF_ALLOC.into(), -            sh_addr, -            sh_offset: self.hash_offset as u64, -            sh_size: self.hash_size as u64, -            sh_link: self.dynsym_index.0, -            sh_info: 0, -            sh_addralign: self.elf_align as u64, -            sh_entsize: 4, -        }); -    } - -    /// Reserve a file range for a GNU hash section. -    /// -    /// `symbol_count` is the number of symbols in the hash, -    /// not the total number of symbols. -    pub fn reserve_gnu_hash(&mut self, bloom_count: u32, bucket_count: u32, symbol_count: u32) { -        self.gnu_hash_size = mem::size_of::<elf::GnuHashHeader<Endianness>>() -            + bloom_count as usize * self.elf_align -            + bucket_count as usize * 4 -            + symbol_count as usize * 4; -        self.gnu_hash_offset = self.reserve(self.gnu_hash_size, self.elf_align); -    } - -    /// Write a GNU hash section. -    /// -    /// `symbol_count` is the number of symbols in the hash. -    /// The argument to `hash` will be in the range `0..symbol_count`. -    /// -    /// This requires that symbols are already sorted by bucket. -    pub fn write_gnu_hash<F>( -        &mut self, -        symbol_base: u32, -        bloom_shift: u32, -        bloom_count: u32, -        bucket_count: u32, -        symbol_count: u32, -        hash: F, -    ) where -        F: Fn(u32) -> u32, -    { -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.gnu_hash_offset, self.buffer.len()); -        self.buffer.write(&elf::GnuHashHeader { -            bucket_count: U32::new(self.endian, bucket_count), -            symbol_base: U32::new(self.endian, symbol_base), -            bloom_count: U32::new(self.endian, bloom_count), -            bloom_shift: U32::new(self.endian, bloom_shift), -        }); - -        // Calculate and write bloom filter. -        if self.is_64 { -            let mut bloom_filters = vec![0; bloom_count as usize]; -            for i in 0..symbol_count { -                let h = hash(i); -                bloom_filters[((h / 64) & (bloom_count - 1)) as usize] |= -                    1 << (h % 64) | 1 << ((h >> bloom_shift) % 64); -            } -            for bloom_filter in bloom_filters { -                self.buffer.write(&U64::new(self.endian, bloom_filter)); -            } -        } else { -            let mut bloom_filters = vec![0; bloom_count as usize]; -            for i in 0..symbol_count { -                let h = hash(i); -                bloom_filters[((h / 32) & (bloom_count - 1)) as usize] |= -                    1 << (h % 32) | 1 << ((h >> bloom_shift) % 32); -            } -            for bloom_filter in bloom_filters { -                self.buffer.write(&U32::new(self.endian, bloom_filter)); -            } -        } - -        // Write buckets. -        // -        // This requires that symbols are already sorted by bucket. -        let mut bucket = 0; -        for i in 0..symbol_count { -            let symbol_bucket = hash(i) % bucket_count; -            while bucket < symbol_bucket { -                self.buffer.write(&U32::new(self.endian, 0)); -                bucket += 1; -            } -            if bucket == symbol_bucket { -                self.buffer.write(&U32::new(self.endian, symbol_base + i)); -                bucket += 1; -            } -        } -        while bucket < bucket_count { -            self.buffer.write(&U32::new(self.endian, 0)); -            bucket += 1; -        } - -        // Write hash values. -        for i in 0..symbol_count { -            let mut h = hash(i); -            if i == symbol_count - 1 || h % bucket_count != hash(i + 1) % bucket_count { -                h |= 1; -            } else { -                h &= !1; -            } -            self.buffer.write(&U32::new(self.endian, h)); -        } -    } - -    /// Reserve the section index for the GNU hash table. -    pub fn reserve_gnu_hash_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.gnu_hash_str_id.is_none()); -        self.gnu_hash_str_id = Some(self.add_section_name(&b".gnu.hash"[..])); -        self.reserve_section_index() -    } - -    /// Write the section header for the GNU hash table. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_gnu_hash_section_header(&mut self, sh_addr: u64) { -        if self.gnu_hash_str_id.is_none() { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.gnu_hash_str_id, -            sh_type: elf::SHT_GNU_HASH, -            sh_flags: elf::SHF_ALLOC.into(), -            sh_addr, -            sh_offset: self.gnu_hash_offset as u64, -            sh_size: self.gnu_hash_size as u64, -            sh_link: self.dynsym_index.0, -            sh_info: 0, -            sh_addralign: self.elf_align as u64, -            sh_entsize: 0, -        }); -    } - -    /// Reserve the range for the `.gnu.version` section. -    /// -    /// This function does nothing if no dynamic symbols were reserved. -    pub fn reserve_gnu_versym(&mut self) { -        debug_assert_eq!(self.gnu_versym_offset, 0); -        if self.dynsym_num == 0 { -            return; -        } -        self.gnu_versym_offset = self.reserve(self.dynsym_num as usize * 2, 2); -    } - -    /// Write the null symbol version entry. -    /// -    /// This must be the first symbol version that is written. -    /// This function does nothing if no dynamic symbols were reserved. -    pub fn write_null_gnu_versym(&mut self) { -        if self.dynsym_num == 0 { -            return; -        } -        util::write_align(self.buffer, 2); -        debug_assert_eq!(self.gnu_versym_offset, self.buffer.len()); -        self.write_gnu_versym(0); -    } - -    /// Write a symbol version entry. -    pub fn write_gnu_versym(&mut self, versym: u16) { -        self.buffer.write(&U16::new(self.endian, versym)); -    } - -    /// Reserve the section index for the `.gnu.version` section. -    pub fn reserve_gnu_versym_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.gnu_versym_str_id.is_none()); -        self.gnu_versym_str_id = Some(self.add_section_name(&b".gnu.version"[..])); -        self.reserve_section_index() -    } - -    /// Write the section header for the `.gnu.version` section. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_gnu_versym_section_header(&mut self, sh_addr: u64) { -        if self.gnu_versym_str_id.is_none() { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.gnu_versym_str_id, -            sh_type: elf::SHT_GNU_VERSYM, -            sh_flags: elf::SHF_ALLOC.into(), -            sh_addr, -            sh_offset: self.gnu_versym_offset as u64, -            sh_size: self.dynsym_num as u64 * 2, -            sh_link: self.dynsym_index.0, -            sh_info: 0, -            sh_addralign: 2, -            sh_entsize: 2, -        }); -    } - -    /// Reserve the range for the `.gnu.version_d` section. -    pub fn reserve_gnu_verdef(&mut self, verdef_count: usize, verdaux_count: usize) { -        debug_assert_eq!(self.gnu_verdef_offset, 0); -        if verdef_count == 0 { -            return; -        } -        self.gnu_verdef_size = verdef_count * mem::size_of::<elf::Verdef<Endianness>>() -            + verdaux_count * mem::size_of::<elf::Verdaux<Endianness>>(); -        self.gnu_verdef_offset = self.reserve(self.gnu_verdef_size, self.elf_align); -        self.gnu_verdef_count = verdef_count as u16; -        self.gnu_verdef_remaining = self.gnu_verdef_count; -    } - -    /// Write alignment padding bytes prior to a `.gnu.version_d` section. -    pub fn write_align_gnu_verdef(&mut self) { -        if self.gnu_verdef_offset == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.gnu_verdef_offset, self.buffer.len()); -    } - -    /// Write a version definition entry. -    pub fn write_gnu_verdef(&mut self, verdef: &Verdef) { -        debug_assert_ne!(self.gnu_verdef_remaining, 0); -        self.gnu_verdef_remaining -= 1; -        let vd_next = if self.gnu_verdef_remaining == 0 { -            0 -        } else { -            mem::size_of::<elf::Verdef<Endianness>>() as u32 -                + verdef.aux_count as u32 * mem::size_of::<elf::Verdaux<Endianness>>() as u32 -        }; - -        self.gnu_verdaux_remaining = verdef.aux_count; -        let vd_aux = if verdef.aux_count == 0 { -            0 -        } else { -            mem::size_of::<elf::Verdef<Endianness>>() as u32 -        }; - -        self.buffer.write(&elf::Verdef { -            vd_version: U16::new(self.endian, verdef.version), -            vd_flags: U16::new(self.endian, verdef.flags), -            vd_ndx: U16::new(self.endian, verdef.index), -            vd_cnt: U16::new(self.endian, verdef.aux_count), -            vd_hash: U32::new(self.endian, elf::hash(self.dynstr.get_string(verdef.name))), -            vd_aux: U32::new(self.endian, vd_aux), -            vd_next: U32::new(self.endian, vd_next), -        }); -        self.write_gnu_verdaux(verdef.name); -    } - -    /// Write a version definition auxiliary entry. -    pub fn write_gnu_verdaux(&mut self, name: StringId) { -        debug_assert_ne!(self.gnu_verdaux_remaining, 0); -        self.gnu_verdaux_remaining -= 1; -        let vda_next = if self.gnu_verdaux_remaining == 0 { -            0 -        } else { -            mem::size_of::<elf::Verdaux<Endianness>>() as u32 -        }; -        self.buffer.write(&elf::Verdaux { -            vda_name: U32::new(self.endian, self.dynstr.get_offset(name) as u32), -            vda_next: U32::new(self.endian, vda_next), -        }); -    } - -    /// Reserve the section index for the `.gnu.version_d` section. -    pub fn reserve_gnu_verdef_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.gnu_verdef_str_id.is_none()); -        self.gnu_verdef_str_id = Some(self.add_section_name(&b".gnu.version_d"[..])); -        self.reserve_section_index() -    } - -    /// Write the section header for the `.gnu.version_d` section. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_gnu_verdef_section_header(&mut self, sh_addr: u64) { -        if self.gnu_verdef_str_id.is_none() { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.gnu_verdef_str_id, -            sh_type: elf::SHT_GNU_VERDEF, -            sh_flags: elf::SHF_ALLOC.into(), -            sh_addr, -            sh_offset: self.gnu_verdef_offset as u64, -            sh_size: self.gnu_verdef_size as u64, -            sh_link: self.dynstr_index.0, -            sh_info: self.gnu_verdef_count.into(), -            sh_addralign: self.elf_align as u64, -            sh_entsize: 0, -        }); -    } - -    /// Reserve the range for the `.gnu.version_r` section. -    pub fn reserve_gnu_verneed(&mut self, verneed_count: usize, vernaux_count: usize) { -        debug_assert_eq!(self.gnu_verneed_offset, 0); -        if verneed_count == 0 { -            return; -        } -        self.gnu_verneed_size = verneed_count * mem::size_of::<elf::Verneed<Endianness>>() -            + vernaux_count * mem::size_of::<elf::Vernaux<Endianness>>(); -        self.gnu_verneed_offset = self.reserve(self.gnu_verneed_size, self.elf_align); -        self.gnu_verneed_count = verneed_count as u16; -        self.gnu_verneed_remaining = self.gnu_verneed_count; -    } - -    /// Write alignment padding bytes prior to a `.gnu.version_r` section. -    pub fn write_align_gnu_verneed(&mut self) { -        if self.gnu_verneed_offset == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.gnu_verneed_offset, self.buffer.len()); -    } - -    /// Write a version need entry. -    pub fn write_gnu_verneed(&mut self, verneed: &Verneed) { -        debug_assert_ne!(self.gnu_verneed_remaining, 0); -        self.gnu_verneed_remaining -= 1; -        let vn_next = if self.gnu_verneed_remaining == 0 { -            0 -        } else { -            mem::size_of::<elf::Verneed<Endianness>>() as u32 -                + verneed.aux_count as u32 * mem::size_of::<elf::Vernaux<Endianness>>() as u32 -        }; - -        self.gnu_vernaux_remaining = verneed.aux_count; -        let vn_aux = if verneed.aux_count == 0 { -            0 -        } else { -            mem::size_of::<elf::Verneed<Endianness>>() as u32 -        }; - -        self.buffer.write(&elf::Verneed { -            vn_version: U16::new(self.endian, verneed.version), -            vn_cnt: U16::new(self.endian, verneed.aux_count), -            vn_file: U32::new(self.endian, self.dynstr.get_offset(verneed.file) as u32), -            vn_aux: U32::new(self.endian, vn_aux), -            vn_next: U32::new(self.endian, vn_next), -        }); -    } - -    /// Write a version need auxiliary entry. -    pub fn write_gnu_vernaux(&mut self, vernaux: &Vernaux) { -        debug_assert_ne!(self.gnu_vernaux_remaining, 0); -        self.gnu_vernaux_remaining -= 1; -        let vna_next = if self.gnu_vernaux_remaining == 0 { -            0 -        } else { -            mem::size_of::<elf::Vernaux<Endianness>>() as u32 -        }; -        self.buffer.write(&elf::Vernaux { -            vna_hash: U32::new(self.endian, elf::hash(self.dynstr.get_string(vernaux.name))), -            vna_flags: U16::new(self.endian, vernaux.flags), -            vna_other: U16::new(self.endian, vernaux.index), -            vna_name: U32::new(self.endian, self.dynstr.get_offset(vernaux.name) as u32), -            vna_next: U32::new(self.endian, vna_next), -        }); -    } - -    /// Reserve the section index for the `.gnu.version_r` section. -    pub fn reserve_gnu_verneed_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.gnu_verneed_str_id.is_none()); -        self.gnu_verneed_str_id = Some(self.add_section_name(&b".gnu.version_r"[..])); -        self.reserve_section_index() -    } - -    /// Write the section header for the `.gnu.version_r` section. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_gnu_verneed_section_header(&mut self, sh_addr: u64) { -        if self.gnu_verneed_str_id.is_none() { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.gnu_verneed_str_id, -            sh_type: elf::SHT_GNU_VERNEED, -            sh_flags: elf::SHF_ALLOC.into(), -            sh_addr, -            sh_offset: self.gnu_verneed_offset as u64, -            sh_size: self.gnu_verneed_size as u64, -            sh_link: self.dynstr_index.0, -            sh_info: self.gnu_verneed_count.into(), -            sh_addralign: self.elf_align as u64, -            sh_entsize: 0, -        }); -    } - -    /// Reserve the section index for the `.gnu.attributes` section. -    pub fn reserve_gnu_attributes_section_index(&mut self) -> SectionIndex { -        debug_assert!(self.gnu_attributes_str_id.is_none()); -        self.gnu_attributes_str_id = Some(self.add_section_name(&b".gnu.attributes"[..])); -        self.reserve_section_index() -    } - -    /// Reserve the range for the `.gnu.attributes` section. -    pub fn reserve_gnu_attributes(&mut self, gnu_attributes_size: usize) { -        debug_assert_eq!(self.gnu_attributes_offset, 0); -        if gnu_attributes_size == 0 { -            return; -        } -        self.gnu_attributes_size = gnu_attributes_size; -        self.gnu_attributes_offset = self.reserve(self.gnu_attributes_size, self.elf_align); -    } - -    /// Write the section header for the `.gnu.attributes` section. -    /// -    /// This function does nothing if the section index was not reserved. -    pub fn write_gnu_attributes_section_header(&mut self) { -        if self.gnu_attributes_str_id.is_none() { -            return; -        } -        self.write_section_header(&SectionHeader { -            name: self.gnu_attributes_str_id, -            sh_type: elf::SHT_GNU_ATTRIBUTES, -            sh_flags: 0, -            sh_addr: 0, -            sh_offset: self.gnu_attributes_offset as u64, -            sh_size: self.gnu_attributes_size as u64, -            sh_link: self.dynstr_index.0, -            sh_info: 0, // TODO -            sh_addralign: self.elf_align as u64, -            sh_entsize: 0, -        }); -    } - -    /// Write the data for the `.gnu.attributes` section. -    pub fn write_gnu_attributes(&mut self, data: &[u8]) { -        if self.gnu_attributes_offset == 0 { -            return; -        } -        util::write_align(self.buffer, self.elf_align); -        debug_assert_eq!(self.gnu_attributes_offset, self.buffer.len()); -        self.buffer.write_bytes(data); -    } - -    /// Reserve a file range for the given number of relocations. -    /// -    /// Returns the offset of the range. -    pub fn reserve_relocations(&mut self, count: usize, is_rela: bool) -> usize { -        self.reserve(count * self.rel_size(is_rela), self.elf_align) -    } - -    /// Write alignment padding bytes prior to a relocation section. -    pub fn write_align_relocation(&mut self) { -        util::write_align(self.buffer, self.elf_align); -    } - -    /// Write a relocation. -    pub fn write_relocation(&mut self, is_rela: bool, rel: &Rel) { -        let endian = self.endian; -        if self.is_64 { -            if is_rela { -                let rel = elf::Rela64 { -                    r_offset: U64::new(endian, rel.r_offset), -                    r_info: elf::Rela64::r_info(endian, self.is_mips64el, rel.r_sym, rel.r_type), -                    r_addend: I64::new(endian, rel.r_addend), -                }; -                self.buffer.write(&rel); -            } else { -                let rel = elf::Rel64 { -                    r_offset: U64::new(endian, rel.r_offset), -                    r_info: elf::Rel64::r_info(endian, rel.r_sym, rel.r_type), -                }; -                self.buffer.write(&rel); -            } -        } else { -            if is_rela { -                let rel = elf::Rela32 { -                    r_offset: U32::new(endian, rel.r_offset as u32), -                    r_info: elf::Rel32::r_info(endian, rel.r_sym, rel.r_type as u8), -                    r_addend: I32::new(endian, rel.r_addend as i32), -                }; -                self.buffer.write(&rel); -            } else { -                let rel = elf::Rel32 { -                    r_offset: U32::new(endian, rel.r_offset as u32), -                    r_info: elf::Rel32::r_info(endian, rel.r_sym, rel.r_type as u8), -                }; -                self.buffer.write(&rel); -            } -        } -    } - -    /// Write the section header for a relocation section. -    /// -    /// `section` is the index of the section the relocations apply to, -    /// or 0 if none. -    /// -    /// `symtab` is the index of the symbol table the relocations refer to, -    /// or 0 if none. -    /// -    /// `offset` is the file offset of the relocations. -    pub fn write_relocation_section_header( -        &mut self, -        name: StringId, -        section: SectionIndex, -        symtab: SectionIndex, -        offset: usize, -        count: usize, -        is_rela: bool, -    ) { -        self.write_section_header(&SectionHeader { -            name: Some(name), -            sh_type: if is_rela { elf::SHT_RELA } else { elf::SHT_REL }, -            sh_flags: elf::SHF_INFO_LINK.into(), -            sh_addr: 0, -            sh_offset: offset as u64, -            sh_size: (count * self.rel_size(is_rela)) as u64, -            sh_link: symtab.0, -            sh_info: section.0, -            sh_addralign: self.elf_align as u64, -            sh_entsize: self.rel_size(is_rela) as u64, -        }); -    } - -    /// Reserve a file range for a COMDAT section. -    /// -    /// `count` is the number of sections in the COMDAT group. -    /// -    /// Returns the offset of the range. -    pub fn reserve_comdat(&mut self, count: usize) -> usize { -        self.reserve((count + 1) * 4, 4) -    } - -    /// Write `GRP_COMDAT` at the start of the COMDAT section. -    pub fn write_comdat_header(&mut self) { -        util::write_align(self.buffer, 4); -        self.buffer.write(&U32::new(self.endian, elf::GRP_COMDAT)); -    } - -    /// Write an entry in a COMDAT section. -    pub fn write_comdat_entry(&mut self, entry: SectionIndex) { -        self.buffer.write(&U32::new(self.endian, entry.0)); -    } - -    /// Write the section header for a COMDAT section. -    pub fn write_comdat_section_header( -        &mut self, -        name: StringId, -        symtab: SectionIndex, -        symbol: SymbolIndex, -        offset: usize, -        count: usize, -    ) { -        self.write_section_header(&SectionHeader { -            name: Some(name), -            sh_type: elf::SHT_GROUP, -            sh_flags: 0, -            sh_addr: 0, -            sh_offset: offset as u64, -            sh_size: ((count + 1) * 4) as u64, -            sh_link: symtab.0, -            sh_info: symbol.0, -            sh_addralign: 4, -            sh_entsize: 4, -        }); -    } - -    /// Return a helper for writing an attributes section. -    pub fn attributes_writer(&self) -> AttributesWriter { -        AttributesWriter::new(self.endian) -    } -} - -/// A helper for writing an attributes section. -/// -/// Attributes have a variable length encoding, so it is awkward to write them in a -/// single pass. Instead, we build the entire attributes section data in memory, using -/// placeholders for unknown lengths that are filled in later. -#[allow(missing_debug_implementations)] -pub struct AttributesWriter { -    endian: Endianness, -    data: Vec<u8>, -    subsection_offset: usize, -    subsubsection_offset: usize, -} - -impl AttributesWriter { -    /// Create a new `AttributesWriter` for the given endianness. -    pub fn new(endian: Endianness) -> Self { -        AttributesWriter { -            endian, -            data: vec![0x41], -            subsection_offset: 0, -            subsubsection_offset: 0, -        } -    } - -    /// Start a new subsection with the given vendor name. -    pub fn start_subsection(&mut self, vendor: &[u8]) { -        debug_assert_eq!(self.subsection_offset, 0); -        debug_assert_eq!(self.subsubsection_offset, 0); -        self.subsection_offset = self.data.len(); -        self.data.extend_from_slice(&[0; 4]); -        self.data.extend_from_slice(vendor); -        self.data.push(0); -    } - -    /// End the subsection. -    /// -    /// The subsection length is automatically calculated and written. -    pub fn end_subsection(&mut self) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_eq!(self.subsubsection_offset, 0); -        let length = self.data.len() - self.subsection_offset; -        self.data[self.subsection_offset..][..4] -            .copy_from_slice(pod::bytes_of(&U32::new(self.endian, length as u32))); -        self.subsection_offset = 0; -    } - -    /// Start a new sub-subsection with the given tag. -    pub fn start_subsubsection(&mut self, tag: u8) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_eq!(self.subsubsection_offset, 0); -        self.subsubsection_offset = self.data.len(); -        self.data.push(tag); -        self.data.extend_from_slice(&[0; 4]); -    } - -    /// Write a section or symbol index to the sub-subsection. -    /// -    /// The user must also call this function to write the terminating 0 index. -    pub fn write_subsubsection_index(&mut self, index: u32) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_ne!(self.subsubsection_offset, 0); -        util::write_uleb128(&mut self.data, u64::from(index)); -    } - -    /// Write raw index data to the sub-subsection. -    /// -    /// The terminating 0 index is automatically written. -    pub fn write_subsubsection_indices(&mut self, indices: &[u8]) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_ne!(self.subsubsection_offset, 0); -        self.data.extend_from_slice(indices); -        self.data.push(0); -    } - -    /// Write an attribute tag to the sub-subsection. -    pub fn write_attribute_tag(&mut self, tag: u64) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_ne!(self.subsubsection_offset, 0); -        util::write_uleb128(&mut self.data, tag); -    } - -    /// Write an attribute integer value to the sub-subsection. -    pub fn write_attribute_integer(&mut self, value: u64) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_ne!(self.subsubsection_offset, 0); -        util::write_uleb128(&mut self.data, value); -    } - -    /// Write an attribute string value to the sub-subsection. -    /// -    /// The value must not include the null terminator. -    pub fn write_attribute_string(&mut self, value: &[u8]) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_ne!(self.subsubsection_offset, 0); -        self.data.extend_from_slice(value); -        self.data.push(0); -    } - -    /// Write raw attribute data to the sub-subsection. -    pub fn write_subsubsection_attributes(&mut self, attributes: &[u8]) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_ne!(self.subsubsection_offset, 0); -        self.data.extend_from_slice(attributes); -    } - -    /// End the sub-subsection. -    /// -    /// The sub-subsection length is automatically calculated and written. -    pub fn end_subsubsection(&mut self) { -        debug_assert_ne!(self.subsection_offset, 0); -        debug_assert_ne!(self.subsubsection_offset, 0); -        let length = self.data.len() - self.subsubsection_offset; -        self.data[self.subsubsection_offset + 1..][..4] -            .copy_from_slice(pod::bytes_of(&U32::new(self.endian, length as u32))); -        self.subsubsection_offset = 0; -    } - -    /// Return the completed section data. -    pub fn data(self) -> Vec<u8> { -        debug_assert_eq!(self.subsection_offset, 0); -        debug_assert_eq!(self.subsubsection_offset, 0); -        self.data -    } -} - -/// Native endian version of [`elf::FileHeader64`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct FileHeader { -    pub os_abi: u8, -    pub abi_version: u8, -    pub e_type: u16, -    pub e_machine: u16, -    pub e_entry: u64, -    pub e_flags: u32, -} - -/// Native endian version of [`elf::ProgramHeader64`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct ProgramHeader { -    pub p_type: u32, -    pub p_flags: u32, -    pub p_offset: u64, -    pub p_vaddr: u64, -    pub p_paddr: u64, -    pub p_filesz: u64, -    pub p_memsz: u64, -    pub p_align: u64, -} - -/// Native endian version of [`elf::SectionHeader64`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct SectionHeader { -    pub name: Option<StringId>, -    pub sh_type: u32, -    pub sh_flags: u64, -    pub sh_addr: u64, -    pub sh_offset: u64, -    pub sh_size: u64, -    pub sh_link: u32, -    pub sh_info: u32, -    pub sh_addralign: u64, -    pub sh_entsize: u64, -} - -/// Native endian version of [`elf::Sym64`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct Sym { -    pub name: Option<StringId>, -    pub section: Option<SectionIndex>, -    pub st_info: u8, -    pub st_other: u8, -    pub st_shndx: u16, -    pub st_value: u64, -    pub st_size: u64, -} - -/// Unified native endian version of [`elf::Rel64`] and [`elf::Rela64`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct Rel { -    pub r_offset: u64, -    pub r_sym: u32, -    pub r_type: u32, -    pub r_addend: i64, -} - -/// Information required for writing [`elf::Verdef`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct Verdef { -    pub version: u16, -    pub flags: u16, -    pub index: u16, -    pub aux_count: u16, -    /// The name for the first [`elf::Verdaux`] entry. -    pub name: StringId, -} - -/// Information required for writing [`elf::Verneed`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct Verneed { -    pub version: u16, -    pub aux_count: u16, -    pub file: StringId, -} - -/// Information required for writing [`elf::Vernaux`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct Vernaux { -    pub flags: u16, -    pub index: u16, -    pub name: StringId, -} diff --git a/vendor/object/src/write/macho.rs b/vendor/object/src/write/macho.rs deleted file mode 100644 index 1c61523..0000000 --- a/vendor/object/src/write/macho.rs +++ /dev/null @@ -1,1095 +0,0 @@ -use core::mem; - -use crate::endian::*; -use crate::macho; -use crate::write::string::*; -use crate::write::util::*; -use crate::write::*; -use crate::AddressSize; - -#[derive(Default, Clone, Copy)] -struct SectionOffsets { -    index: usize, -    offset: usize, -    address: u64, -    reloc_offset: usize, -    reloc_count: usize, -} - -#[derive(Default, Clone, Copy)] -struct SymbolOffsets { -    index: usize, -    str_id: Option<StringId>, -} - -/// The customizable portion of a [`macho::BuildVersionCommand`]. -#[derive(Debug, Default, Clone, Copy)] -#[non_exhaustive] // May want to add the tool list? -pub struct MachOBuildVersion { -    /// One of the `PLATFORM_` constants (for example, -    /// [`object::macho::PLATFORM_MACOS`](macho::PLATFORM_MACOS)). -    pub platform: u32, -    /// The minimum OS version, where `X.Y.Z` is encoded in nibbles as -    /// `xxxx.yy.zz`. -    pub minos: u32, -    /// The SDK version as `X.Y.Z`, where `X.Y.Z` is encoded in nibbles as -    /// `xxxx.yy.zz`. -    pub sdk: u32, -} - -impl MachOBuildVersion { -    fn cmdsize(&self) -> u32 { -        // Same size for both endianness, and we don't have `ntools`. -        let sz = mem::size_of::<macho::BuildVersionCommand<Endianness>>(); -        debug_assert!(sz <= u32::MAX as usize); -        sz as u32 -    } -} - -// Public methods. -impl<'a> Object<'a> { -    /// Specify the Mach-O CPU subtype. -    /// -    /// Requires `feature = "macho"`. -    #[inline] -    pub fn set_macho_cpu_subtype(&mut self, cpu_subtype: u32) { -        self.macho_cpu_subtype = Some(cpu_subtype); -    } - -    /// Specify information for a Mach-O `LC_BUILD_VERSION` command. -    /// -    /// Requires `feature = "macho"`. -    #[inline] -    pub fn set_macho_build_version(&mut self, info: MachOBuildVersion) { -        self.macho_build_version = Some(info); -    } -} - -// Private methods. -impl<'a> Object<'a> { -    pub(crate) fn macho_set_subsections_via_symbols(&mut self) { -        let flags = match self.flags { -            FileFlags::MachO { flags } => flags, -            _ => 0, -        }; -        self.flags = FileFlags::MachO { -            flags: flags | macho::MH_SUBSECTIONS_VIA_SYMBOLS, -        }; -    } - -    pub(crate) fn macho_segment_name(&self, segment: StandardSegment) -> &'static [u8] { -        match segment { -            StandardSegment::Text => &b"__TEXT"[..], -            StandardSegment::Data => &b"__DATA"[..], -            StandardSegment::Debug => &b"__DWARF"[..], -        } -    } - -    pub(crate) fn macho_section_info( -        &self, -        section: StandardSection, -    ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { -        match section { -            StandardSection::Text => ( -                &b"__TEXT"[..], -                &b"__text"[..], -                SectionKind::Text, -                SectionFlags::None, -            ), -            StandardSection::Data => ( -                &b"__DATA"[..], -                &b"__data"[..], -                SectionKind::Data, -                SectionFlags::None, -            ), -            StandardSection::ReadOnlyData => ( -                &b"__TEXT"[..], -                &b"__const"[..], -                SectionKind::ReadOnlyData, -                SectionFlags::None, -            ), -            StandardSection::ReadOnlyDataWithRel => ( -                &b"__DATA"[..], -                &b"__const"[..], -                SectionKind::ReadOnlyDataWithRel, -                SectionFlags::None, -            ), -            StandardSection::ReadOnlyString => ( -                &b"__TEXT"[..], -                &b"__cstring"[..], -                SectionKind::ReadOnlyString, -                SectionFlags::None, -            ), -            StandardSection::UninitializedData => ( -                &b"__DATA"[..], -                &b"__bss"[..], -                SectionKind::UninitializedData, -                SectionFlags::None, -            ), -            StandardSection::Tls => ( -                &b"__DATA"[..], -                &b"__thread_data"[..], -                SectionKind::Tls, -                SectionFlags::None, -            ), -            StandardSection::UninitializedTls => ( -                &b"__DATA"[..], -                &b"__thread_bss"[..], -                SectionKind::UninitializedTls, -                SectionFlags::None, -            ), -            StandardSection::TlsVariables => ( -                &b"__DATA"[..], -                &b"__thread_vars"[..], -                SectionKind::TlsVariables, -                SectionFlags::None, -            ), -            StandardSection::Common => ( -                &b"__DATA"[..], -                &b"__common"[..], -                SectionKind::Common, -                SectionFlags::None, -            ), -            StandardSection::GnuProperty => { -                // Unsupported section. -                (&[], &[], SectionKind::Note, SectionFlags::None) -            } -        } -    } - -    fn macho_tlv_bootstrap(&mut self) -> SymbolId { -        match self.tlv_bootstrap { -            Some(id) => id, -            None => { -                let id = self.add_symbol(Symbol { -                    name: b"_tlv_bootstrap".to_vec(), -                    value: 0, -                    size: 0, -                    kind: SymbolKind::Text, -                    scope: SymbolScope::Dynamic, -                    weak: false, -                    section: SymbolSection::Undefined, -                    flags: SymbolFlags::None, -                }); -                self.tlv_bootstrap = Some(id); -                id -            } -        } -    } - -    /// Create the `__thread_vars` entry for a TLS variable. -    /// -    /// The symbol given by `symbol_id` will be updated to point to this entry. -    /// -    /// A new `SymbolId` will be returned. The caller must update this symbol -    /// to point to the initializer. -    /// -    /// If `symbol_id` is not for a TLS variable, then it is returned unchanged. -    pub(crate) fn macho_add_thread_var(&mut self, symbol_id: SymbolId) -> SymbolId { -        let symbol = self.symbol_mut(symbol_id); -        if symbol.kind != SymbolKind::Tls { -            return symbol_id; -        } - -        // Create the initializer symbol. -        let mut name = symbol.name.clone(); -        name.extend_from_slice(b"$tlv$init"); -        let init_symbol_id = self.add_raw_symbol(Symbol { -            name, -            value: 0, -            size: 0, -            kind: SymbolKind::Tls, -            scope: SymbolScope::Compilation, -            weak: false, -            section: SymbolSection::Undefined, -            flags: SymbolFlags::None, -        }); - -        // Add the tlv entry. -        // Three pointers in size: -        //   - __tlv_bootstrap - used to make sure support exists -        //   - spare pointer - used when mapped by the runtime -        //   - pointer to symbol initializer -        let section = self.section_id(StandardSection::TlsVariables); -        let address_size = self.architecture.address_size().unwrap().bytes(); -        let size = u64::from(address_size) * 3; -        let data = vec![0; size as usize]; -        let offset = self.append_section_data(section, &data, u64::from(address_size)); - -        let tlv_bootstrap = self.macho_tlv_bootstrap(); -        self.add_relocation( -            section, -            Relocation { -                offset, -                size: address_size * 8, -                kind: RelocationKind::Absolute, -                encoding: RelocationEncoding::Generic, -                symbol: tlv_bootstrap, -                addend: 0, -            }, -        ) -        .unwrap(); -        self.add_relocation( -            section, -            Relocation { -                offset: offset + u64::from(address_size) * 2, -                size: address_size * 8, -                kind: RelocationKind::Absolute, -                encoding: RelocationEncoding::Generic, -                symbol: init_symbol_id, -                addend: 0, -            }, -        ) -        .unwrap(); - -        // Update the symbol to point to the tlv. -        let symbol = self.symbol_mut(symbol_id); -        symbol.value = offset; -        symbol.size = size; -        symbol.section = SymbolSection::Section(section); - -        init_symbol_id -    } - -    pub(crate) fn macho_fixup_relocation(&mut self, relocation: &mut Relocation) -> i64 { -        let relative = match relocation.kind { -            RelocationKind::Relative -            | RelocationKind::GotRelative -            | RelocationKind::PltRelative -            | RelocationKind::MachO { relative: true, .. } => true, -            _ => false, -        }; -        if relative { -            // For PC relative relocations on some architectures, the -            // addend does not include the offset required due to the -            // PC being different from the place of the relocation. -            // This differs from other file formats, so adjust the -            // addend here to account for this. -            let pcrel_offset = match self.architecture { -                Architecture::I386 => 4, -                Architecture::X86_64 => match relocation.kind { -                    RelocationKind::MachO { -                        value: macho::X86_64_RELOC_SIGNED_1, -                        .. -                    } => 5, -                    RelocationKind::MachO { -                        value: macho::X86_64_RELOC_SIGNED_2, -                        .. -                    } => 6, -                    RelocationKind::MachO { -                        value: macho::X86_64_RELOC_SIGNED_4, -                        .. -                    } => 8, -                    _ => 4, -                }, -                // TODO: maybe missing support for some architectures and relocations -                _ => 0, -            }; -            relocation.addend += pcrel_offset; -        } -        // Aarch64 relocs of these sizes act as if they are double-word length -        if self.architecture == Architecture::Aarch64 && matches!(relocation.size, 12 | 21 | 26) { -            relocation.size = 32; -        } -        // Check for relocations that use an explicit addend. -        if self.architecture == Architecture::Aarch64 { -            if relocation.encoding == RelocationEncoding::AArch64Call { -                return 0; -            } -            if let RelocationKind::MachO { value, .. } = relocation.kind { -                match value { -                    macho::ARM64_RELOC_BRANCH26 -                    | macho::ARM64_RELOC_PAGE21 -                    | macho::ARM64_RELOC_PAGEOFF12 => return 0, -                    _ => {} -                } -            } -        } -        // Signify implicit addend. -        let constant = relocation.addend; -        relocation.addend = 0; -        constant -    } - -    pub(crate) fn macho_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> { -        let address_size = self.architecture.address_size().unwrap(); -        let endian = self.endian; -        let macho32 = MachO32 { endian }; -        let macho64 = MachO64 { endian }; -        let macho: &dyn MachO = match address_size { -            AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => &macho32, -            AddressSize::U64 => &macho64, -        }; -        let pointer_align = address_size.bytes() as usize; - -        // Calculate offsets of everything, and build strtab. -        let mut offset = 0; - -        // Calculate size of Mach-O header. -        offset += macho.mach_header_size(); - -        // Calculate size of commands. -        let mut ncmds = 0; -        let command_offset = offset; - -        // Calculate size of segment command and section headers. -        let segment_command_offset = offset; -        let segment_command_len = -            macho.segment_command_size() + self.sections.len() * macho.section_header_size(); -        offset += segment_command_len; -        ncmds += 1; - -        // Calculate size of build version. -        let build_version_offset = offset; -        if let Some(version) = &self.macho_build_version { -            offset += version.cmdsize() as usize; -            ncmds += 1; -        } - -        // Calculate size of symtab command. -        let symtab_command_offset = offset; -        let symtab_command_len = mem::size_of::<macho::SymtabCommand<Endianness>>(); -        offset += symtab_command_len; -        ncmds += 1; - -        // Calculate size of dysymtab command. -        let dysymtab_command_offset = offset; -        let dysymtab_command_len = mem::size_of::<macho::DysymtabCommand<Endianness>>(); -        offset += dysymtab_command_len; -        ncmds += 1; - -        let sizeofcmds = offset - command_offset; - -        // Calculate size of section data. -        // Section data can immediately follow the load commands without any alignment padding. -        let segment_file_offset = offset; -        let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()]; -        let mut address = 0; -        for (index, section) in self.sections.iter().enumerate() { -            section_offsets[index].index = 1 + index; -            if !section.is_bss() { -                address = align_u64(address, section.align); -                section_offsets[index].address = address; -                section_offsets[index].offset = segment_file_offset + address as usize; -                address += section.size; -            } -        } -        let segment_file_size = address as usize; -        offset += address as usize; -        for (index, section) in self.sections.iter().enumerate() { -            if section.is_bss() { -                debug_assert!(section.data.is_empty()); -                address = align_u64(address, section.align); -                section_offsets[index].address = address; -                address += section.size; -            } -        } - -        // Partition symbols and add symbol strings to strtab. -        let mut strtab = StringTable::default(); -        let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()]; -        let mut local_symbols = vec![]; -        let mut external_symbols = vec![]; -        let mut undefined_symbols = vec![]; -        for (index, symbol) in self.symbols.iter().enumerate() { -            // The unified API allows creating symbols that we don't emit, so filter -            // them out here. -            // -            // Since we don't actually emit the symbol kind, we validate it here too. -            match symbol.kind { -                SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls | SymbolKind::Unknown => {} -                SymbolKind::File | SymbolKind::Section => continue, -                SymbolKind::Null | SymbolKind::Label => { -                    return Err(Error(format!( -                        "unimplemented symbol `{}` kind {:?}", -                        symbol.name().unwrap_or(""), -                        symbol.kind -                    ))); -                } -            } -            if !symbol.name.is_empty() { -                symbol_offsets[index].str_id = Some(strtab.add(&symbol.name)); -            } -            if symbol.is_undefined() { -                undefined_symbols.push(index); -            } else if symbol.is_local() { -                local_symbols.push(index); -            } else { -                external_symbols.push(index); -            } -        } - -        external_symbols.sort_by_key(|index| &*self.symbols[*index].name); -        undefined_symbols.sort_by_key(|index| &*self.symbols[*index].name); - -        // Count symbols. -        let mut nsyms = 0; -        for index in local_symbols -            .iter() -            .copied() -            .chain(external_symbols.iter().copied()) -            .chain(undefined_symbols.iter().copied()) -        { -            symbol_offsets[index].index = nsyms; -            nsyms += 1; -        } - -        // Calculate size of relocations. -        for (index, section) in self.sections.iter().enumerate() { -            let count: usize = section -                .relocations -                .iter() -                .map(|reloc| 1 + usize::from(reloc.addend != 0)) -                .sum(); -            if count != 0 { -                offset = align(offset, pointer_align); -                section_offsets[index].reloc_offset = offset; -                section_offsets[index].reloc_count = count; -                let len = count * mem::size_of::<macho::Relocation<Endianness>>(); -                offset += len; -            } -        } - -        // Calculate size of symtab. -        offset = align(offset, pointer_align); -        let symtab_offset = offset; -        let symtab_len = nsyms * macho.nlist_size(); -        offset += symtab_len; - -        // Calculate size of strtab. -        let strtab_offset = offset; -        // Start with null name. -        let mut strtab_data = vec![0]; -        strtab.write(1, &mut strtab_data); -        write_align(&mut strtab_data, pointer_align); -        offset += strtab_data.len(); - -        // Start writing. -        buffer -            .reserve(offset) -            .map_err(|_| Error(String::from("Cannot allocate buffer")))?; - -        // Write file header. -        let (cputype, mut cpusubtype) = match (self.architecture, self.sub_architecture) { -            (Architecture::Arm, None) => (macho::CPU_TYPE_ARM, macho::CPU_SUBTYPE_ARM_ALL), -            (Architecture::Aarch64, None) => (macho::CPU_TYPE_ARM64, macho::CPU_SUBTYPE_ARM64_ALL), -            (Architecture::Aarch64, Some(SubArchitecture::Arm64E)) => { -                (macho::CPU_TYPE_ARM64, macho::CPU_SUBTYPE_ARM64E) -            } -            (Architecture::Aarch64_Ilp32, None) => { -                (macho::CPU_TYPE_ARM64_32, macho::CPU_SUBTYPE_ARM64_32_V8) -            } -            (Architecture::I386, None) => (macho::CPU_TYPE_X86, macho::CPU_SUBTYPE_I386_ALL), -            (Architecture::X86_64, None) => (macho::CPU_TYPE_X86_64, macho::CPU_SUBTYPE_X86_64_ALL), -            (Architecture::PowerPc, None) => { -                (macho::CPU_TYPE_POWERPC, macho::CPU_SUBTYPE_POWERPC_ALL) -            } -            (Architecture::PowerPc64, None) => { -                (macho::CPU_TYPE_POWERPC64, macho::CPU_SUBTYPE_POWERPC_ALL) -            } -            _ => { -                return Err(Error(format!( -                    "unimplemented architecture {:?} with sub-architecture {:?}", -                    self.architecture, self.sub_architecture -                ))); -            } -        }; - -        if let Some(cpu_subtype) = self.macho_cpu_subtype { -            cpusubtype = cpu_subtype; -        } - -        let flags = match self.flags { -            FileFlags::MachO { flags } => flags, -            _ => 0, -        }; -        macho.write_mach_header( -            buffer, -            MachHeader { -                cputype, -                cpusubtype, -                filetype: macho::MH_OBJECT, -                ncmds, -                sizeofcmds: sizeofcmds as u32, -                flags, -            }, -        ); - -        // Write segment command. -        debug_assert_eq!(segment_command_offset, buffer.len()); -        macho.write_segment_command( -            buffer, -            SegmentCommand { -                cmdsize: segment_command_len as u32, -                segname: [0; 16], -                vmaddr: 0, -                vmsize: address, -                fileoff: segment_file_offset as u64, -                filesize: segment_file_size as u64, -                maxprot: macho::VM_PROT_READ | macho::VM_PROT_WRITE | macho::VM_PROT_EXECUTE, -                initprot: macho::VM_PROT_READ | macho::VM_PROT_WRITE | macho::VM_PROT_EXECUTE, -                nsects: self.sections.len() as u32, -                flags: 0, -            }, -        ); - -        // Write section headers. -        for (index, section) in self.sections.iter().enumerate() { -            let mut sectname = [0; 16]; -            sectname -                .get_mut(..section.name.len()) -                .ok_or_else(|| { -                    Error(format!( -                        "section name `{}` is too long", -                        section.name().unwrap_or(""), -                    )) -                })? -                .copy_from_slice(§ion.name); -            let mut segname = [0; 16]; -            segname -                .get_mut(..section.segment.len()) -                .ok_or_else(|| { -                    Error(format!( -                        "segment name `{}` is too long", -                        section.segment().unwrap_or(""), -                    )) -                })? -                .copy_from_slice(§ion.segment); -            let flags = if let SectionFlags::MachO { flags } = section.flags { -                flags -            } else { -                match section.kind { -                    SectionKind::Text => { -                        macho::S_ATTR_PURE_INSTRUCTIONS | macho::S_ATTR_SOME_INSTRUCTIONS -                    } -                    SectionKind::Data => 0, -                    SectionKind::ReadOnlyData | SectionKind::ReadOnlyDataWithRel => 0, -                    SectionKind::ReadOnlyString => macho::S_CSTRING_LITERALS, -                    SectionKind::UninitializedData | SectionKind::Common => macho::S_ZEROFILL, -                    SectionKind::Tls => macho::S_THREAD_LOCAL_REGULAR, -                    SectionKind::UninitializedTls => macho::S_THREAD_LOCAL_ZEROFILL, -                    SectionKind::TlsVariables => macho::S_THREAD_LOCAL_VARIABLES, -                    SectionKind::Debug => macho::S_ATTR_DEBUG, -                    SectionKind::OtherString => macho::S_CSTRING_LITERALS, -                    SectionKind::Other | SectionKind::Linker | SectionKind::Metadata => 0, -                    SectionKind::Note | SectionKind::Unknown | SectionKind::Elf(_) => { -                        return Err(Error(format!( -                            "unimplemented section `{}` kind {:?}", -                            section.name().unwrap_or(""), -                            section.kind -                        ))); -                    } -                } -            }; -            macho.write_section( -                buffer, -                SectionHeader { -                    sectname, -                    segname, -                    addr: section_offsets[index].address, -                    size: section.size, -                    offset: section_offsets[index].offset as u32, -                    align: section.align.trailing_zeros(), -                    reloff: section_offsets[index].reloc_offset as u32, -                    nreloc: section_offsets[index].reloc_count as u32, -                    flags, -                }, -            ); -        } - -        // Write build version. -        if let Some(version) = &self.macho_build_version { -            debug_assert_eq!(build_version_offset, buffer.len()); -            buffer.write(&macho::BuildVersionCommand { -                cmd: U32::new(endian, macho::LC_BUILD_VERSION), -                cmdsize: U32::new(endian, version.cmdsize()), -                platform: U32::new(endian, version.platform), -                minos: U32::new(endian, version.minos), -                sdk: U32::new(endian, version.sdk), -                ntools: U32::new(endian, 0), -            }); -        } - -        // Write symtab command. -        debug_assert_eq!(symtab_command_offset, buffer.len()); -        let symtab_command = macho::SymtabCommand { -            cmd: U32::new(endian, macho::LC_SYMTAB), -            cmdsize: U32::new(endian, symtab_command_len as u32), -            symoff: U32::new(endian, symtab_offset as u32), -            nsyms: U32::new(endian, nsyms as u32), -            stroff: U32::new(endian, strtab_offset as u32), -            strsize: U32::new(endian, strtab_data.len() as u32), -        }; -        buffer.write(&symtab_command); - -        // Write dysymtab command. -        debug_assert_eq!(dysymtab_command_offset, buffer.len()); -        let dysymtab_command = macho::DysymtabCommand { -            cmd: U32::new(endian, macho::LC_DYSYMTAB), -            cmdsize: U32::new(endian, dysymtab_command_len as u32), -            ilocalsym: U32::new(endian, 0), -            nlocalsym: U32::new(endian, local_symbols.len() as u32), -            iextdefsym: U32::new(endian, local_symbols.len() as u32), -            nextdefsym: U32::new(endian, external_symbols.len() as u32), -            iundefsym: U32::new( -                endian, -                local_symbols.len() as u32 + external_symbols.len() as u32, -            ), -            nundefsym: U32::new(endian, undefined_symbols.len() as u32), -            tocoff: U32::default(), -            ntoc: U32::default(), -            modtaboff: U32::default(), -            nmodtab: U32::default(), -            extrefsymoff: U32::default(), -            nextrefsyms: U32::default(), -            indirectsymoff: U32::default(), -            nindirectsyms: U32::default(), -            extreloff: U32::default(), -            nextrel: U32::default(), -            locreloff: U32::default(), -            nlocrel: U32::default(), -        }; -        buffer.write(&dysymtab_command); - -        // Write section data. -        for (index, section) in self.sections.iter().enumerate() { -            if !section.is_bss() { -                buffer.resize(section_offsets[index].offset); -                buffer.write_bytes(§ion.data); -            } -        } -        debug_assert_eq!(segment_file_offset + segment_file_size, buffer.len()); - -        // Write relocations. -        for (index, section) in self.sections.iter().enumerate() { -            if !section.relocations.is_empty() { -                write_align(buffer, pointer_align); -                debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len()); -                for reloc in §ion.relocations { -                    let r_length = match reloc.size { -                        8 => 0, -                        16 => 1, -                        32 => 2, -                        64 => 3, -                        _ => return Err(Error(format!("unimplemented reloc size {:?}", reloc))), -                    }; - -                    // Write explicit addend. -                    if reloc.addend != 0 { -                        let r_type = match self.architecture { -                            Architecture::Aarch64 | Architecture::Aarch64_Ilp32 => { -                                macho::ARM64_RELOC_ADDEND -                            } -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))) -                            } -                        }; - -                        let reloc_info = macho::RelocationInfo { -                            r_address: reloc.offset as u32, -                            r_symbolnum: reloc.addend as u32, -                            r_pcrel: false, -                            r_length, -                            r_extern: false, -                            r_type, -                        }; -                        buffer.write(&reloc_info.relocation(endian)); -                    } - -                    let r_extern; -                    let r_symbolnum; -                    let symbol = &self.symbols[reloc.symbol.0]; -                    if symbol.kind == SymbolKind::Section { -                        r_symbolnum = section_offsets[symbol.section.id().unwrap().0].index as u32; -                        r_extern = false; -                    } else { -                        r_symbolnum = symbol_offsets[reloc.symbol.0].index as u32; -                        r_extern = true; -                    } -                    let (r_pcrel, r_type) = match self.architecture { -                        Architecture::I386 => match reloc.kind { -                            RelocationKind::Absolute => (false, macho::GENERIC_RELOC_VANILLA), -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::X86_64 => match (reloc.kind, reloc.encoding) { -                            (RelocationKind::Absolute, RelocationEncoding::Generic) => { -                                (false, macho::X86_64_RELOC_UNSIGNED) -                            } -                            (RelocationKind::Relative, RelocationEncoding::Generic) => { -                                (true, macho::X86_64_RELOC_SIGNED) -                            } -                            (RelocationKind::Relative, RelocationEncoding::X86RipRelative) => { -                                (true, macho::X86_64_RELOC_SIGNED) -                            } -                            (RelocationKind::Relative, RelocationEncoding::X86Branch) => { -                                (true, macho::X86_64_RELOC_BRANCH) -                            } -                            (RelocationKind::PltRelative, RelocationEncoding::X86Branch) => { -                                (true, macho::X86_64_RELOC_BRANCH) -                            } -                            (RelocationKind::GotRelative, RelocationEncoding::Generic) => { -                                (true, macho::X86_64_RELOC_GOT) -                            } -                            ( -                                RelocationKind::GotRelative, -                                RelocationEncoding::X86RipRelativeMovq, -                            ) => (true, macho::X86_64_RELOC_GOT_LOAD), -                            (RelocationKind::MachO { value, relative }, _) => (relative, value), -                            _ => { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        }, -                        Architecture::Aarch64 | Architecture::Aarch64_Ilp32 => { -                            match (reloc.kind, reloc.encoding) { -                                (RelocationKind::Absolute, RelocationEncoding::Generic) => { -                                    (false, macho::ARM64_RELOC_UNSIGNED) -                                } -                                (RelocationKind::Relative, RelocationEncoding::AArch64Call) => { -                                    (true, macho::ARM64_RELOC_BRANCH26) -                                } -                                ( -                                    RelocationKind::MachO { value, relative }, -                                    RelocationEncoding::Generic, -                                ) => (relative, value), -                                _ => { -                                    return Err(Error(format!( -                                        "unimplemented relocation {:?}", -                                        reloc -                                    ))); -                                } -                            } -                        } -                        _ => { -                            if let RelocationKind::MachO { value, relative } = reloc.kind { -                                (relative, value) -                            } else { -                                return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                            } -                        } -                    }; -                    let reloc_info = macho::RelocationInfo { -                        r_address: reloc.offset as u32, -                        r_symbolnum, -                        r_pcrel, -                        r_length, -                        r_extern, -                        r_type, -                    }; -                    buffer.write(&reloc_info.relocation(endian)); -                } -            } -        } - -        // Write symtab. -        write_align(buffer, pointer_align); -        debug_assert_eq!(symtab_offset, buffer.len()); -        for index in local_symbols -            .iter() -            .copied() -            .chain(external_symbols.iter().copied()) -            .chain(undefined_symbols.iter().copied()) -        { -            let symbol = &self.symbols[index]; -            // TODO: N_STAB -            let (mut n_type, n_sect) = match symbol.section { -                SymbolSection::Undefined => (macho::N_UNDF | macho::N_EXT, 0), -                SymbolSection::Absolute => (macho::N_ABS, 0), -                SymbolSection::Section(id) => (macho::N_SECT, id.0 + 1), -                SymbolSection::None | SymbolSection::Common => { -                    return Err(Error(format!( -                        "unimplemented symbol `{}` section {:?}", -                        symbol.name().unwrap_or(""), -                        symbol.section -                    ))); -                } -            }; -            match symbol.scope { -                SymbolScope::Unknown | SymbolScope::Compilation => {} -                SymbolScope::Linkage => { -                    n_type |= macho::N_EXT | macho::N_PEXT; -                } -                SymbolScope::Dynamic => { -                    n_type |= macho::N_EXT; -                } -            } - -            let n_desc = if let SymbolFlags::MachO { n_desc } = symbol.flags { -                n_desc -            } else { -                let mut n_desc = 0; -                if symbol.weak { -                    if symbol.is_undefined() { -                        n_desc |= macho::N_WEAK_REF; -                    } else { -                        n_desc |= macho::N_WEAK_DEF; -                    } -                } -                n_desc -            }; - -            let n_value = match symbol.section.id() { -                Some(section) => section_offsets[section.0].address + symbol.value, -                None => symbol.value, -            }; - -            let n_strx = symbol_offsets[index] -                .str_id -                .map(|id| strtab.get_offset(id)) -                .unwrap_or(0); - -            macho.write_nlist( -                buffer, -                Nlist { -                    n_strx: n_strx as u32, -                    n_type, -                    n_sect: n_sect as u8, -                    n_desc, -                    n_value, -                }, -            ); -        } - -        // Write strtab. -        debug_assert_eq!(strtab_offset, buffer.len()); -        buffer.write_bytes(&strtab_data); - -        debug_assert_eq!(offset, buffer.len()); - -        Ok(()) -    } -} - -struct MachHeader { -    cputype: u32, -    cpusubtype: u32, -    filetype: u32, -    ncmds: u32, -    sizeofcmds: u32, -    flags: u32, -} - -struct SegmentCommand { -    cmdsize: u32, -    segname: [u8; 16], -    vmaddr: u64, -    vmsize: u64, -    fileoff: u64, -    filesize: u64, -    maxprot: u32, -    initprot: u32, -    nsects: u32, -    flags: u32, -} - -pub struct SectionHeader { -    sectname: [u8; 16], -    segname: [u8; 16], -    addr: u64, -    size: u64, -    offset: u32, -    align: u32, -    reloff: u32, -    nreloc: u32, -    flags: u32, -} - -struct Nlist { -    n_strx: u32, -    n_type: u8, -    n_sect: u8, -    n_desc: u16, -    n_value: u64, -} - -trait MachO { -    fn mach_header_size(&self) -> usize; -    fn segment_command_size(&self) -> usize; -    fn section_header_size(&self) -> usize; -    fn nlist_size(&self) -> usize; -    fn write_mach_header(&self, buffer: &mut dyn WritableBuffer, section: MachHeader); -    fn write_segment_command(&self, buffer: &mut dyn WritableBuffer, segment: SegmentCommand); -    fn write_section(&self, buffer: &mut dyn WritableBuffer, section: SectionHeader); -    fn write_nlist(&self, buffer: &mut dyn WritableBuffer, nlist: Nlist); -} - -struct MachO32<E> { -    endian: E, -} - -impl<E: Endian> MachO for MachO32<E> { -    fn mach_header_size(&self) -> usize { -        mem::size_of::<macho::MachHeader32<E>>() -    } - -    fn segment_command_size(&self) -> usize { -        mem::size_of::<macho::SegmentCommand32<E>>() -    } - -    fn section_header_size(&self) -> usize { -        mem::size_of::<macho::Section32<E>>() -    } - -    fn nlist_size(&self) -> usize { -        mem::size_of::<macho::Nlist32<E>>() -    } - -    fn write_mach_header(&self, buffer: &mut dyn WritableBuffer, header: MachHeader) { -        let endian = self.endian; -        let magic = if endian.is_big_endian() { -            macho::MH_MAGIC -        } else { -            macho::MH_CIGAM -        }; -        let header = macho::MachHeader32 { -            magic: U32::new(BigEndian, magic), -            cputype: U32::new(endian, header.cputype), -            cpusubtype: U32::new(endian, header.cpusubtype), -            filetype: U32::new(endian, header.filetype), -            ncmds: U32::new(endian, header.ncmds), -            sizeofcmds: U32::new(endian, header.sizeofcmds), -            flags: U32::new(endian, header.flags), -        }; -        buffer.write(&header); -    } - -    fn write_segment_command(&self, buffer: &mut dyn WritableBuffer, segment: SegmentCommand) { -        let endian = self.endian; -        let segment = macho::SegmentCommand32 { -            cmd: U32::new(endian, macho::LC_SEGMENT), -            cmdsize: U32::new(endian, segment.cmdsize), -            segname: segment.segname, -            vmaddr: U32::new(endian, segment.vmaddr as u32), -            vmsize: U32::new(endian, segment.vmsize as u32), -            fileoff: U32::new(endian, segment.fileoff as u32), -            filesize: U32::new(endian, segment.filesize as u32), -            maxprot: U32::new(endian, segment.maxprot), -            initprot: U32::new(endian, segment.initprot), -            nsects: U32::new(endian, segment.nsects), -            flags: U32::new(endian, segment.flags), -        }; -        buffer.write(&segment); -    } - -    fn write_section(&self, buffer: &mut dyn WritableBuffer, section: SectionHeader) { -        let endian = self.endian; -        let section = macho::Section32 { -            sectname: section.sectname, -            segname: section.segname, -            addr: U32::new(endian, section.addr as u32), -            size: U32::new(endian, section.size as u32), -            offset: U32::new(endian, section.offset), -            align: U32::new(endian, section.align), -            reloff: U32::new(endian, section.reloff), -            nreloc: U32::new(endian, section.nreloc), -            flags: U32::new(endian, section.flags), -            reserved1: U32::default(), -            reserved2: U32::default(), -        }; -        buffer.write(§ion); -    } - -    fn write_nlist(&self, buffer: &mut dyn WritableBuffer, nlist: Nlist) { -        let endian = self.endian; -        let nlist = macho::Nlist32 { -            n_strx: U32::new(endian, nlist.n_strx), -            n_type: nlist.n_type, -            n_sect: nlist.n_sect, -            n_desc: U16::new(endian, nlist.n_desc), -            n_value: U32::new(endian, nlist.n_value as u32), -        }; -        buffer.write(&nlist); -    } -} - -struct MachO64<E> { -    endian: E, -} - -impl<E: Endian> MachO for MachO64<E> { -    fn mach_header_size(&self) -> usize { -        mem::size_of::<macho::MachHeader64<E>>() -    } - -    fn segment_command_size(&self) -> usize { -        mem::size_of::<macho::SegmentCommand64<E>>() -    } - -    fn section_header_size(&self) -> usize { -        mem::size_of::<macho::Section64<E>>() -    } - -    fn nlist_size(&self) -> usize { -        mem::size_of::<macho::Nlist64<E>>() -    } - -    fn write_mach_header(&self, buffer: &mut dyn WritableBuffer, header: MachHeader) { -        let endian = self.endian; -        let magic = if endian.is_big_endian() { -            macho::MH_MAGIC_64 -        } else { -            macho::MH_CIGAM_64 -        }; -        let header = macho::MachHeader64 { -            magic: U32::new(BigEndian, magic), -            cputype: U32::new(endian, header.cputype), -            cpusubtype: U32::new(endian, header.cpusubtype), -            filetype: U32::new(endian, header.filetype), -            ncmds: U32::new(endian, header.ncmds), -            sizeofcmds: U32::new(endian, header.sizeofcmds), -            flags: U32::new(endian, header.flags), -            reserved: U32::default(), -        }; -        buffer.write(&header); -    } - -    fn write_segment_command(&self, buffer: &mut dyn WritableBuffer, segment: SegmentCommand) { -        let endian = self.endian; -        let segment = macho::SegmentCommand64 { -            cmd: U32::new(endian, macho::LC_SEGMENT_64), -            cmdsize: U32::new(endian, segment.cmdsize), -            segname: segment.segname, -            vmaddr: U64::new(endian, segment.vmaddr), -            vmsize: U64::new(endian, segment.vmsize), -            fileoff: U64::new(endian, segment.fileoff), -            filesize: U64::new(endian, segment.filesize), -            maxprot: U32::new(endian, segment.maxprot), -            initprot: U32::new(endian, segment.initprot), -            nsects: U32::new(endian, segment.nsects), -            flags: U32::new(endian, segment.flags), -        }; -        buffer.write(&segment); -    } - -    fn write_section(&self, buffer: &mut dyn WritableBuffer, section: SectionHeader) { -        let endian = self.endian; -        let section = macho::Section64 { -            sectname: section.sectname, -            segname: section.segname, -            addr: U64::new(endian, section.addr), -            size: U64::new(endian, section.size), -            offset: U32::new(endian, section.offset), -            align: U32::new(endian, section.align), -            reloff: U32::new(endian, section.reloff), -            nreloc: U32::new(endian, section.nreloc), -            flags: U32::new(endian, section.flags), -            reserved1: U32::default(), -            reserved2: U32::default(), -            reserved3: U32::default(), -        }; -        buffer.write(§ion); -    } - -    fn write_nlist(&self, buffer: &mut dyn WritableBuffer, nlist: Nlist) { -        let endian = self.endian; -        let nlist = macho::Nlist64 { -            n_strx: U32::new(endian, nlist.n_strx), -            n_type: nlist.n_type, -            n_sect: nlist.n_sect, -            n_desc: U16::new(endian, nlist.n_desc), -            n_value: U64Bytes::new(endian, nlist.n_value), -        }; -        buffer.write(&nlist); -    } -} diff --git a/vendor/object/src/write/mod.rs b/vendor/object/src/write/mod.rs deleted file mode 100644 index cea4d2e..0000000 --- a/vendor/object/src/write/mod.rs +++ /dev/null @@ -1,961 +0,0 @@ -//! Interface for writing object files. - -use alloc::borrow::Cow; -use alloc::string::String; -use alloc::vec::Vec; -use core::{fmt, result, str}; -#[cfg(not(feature = "std"))] -use hashbrown::HashMap; -#[cfg(feature = "std")] -use std::{boxed::Box, collections::HashMap, error, io}; - -use crate::endian::{Endianness, U32, U64}; -use crate::{ -    Architecture, BinaryFormat, ComdatKind, FileFlags, RelocationEncoding, RelocationKind, -    SectionFlags, SectionKind, SubArchitecture, SymbolFlags, SymbolKind, SymbolScope, -}; - -#[cfg(feature = "coff")] -pub mod coff; -#[cfg(feature = "coff")] -pub use coff::CoffExportStyle; - -#[cfg(feature = "elf")] -pub mod elf; - -#[cfg(feature = "macho")] -mod macho; -#[cfg(feature = "macho")] -pub use macho::MachOBuildVersion; - -#[cfg(feature = "pe")] -pub mod pe; - -#[cfg(feature = "xcoff")] -mod xcoff; - -mod string; -pub use string::StringId; - -mod util; -pub use util::*; - -/// The error type used within the write module. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Error(String); - -impl fmt::Display for Error { -    #[inline] -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        f.write_str(&self.0) -    } -} - -#[cfg(feature = "std")] -impl error::Error for Error {} - -/// The result type used within the write module. -pub type Result<T> = result::Result<T, Error>; - -/// A writable relocatable object file. -#[derive(Debug)] -pub struct Object<'a> { -    format: BinaryFormat, -    architecture: Architecture, -    sub_architecture: Option<SubArchitecture>, -    endian: Endianness, -    sections: Vec<Section<'a>>, -    standard_sections: HashMap<StandardSection, SectionId>, -    symbols: Vec<Symbol>, -    symbol_map: HashMap<Vec<u8>, SymbolId>, -    stub_symbols: HashMap<SymbolId, SymbolId>, -    comdats: Vec<Comdat>, -    /// File flags that are specific to each file format. -    pub flags: FileFlags, -    /// The symbol name mangling scheme. -    pub mangling: Mangling, -    /// Mach-O "_tlv_bootstrap" symbol. -    tlv_bootstrap: Option<SymbolId>, -    /// Mach-O CPU subtype. -    #[cfg(feature = "macho")] -    macho_cpu_subtype: Option<u32>, -    #[cfg(feature = "macho")] -    macho_build_version: Option<MachOBuildVersion>, -} - -impl<'a> Object<'a> { -    /// Create an empty object file. -    pub fn new(format: BinaryFormat, architecture: Architecture, endian: Endianness) -> Object<'a> { -        Object { -            format, -            architecture, -            sub_architecture: None, -            endian, -            sections: Vec::new(), -            standard_sections: HashMap::new(), -            symbols: Vec::new(), -            symbol_map: HashMap::new(), -            stub_symbols: HashMap::new(), -            comdats: Vec::new(), -            flags: FileFlags::None, -            mangling: Mangling::default(format, architecture), -            tlv_bootstrap: None, -            #[cfg(feature = "macho")] -            macho_cpu_subtype: None, -            #[cfg(feature = "macho")] -            macho_build_version: None, -        } -    } - -    /// Return the file format. -    #[inline] -    pub fn format(&self) -> BinaryFormat { -        self.format -    } - -    /// Return the architecture. -    #[inline] -    pub fn architecture(&self) -> Architecture { -        self.architecture -    } - -    /// Return the sub-architecture. -    #[inline] -    pub fn sub_architecture(&self) -> Option<SubArchitecture> { -        self.sub_architecture -    } - -    /// Specify the sub-architecture. -    pub fn set_sub_architecture(&mut self, sub_architecture: Option<SubArchitecture>) { -        self.sub_architecture = sub_architecture; -    } - -    /// Return the current mangling setting. -    #[inline] -    pub fn mangling(&self) -> Mangling { -        self.mangling -    } - -    /// Specify the mangling setting. -    #[inline] -    pub fn set_mangling(&mut self, mangling: Mangling) { -        self.mangling = mangling; -    } - -    /// Return the name for a standard segment. -    /// -    /// This will vary based on the file format. -    #[allow(unused_variables)] -    pub fn segment_name(&self, segment: StandardSegment) -> &'static [u8] { -        match self.format { -            #[cfg(feature = "coff")] -            BinaryFormat::Coff => &[], -            #[cfg(feature = "elf")] -            BinaryFormat::Elf => &[], -            #[cfg(feature = "macho")] -            BinaryFormat::MachO => self.macho_segment_name(segment), -            _ => unimplemented!(), -        } -    } - -    /// Get the section with the given `SectionId`. -    #[inline] -    pub fn section(&self, section: SectionId) -> &Section<'a> { -        &self.sections[section.0] -    } - -    /// Mutably get the section with the given `SectionId`. -    #[inline] -    pub fn section_mut(&mut self, section: SectionId) -> &mut Section<'a> { -        &mut self.sections[section.0] -    } - -    /// Set the data for an existing section. -    /// -    /// Must not be called for sections that already have data, or that contain uninitialized data. -    pub fn set_section_data<T>(&mut self, section: SectionId, data: T, align: u64) -    where -        T: Into<Cow<'a, [u8]>>, -    { -        self.sections[section.0].set_data(data, align) -    } - -    /// Append data to an existing section. Returns the section offset of the data. -    pub fn append_section_data(&mut self, section: SectionId, data: &[u8], align: u64) -> u64 { -        self.sections[section.0].append_data(data, align) -    } - -    /// Append zero-initialized data to an existing section. Returns the section offset of the data. -    pub fn append_section_bss(&mut self, section: SectionId, size: u64, align: u64) -> u64 { -        self.sections[section.0].append_bss(size, align) -    } - -    /// Return the `SectionId` of a standard section. -    /// -    /// If the section doesn't already exist then it is created. -    pub fn section_id(&mut self, section: StandardSection) -> SectionId { -        self.standard_sections -            .get(§ion) -            .cloned() -            .unwrap_or_else(|| { -                let (segment, name, kind, flags) = self.section_info(section); -                let id = self.add_section(segment.to_vec(), name.to_vec(), kind); -                self.section_mut(id).flags = flags; -                id -            }) -    } - -    /// Add a new section and return its `SectionId`. -    /// -    /// This also creates a section symbol. -    pub fn add_section(&mut self, segment: Vec<u8>, name: Vec<u8>, kind: SectionKind) -> SectionId { -        let id = SectionId(self.sections.len()); -        self.sections.push(Section { -            segment, -            name, -            kind, -            size: 0, -            align: 1, -            data: Cow::Borrowed(&[]), -            relocations: Vec::new(), -            symbol: None, -            flags: SectionFlags::None, -        }); - -        // Add to self.standard_sections if required. This may match multiple standard sections. -        let section = &self.sections[id.0]; -        for standard_section in StandardSection::all() { -            if !self.standard_sections.contains_key(standard_section) { -                let (segment, name, kind, _flags) = self.section_info(*standard_section); -                if segment == &*section.segment && name == &*section.name && kind == section.kind { -                    self.standard_sections.insert(*standard_section, id); -                } -            } -        } - -        id -    } - -    fn section_info( -        &self, -        section: StandardSection, -    ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { -        match self.format { -            #[cfg(feature = "coff")] -            BinaryFormat::Coff => self.coff_section_info(section), -            #[cfg(feature = "elf")] -            BinaryFormat::Elf => self.elf_section_info(section), -            #[cfg(feature = "macho")] -            BinaryFormat::MachO => self.macho_section_info(section), -            #[cfg(feature = "xcoff")] -            BinaryFormat::Xcoff => self.xcoff_section_info(section), -            _ => unimplemented!(), -        } -    } - -    /// Add a subsection. Returns the `SectionId` and section offset of the data. -    pub fn add_subsection( -        &mut self, -        section: StandardSection, -        name: &[u8], -        data: &[u8], -        align: u64, -    ) -> (SectionId, u64) { -        let section_id = if self.has_subsections_via_symbols() { -            self.set_subsections_via_symbols(); -            self.section_id(section) -        } else { -            let (segment, name, kind, flags) = self.subsection_info(section, name); -            let id = self.add_section(segment.to_vec(), name, kind); -            self.section_mut(id).flags = flags; -            id -        }; -        let offset = self.append_section_data(section_id, data, align); -        (section_id, offset) -    } - -    fn has_subsections_via_symbols(&self) -> bool { -        match self.format { -            BinaryFormat::Coff | BinaryFormat::Elf | BinaryFormat::Xcoff => false, -            BinaryFormat::MachO => true, -            _ => unimplemented!(), -        } -    } - -    fn set_subsections_via_symbols(&mut self) { -        match self.format { -            #[cfg(feature = "macho")] -            BinaryFormat::MachO => self.macho_set_subsections_via_symbols(), -            _ => unimplemented!(), -        } -    } - -    fn subsection_info( -        &self, -        section: StandardSection, -        value: &[u8], -    ) -> (&'static [u8], Vec<u8>, SectionKind, SectionFlags) { -        let (segment, section, kind, flags) = self.section_info(section); -        let name = self.subsection_name(section, value); -        (segment, name, kind, flags) -    } - -    #[allow(unused_variables)] -    fn subsection_name(&self, section: &[u8], value: &[u8]) -> Vec<u8> { -        debug_assert!(!self.has_subsections_via_symbols()); -        match self.format { -            #[cfg(feature = "coff")] -            BinaryFormat::Coff => self.coff_subsection_name(section, value), -            #[cfg(feature = "elf")] -            BinaryFormat::Elf => self.elf_subsection_name(section, value), -            _ => unimplemented!(), -        } -    } - -    /// Get the COMDAT section group with the given `ComdatId`. -    #[inline] -    pub fn comdat(&self, comdat: ComdatId) -> &Comdat { -        &self.comdats[comdat.0] -    } - -    /// Mutably get the COMDAT section group with the given `ComdatId`. -    #[inline] -    pub fn comdat_mut(&mut self, comdat: ComdatId) -> &mut Comdat { -        &mut self.comdats[comdat.0] -    } - -    /// Add a new COMDAT section group and return its `ComdatId`. -    pub fn add_comdat(&mut self, comdat: Comdat) -> ComdatId { -        let comdat_id = ComdatId(self.comdats.len()); -        self.comdats.push(comdat); -        comdat_id -    } - -    /// Get the `SymbolId` of the symbol with the given name. -    pub fn symbol_id(&self, name: &[u8]) -> Option<SymbolId> { -        self.symbol_map.get(name).cloned() -    } - -    /// Get the symbol with the given `SymbolId`. -    #[inline] -    pub fn symbol(&self, symbol: SymbolId) -> &Symbol { -        &self.symbols[symbol.0] -    } - -    /// Mutably get the symbol with the given `SymbolId`. -    #[inline] -    pub fn symbol_mut(&mut self, symbol: SymbolId) -> &mut Symbol { -        &mut self.symbols[symbol.0] -    } - -    /// Add a new symbol and return its `SymbolId`. -    pub fn add_symbol(&mut self, mut symbol: Symbol) -> SymbolId { -        // Defined symbols must have a scope. -        debug_assert!(symbol.is_undefined() || symbol.scope != SymbolScope::Unknown); -        if symbol.kind == SymbolKind::Section { -            // There can only be one section symbol, but update its flags, since -            // the automatically generated section symbol will have none. -            let symbol_id = self.section_symbol(symbol.section.id().unwrap()); -            if symbol.flags != SymbolFlags::None { -                self.symbol_mut(symbol_id).flags = symbol.flags; -            } -            return symbol_id; -        } -        if !symbol.name.is_empty() -            && (symbol.kind == SymbolKind::Text -                || symbol.kind == SymbolKind::Data -                || symbol.kind == SymbolKind::Tls) -        { -            let unmangled_name = symbol.name.clone(); -            if let Some(prefix) = self.mangling.global_prefix() { -                symbol.name.insert(0, prefix); -            } -            let symbol_id = self.add_raw_symbol(symbol); -            self.symbol_map.insert(unmangled_name, symbol_id); -            symbol_id -        } else { -            self.add_raw_symbol(symbol) -        } -    } - -    fn add_raw_symbol(&mut self, symbol: Symbol) -> SymbolId { -        let symbol_id = SymbolId(self.symbols.len()); -        self.symbols.push(symbol); -        symbol_id -    } - -    /// Return true if the file format supports `StandardSection::UninitializedTls`. -    #[inline] -    pub fn has_uninitialized_tls(&self) -> bool { -        self.format != BinaryFormat::Coff -    } - -    /// Return true if the file format supports `StandardSection::Common`. -    #[inline] -    pub fn has_common(&self) -> bool { -        self.format == BinaryFormat::MachO -    } - -    /// Add a new common symbol and return its `SymbolId`. -    /// -    /// For Mach-O, this appends the symbol to the `__common` section. -    pub fn add_common_symbol(&mut self, mut symbol: Symbol, size: u64, align: u64) -> SymbolId { -        if self.has_common() { -            let symbol_id = self.add_symbol(symbol); -            let section = self.section_id(StandardSection::Common); -            self.add_symbol_bss(symbol_id, section, size, align); -            symbol_id -        } else { -            symbol.section = SymbolSection::Common; -            symbol.size = size; -            self.add_symbol(symbol) -        } -    } - -    /// Add a new file symbol and return its `SymbolId`. -    pub fn add_file_symbol(&mut self, name: Vec<u8>) -> SymbolId { -        self.add_raw_symbol(Symbol { -            name, -            value: 0, -            size: 0, -            kind: SymbolKind::File, -            scope: SymbolScope::Compilation, -            weak: false, -            section: SymbolSection::None, -            flags: SymbolFlags::None, -        }) -    } - -    /// Get the symbol for a section. -    pub fn section_symbol(&mut self, section_id: SectionId) -> SymbolId { -        let section = &mut self.sections[section_id.0]; -        if let Some(symbol) = section.symbol { -            return symbol; -        } -        let name = if self.format == BinaryFormat::Coff { -            section.name.clone() -        } else { -            Vec::new() -        }; -        let symbol_id = SymbolId(self.symbols.len()); -        self.symbols.push(Symbol { -            name, -            value: 0, -            size: 0, -            kind: SymbolKind::Section, -            scope: SymbolScope::Compilation, -            weak: false, -            section: SymbolSection::Section(section_id), -            flags: SymbolFlags::None, -        }); -        section.symbol = Some(symbol_id); -        symbol_id -    } - -    /// Append data to an existing section, and update a symbol to refer to it. -    /// -    /// For Mach-O, this also creates a `__thread_vars` entry for TLS symbols, and the -    /// symbol will indirectly point to the added data via the `__thread_vars` entry. -    /// -    /// Returns the section offset of the data. -    pub fn add_symbol_data( -        &mut self, -        symbol_id: SymbolId, -        section: SectionId, -        data: &[u8], -        align: u64, -    ) -> u64 { -        let offset = self.append_section_data(section, data, align); -        self.set_symbol_data(symbol_id, section, offset, data.len() as u64); -        offset -    } - -    /// Append zero-initialized data to an existing section, and update a symbol to refer to it. -    /// -    /// For Mach-O, this also creates a `__thread_vars` entry for TLS symbols, and the -    /// symbol will indirectly point to the added data via the `__thread_vars` entry. -    /// -    /// Returns the section offset of the data. -    pub fn add_symbol_bss( -        &mut self, -        symbol_id: SymbolId, -        section: SectionId, -        size: u64, -        align: u64, -    ) -> u64 { -        let offset = self.append_section_bss(section, size, align); -        self.set_symbol_data(symbol_id, section, offset, size); -        offset -    } - -    /// Update a symbol to refer to the given data within a section. -    /// -    /// For Mach-O, this also creates a `__thread_vars` entry for TLS symbols, and the -    /// symbol will indirectly point to the data via the `__thread_vars` entry. -    #[allow(unused_mut)] -    pub fn set_symbol_data( -        &mut self, -        mut symbol_id: SymbolId, -        section: SectionId, -        offset: u64, -        size: u64, -    ) { -        // Defined symbols must have a scope. -        debug_assert!(self.symbol(symbol_id).scope != SymbolScope::Unknown); -        match self.format { -            #[cfg(feature = "macho")] -            BinaryFormat::MachO => symbol_id = self.macho_add_thread_var(symbol_id), -            _ => {} -        } -        let symbol = self.symbol_mut(symbol_id); -        symbol.value = offset; -        symbol.size = size; -        symbol.section = SymbolSection::Section(section); -    } - -    /// Convert a symbol to a section symbol and offset. -    /// -    /// Returns `None` if the symbol does not have a section. -    pub fn symbol_section_and_offset(&mut self, symbol_id: SymbolId) -> Option<(SymbolId, u64)> { -        let symbol = self.symbol(symbol_id); -        if symbol.kind == SymbolKind::Section { -            return Some((symbol_id, 0)); -        } -        let symbol_offset = symbol.value; -        let section = symbol.section.id()?; -        let section_symbol = self.section_symbol(section); -        Some((section_symbol, symbol_offset)) -    } - -    /// Add a relocation to a section. -    /// -    /// Relocations must only be added after the referenced symbols have been added -    /// and defined (if applicable). -    pub fn add_relocation(&mut self, section: SectionId, mut relocation: Relocation) -> Result<()> { -        let addend = match self.format { -            #[cfg(feature = "coff")] -            BinaryFormat::Coff => self.coff_fixup_relocation(&mut relocation), -            #[cfg(feature = "elf")] -            BinaryFormat::Elf => self.elf_fixup_relocation(&mut relocation)?, -            #[cfg(feature = "macho")] -            BinaryFormat::MachO => self.macho_fixup_relocation(&mut relocation), -            #[cfg(feature = "xcoff")] -            BinaryFormat::Xcoff => self.xcoff_fixup_relocation(&mut relocation), -            _ => unimplemented!(), -        }; -        if addend != 0 { -            self.write_relocation_addend(section, &relocation, addend)?; -        } -        self.sections[section.0].relocations.push(relocation); -        Ok(()) -    } - -    fn write_relocation_addend( -        &mut self, -        section: SectionId, -        relocation: &Relocation, -        addend: i64, -    ) -> Result<()> { -        let data = self.sections[section.0].data_mut(); -        let offset = relocation.offset as usize; -        match relocation.size { -            32 => data.write_at(offset, &U32::new(self.endian, addend as u32)), -            64 => data.write_at(offset, &U64::new(self.endian, addend as u64)), -            _ => { -                return Err(Error(format!( -                    "unimplemented relocation addend {:?}", -                    relocation -                ))); -            } -        } -        .map_err(|_| { -            Error(format!( -                "invalid relocation offset {}+{} (max {})", -                relocation.offset, -                relocation.size, -                data.len() -            )) -        }) -    } - -    /// Write the object to a `Vec`. -    pub fn write(&self) -> Result<Vec<u8>> { -        let mut buffer = Vec::new(); -        self.emit(&mut buffer)?; -        Ok(buffer) -    } - -    /// Write the object to a `Write` implementation. -    /// -    /// Also flushes the writer. -    /// -    /// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter) -    /// instead of an unbuffered writer like [`File`](std::fs::File). -    #[cfg(feature = "std")] -    pub fn write_stream<W: io::Write>(&self, w: W) -> result::Result<(), Box<dyn error::Error>> { -        let mut stream = StreamingBuffer::new(w); -        self.emit(&mut stream)?; -        stream.result()?; -        stream.into_inner().flush()?; -        Ok(()) -    } - -    /// Write the object to a `WritableBuffer`. -    pub fn emit(&self, buffer: &mut dyn WritableBuffer) -> Result<()> { -        match self.format { -            #[cfg(feature = "coff")] -            BinaryFormat::Coff => self.coff_write(buffer), -            #[cfg(feature = "elf")] -            BinaryFormat::Elf => self.elf_write(buffer), -            #[cfg(feature = "macho")] -            BinaryFormat::MachO => self.macho_write(buffer), -            #[cfg(feature = "xcoff")] -            BinaryFormat::Xcoff => self.xcoff_write(buffer), -            _ => unimplemented!(), -        } -    } -} - -/// A standard segment kind. -#[allow(missing_docs)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[non_exhaustive] -pub enum StandardSegment { -    Text, -    Data, -    Debug, -} - -/// A standard section kind. -#[allow(missing_docs)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[non_exhaustive] -pub enum StandardSection { -    Text, -    Data, -    ReadOnlyData, -    ReadOnlyDataWithRel, -    ReadOnlyString, -    UninitializedData, -    Tls, -    /// Zero-fill TLS initializers. Unsupported for COFF. -    UninitializedTls, -    /// TLS variable structures. Only supported for Mach-O. -    TlsVariables, -    /// Common data. Only supported for Mach-O. -    Common, -    /// Notes for GNU properties. Only supported for ELF. -    GnuProperty, -} - -impl StandardSection { -    /// Return the section kind of a standard section. -    pub fn kind(self) -> SectionKind { -        match self { -            StandardSection::Text => SectionKind::Text, -            StandardSection::Data => SectionKind::Data, -            StandardSection::ReadOnlyData => SectionKind::ReadOnlyData, -            StandardSection::ReadOnlyDataWithRel => SectionKind::ReadOnlyDataWithRel, -            StandardSection::ReadOnlyString => SectionKind::ReadOnlyString, -            StandardSection::UninitializedData => SectionKind::UninitializedData, -            StandardSection::Tls => SectionKind::Tls, -            StandardSection::UninitializedTls => SectionKind::UninitializedTls, -            StandardSection::TlsVariables => SectionKind::TlsVariables, -            StandardSection::Common => SectionKind::Common, -            StandardSection::GnuProperty => SectionKind::Note, -        } -    } - -    // TODO: remembering to update this is error-prone, can we do better? -    fn all() -> &'static [StandardSection] { -        &[ -            StandardSection::Text, -            StandardSection::Data, -            StandardSection::ReadOnlyData, -            StandardSection::ReadOnlyDataWithRel, -            StandardSection::ReadOnlyString, -            StandardSection::UninitializedData, -            StandardSection::Tls, -            StandardSection::UninitializedTls, -            StandardSection::TlsVariables, -            StandardSection::Common, -            StandardSection::GnuProperty, -        ] -    } -} - -/// An identifier used to reference a section. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SectionId(usize); - -/// A section in an object file. -#[derive(Debug)] -pub struct Section<'a> { -    segment: Vec<u8>, -    name: Vec<u8>, -    kind: SectionKind, -    size: u64, -    align: u64, -    data: Cow<'a, [u8]>, -    relocations: Vec<Relocation>, -    symbol: Option<SymbolId>, -    /// Section flags that are specific to each file format. -    pub flags: SectionFlags, -} - -impl<'a> Section<'a> { -    /// Try to convert the name to a utf8 string. -    #[inline] -    pub fn name(&self) -> Option<&str> { -        str::from_utf8(&self.name).ok() -    } - -    /// Try to convert the segment to a utf8 string. -    #[inline] -    pub fn segment(&self) -> Option<&str> { -        str::from_utf8(&self.segment).ok() -    } - -    /// Return true if this section contains zerofill data. -    #[inline] -    pub fn is_bss(&self) -> bool { -        self.kind.is_bss() -    } - -    /// Set the data for a section. -    /// -    /// Must not be called for sections that already have data, or that contain uninitialized data. -    pub fn set_data<T>(&mut self, data: T, align: u64) -    where -        T: Into<Cow<'a, [u8]>>, -    { -        debug_assert!(!self.is_bss()); -        debug_assert_eq!(align & (align - 1), 0); -        debug_assert!(self.data.is_empty()); -        self.data = data.into(); -        self.size = self.data.len() as u64; -        self.align = align; -    } - -    /// Append data to a section. -    /// -    /// Must not be called for sections that contain uninitialized data. -    pub fn append_data(&mut self, append_data: &[u8], align: u64) -> u64 { -        debug_assert!(!self.is_bss()); -        debug_assert_eq!(align & (align - 1), 0); -        if self.align < align { -            self.align = align; -        } -        let align = align as usize; -        let data = self.data.to_mut(); -        let mut offset = data.len(); -        if offset & (align - 1) != 0 { -            offset += align - (offset & (align - 1)); -            data.resize(offset, 0); -        } -        data.extend_from_slice(append_data); -        self.size = data.len() as u64; -        offset as u64 -    } - -    /// Append uninitialized data to a section. -    /// -    /// Must not be called for sections that contain initialized data. -    pub fn append_bss(&mut self, size: u64, align: u64) -> u64 { -        debug_assert!(self.is_bss()); -        debug_assert_eq!(align & (align - 1), 0); -        if self.align < align { -            self.align = align; -        } -        let mut offset = self.size; -        if offset & (align - 1) != 0 { -            offset += align - (offset & (align - 1)); -            self.size = offset; -        } -        self.size += size; -        offset -    } - -    /// Returns the section as-built so far. -    /// -    /// This requires that the section is not a bss section. -    pub fn data(&self) -> &[u8] { -        debug_assert!(!self.is_bss()); -        &self.data -    } - -    /// Returns the section as-built so far. -    /// -    /// This requires that the section is not a bss section. -    pub fn data_mut(&mut self) -> &mut [u8] { -        debug_assert!(!self.is_bss()); -        self.data.to_mut() -    } -} - -/// The section where a symbol is defined. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum SymbolSection { -    /// The section is not applicable for this symbol (such as file symbols). -    None, -    /// The symbol is undefined. -    Undefined, -    /// The symbol has an absolute value. -    Absolute, -    /// The symbol is a zero-initialized symbol that will be combined with duplicate definitions. -    Common, -    /// The symbol is defined in the given section. -    Section(SectionId), -} - -impl SymbolSection { -    /// Returns the section id for the section where the symbol is defined. -    /// -    /// May return `None` if the symbol is not defined in a section. -    #[inline] -    pub fn id(self) -> Option<SectionId> { -        if let SymbolSection::Section(id) = self { -            Some(id) -        } else { -            None -        } -    } -} - -/// An identifier used to reference a symbol. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SymbolId(usize); - -/// A symbol in an object file. -#[derive(Debug)] -pub struct Symbol { -    /// The name of the symbol. -    pub name: Vec<u8>, -    /// The value of the symbol. -    /// -    /// If the symbol defined in a section, then this is the section offset of the symbol. -    pub value: u64, -    /// The size of the symbol. -    pub size: u64, -    /// The kind of the symbol. -    pub kind: SymbolKind, -    /// The scope of the symbol. -    pub scope: SymbolScope, -    /// Whether the symbol has weak binding. -    pub weak: bool, -    /// The section containing the symbol. -    pub section: SymbolSection, -    /// Symbol flags that are specific to each file format. -    pub flags: SymbolFlags<SectionId, SymbolId>, -} - -impl Symbol { -    /// Try to convert the name to a utf8 string. -    #[inline] -    pub fn name(&self) -> Option<&str> { -        str::from_utf8(&self.name).ok() -    } - -    /// Return true if the symbol is undefined. -    #[inline] -    pub fn is_undefined(&self) -> bool { -        self.section == SymbolSection::Undefined -    } - -    /// Return true if the symbol is common data. -    /// -    /// Note: does not check for `SymbolSection::Section` with `SectionKind::Common`. -    #[inline] -    pub fn is_common(&self) -> bool { -        self.section == SymbolSection::Common -    } - -    /// Return true if the symbol scope is local. -    #[inline] -    pub fn is_local(&self) -> bool { -        self.scope == SymbolScope::Compilation -    } -} - -/// A relocation in an object file. -#[derive(Debug)] -pub struct Relocation { -    /// The section offset of the place of the relocation. -    pub offset: u64, -    /// The size in bits of the place of relocation. -    pub size: u8, -    /// The operation used to calculate the result of the relocation. -    pub kind: RelocationKind, -    /// Information about how the result of the relocation operation is encoded in the place. -    pub encoding: RelocationEncoding, -    /// The symbol referred to by the relocation. -    /// -    /// This may be a section symbol. -    pub symbol: SymbolId, -    /// The addend to use in the relocation calculation. -    /// -    /// This may be in addition to an implicit addend stored at the place of the relocation. -    pub addend: i64, -} - -/// An identifier used to reference a COMDAT section group. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ComdatId(usize); - -/// A COMDAT section group. -#[derive(Debug)] -pub struct Comdat { -    /// The COMDAT selection kind. -    /// -    /// This determines the way in which the linker resolves multiple definitions of the COMDAT -    /// sections. -    pub kind: ComdatKind, -    /// The COMDAT symbol. -    /// -    /// If this symbol is referenced, then all sections in the group will be included by the -    /// linker. -    pub symbol: SymbolId, -    /// The sections in the group. -    pub sections: Vec<SectionId>, -} - -/// The symbol name mangling scheme. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum Mangling { -    /// No symbol mangling. -    None, -    /// Windows COFF symbol mangling. -    Coff, -    /// Windows COFF i386 symbol mangling. -    CoffI386, -    /// ELF symbol mangling. -    Elf, -    /// Mach-O symbol mangling. -    MachO, -    /// Xcoff symbol mangling. -    Xcoff, -} - -impl Mangling { -    /// Return the default symboling mangling for the given format and architecture. -    pub fn default(format: BinaryFormat, architecture: Architecture) -> Self { -        match (format, architecture) { -            (BinaryFormat::Coff, Architecture::I386) => Mangling::CoffI386, -            (BinaryFormat::Coff, _) => Mangling::Coff, -            (BinaryFormat::Elf, _) => Mangling::Elf, -            (BinaryFormat::MachO, _) => Mangling::MachO, -            (BinaryFormat::Xcoff, _) => Mangling::Xcoff, -            _ => Mangling::None, -        } -    } - -    /// Return the prefix to use for global symbols. -    pub fn global_prefix(self) -> Option<u8> { -        match self { -            Mangling::None | Mangling::Elf | Mangling::Coff | Mangling::Xcoff => None, -            Mangling::CoffI386 | Mangling::MachO => Some(b'_'), -        } -    } -} diff --git a/vendor/object/src/write/pe.rs b/vendor/object/src/write/pe.rs deleted file mode 100644 index 70da3a0..0000000 --- a/vendor/object/src/write/pe.rs +++ /dev/null @@ -1,847 +0,0 @@ -//! Helper for writing PE files. -use alloc::string::String; -use alloc::vec::Vec; -use core::mem; - -use crate::endian::{LittleEndian as LE, *}; -use crate::pe; -use crate::write::util; -use crate::write::{Error, Result, WritableBuffer}; - -/// A helper for writing PE files. -/// -/// Writing uses a two phase approach. The first phase reserves file ranges and virtual -/// address ranges for everything in the order that they will be written. -/// -/// The second phase writes everything out in order. Thus the caller must ensure writing -/// is in the same order that file ranges were reserved. -#[allow(missing_debug_implementations)] -pub struct Writer<'a> { -    is_64: bool, -    section_alignment: u32, -    file_alignment: u32, - -    buffer: &'a mut dyn WritableBuffer, -    len: u32, -    virtual_len: u32, -    headers_len: u32, - -    code_address: u32, -    data_address: u32, -    code_len: u32, -    data_len: u32, -    bss_len: u32, - -    nt_headers_offset: u32, -    data_directories: Vec<DataDirectory>, -    section_header_num: u16, -    sections: Vec<Section>, - -    symbol_offset: u32, -    symbol_num: u32, - -    reloc_blocks: Vec<RelocBlock>, -    relocs: Vec<U16<LE>>, -    reloc_offset: u32, -} - -impl<'a> Writer<'a> { -    /// Create a new `Writer`. -    pub fn new( -        is_64: bool, -        section_alignment: u32, -        file_alignment: u32, -        buffer: &'a mut dyn WritableBuffer, -    ) -> Self { -        Writer { -            is_64, -            section_alignment, -            file_alignment, - -            buffer, -            len: 0, -            virtual_len: 0, -            headers_len: 0, - -            code_address: 0, -            data_address: 0, -            code_len: 0, -            data_len: 0, -            bss_len: 0, - -            nt_headers_offset: 0, -            data_directories: Vec::new(), -            section_header_num: 0, -            sections: Vec::new(), - -            symbol_offset: 0, -            symbol_num: 0, - -            reloc_blocks: Vec::new(), -            relocs: Vec::new(), -            reloc_offset: 0, -        } -    } - -    /// Return the current virtual address size that has been reserved. -    /// -    /// This is only valid after section headers have been reserved. -    pub fn virtual_len(&self) -> u32 { -        self.virtual_len -    } - -    /// Reserve a virtual address range with the given size. -    /// -    /// The reserved length will be increased to match the section alignment. -    /// -    /// Returns the aligned offset of the start of the range. -    pub fn reserve_virtual(&mut self, len: u32) -> u32 { -        let offset = self.virtual_len; -        self.virtual_len += len; -        self.virtual_len = util::align_u32(self.virtual_len, self.section_alignment); -        offset -    } - -    /// Reserve up to the given virtual address. -    /// -    /// The reserved length will be increased to match the section alignment. -    pub fn reserve_virtual_until(&mut self, address: u32) { -        debug_assert!(self.virtual_len <= address); -        self.virtual_len = util::align_u32(address, self.section_alignment); -    } - -    /// Return the current file length that has been reserved. -    pub fn reserved_len(&self) -> u32 { -        self.len -    } - -    /// Return the current file length that has been written. -    #[allow(clippy::len_without_is_empty)] -    pub fn len(&self) -> usize { -        self.buffer.len() -    } - -    /// Reserve a file range with the given size and starting alignment. -    /// -    /// Returns the aligned offset of the start of the range. -    pub fn reserve(&mut self, len: u32, align_start: u32) -> u32 { -        if len == 0 { -            return self.len; -        } -        self.reserve_align(align_start); -        let offset = self.len; -        self.len += len; -        offset -    } - -    /// Reserve a file range with the given size and using the file alignment. -    /// -    /// Returns the aligned offset of the start of the range. -    pub fn reserve_file(&mut self, len: u32) -> u32 { -        self.reserve(len, self.file_alignment) -    } - -    /// Write data. -    pub fn write(&mut self, data: &[u8]) { -        self.buffer.write_bytes(data); -    } - -    /// Reserve alignment padding bytes. -    pub fn reserve_align(&mut self, align_start: u32) { -        self.len = util::align_u32(self.len, align_start); -    } - -    /// Write alignment padding bytes. -    pub fn write_align(&mut self, align_start: u32) { -        util::write_align(self.buffer, align_start as usize); -    } - -    /// Write padding up to the next multiple of file alignment. -    pub fn write_file_align(&mut self) { -        self.write_align(self.file_alignment); -    } - -    /// Reserve the file range up to the given file offset. -    pub fn reserve_until(&mut self, offset: u32) { -        debug_assert!(self.len <= offset); -        self.len = offset; -    } - -    /// Write padding up to the given file offset. -    pub fn pad_until(&mut self, offset: u32) { -        debug_assert!(self.buffer.len() <= offset as usize); -        self.buffer.resize(offset as usize); -    } - -    /// Reserve the range for the DOS header. -    /// -    /// This must be at the start of the file. -    /// -    /// When writing, you may use `write_custom_dos_header` or `write_empty_dos_header`. -    pub fn reserve_dos_header(&mut self) { -        debug_assert_eq!(self.len, 0); -        self.reserve(mem::size_of::<pe::ImageDosHeader>() as u32, 1); -    } - -    /// Write a custom DOS header. -    /// -    /// This must be at the start of the file. -    pub fn write_custom_dos_header(&mut self, dos_header: &pe::ImageDosHeader) -> Result<()> { -        debug_assert_eq!(self.buffer.len(), 0); - -        // Start writing. -        self.buffer -            .reserve(self.len as usize) -            .map_err(|_| Error(String::from("Cannot allocate buffer")))?; - -        self.buffer.write(dos_header); -        Ok(()) -    } - -    /// Write the DOS header for a file without a stub. -    /// -    /// This must be at the start of the file. -    /// -    /// Uses default values for all fields. -    pub fn write_empty_dos_header(&mut self) -> Result<()> { -        self.write_custom_dos_header(&pe::ImageDosHeader { -            e_magic: U16::new(LE, pe::IMAGE_DOS_SIGNATURE), -            e_cblp: U16::new(LE, 0), -            e_cp: U16::new(LE, 0), -            e_crlc: U16::new(LE, 0), -            e_cparhdr: U16::new(LE, 0), -            e_minalloc: U16::new(LE, 0), -            e_maxalloc: U16::new(LE, 0), -            e_ss: U16::new(LE, 0), -            e_sp: U16::new(LE, 0), -            e_csum: U16::new(LE, 0), -            e_ip: U16::new(LE, 0), -            e_cs: U16::new(LE, 0), -            e_lfarlc: U16::new(LE, 0), -            e_ovno: U16::new(LE, 0), -            e_res: [U16::new(LE, 0); 4], -            e_oemid: U16::new(LE, 0), -            e_oeminfo: U16::new(LE, 0), -            e_res2: [U16::new(LE, 0); 10], -            e_lfanew: U32::new(LE, self.nt_headers_offset), -        }) -    } - -    /// Reserve a fixed DOS header and stub. -    /// -    /// Use `reserve_dos_header` and `reserve` if you need a custom stub. -    pub fn reserve_dos_header_and_stub(&mut self) { -        self.reserve_dos_header(); -        self.reserve(64, 1); -    } - -    /// Write a fixed DOS header and stub. -    /// -    /// Use `write_custom_dos_header` and `write` if you need a custom stub. -    pub fn write_dos_header_and_stub(&mut self) -> Result<()> { -        self.write_custom_dos_header(&pe::ImageDosHeader { -            e_magic: U16::new(LE, pe::IMAGE_DOS_SIGNATURE), -            e_cblp: U16::new(LE, 0x90), -            e_cp: U16::new(LE, 3), -            e_crlc: U16::new(LE, 0), -            e_cparhdr: U16::new(LE, 4), -            e_minalloc: U16::new(LE, 0), -            e_maxalloc: U16::new(LE, 0xffff), -            e_ss: U16::new(LE, 0), -            e_sp: U16::new(LE, 0xb8), -            e_csum: U16::new(LE, 0), -            e_ip: U16::new(LE, 0), -            e_cs: U16::new(LE, 0), -            e_lfarlc: U16::new(LE, 0x40), -            e_ovno: U16::new(LE, 0), -            e_res: [U16::new(LE, 0); 4], -            e_oemid: U16::new(LE, 0), -            e_oeminfo: U16::new(LE, 0), -            e_res2: [U16::new(LE, 0); 10], -            e_lfanew: U32::new(LE, self.nt_headers_offset), -        })?; - -        #[rustfmt::skip] -        self.buffer.write_bytes(&[ -            0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, -            0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, -            0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, -            0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, -            0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, -            0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, -            0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, -            0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -        ]); - -        Ok(()) -    } - -    fn nt_headers_size(&self) -> u32 { -        if self.is_64 { -            mem::size_of::<pe::ImageNtHeaders64>() as u32 -        } else { -            mem::size_of::<pe::ImageNtHeaders32>() as u32 -        } -    } - -    fn optional_header_size(&self) -> u32 { -        let size = if self.is_64 { -            mem::size_of::<pe::ImageOptionalHeader64>() as u32 -        } else { -            mem::size_of::<pe::ImageOptionalHeader32>() as u32 -        }; -        size + self.data_directories.len() as u32 * mem::size_of::<pe::ImageDataDirectory>() as u32 -    } - -    /// Return the offset of the NT headers, if reserved. -    pub fn nt_headers_offset(&self) -> u32 { -        self.nt_headers_offset -    } - -    /// Reserve the range for the NT headers. -    pub fn reserve_nt_headers(&mut self, data_directory_num: usize) { -        debug_assert_eq!(self.nt_headers_offset, 0); -        self.nt_headers_offset = self.reserve(self.nt_headers_size(), 8); -        self.data_directories = vec![DataDirectory::default(); data_directory_num]; -        self.reserve( -            data_directory_num as u32 * mem::size_of::<pe::ImageDataDirectory>() as u32, -            1, -        ); -    } - -    /// Set the virtual address and size of a data directory. -    pub fn set_data_directory(&mut self, index: usize, virtual_address: u32, size: u32) { -        self.data_directories[index] = DataDirectory { -            virtual_address, -            size, -        } -    } - -    /// Write the NT headers. -    pub fn write_nt_headers(&mut self, nt_headers: NtHeaders) { -        self.pad_until(self.nt_headers_offset); -        self.buffer.write(&U32::new(LE, pe::IMAGE_NT_SIGNATURE)); -        let file_header = pe::ImageFileHeader { -            machine: U16::new(LE, nt_headers.machine), -            number_of_sections: U16::new(LE, self.section_header_num), -            time_date_stamp: U32::new(LE, nt_headers.time_date_stamp), -            pointer_to_symbol_table: U32::new(LE, self.symbol_offset), -            number_of_symbols: U32::new(LE, self.symbol_num), -            size_of_optional_header: U16::new(LE, self.optional_header_size() as u16), -            characteristics: U16::new(LE, nt_headers.characteristics), -        }; -        self.buffer.write(&file_header); -        if self.is_64 { -            let optional_header = pe::ImageOptionalHeader64 { -                magic: U16::new(LE, pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC), -                major_linker_version: nt_headers.major_linker_version, -                minor_linker_version: nt_headers.minor_linker_version, -                size_of_code: U32::new(LE, self.code_len), -                size_of_initialized_data: U32::new(LE, self.data_len), -                size_of_uninitialized_data: U32::new(LE, self.bss_len), -                address_of_entry_point: U32::new(LE, nt_headers.address_of_entry_point), -                base_of_code: U32::new(LE, self.code_address), -                image_base: U64::new(LE, nt_headers.image_base), -                section_alignment: U32::new(LE, self.section_alignment), -                file_alignment: U32::new(LE, self.file_alignment), -                major_operating_system_version: U16::new( -                    LE, -                    nt_headers.major_operating_system_version, -                ), -                minor_operating_system_version: U16::new( -                    LE, -                    nt_headers.minor_operating_system_version, -                ), -                major_image_version: U16::new(LE, nt_headers.major_image_version), -                minor_image_version: U16::new(LE, nt_headers.minor_image_version), -                major_subsystem_version: U16::new(LE, nt_headers.major_subsystem_version), -                minor_subsystem_version: U16::new(LE, nt_headers.minor_subsystem_version), -                win32_version_value: U32::new(LE, 0), -                size_of_image: U32::new(LE, self.virtual_len), -                size_of_headers: U32::new(LE, self.headers_len), -                check_sum: U32::new(LE, 0), -                subsystem: U16::new(LE, nt_headers.subsystem), -                dll_characteristics: U16::new(LE, nt_headers.dll_characteristics), -                size_of_stack_reserve: U64::new(LE, nt_headers.size_of_stack_reserve), -                size_of_stack_commit: U64::new(LE, nt_headers.size_of_stack_commit), -                size_of_heap_reserve: U64::new(LE, nt_headers.size_of_heap_reserve), -                size_of_heap_commit: U64::new(LE, nt_headers.size_of_heap_commit), -                loader_flags: U32::new(LE, 0), -                number_of_rva_and_sizes: U32::new(LE, self.data_directories.len() as u32), -            }; -            self.buffer.write(&optional_header); -        } else { -            let optional_header = pe::ImageOptionalHeader32 { -                magic: U16::new(LE, pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC), -                major_linker_version: nt_headers.major_linker_version, -                minor_linker_version: nt_headers.minor_linker_version, -                size_of_code: U32::new(LE, self.code_len), -                size_of_initialized_data: U32::new(LE, self.data_len), -                size_of_uninitialized_data: U32::new(LE, self.bss_len), -                address_of_entry_point: U32::new(LE, nt_headers.address_of_entry_point), -                base_of_code: U32::new(LE, self.code_address), -                base_of_data: U32::new(LE, self.data_address), -                image_base: U32::new(LE, nt_headers.image_base as u32), -                section_alignment: U32::new(LE, self.section_alignment), -                file_alignment: U32::new(LE, self.file_alignment), -                major_operating_system_version: U16::new( -                    LE, -                    nt_headers.major_operating_system_version, -                ), -                minor_operating_system_version: U16::new( -                    LE, -                    nt_headers.minor_operating_system_version, -                ), -                major_image_version: U16::new(LE, nt_headers.major_image_version), -                minor_image_version: U16::new(LE, nt_headers.minor_image_version), -                major_subsystem_version: U16::new(LE, nt_headers.major_subsystem_version), -                minor_subsystem_version: U16::new(LE, nt_headers.minor_subsystem_version), -                win32_version_value: U32::new(LE, 0), -                size_of_image: U32::new(LE, self.virtual_len), -                size_of_headers: U32::new(LE, self.headers_len), -                check_sum: U32::new(LE, 0), -                subsystem: U16::new(LE, nt_headers.subsystem), -                dll_characteristics: U16::new(LE, nt_headers.dll_characteristics), -                size_of_stack_reserve: U32::new(LE, nt_headers.size_of_stack_reserve as u32), -                size_of_stack_commit: U32::new(LE, nt_headers.size_of_stack_commit as u32), -                size_of_heap_reserve: U32::new(LE, nt_headers.size_of_heap_reserve as u32), -                size_of_heap_commit: U32::new(LE, nt_headers.size_of_heap_commit as u32), -                loader_flags: U32::new(LE, 0), -                number_of_rva_and_sizes: U32::new(LE, self.data_directories.len() as u32), -            }; -            self.buffer.write(&optional_header); -        } - -        for dir in &self.data_directories { -            self.buffer.write(&pe::ImageDataDirectory { -                virtual_address: U32::new(LE, dir.virtual_address), -                size: U32::new(LE, dir.size), -            }) -        } -    } - -    /// Reserve the section headers. -    /// -    /// The number of reserved section headers must be the same as the number of sections that -    /// are later reserved. -    // TODO: change this to a maximum number of sections? -    pub fn reserve_section_headers(&mut self, section_header_num: u16) { -        debug_assert_eq!(self.section_header_num, 0); -        self.section_header_num = section_header_num; -        self.reserve( -            u32::from(section_header_num) * mem::size_of::<pe::ImageSectionHeader>() as u32, -            1, -        ); -        // Padding before sections must be included in headers_len. -        self.reserve_align(self.file_alignment); -        self.headers_len = self.len; -        self.reserve_virtual(self.len); -    } - -    /// Write the section headers. -    /// -    /// This uses information that was recorded when the sections were reserved. -    pub fn write_section_headers(&mut self) { -        debug_assert_eq!(self.section_header_num as usize, self.sections.len()); -        for section in &self.sections { -            let section_header = pe::ImageSectionHeader { -                name: section.name, -                virtual_size: U32::new(LE, section.range.virtual_size), -                virtual_address: U32::new(LE, section.range.virtual_address), -                size_of_raw_data: U32::new(LE, section.range.file_size), -                pointer_to_raw_data: U32::new(LE, section.range.file_offset), -                pointer_to_relocations: U32::new(LE, 0), -                pointer_to_linenumbers: U32::new(LE, 0), -                number_of_relocations: U16::new(LE, 0), -                number_of_linenumbers: U16::new(LE, 0), -                characteristics: U32::new(LE, section.characteristics), -            }; -            self.buffer.write(§ion_header); -        } -    } - -    /// Reserve a section. -    /// -    /// Returns the file range and virtual address range that are reserved -    /// for the section. -    pub fn reserve_section( -        &mut self, -        name: [u8; 8], -        characteristics: u32, -        virtual_size: u32, -        data_size: u32, -    ) -> SectionRange { -        let virtual_address = self.reserve_virtual(virtual_size); - -        // Padding after section must be included in section file size. -        let file_size = util::align_u32(data_size, self.file_alignment); -        let file_offset = if file_size != 0 { -            self.reserve(file_size, self.file_alignment) -        } else { -            0 -        }; - -        // Sizes in optional header use the virtual size with the file alignment. -        let aligned_virtual_size = util::align_u32(virtual_size, self.file_alignment); -        if characteristics & pe::IMAGE_SCN_CNT_CODE != 0 { -            if self.code_address == 0 { -                self.code_address = virtual_address; -            } -            self.code_len += aligned_virtual_size; -        } else if characteristics & pe::IMAGE_SCN_CNT_INITIALIZED_DATA != 0 { -            if self.data_address == 0 { -                self.data_address = virtual_address; -            } -            self.data_len += aligned_virtual_size; -        } else if characteristics & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 { -            if self.data_address == 0 { -                self.data_address = virtual_address; -            } -            self.bss_len += aligned_virtual_size; -        } - -        let range = SectionRange { -            virtual_address, -            virtual_size, -            file_offset, -            file_size, -        }; -        self.sections.push(Section { -            name, -            characteristics, -            range, -        }); -        range -    } - -    /// Write the data for a section. -    pub fn write_section(&mut self, offset: u32, data: &[u8]) { -        if data.is_empty() { -            return; -        } -        self.pad_until(offset); -        self.write(data); -        self.write_align(self.file_alignment); -    } - -    /// Reserve a `.text` section. -    /// -    /// Contains executable code. -    pub fn reserve_text_section(&mut self, size: u32) -> SectionRange { -        self.reserve_section( -            *b".text\0\0\0", -            pe::IMAGE_SCN_CNT_CODE | pe::IMAGE_SCN_MEM_EXECUTE | pe::IMAGE_SCN_MEM_READ, -            size, -            size, -        ) -    } - -    /// Reserve a `.data` section. -    /// -    /// Contains initialized data. -    /// -    /// May also contain uninitialized data if `virtual_size` is greater than `data_size`. -    pub fn reserve_data_section(&mut self, virtual_size: u32, data_size: u32) -> SectionRange { -        self.reserve_section( -            *b".data\0\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_MEM_WRITE, -            virtual_size, -            data_size, -        ) -    } - -    /// Reserve a `.rdata` section. -    /// -    /// Contains read-only initialized data. -    pub fn reserve_rdata_section(&mut self, size: u32) -> SectionRange { -        self.reserve_section( -            *b".rdata\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ, -            size, -            size, -        ) -    } - -    /// Reserve a `.bss` section. -    /// -    /// Contains uninitialized data. -    pub fn reserve_bss_section(&mut self, size: u32) -> SectionRange { -        self.reserve_section( -            *b".bss\0\0\0\0", -            pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_MEM_WRITE, -            size, -            0, -        ) -    } - -    /// Reserve an `.idata` section. -    /// -    /// Contains import tables. Note that it is permissible to store import tables in a different -    /// section. -    /// -    /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_IMPORT` data directory. -    pub fn reserve_idata_section(&mut self, size: u32) -> SectionRange { -        let range = self.reserve_section( -            *b".idata\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_MEM_WRITE, -            size, -            size, -        ); -        let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_IMPORT]; -        debug_assert_eq!(dir.virtual_address, 0); -        *dir = DataDirectory { -            virtual_address: range.virtual_address, -            size, -        }; -        range -    } - -    /// Reserve an `.edata` section. -    /// -    /// Contains export tables. -    /// -    /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_EXPORT` data directory. -    pub fn reserve_edata_section(&mut self, size: u32) -> SectionRange { -        let range = self.reserve_section( -            *b".edata\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ, -            size, -            size, -        ); -        let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_EXPORT]; -        debug_assert_eq!(dir.virtual_address, 0); -        *dir = DataDirectory { -            virtual_address: range.virtual_address, -            size, -        }; -        range -    } - -    /// Reserve a `.pdata` section. -    /// -    /// Contains exception information. -    /// -    /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_EXCEPTION` data directory. -    pub fn reserve_pdata_section(&mut self, size: u32) -> SectionRange { -        let range = self.reserve_section( -            *b".pdata\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ, -            size, -            size, -        ); -        let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_EXCEPTION]; -        debug_assert_eq!(dir.virtual_address, 0); -        *dir = DataDirectory { -            virtual_address: range.virtual_address, -            size, -        }; -        range -    } - -    /// Reserve a `.xdata` section. -    /// -    /// Contains exception information. -    pub fn reserve_xdata_section(&mut self, size: u32) -> SectionRange { -        self.reserve_section( -            *b".xdata\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ, -            size, -            size, -        ) -    } - -    /// Reserve a `.rsrc` section. -    /// -    /// Contains the resource directory. -    /// -    /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_RESOURCE` data directory. -    pub fn reserve_rsrc_section(&mut self, size: u32) -> SectionRange { -        let range = self.reserve_section( -            *b".rsrc\0\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ, -            size, -            size, -        ); -        let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_RESOURCE]; -        debug_assert_eq!(dir.virtual_address, 0); -        *dir = DataDirectory { -            virtual_address: range.virtual_address, -            size, -        }; -        range -    } - -    /// Add a base relocation. -    /// -    /// `typ` must be one of the `IMAGE_REL_BASED_*` constants. -    pub fn add_reloc(&mut self, mut virtual_address: u32, typ: u16) { -        let reloc = U16::new(LE, typ << 12 | (virtual_address & 0xfff) as u16); -        virtual_address &= !0xfff; -        if let Some(block) = self.reloc_blocks.last_mut() { -            if block.virtual_address == virtual_address { -                self.relocs.push(reloc); -                block.count += 1; -                return; -            } -            // Blocks must have an even number of relocations. -            if block.count & 1 != 0 { -                self.relocs.push(U16::new(LE, 0)); -                block.count += 1; -            } -            debug_assert!(block.virtual_address < virtual_address); -        } -        self.relocs.push(reloc); -        self.reloc_blocks.push(RelocBlock { -            virtual_address, -            count: 1, -        }); -    } - -    /// Return true if a base relocation has been added. -    pub fn has_relocs(&mut self) -> bool { -        !self.relocs.is_empty() -    } - -    /// Reserve a `.reloc` section. -    /// -    /// This contains the base relocations that were added with `add_reloc`. -    /// -    /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_BASERELOC` data directory. -    pub fn reserve_reloc_section(&mut self) -> SectionRange { -        if let Some(block) = self.reloc_blocks.last_mut() { -            // Blocks must have an even number of relocations. -            if block.count & 1 != 0 { -                self.relocs.push(U16::new(LE, 0)); -                block.count += 1; -            } -        } -        let size = self.reloc_blocks.iter().map(RelocBlock::size).sum(); -        let range = self.reserve_section( -            *b".reloc\0\0", -            pe::IMAGE_SCN_CNT_INITIALIZED_DATA -                | pe::IMAGE_SCN_MEM_READ -                | pe::IMAGE_SCN_MEM_DISCARDABLE, -            size, -            size, -        ); -        let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_BASERELOC]; -        debug_assert_eq!(dir.virtual_address, 0); -        *dir = DataDirectory { -            virtual_address: range.virtual_address, -            size, -        }; -        self.reloc_offset = range.file_offset; -        range -    } - -    /// Write a `.reloc` section. -    /// -    /// This contains the base relocations that were added with `add_reloc`. -    pub fn write_reloc_section(&mut self) { -        if self.reloc_offset == 0 { -            return; -        } -        self.pad_until(self.reloc_offset); - -        let mut total = 0; -        for block in &self.reloc_blocks { -            self.buffer.write(&pe::ImageBaseRelocation { -                virtual_address: U32::new(LE, block.virtual_address), -                size_of_block: U32::new(LE, block.size()), -            }); -            self.buffer -                .write_slice(&self.relocs[total..][..block.count as usize]); -            total += block.count as usize; -        } -        debug_assert_eq!(total, self.relocs.len()); - -        self.write_align(self.file_alignment); -    } - -    /// Reserve the certificate table. -    /// -    /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_SECURITY` data directory. -    // TODO: reserve individual certificates -    pub fn reserve_certificate_table(&mut self, size: u32) { -        let size = util::align_u32(size, 8); -        let offset = self.reserve(size, 8); -        let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_SECURITY]; -        debug_assert_eq!(dir.virtual_address, 0); -        *dir = DataDirectory { -            virtual_address: offset, -            size, -        }; -    } - -    /// Write the certificate table. -    // TODO: write individual certificates -    pub fn write_certificate_table(&mut self, data: &[u8]) { -        let dir = self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_SECURITY]; -        self.pad_until(dir.virtual_address); -        self.write(data); -        self.pad_until(dir.virtual_address + dir.size); -    } -} - -/// Information required for writing [`pe::ImageNtHeaders32`] or [`pe::ImageNtHeaders64`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct NtHeaders { -    // ImageFileHeader -    pub machine: u16, -    pub time_date_stamp: u32, -    pub characteristics: u16, -    // ImageOptionalHeader -    pub major_linker_version: u8, -    pub minor_linker_version: u8, -    pub address_of_entry_point: u32, -    pub image_base: u64, -    pub major_operating_system_version: u16, -    pub minor_operating_system_version: u16, -    pub major_image_version: u16, -    pub minor_image_version: u16, -    pub major_subsystem_version: u16, -    pub minor_subsystem_version: u16, -    pub subsystem: u16, -    pub dll_characteristics: u16, -    pub size_of_stack_reserve: u64, -    pub size_of_stack_commit: u64, -    pub size_of_heap_reserve: u64, -    pub size_of_heap_commit: u64, -} - -#[derive(Default, Clone, Copy)] -struct DataDirectory { -    virtual_address: u32, -    size: u32, -} - -/// Information required for writing [`pe::ImageSectionHeader`]. -#[allow(missing_docs)] -#[derive(Debug, Clone)] -pub struct Section { -    pub name: [u8; pe::IMAGE_SIZEOF_SHORT_NAME], -    pub characteristics: u32, -    pub range: SectionRange, -} - -/// The file range and virtual address range for a section. -#[allow(missing_docs)] -#[derive(Debug, Default, Clone, Copy)] -pub struct SectionRange { -    pub virtual_address: u32, -    pub virtual_size: u32, -    pub file_offset: u32, -    pub file_size: u32, -} - -struct RelocBlock { -    virtual_address: u32, -    count: u32, -} - -impl RelocBlock { -    fn size(&self) -> u32 { -        mem::size_of::<pe::ImageBaseRelocation>() as u32 + self.count * mem::size_of::<u16>() as u32 -    } -} diff --git a/vendor/object/src/write/string.rs b/vendor/object/src/write/string.rs deleted file mode 100644 index b23274a..0000000 --- a/vendor/object/src/write/string.rs +++ /dev/null @@ -1,159 +0,0 @@ -use alloc::vec::Vec; - -#[cfg(feature = "std")] -type IndexSet<K> = indexmap::IndexSet<K>; -#[cfg(not(feature = "std"))] -type IndexSet<K> = indexmap::IndexSet<K, hashbrown::hash_map::DefaultHashBuilder>; - -/// An identifier for an entry in a string table. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct StringId(usize); - -#[derive(Debug, Default)] -pub(crate) struct StringTable<'a> { -    strings: IndexSet<&'a [u8]>, -    offsets: Vec<usize>, -} - -impl<'a> StringTable<'a> { -    /// Add a string to the string table. -    /// -    /// Panics if the string table has already been written, or -    /// if the string contains a null byte. -    pub fn add(&mut self, string: &'a [u8]) -> StringId { -        assert!(self.offsets.is_empty()); -        assert!(!string.contains(&0)); -        let id = self.strings.insert_full(string).0; -        StringId(id) -    } - -    /// Return the id of the given string. -    /// -    /// Panics if the string is not in the string table. -    pub fn get_id(&self, string: &[u8]) -> StringId { -        let id = self.strings.get_index_of(string).unwrap(); -        StringId(id) -    } - -    /// Return the string for the given id. -    /// -    /// Panics if the string is not in the string table. -    pub fn get_string(&self, id: StringId) -> &'a [u8] { -        self.strings.get_index(id.0).unwrap() -    } - -    /// Return the offset of the given string. -    /// -    /// Panics if the string table has not been written, or -    /// if the string is not in the string table. -    pub fn get_offset(&self, id: StringId) -> usize { -        self.offsets[id.0] -    } - -    /// Append the string table to the given `Vec`, and -    /// calculate the list of string offsets. -    /// -    /// `base` is the initial string table offset. For example, -    /// this should be 1 for ELF, to account for the initial -    /// null byte (which must have been written by the caller). -    pub fn write(&mut self, base: usize, w: &mut Vec<u8>) { -        assert!(self.offsets.is_empty()); - -        let mut ids: Vec<_> = (0..self.strings.len()).collect(); -        sort(&mut ids, 1, &self.strings); - -        self.offsets = vec![0; ids.len()]; -        let mut offset = base; -        let mut previous = &[][..]; -        for id in ids { -            let string = self.strings.get_index(id).unwrap(); -            if previous.ends_with(string) { -                self.offsets[id] = offset - string.len() - 1; -            } else { -                self.offsets[id] = offset; -                w.extend_from_slice(string); -                w.push(0); -                offset += string.len() + 1; -                previous = string; -            } -        } -    } -} - -// Multi-key quicksort. -// -// Ordering is such that if a string is a suffix of at least one other string, -// then it is placed immediately after one of those strings. That is: -// - comparison starts at the end of the string -// - shorter strings come later -// -// Based on the implementation in LLVM. -fn sort(mut ids: &mut [usize], mut pos: usize, strings: &IndexSet<&[u8]>) { -    loop { -        if ids.len() <= 1 { -            return; -        } - -        let pivot = byte(ids[0], pos, strings); -        let mut lower = 0; -        let mut upper = ids.len(); -        let mut i = 1; -        while i < upper { -            let b = byte(ids[i], pos, strings); -            if b > pivot { -                ids.swap(lower, i); -                lower += 1; -                i += 1; -            } else if b < pivot { -                upper -= 1; -                ids.swap(upper, i); -            } else { -                i += 1; -            } -        } - -        sort(&mut ids[..lower], pos, strings); -        sort(&mut ids[upper..], pos, strings); - -        if pivot == 0 { -            return; -        } -        ids = &mut ids[lower..upper]; -        pos += 1; -    } -} - -fn byte(id: usize, pos: usize, strings: &IndexSet<&[u8]>) -> u8 { -    let string = strings.get_index(id).unwrap(); -    let len = string.len(); -    if len >= pos { -        string[len - pos] -    } else { -        // We know the strings don't contain null bytes. -        0 -    } -} - -#[cfg(test)] -mod tests { -    use super::*; - -    #[test] -    fn string_table() { -        let mut table = StringTable::default(); -        let id0 = table.add(b""); -        let id1 = table.add(b"foo"); -        let id2 = table.add(b"bar"); -        let id3 = table.add(b"foobar"); - -        let mut data = Vec::new(); -        data.push(0); -        table.write(1, &mut data); -        assert_eq!(data, b"\0foobar\0foo\0"); - -        assert_eq!(table.get_offset(id0), 11); -        assert_eq!(table.get_offset(id1), 8); -        assert_eq!(table.get_offset(id2), 4); -        assert_eq!(table.get_offset(id3), 1); -    } -} diff --git a/vendor/object/src/write/util.rs b/vendor/object/src/write/util.rs deleted file mode 100644 index f7ee2f4..0000000 --- a/vendor/object/src/write/util.rs +++ /dev/null @@ -1,260 +0,0 @@ -use alloc::vec::Vec; -#[cfg(feature = "std")] -use std::{io, mem}; - -use crate::pod::{bytes_of, bytes_of_slice, Pod}; - -/// Trait for writable buffer. -#[allow(clippy::len_without_is_empty)] -pub trait WritableBuffer { -    /// Returns position/offset for data to be written at. -    /// -    /// Should only be used in debug assertions -    fn len(&self) -> usize; - -    /// Reserves specified number of bytes in the buffer. -    /// -    /// This will be called exactly once before writing anything to the buffer, -    /// and the given size is the exact total number of bytes that will be written. -    fn reserve(&mut self, size: usize) -> Result<(), ()>; - -    /// Writes zero bytes at the end of the buffer until the buffer -    /// has the specified length. -    fn resize(&mut self, new_len: usize); - -    /// Writes the specified slice of bytes at the end of the buffer. -    fn write_bytes(&mut self, val: &[u8]); - -    /// Writes the specified `Pod` type at the end of the buffer. -    fn write_pod<T: Pod>(&mut self, val: &T) -    where -        Self: Sized, -    { -        self.write_bytes(bytes_of(val)) -    } - -    /// Writes the specified `Pod` slice at the end of the buffer. -    fn write_pod_slice<T: Pod>(&mut self, val: &[T]) -    where -        Self: Sized, -    { -        self.write_bytes(bytes_of_slice(val)) -    } -} - -impl<'a> dyn WritableBuffer + 'a { -    /// Writes the specified `Pod` type at the end of the buffer. -    pub fn write<T: Pod>(&mut self, val: &T) { -        self.write_bytes(bytes_of(val)) -    } - -    /// Writes the specified `Pod` slice at the end of the buffer. -    pub fn write_slice<T: Pod>(&mut self, val: &[T]) { -        self.write_bytes(bytes_of_slice(val)) -    } -} - -impl WritableBuffer for Vec<u8> { -    #[inline] -    fn len(&self) -> usize { -        self.len() -    } - -    #[inline] -    fn reserve(&mut self, size: usize) -> Result<(), ()> { -        debug_assert!(self.is_empty()); -        self.reserve(size); -        Ok(()) -    } - -    #[inline] -    fn resize(&mut self, new_len: usize) { -        debug_assert!(new_len >= self.len()); -        self.resize(new_len, 0); -    } - -    #[inline] -    fn write_bytes(&mut self, val: &[u8]) { -        debug_assert!(self.len() + val.len() <= self.capacity()); -        self.extend_from_slice(val) -    } -} - -/// A [`WritableBuffer`] that streams data to a [`Write`](std::io::Write) implementation. -/// -/// [`Self::result`] must be called to determine if an I/O error occurred during writing. -/// -/// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter) -/// instead of an unbuffered writer like [`File`](std::fs::File). -#[cfg(feature = "std")] -#[derive(Debug)] -pub struct StreamingBuffer<W> { -    writer: W, -    len: usize, -    result: Result<(), io::Error>, -} - -#[cfg(feature = "std")] -impl<W> StreamingBuffer<W> { -    /// Create a new `StreamingBuffer` backed by the given writer. -    pub fn new(writer: W) -> Self { -        StreamingBuffer { -            writer, -            len: 0, -            result: Ok(()), -        } -    } - -    /// Unwraps this [`StreamingBuffer`] giving back the original writer. -    pub fn into_inner(self) -> W { -        self.writer -    } - -    /// Returns any error that occurred during writing. -    pub fn result(&mut self) -> Result<(), io::Error> { -        mem::replace(&mut self.result, Ok(())) -    } -} - -#[cfg(feature = "std")] -impl<W: io::Write> WritableBuffer for StreamingBuffer<W> { -    #[inline] -    fn len(&self) -> usize { -        self.len -    } - -    #[inline] -    fn reserve(&mut self, _size: usize) -> Result<(), ()> { -        Ok(()) -    } - -    #[inline] -    fn resize(&mut self, new_len: usize) { -        debug_assert!(self.len <= new_len); -        while self.len < new_len { -            let write_amt = (new_len - self.len - 1) % 1024 + 1; -            self.write_bytes(&[0; 1024][..write_amt]); -        } -    } - -    #[inline] -    fn write_bytes(&mut self, val: &[u8]) { -        if self.result.is_ok() { -            self.result = self.writer.write_all(val); -        } -        self.len += val.len(); -    } -} - -/// A trait for mutable byte slices. -/// -/// It provides convenience methods for `Pod` types. -pub(crate) trait BytesMut { -    fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()>; -} - -impl<'a> BytesMut for &'a mut [u8] { -    #[inline] -    fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()> { -        let src = bytes_of(val); -        let dest = self.get_mut(offset..).ok_or(())?; -        let dest = dest.get_mut(..src.len()).ok_or(())?; -        dest.copy_from_slice(src); -        Ok(()) -    } -} - -/// Write an unsigned number using the LEB128 encoding to a buffer. -/// -/// Returns the number of bytes written. -pub(crate) fn write_uleb128(buf: &mut Vec<u8>, mut val: u64) -> usize { -    let mut len = 0; -    loop { -        let mut byte = (val & 0x7f) as u8; -        val >>= 7; -        let done = val == 0; -        if !done { -            byte |= 0x80; -        } - -        buf.push(byte); -        len += 1; - -        if done { -            return len; -        } -    } -} - -/// Write a signed number using the LEB128 encoding to a buffer. -/// -/// Returns the number of bytes written. -#[allow(dead_code)] -pub(crate) fn write_sleb128(buf: &mut Vec<u8>, mut val: i64) -> usize { -    let mut len = 0; -    loop { -        let mut byte = val as u8; -        // Keep the sign bit for testing -        val >>= 6; -        let done = val == 0 || val == -1; -        if done { -            byte &= !0x80; -        } else { -            // Remove the sign bit -            val >>= 1; -            byte |= 0x80; -        } - -        buf.push(byte); -        len += 1; - -        if done { -            return len; -        } -    } -} - -pub(crate) fn align(offset: usize, size: usize) -> usize { -    (offset + (size - 1)) & !(size - 1) -} - -#[allow(dead_code)] -pub(crate) fn align_u32(offset: u32, size: u32) -> u32 { -    (offset + (size - 1)) & !(size - 1) -} - -#[allow(dead_code)] -pub(crate) fn align_u64(offset: u64, size: u64) -> u64 { -    (offset + (size - 1)) & !(size - 1) -} - -pub(crate) fn write_align(buffer: &mut dyn WritableBuffer, size: usize) { -    let new_len = align(buffer.len(), size); -    buffer.resize(new_len); -} - -#[cfg(test)] -mod tests { -    use super::*; - -    #[test] -    fn bytes_mut() { -        let data = vec![0x01, 0x23, 0x45, 0x67]; - -        let mut bytes = data.clone(); -        bytes.extend_from_slice(bytes_of(&u16::to_be(0x89ab))); -        assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab]); - -        let mut bytes = data.clone(); -        assert_eq!(bytes.write_at(0, &u16::to_be(0x89ab)), Ok(())); -        assert_eq!(bytes, [0x89, 0xab, 0x45, 0x67]); - -        let mut bytes = data.clone(); -        assert_eq!(bytes.write_at(2, &u16::to_be(0x89ab)), Ok(())); -        assert_eq!(bytes, [0x01, 0x23, 0x89, 0xab]); - -        assert_eq!(bytes.write_at(3, &u16::to_be(0x89ab)), Err(())); -        assert_eq!(bytes.write_at(4, &u16::to_be(0x89ab)), Err(())); -        assert_eq!(vec![].write_at(0, &u32::to_be(0x89ab)), Err(())); -    } -} diff --git a/vendor/object/src/write/xcoff.rs b/vendor/object/src/write/xcoff.rs deleted file mode 100644 index fc58886..0000000 --- a/vendor/object/src/write/xcoff.rs +++ /dev/null @@ -1,556 +0,0 @@ -use core::mem; - -use crate::endian::{BigEndian as BE, I16, U16, U32}; -use crate::write::string::*; -use crate::write::util::*; -use crate::write::*; - -use crate::{xcoff, AddressSize}; - -#[derive(Default, Clone, Copy)] -struct SectionOffsets { -    address: u64, -    data_offset: usize, -    reloc_offset: usize, -} - -#[derive(Default, Clone, Copy)] -struct SymbolOffsets { -    index: usize, -    str_id: Option<StringId>, -    aux_count: u8, -    storage_class: u8, -} - -impl<'a> Object<'a> { -    pub(crate) fn xcoff_section_info( -        &self, -        section: StandardSection, -    ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { -        match section { -            StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None), -            StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None), -            StandardSection::ReadOnlyData -            | StandardSection::ReadOnlyDataWithRel -            | StandardSection::ReadOnlyString => ( -                &[], -                &b".rdata"[..], -                SectionKind::ReadOnlyData, -                SectionFlags::None, -            ), -            StandardSection::UninitializedData => ( -                &[], -                &b".bss"[..], -                SectionKind::UninitializedData, -                SectionFlags::None, -            ), -            StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls, SectionFlags::None), -            StandardSection::UninitializedTls => ( -                &[], -                &b".tbss"[..], -                SectionKind::UninitializedTls, -                SectionFlags::None, -            ), -            StandardSection::TlsVariables => { -                // Unsupported section. -                (&[], &[], SectionKind::TlsVariables, SectionFlags::None) -            } -            StandardSection::Common => { -                // Unsupported section. -                (&[], &[], SectionKind::Common, SectionFlags::None) -            } -            StandardSection::GnuProperty => { -                // Unsupported section. -                (&[], &[], SectionKind::Note, SectionFlags::None) -            } -        } -    } - -    pub(crate) fn xcoff_fixup_relocation(&mut self, relocation: &mut Relocation) -> i64 { -        let constant = match relocation.kind { -            RelocationKind::Relative => relocation.addend + 4, -            _ => relocation.addend, -        }; -        relocation.addend -= constant; -        constant -    } - -    pub(crate) fn xcoff_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> { -        let is_64 = match self.architecture.address_size().unwrap() { -            AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false, -            AddressSize::U64 => true, -        }; - -        let (hdr_size, sechdr_size, rel_size, sym_size) = if is_64 { -            ( -                mem::size_of::<xcoff::FileHeader64>(), -                mem::size_of::<xcoff::SectionHeader64>(), -                mem::size_of::<xcoff::Rel64>(), -                mem::size_of::<xcoff::Symbol64>(), -            ) -        } else { -            ( -                mem::size_of::<xcoff::FileHeader32>(), -                mem::size_of::<xcoff::SectionHeader32>(), -                mem::size_of::<xcoff::Rel32>(), -                mem::size_of::<xcoff::Symbol32>(), -            ) -        }; - -        // Calculate offsets and build strtab. -        let mut offset = 0; -        let mut strtab = StringTable::default(); -        // We place the shared address 0 immediately after the section header table. -        let mut address = 0; - -        // XCOFF file header. -        offset += hdr_size; -        // Section headers. -        offset += self.sections.len() * sechdr_size; - -        // Calculate size of section data. -        let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()]; -        for (index, section) in self.sections.iter().enumerate() { -            let len = section.data.len(); -            let sectype = section.kind; -            // Section address should be 0 for all sections except the .text, .data, and .bss sections. -            if sectype == SectionKind::Data -                || sectype == SectionKind::Text -                || sectype == SectionKind::UninitializedData -            { -                section_offsets[index].address = address as u64; -                address += len; -                address = align(address, 4); -            } else { -                section_offsets[index].address = 0; -            } -            if len != 0 { -                // Set the default section alignment as 4. -                offset = align(offset, 4); -                section_offsets[index].data_offset = offset; -                offset += len; -            } else { -                section_offsets[index].data_offset = 0; -            } -        } - -        // Calculate size of relocations. -        for (index, section) in self.sections.iter().enumerate() { -            let count = section.relocations.len(); -            if count != 0 { -                section_offsets[index].reloc_offset = offset; -                offset += count * rel_size; -            } else { -                section_offsets[index].reloc_offset = 0; -            } -        } - -        // Calculate size of symbols. -        let mut file_str_id = None; -        let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()]; -        let mut symtab_count = 0; -        for (index, symbol) in self.symbols.iter().enumerate() { -            symbol_offsets[index].index = symtab_count; -            symtab_count += 1; - -            let storage_class = if let SymbolFlags::Xcoff { n_sclass, .. } = symbol.flags { -                n_sclass -            } else { -                match symbol.kind { -                    SymbolKind::Null => xcoff::C_NULL, -                    SymbolKind::File => xcoff::C_FILE, -                    SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls => { -                        if symbol.is_local() { -                            xcoff::C_STAT -                        } else if symbol.weak { -                            xcoff::C_WEAKEXT -                        } else { -                            xcoff::C_EXT -                        } -                    } -                    SymbolKind::Section | SymbolKind::Label | SymbolKind::Unknown => { -                        return Err(Error(format!( -                            "unimplemented symbol `{}` kind {:?}", -                            symbol.name().unwrap_or(""), -                            symbol.kind -                        ))); -                    } -                } -            }; -            symbol_offsets[index].storage_class = storage_class; - -            if storage_class == xcoff::C_FILE { -                if is_64 && file_str_id.is_none() { -                    file_str_id = Some(strtab.add(b".file")); -                } -                if symbol.name.len() > 8 { -                    symbol_offsets[index].str_id = Some(strtab.add(&symbol.name)); -                } -            } else if is_64 || symbol.name.len() > 8 { -                symbol_offsets[index].str_id = Some(strtab.add(&symbol.name)); -            } - -            symbol_offsets[index].aux_count = 0; -            match storage_class { -                xcoff::C_FILE => { -                    symbol_offsets[index].aux_count = 1; -                    symtab_count += 1; -                } -                xcoff::C_EXT | xcoff::C_WEAKEXT | xcoff::C_HIDEXT => { -                    symbol_offsets[index].aux_count = 1; -                    symtab_count += 1; -                } -                // TODO: support auxiliary entry for other types of symbol. -                _ => {} -            } -        } -        let symtab_offset = offset; -        let symtab_len = symtab_count * sym_size; -        offset += symtab_len; - -        // Calculate size of strtab. -        let strtab_offset = offset; -        let mut strtab_data = Vec::new(); -        // First 4 bytes of strtab are the length. -        strtab.write(4, &mut strtab_data); -        let strtab_len = strtab_data.len() + 4; -        offset += strtab_len; - -        // Start writing. -        buffer -            .reserve(offset) -            .map_err(|_| Error(String::from("Cannot allocate buffer")))?; - -        // Write file header. -        if is_64 { -            let header = xcoff::FileHeader64 { -                f_magic: U16::new(BE, xcoff::MAGIC_64), -                f_nscns: U16::new(BE, self.sections.len() as u16), -                f_timdat: U32::new(BE, 0), -                f_symptr: U64::new(BE, symtab_offset as u64), -                f_nsyms: U32::new(BE, symtab_count as u32), -                f_opthdr: U16::new(BE, 0), -                f_flags: match self.flags { -                    FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags), -                    _ => U16::default(), -                }, -            }; -            buffer.write(&header); -        } else { -            let header = xcoff::FileHeader32 { -                f_magic: U16::new(BE, xcoff::MAGIC_32), -                f_nscns: U16::new(BE, self.sections.len() as u16), -                f_timdat: U32::new(BE, 0), -                f_symptr: U32::new(BE, symtab_offset as u32), -                f_nsyms: U32::new(BE, symtab_count as u32), -                f_opthdr: U16::new(BE, 0), -                f_flags: match self.flags { -                    FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags), -                    _ => U16::default(), -                }, -            }; -            buffer.write(&header); -        } - -        // Write section headers. -        for (index, section) in self.sections.iter().enumerate() { -            let mut sectname = [0; 8]; -            sectname -                .get_mut(..section.name.len()) -                .ok_or_else(|| { -                    Error(format!( -                        "section name `{}` is too long", -                        section.name().unwrap_or(""), -                    )) -                })? -                .copy_from_slice(§ion.name); -            let flags = if let SectionFlags::Xcoff { s_flags } = section.flags { -                s_flags -            } else { -                match section.kind { -                    SectionKind::Text -                    | SectionKind::ReadOnlyData -                    | SectionKind::ReadOnlyString -                    | SectionKind::ReadOnlyDataWithRel => xcoff::STYP_TEXT, -                    SectionKind::Data => xcoff::STYP_DATA, -                    SectionKind::UninitializedData => xcoff::STYP_BSS, -                    SectionKind::Tls => xcoff::STYP_TDATA, -                    SectionKind::UninitializedTls => xcoff::STYP_TBSS, -                    SectionKind::OtherString => xcoff::STYP_INFO, -                    SectionKind::Debug => xcoff::STYP_DEBUG, -                    SectionKind::Other | SectionKind::Metadata => 0, -                    SectionKind::Note -                    | SectionKind::Linker -                    | SectionKind::Common -                    | SectionKind::Unknown -                    | SectionKind::TlsVariables -                    | SectionKind::Elf(_) => { -                        return Err(Error(format!( -                            "unimplemented section `{}` kind {:?}", -                            section.name().unwrap_or(""), -                            section.kind -                        ))); -                    } -                } -                .into() -            }; -            if is_64 { -                let section_header = xcoff::SectionHeader64 { -                    s_name: sectname, -                    s_paddr: U64::new(BE, section_offsets[index].address), -                    // This field has the same value as the s_paddr field. -                    s_vaddr: U64::new(BE, section_offsets[index].address), -                    s_size: U64::new(BE, section.data.len() as u64), -                    s_scnptr: U64::new(BE, section_offsets[index].data_offset as u64), -                    s_relptr: U64::new(BE, section_offsets[index].reloc_offset as u64), -                    s_lnnoptr: U64::new(BE, 0), -                    s_nreloc: U32::new(BE, section.relocations.len() as u32), -                    s_nlnno: U32::new(BE, 0), -                    s_flags: U32::new(BE, flags), -                    s_reserve: U32::new(BE, 0), -                }; -                buffer.write(§ion_header); -            } else { -                let section_header = xcoff::SectionHeader32 { -                    s_name: sectname, -                    s_paddr: U32::new(BE, section_offsets[index].address as u32), -                    // This field has the same value as the s_paddr field. -                    s_vaddr: U32::new(BE, section_offsets[index].address as u32), -                    s_size: U32::new(BE, section.data.len() as u32), -                    s_scnptr: U32::new(BE, section_offsets[index].data_offset as u32), -                    s_relptr: U32::new(BE, section_offsets[index].reloc_offset as u32), -                    s_lnnoptr: U32::new(BE, 0), -                    // 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. -                    s_nreloc: U16::new(BE, section.relocations.len() as u16), -                    s_nlnno: U16::new(BE, 0), -                    s_flags: U32::new(BE, flags), -                }; -                buffer.write(§ion_header); -            } -        } - -        // Write section data. -        for (index, section) in self.sections.iter().enumerate() { -            let len = section.data.len(); -            if len != 0 { -                write_align(buffer, 4); -                debug_assert_eq!(section_offsets[index].data_offset, buffer.len()); -                buffer.write_bytes(§ion.data); -            } -        } - -        // Write relocations. -        for (index, section) in self.sections.iter().enumerate() { -            if !section.relocations.is_empty() { -                debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len()); -                for reloc in §ion.relocations { -                    let rtype = match reloc.kind { -                        RelocationKind::Absolute => xcoff::R_POS, -                        RelocationKind::Relative => xcoff::R_REL, -                        RelocationKind::Got => xcoff::R_TOC, -                        RelocationKind::Xcoff(x) => x, -                        _ => { -                            return Err(Error(format!("unimplemented relocation {:?}", reloc))); -                        } -                    }; -                    if is_64 { -                        let xcoff_rel = xcoff::Rel64 { -                            r_vaddr: U64::new(BE, reloc.offset), -                            r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32), -                            // Specifies the bit length of the relocatable reference minus one. -                            r_rsize: (reloc.size - 1), -                            r_rtype: rtype, -                        }; -                        buffer.write(&xcoff_rel); -                    } else { -                        let xcoff_rel = xcoff::Rel32 { -                            r_vaddr: U32::new(BE, reloc.offset as u32), -                            r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32), -                            r_rsize: (reloc.size - 1), -                            r_rtype: rtype, -                        }; -                        buffer.write(&xcoff_rel); -                    } -                } -            } -        } - -        // Write symbols. -        debug_assert_eq!(symtab_offset, buffer.len()); -        for (index, symbol) in self.symbols.iter().enumerate() { -            let (n_value, section_kind) = if let SymbolSection::Section(id) = symbol.section { -                ( -                    section_offsets[id.0].address + symbol.value, -                    self.sections[id.0].kind, -                ) -            } else { -                (symbol.value, SectionKind::Unknown) -            }; -            let n_scnum = match symbol.section { -                SymbolSection::None => { -                    debug_assert_eq!(symbol.kind, SymbolKind::File); -                    xcoff::N_DEBUG -                } -                SymbolSection::Undefined | SymbolSection::Common => xcoff::N_UNDEF, -                SymbolSection::Absolute => xcoff::N_ABS, -                SymbolSection::Section(id) => id.0 as i16 + 1, -            }; -            let n_sclass = symbol_offsets[index].storage_class; -            let n_type = if (symbol.scope == SymbolScope::Linkage) -                && (n_sclass == xcoff::C_EXT -                    || n_sclass == xcoff::C_WEAKEXT -                    || n_sclass == xcoff::C_HIDEXT) -            { -                xcoff::SYM_V_HIDDEN -            } else { -                0 -            }; -            let n_numaux = symbol_offsets[index].aux_count; -            if is_64 { -                let str_id = if n_sclass == xcoff::C_FILE { -                    file_str_id.unwrap() -                } else { -                    symbol_offsets[index].str_id.unwrap() -                }; -                let xcoff_sym = xcoff::Symbol64 { -                    n_value: U64::new(BE, n_value), -                    n_offset: U32::new(BE, strtab.get_offset(str_id) as u32), -                    n_scnum: I16::new(BE, n_scnum), -                    n_type: U16::new(BE, n_type), -                    n_sclass, -                    n_numaux, -                }; -                buffer.write(&xcoff_sym); -            } else { -                let mut sym_name = [0; 8]; -                if n_sclass == xcoff::C_FILE { -                    sym_name[..5].copy_from_slice(b".file"); -                } else if symbol.name.len() <= 8 { -                    sym_name[..symbol.name.len()].copy_from_slice(&symbol.name[..]); -                } else { -                    let str_offset = strtab.get_offset(symbol_offsets[index].str_id.unwrap()); -                    sym_name[4..8].copy_from_slice(&u32::to_be_bytes(str_offset as u32)); -                } -                let xcoff_sym = xcoff::Symbol32 { -                    n_name: sym_name, -                    n_value: U32::new(BE, n_value as u32), -                    n_scnum: I16::new(BE, n_scnum), -                    n_type: U16::new(BE, n_type), -                    n_sclass, -                    n_numaux, -                }; -                buffer.write(&xcoff_sym); -            } -            // Generate auxiliary entries. -            if n_sclass == xcoff::C_FILE { -                debug_assert_eq!(n_numaux, 1); -                let mut x_fname = [0; 8]; -                if symbol.name.len() <= 8 { -                    x_fname[..symbol.name.len()].copy_from_slice(&symbol.name[..]); -                } else { -                    let str_offset = strtab.get_offset(symbol_offsets[index].str_id.unwrap()); -                    x_fname[4..8].copy_from_slice(&u32::to_be_bytes(str_offset as u32)); -                } -                if is_64 { -                    let file_aux = xcoff::FileAux64 { -                        x_fname, -                        x_fpad: Default::default(), -                        x_ftype: xcoff::XFT_FN, -                        x_freserve: Default::default(), -                        x_auxtype: xcoff::AUX_FILE, -                    }; -                    buffer.write(&file_aux); -                } else { -                    let file_aux = xcoff::FileAux32 { -                        x_fname, -                        x_fpad: Default::default(), -                        x_ftype: xcoff::XFT_FN, -                        x_freserve: Default::default(), -                    }; -                    buffer.write(&file_aux); -                } -            } else if n_sclass == xcoff::C_EXT -                || n_sclass == xcoff::C_WEAKEXT -                || n_sclass == xcoff::C_HIDEXT -            { -                debug_assert_eq!(n_numaux, 1); -                let (x_smtyp, x_smclas) = if let SymbolFlags::Xcoff { -                    x_smtyp, x_smclas, .. -                } = symbol.flags -                { -                    (x_smtyp, x_smclas) -                } else { -                    match symbol.kind { -                        SymbolKind::Text => (xcoff::XTY_SD, xcoff::XMC_PR), -                        SymbolKind::Data => { -                            if section_kind == SectionKind::UninitializedData { -                                (xcoff::XTY_CM, xcoff::XMC_BS) -                            } else if section_kind == SectionKind::ReadOnlyData { -                                (xcoff::XTY_SD, xcoff::XMC_RO) -                            } else { -                                (xcoff::XTY_SD, xcoff::XMC_RW) -                            } -                        } -                        SymbolKind::Tls => { -                            if section_kind == SectionKind::UninitializedTls { -                                (xcoff::XTY_CM, xcoff::XMC_UL) -                            } else { -                                (xcoff::XTY_SD, xcoff::XMC_TL) -                            } -                        } -                        _ => { -                            return Err(Error(format!( -                                "unimplemented symbol `{}` kind {:?}", -                                symbol.name().unwrap_or(""), -                                symbol.kind -                            ))); -                        } -                    } -                }; -                let scnlen = if let SymbolFlags::Xcoff { -                    containing_csect: Some(containing_csect), -                    .. -                } = symbol.flags -                { -                    symbol_offsets[containing_csect.0].index as u64 -                } else { -                    symbol.size -                }; -                if is_64 { -                    let csect_aux = xcoff::CsectAux64 { -                        x_scnlen_lo: U32::new(BE, (scnlen & 0xFFFFFFFF) as u32), -                        x_scnlen_hi: U32::new(BE, ((scnlen >> 32) & 0xFFFFFFFF) as u32), -                        x_parmhash: U32::new(BE, 0), -                        x_snhash: U16::new(BE, 0), -                        x_smtyp, -                        x_smclas, -                        pad: 0, -                        x_auxtype: xcoff::AUX_CSECT, -                    }; -                    buffer.write(&csect_aux); -                } else { -                    let csect_aux = xcoff::CsectAux32 { -                        x_scnlen: U32::new(BE, scnlen as u32), -                        x_parmhash: U32::new(BE, 0), -                        x_snhash: U16::new(BE, 0), -                        x_smtyp, -                        x_smclas, -                        x_stab: U32::new(BE, 0), -                        x_snstab: U16::new(BE, 0), -                    }; -                    buffer.write(&csect_aux); -                } -            } -        } - -        // Write string table. -        debug_assert_eq!(strtab_offset, buffer.len()); -        buffer.write_bytes(&u32::to_be_bytes(strtab_len as u32)); -        buffer.write_bytes(&strtab_data); - -        debug_assert_eq!(offset, buffer.len()); -        Ok(()) -    } -} diff --git a/vendor/object/src/xcoff.rs b/vendor/object/src/xcoff.rs deleted file mode 100644 index dbe5d73..0000000 --- a/vendor/object/src/xcoff.rs +++ /dev/null @@ -1,905 +0,0 @@ -//! XCOFF definitions -//! -//! These definitions are independent of read/write support, although we do implement -//! some traits useful for those. -//! -//! This module is the equivalent of /usr/include/xcoff.h, and is based heavily on it. - -#![allow(missing_docs)] - -use crate::endian::{BigEndian as BE, I16, U16, U32, U64}; -use crate::pod::Pod; - -/// The header at the start of every 32-bit XCOFF file. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FileHeader32 { -    /// Magic number. Must be 0x01DF. -    pub f_magic: U16<BE>, -    /// Number of sections. -    pub f_nscns: U16<BE>, -    /// Time and date of file creation. -    pub f_timdat: U32<BE>, -    /// Byte offset to symbol table start. -    pub f_symptr: U32<BE>, -    /// Number of entries in symbol table. -    pub f_nsyms: U32<BE>, -    /// Number of bytes in optional header -    pub f_opthdr: U16<BE>, -    /// Extra flags. -    pub f_flags: U16<BE>, -} - -/// The header at the start of every 64-bit XCOFF file. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FileHeader64 { -    /// Magic number. Must be 0x01F7. -    pub f_magic: U16<BE>, -    /// Number of sections. -    pub f_nscns: U16<BE>, -    /// Time and date of file creation -    pub f_timdat: U32<BE>, -    /// Byte offset to symbol table start. -    pub f_symptr: U64<BE>, -    /// Number of bytes in optional header -    pub f_opthdr: U16<BE>, -    /// Extra flags. -    pub f_flags: U16<BE>, -    /// Number of entries in symbol table. -    pub f_nsyms: U32<BE>, -} - -// Values for `f_magic`. -// -/// the 64-bit mach magic number -pub const MAGIC_64: u16 = 0x01F7; -/// the 32-bit mach magic number -pub const MAGIC_32: u16 = 0x01DF; - -// Values for `f_flags`. -// -/// Indicates that the relocation information for binding has been removed from -/// the file. -pub const F_RELFLG: u16 = 0x0001; -/// Indicates that the file is executable. No unresolved external references exist. -pub const F_EXEC: u16 = 0x0002; -/// Indicates that line numbers have been stripped from the file by a utility program. -pub const F_LNNO: u16 = 0x0004; -/// Indicates that the file was profiled with the fdpr command. -pub const F_FDPR_PROF: u16 = 0x0010; -/// Indicates that the file was reordered with the fdpr command. -pub const F_FDPR_OPTI: u16 = 0x0020; -/// Indicates that the file uses Very Large Program Support. -pub const F_DSA: u16 = 0x0040; -/// Indicates that one of the members of the auxiliary header specifying the -/// medium page sizes is non-zero. -pub const F_VARPG: u16 = 0x0100; -/// Indicates the file is dynamically loadable and executable. External references -/// are resolved by way of imports, and the file might contain exports and loader -/// relocation. -pub const F_DYNLOAD: u16 = 0x1000; -/// Indicates the file is a shared object (shared library). The file is separately -/// loadable. That is, it is not normally bound with other objects, and its loader -/// exports symbols are used as automatic import symbols for other object files. -pub const F_SHROBJ: u16 = 0x2000; -/// If the object file is a member of an archive, it can be loaded by the system -/// loader, but the member is ignored by the binder. If the object file is not in -/// an archive, this flag has no effect. -pub const F_LOADONLY: u16 = 0x4000; - -/// The auxiliary header immediately following file header. If the value of the -/// f_opthdr field in the file header is 0, the auxiliary header does not exist. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AuxHeader32 { -    /// Flags. -    pub o_mflag: U16<BE>, -    /// Version. -    pub o_vstamp: U16<BE>, -    /// Text size in bytes. -    pub o_tsize: U32<BE>, -    /// Initialized data size in bytes. -    pub o_dsize: U32<BE>, -    /// Uninitialized data size in bytes. -    pub o_bsize: U32<BE>, -    /// Entry point descriptor (virtual address). -    pub o_entry: U32<BE>, -    /// Base address of text (virtual address). -    pub o_text_start: U32<BE>, -    /// Base address of data (virtual address). -    pub o_data_start: U32<BE>, -    /// Address of TOC anchor. -    pub o_toc: U32<BE>, -    /// Section number for entry point. -    pub o_snentry: U16<BE>, -    /// Section number for .text. -    pub o_sntext: U16<BE>, -    /// Section number for .data. -    pub o_sndata: U16<BE>, -    /// Section number for TOC. -    pub o_sntoc: U16<BE>, -    /// Section number for loader data. -    pub o_snloader: U16<BE>, -    /// Section number for .bss. -    pub o_snbss: U16<BE>, -    /// Maximum alignment for .text. -    pub o_algntext: U16<BE>, -    /// Maximum alignment for .data. -    pub o_algndata: U16<BE>, -    /// Module type field. -    pub o_modtype: U16<BE>, -    /// Bit flags - cpu types of objects. -    pub o_cpuflag: u8, -    /// Reserved for CPU type. -    pub o_cputype: u8, -    /// Maximum stack size allowed (bytes). -    pub o_maxstack: U32<BE>, -    /// Maximum data size allowed (bytes). -    pub o_maxdata: U32<BE>, -    /// Reserved for debuggers. -    pub o_debugger: U32<BE>, -    /// Requested text page size. -    pub o_textpsize: u8, -    /// Requested data page size. -    pub o_datapsize: u8, -    /// Requested stack page size. -    pub o_stackpsize: u8, -    /// Flags and thread-local storage alignment. -    pub o_flags: u8, -    /// Section number for .tdata. -    pub o_sntdata: U16<BE>, -    /// Section number for .tbss. -    pub o_sntbss: U16<BE>, -} - -/// The auxiliary header immediately following file header. If the value of the -/// f_opthdr field in the file header is 0, the auxiliary header does not exist. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct AuxHeader64 { -    /// Flags. -    pub o_mflag: U16<BE>, -    /// Version. -    pub o_vstamp: U16<BE>, -    /// Reserved for debuggers. -    pub o_debugger: U32<BE>, -    /// Base address of text (virtual address). -    pub o_text_start: U64<BE>, -    /// Base address of data (virtual address). -    pub o_data_start: U64<BE>, -    /// Address of TOC anchor. -    pub o_toc: U64<BE>, -    /// Section number for entry point. -    pub o_snentry: U16<BE>, -    /// Section number for .text. -    pub o_sntext: U16<BE>, -    /// Section number for .data. -    pub o_sndata: U16<BE>, -    /// Section number for TOC. -    pub o_sntoc: U16<BE>, -    /// Section number for loader data. -    pub o_snloader: U16<BE>, -    /// Section number for .bss. -    pub o_snbss: U16<BE>, -    /// Maximum alignment for .text. -    pub o_algntext: U16<BE>, -    /// Maximum alignment for .data. -    pub o_algndata: U16<BE>, -    /// Module type field. -    pub o_modtype: U16<BE>, -    /// Bit flags - cpu types of objects. -    pub o_cpuflag: u8, -    /// Reserved for CPU type. -    pub o_cputype: u8, -    /// Requested text page size. -    pub o_textpsize: u8, -    /// Requested data page size. -    pub o_datapsize: u8, -    /// Requested stack page size. -    pub o_stackpsize: u8, -    /// Flags and thread-local storage alignment. -    pub o_flags: u8, -    /// Text size in bytes. -    pub o_tsize: U64<BE>, -    /// Initialized data size in bytes. -    pub o_dsize: U64<BE>, -    /// Uninitialized data size in bytes. -    pub o_bsize: U64<BE>, -    /// Entry point descriptor (virtual address). -    pub o_entry: U64<BE>, -    /// Maximum stack size allowed (bytes). -    pub o_maxstack: U64<BE>, -    /// Maximum data size allowed (bytes). -    pub o_maxdata: U64<BE>, -    /// Section number for .tdata. -    pub o_sntdata: U16<BE>, -    /// Section number for .tbss. -    pub o_sntbss: U16<BE>, -    /// XCOFF64 flags. -    pub o_x64flags: U16<BE>, -    /// Reserved. -    pub o_resv3a: U16<BE>, -    /// Reserved. -    pub o_resv3: [U32<BE>; 2], -} - -/// Some AIX programs generate auxiliary headers for 32-bit object files that -/// end after the data_start field. -pub const AOUTHSZ_SHORT: u16 = 28; - -/// Section header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SectionHeader32 { -    /// Section name. -    pub s_name: [u8; 8], -    /// Physical address. -    pub s_paddr: U32<BE>, -    /// Virtual address (same as physical address). -    pub s_vaddr: U32<BE>, -    /// Section size. -    pub s_size: U32<BE>, -    /// Offset in file to raw data for section. -    pub s_scnptr: U32<BE>, -    /// Offset in file to relocation entries for section. -    pub s_relptr: U32<BE>, -    /// Offset in file to line number entries for section. -    pub s_lnnoptr: U32<BE>, -    /// Number of relocation entries. -    pub s_nreloc: U16<BE>, -    /// Number of line number entries. -    pub s_nlnno: U16<BE>, -    /// Flags to define the section type. -    pub s_flags: U32<BE>, -} - -/// Section header. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SectionHeader64 { -    /// Section name. -    pub s_name: [u8; 8], -    /// Physical address. -    pub s_paddr: U64<BE>, -    /// Virtual address (same as physical address). -    pub s_vaddr: U64<BE>, -    /// Section size. -    pub s_size: U64<BE>, -    /// Offset in file to raw data for section. -    pub s_scnptr: U64<BE>, -    /// Offset in file to relocation entries for section. -    pub s_relptr: U64<BE>, -    /// Offset in file to line number entries for section. -    pub s_lnnoptr: U64<BE>, -    /// Number of relocation entries. -    pub s_nreloc: U32<BE>, -    /// Number of line number entries. -    pub s_nlnno: U32<BE>, -    /// Flags to define the section type. -    pub s_flags: U32<BE>, -    /// Reserved. -    pub s_reserve: U32<BE>, -} - -// Values for `s_flags`. -// -/// "regular" section -pub const STYP_REG: u16 = 0x00; -/// Specifies a pad section. A section of this type is used to provide alignment -/// padding between sections within an XCOFF executable object file. This section -/// header type is obsolete since padding is allowed in an XCOFF file without a -/// corresponding pad section header. -pub const STYP_PAD: u16 = 0x08; -/// Specifies a DWARF debugging section, which provide source file and symbol -/// information for the symbolic debugger. -pub const STYP_DWARF: u16 = 0x10; -/// Specifies an executable text (code) section. A section of this type contains -/// the executable instructions of a program. -pub const STYP_TEXT: u16 = 0x20; -/// Specifies an initialized data section. A section of this type contains the -/// initialized data and the TOC of a program. -pub const STYP_DATA: u16 = 0x40; -/// Specifies an uninitialized data section. A section header of this type -/// defines the uninitialized data of a program. -pub const STYP_BSS: u16 = 0x80; -/// Specifies an exception section. A section of this type provides information -/// to identify the reason that a trap or exception occurred within an executable -/// object program. -pub const STYP_EXCEPT: u16 = 0x0100; -/// Specifies a comment section. A section of this type provides comments or data -/// to special processing utility programs. -pub const STYP_INFO: u16 = 0x0200; -/// Specifies an initialized thread-local data section. -pub const STYP_TDATA: u16 = 0x0400; -/// Specifies an uninitialized thread-local data section. -pub const STYP_TBSS: u16 = 0x0800; -/// Specifies a loader section. A section of this type contains object file -/// information for the system loader to load an XCOFF executable. The information -/// includes imported symbols, exported symbols, relocation data, type-check -/// information, and shared object names. -pub const STYP_LOADER: u16 = 0x1000; -/// Specifies a debug section. A section of this type contains stabstring -/// information used by the symbolic debugger. -pub const STYP_DEBUG: u16 = 0x2000; -/// Specifies a type-check section. A section of this type contains -/// parameter/argument type-check strings used by the binder. -pub const STYP_TYPCHK: u16 = 0x4000; -/// Specifies a relocation or line-number field overflow section. A section -/// header of this type contains the count of relocation entries and line -/// number entries for some other section. This section header is required -/// when either of the counts exceeds 65,534. -pub const STYP_OVRFLO: u16 = 0x8000; - -pub const SSUBTYP_DWINFO: u32 = 0x10000; -pub const SSUBTYP_DWLINE: u32 = 0x20000; -pub const SSUBTYP_DWPBNMS: u32 = 0x30000; -pub const SSUBTYP_DWPBTYP: u32 = 0x40000; -pub const SSUBTYP_DWARNGE: u32 = 0x50000; -pub const SSUBTYP_DWABREV: u32 = 0x60000; -pub const SSUBTYP_DWSTR: u32 = 0x70000; -pub const SSUBTYP_DWRNGES: u32 = 0x80000; -pub const SSUBTYP_DWLOC: u32 = 0x90000; -pub const SSUBTYP_DWFRAME: u32 = 0xA0000; -pub const SSUBTYP_DWMAC: u32 = 0xB0000; - -pub const SIZEOF_SYMBOL: usize = 18; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct SymbolBytes(pub [u8; SIZEOF_SYMBOL]); - -/// Symbol table entry. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Symbol32 { -    /// Symbol name. -    /// -    /// If first 4 bytes are 0, then second 4 bytes are offset into string table. -    pub n_name: [u8; 8], -    /// Symbol value; storage class-dependent. -    pub n_value: U32<BE>, -    /// Section number of symbol. -    pub n_scnum: I16<BE>, -    /// Basic and derived type specification. -    pub n_type: U16<BE>, -    /// Storage class of symbol. -    pub n_sclass: u8, -    /// Number of auxiliary entries. -    pub n_numaux: u8, -} - -/// Symbol table entry. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Symbol64 { -    /// Symbol value; storage class-dependent. -    pub n_value: U64<BE>, -    /// Offset of the name in string table or .debug section. -    pub n_offset: U32<BE>, -    /// Section number of symbol. -    pub n_scnum: I16<BE>, -    /// Basic and derived type specification. -    pub n_type: U16<BE>, -    /// Storage class of symbol. -    pub n_sclass: u8, -    /// Number of auxiliary entries. -    pub n_numaux: u8, -} - -// Values for `n_scnum`. -// -/// A special symbolic debugging symbol. -pub const N_DEBUG: i16 = -2; -/// An absolute symbol. The symbol has a value but is not relocatable. -pub const N_ABS: i16 = -1; -/// An undefined external symbol. -pub const N_UNDEF: i16 = 0; - -// Vlaues for `n_type`. -// -/// Values for visibility as they would appear when encoded in the high 4 bits -/// of the 16-bit unsigned n_type field of symbol table entries. Valid for -/// 32-bit XCOFF only when the o_vstamp in the auxiliary header is greater than 1. -pub const SYM_V_MASK: u16 = 0xF000; -pub const SYM_V_INTERNAL: u16 = 0x1000; -pub const SYM_V_HIDDEN: u16 = 0x2000; -pub const SYM_V_PROTECTED: u16 = 0x3000; -pub const SYM_V_EXPORTED: u16 = 0x4000; - -// Values for `n_sclass`. -// -// Storage classes used for symbolic debugging symbols. -// -/// Source file name and compiler information. -pub const C_FILE: u8 = 103; -/// Beginning of include file. -pub const C_BINCL: u8 = 108; -/// Ending of include file. -pub const C_EINCL: u8 = 109; -/// Global variable. -pub const C_GSYM: u8 = 128; -/// Statically allocated symbol. -pub const C_STSYM: u8 = 133; -/// Beginning of common block. -pub const C_BCOMM: u8 = 135; -/// End of common block. -pub const C_ECOMM: u8 = 137; -/// Alternate entry. -pub const C_ENTRY: u8 = 141; -/// Beginning of static block. -pub const C_BSTAT: u8 = 143; -/// End of static block. -pub const C_ESTAT: u8 = 144; -/// Global thread-local variable. -pub const C_GTLS: u8 = 145; -/// Static thread-local variable. -pub const C_STTLS: u8 = 146; -/// DWARF section symbol. -pub const C_DWARF: u8 = 112; -// -// Storage classes used for absolute symbols. -// -/// Automatic variable allocated on stack. -pub const C_LSYM: u8 = 129; -/// Argument to subroutine allocated on stack. -pub const C_PSYM: u8 = 130; -/// Register variable. -pub const C_RSYM: u8 = 131; -/// Argument to function or procedure stored in register. -pub const C_RPSYM: u8 = 132; -/// Local member of common block. -pub const C_ECOML: u8 = 136; -/// Function or procedure. -pub const C_FUN: u8 = 142; -// -// Storage classes used for undefined external symbols or symbols of general sections. -// -/// External symbol. -pub const C_EXT: u8 = 2; -/// Weak external symbol. -pub const C_WEAKEXT: u8 = 111; -// -// Storage classes used for symbols of general sections. -// -/// Symbol table entry marked for deletion. -pub const C_NULL: u8 = 0; -/// Static. -pub const C_STAT: u8 = 3; -/// Beginning or end of inner block. -pub const C_BLOCK: u8 = 100; -/// Beginning or end of function. -pub const C_FCN: u8 = 101; -/// Un-named external symbol. -pub const C_HIDEXT: u8 = 107; -/// Comment string in .info section. -pub const C_INFO: u8 = 110; -/// Declaration of object (type). -pub const C_DECL: u8 = 140; -// -// Storage classes - Obsolete/Undocumented. -// -/// Automatic variable. -pub const C_AUTO: u8 = 1; -/// Register variable. -pub const C_REG: u8 = 4; -/// External definition. -pub const C_EXTDEF: u8 = 5; -/// Label. -pub const C_LABEL: u8 = 6; -/// Undefined label. -pub const C_ULABEL: u8 = 7; -/// Member of structure. -pub const C_MOS: u8 = 8; -/// Function argument. -pub const C_ARG: u8 = 9; -/// Structure tag. -pub const C_STRTAG: u8 = 10; -/// Member of union. -pub const C_MOU: u8 = 11; -/// Union tag. -pub const C_UNTAG: u8 = 12; -/// Type definition. -pub const C_TPDEF: u8 = 13; -/// Undefined static. -pub const C_USTATIC: u8 = 14; -/// Enumeration tag. -pub const C_ENTAG: u8 = 15; -/// Member of enumeration. -pub const C_MOE: u8 = 16; -/// Register parameter. -pub const C_REGPARM: u8 = 17; -/// Bit field. -pub const C_FIELD: u8 = 18; -/// End of structure. -pub const C_EOS: u8 = 102; -/// Duplicate tag. -pub const C_ALIAS: u8 = 105; -/// Special storage class for external. -pub const C_HIDDEN: u8 = 106; -/// Physical end of function. -pub const C_EFCN: u8 = 255; -/// Reserved. -pub const C_TCSYM: u8 = 134; - -/// File Auxiliary Entry for C_FILE Symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FileAux32 { -    /// The source file name or compiler-related string. -    /// -    /// If first 4 bytes are 0, then second 4 bytes are offset into string table. -    pub x_fname: [u8; 8], -    /// Pad size for file name. -    pub x_fpad: [u8; 6], -    /// The source-file string type. -    pub x_ftype: u8, -    /// Reserved. -    pub x_freserve: [u8; 3], -} - -/// File Auxiliary Entry for C_FILE Symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FileAux64 { -    /// The source file name or compiler-related string. -    /// -    /// If first 4 bytes are 0, then second 4 bytes are offset into string table. -    pub x_fname: [u8; 8], -    /// Pad size for file name. -    pub x_fpad: [u8; 6], -    /// The source-file string type. -    pub x_ftype: u8, -    /// Reserved. -    pub x_freserve: [u8; 2], -    /// Specifies the type of auxiliary entry. Contains _AUX_FILE for this auxiliary entry. -    pub x_auxtype: u8, -} - -// Values for `x_ftype`. -// -/// Specifies the source-file name. -pub const XFT_FN: u8 = 0; -/// Specifies the compiler time stamp. -pub const XFT_CT: u8 = 1; -/// Specifies the compiler version number. -pub const XFT_CV: u8 = 2; -/// Specifies compiler-defined information. -pub const XFT_CD: u8 = 128; - -/// Csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct CsectAux32 { -    /// Section length. -    pub x_scnlen: U32<BE>, -    /// Offset of parameter type-check hash in .typchk section. -    pub x_parmhash: U32<BE>, -    /// .typchk section number. -    pub x_snhash: U16<BE>, -    /// Symbol alignment and type. -    pub x_smtyp: u8, -    /// Storage mapping class. -    pub x_smclas: u8, -    /// Reserved. -    pub x_stab: U32<BE>, -    /// x_snstab. -    pub x_snstab: U16<BE>, -} - -/// Csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct CsectAux64 { -    /// Low 4 bytes of section length. -    pub x_scnlen_lo: U32<BE>, -    /// Offset of parameter type-check hash in .typchk section. -    pub x_parmhash: U32<BE>, -    /// .typchk section number. -    pub x_snhash: U16<BE>, -    /// Symbol alignment and type. -    pub x_smtyp: u8, -    /// Storage mapping class. -    pub x_smclas: u8, -    /// High 4 bytes of section length. -    pub x_scnlen_hi: U32<BE>, -    /// Reserved. -    pub pad: u8, -    /// Contains _AUX_CSECT; indicates type of auxiliary entry. -    pub x_auxtype: u8, -} - -// Values for `x_smtyp`. -// -/// External reference. -pub const XTY_ER: u8 = 0; -/// Csect definition for initialized storage. -pub const XTY_SD: u8 = 1; -/// Defines an entry point to an initialized csect. -pub const XTY_LD: u8 = 2; -/// Common csect definition. For uninitialized storage. -pub const XTY_CM: u8 = 3; - -// Values for `x_smclas`. -// -// READ ONLY CLASSES -// -/// Program Code -pub const XMC_PR: u8 = 0; -/// Read Only Constant -pub const XMC_RO: u8 = 1; -/// Debug Dictionary Table -pub const XMC_DB: u8 = 2; -/// Global Linkage (Interfile Interface Code) -pub const XMC_GL: u8 = 6; -/// Extended Operation (Pseudo Machine Instruction) -pub const XMC_XO: u8 = 7; -/// Supervisor Call (32-bit process only) -pub const XMC_SV: u8 = 8; -/// Supervisor Call for 64-bit process -pub const XMC_SV64: u8 = 17; -/// Supervisor Call for both 32- and 64-bit processes -pub const XMC_SV3264: u8 = 18; -/// Traceback Index csect -pub const XMC_TI: u8 = 12; -/// Traceback Table csect -pub const XMC_TB: u8 = 13; -// -// READ WRITE CLASSES -// -/// Read Write Data -pub const XMC_RW: u8 = 5; -/// TOC Anchor for TOC Addressability -pub const XMC_TC0: u8 = 15; -/// General TOC item -pub const XMC_TC: u8 = 3; -/// Scalar data item in the TOC -pub const XMC_TD: u8 = 16; -/// Descriptor csect -pub const XMC_DS: u8 = 10; -/// Unclassified - Treated as Read Write -pub const XMC_UA: u8 = 4; -/// BSS class (uninitialized static internal) -pub const XMC_BS: u8 = 9; -/// Un-named Fortran Common -pub const XMC_UC: u8 = 11; -/// Initialized thread-local variable -pub const XMC_TL: u8 = 20; -/// Uninitialized thread-local variable -pub const XMC_UL: u8 = 21; -/// Symbol mapped at the end of TOC -pub const XMC_TE: u8 = 22; - -/// Function auxiliary entry. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FunAux32 { -    /// File offset to exception table entry. -    pub x_exptr: U32<BE>, -    /// Size of function in bytes. -    pub x_fsize: U32<BE>, -    /// File pointer to line number -    pub x_lnnoptr: U32<BE>, -    /// Symbol table index of next entry beyond this function. -    pub x_endndx: U32<BE>, -    /// Pad -    pub pad: U16<BE>, -} - -/// Function auxiliary entry. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct FunAux64 { -    /// File pointer to line number -    pub x_lnnoptr: U64<BE>, -    /// Size of function in bytes. -    pub x_fsize: U32<BE>, -    /// Symbol table index of next entry beyond this function. -    pub x_endndx: U32<BE>, -    /// Pad -    pub pad: u8, -    /// Contains _AUX_FCN; Type of auxiliary entry. -    pub x_auxtype: u8, -} - -/// Exception auxiliary entry. (XCOFF64 only) -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct ExpAux { -    /// File offset to exception table entry. -    pub x_exptr: U64<BE>, -    /// Size of function in bytes. -    pub x_fsize: U32<BE>, -    /// Symbol table index of next entry beyond this function. -    pub x_endndx: U32<BE>, -    /// Pad -    pub pad: u8, -    /// Contains _AUX_EXCEPT; Type of auxiliary entry -    pub x_auxtype: u8, -} - -/// Block auxiliary entry for the C_BLOCK and C_FCN Symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct BlockAux32 { -    /// Reserved. -    pub pad: [u8; 2], -    /// High-order 2 bytes of the source line number. -    pub x_lnnohi: U16<BE>, -    /// Low-order 2 bytes of the source line number. -    pub x_lnnolo: U16<BE>, -    /// Reserved. -    pub pad2: [u8; 12], -} - -/// Block auxiliary entry for the C_BLOCK and C_FCN Symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct BlockAux64 { -    /// Source line number. -    pub x_lnno: U32<BE>, -    /// Reserved. -    pub pad: [u8; 13], -    /// Contains _AUX_SYM; Type of auxiliary entry. -    pub x_auxtype: u8, -} - -/// Section auxiliary entry for the C_STAT Symbol. (XCOFF32 Only) -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct StatAux { -    /// Section length. -    pub x_scnlen: U32<BE>, -    /// Number of relocation entries. -    pub x_nreloc: U16<BE>, -    /// Number of line numbers. -    pub x_nlinno: U16<BE>, -    /// Reserved. -    pub pad: [u8; 10], -} - -/// Section auxiliary entry Format for C_DWARF symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DwarfAux32 { -    /// Length of portion of section represented by symbol. -    pub x_scnlen: U32<BE>, -    /// Reserved. -    pub pad: [u8; 4], -    /// Number of relocation entries in section. -    pub x_nreloc: U32<BE>, -    /// Reserved. -    pub pad2: [u8; 6], -} - -/// Section auxiliary entry Format for C_DWARF symbols. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct DwarfAux64 { -    /// Length of portion of section represented by symbol. -    pub x_scnlen: U64<BE>, -    /// Number of relocation entries in section. -    pub x_nreloc: U64<BE>, -    /// Reserved. -    pub pad: u8, -    /// Contains _AUX_SECT; Type of Auxiliary entry. -    pub x_auxtype: u8, -} - -// Values for `x_auxtype` -// -/// Identifies an exception auxiliary entry. -pub const AUX_EXCEPT: u8 = 255; -/// Identifies a function auxiliary entry. -pub const AUX_FCN: u8 = 254; -/// Identifies a symbol auxiliary entry. -pub const AUX_SYM: u8 = 253; -/// Identifies a file auxiliary entry. -pub const AUX_FILE: u8 = 252; -/// Identifies a csect auxiliary entry. -pub const AUX_CSECT: u8 = 251; -/// Identifies a SECT auxiliary entry. -pub const AUX_SECT: u8 = 250; - -/// Relocation table entry -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Rel32 { -    /// Virtual address (position) in section to be relocated. -    pub r_vaddr: U32<BE>, -    /// Symbol table index of item that is referenced. -    pub r_symndx: U32<BE>, -    /// Relocation size and information. -    pub r_rsize: u8, -    /// Relocation type. -    pub r_rtype: u8, -} - -/// Relocation table entry -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Rel64 { -    /// Virtual address (position) in section to be relocated. -    pub r_vaddr: U64<BE>, -    /// Symbol table index of item that is referenced. -    pub r_symndx: U32<BE>, -    /// Relocation size and information. -    pub r_rsize: u8, -    /// Relocation type. -    pub r_rtype: u8, -} - -// Values for `r_rtype`. -// -/// Positive relocation. -pub const R_POS: u8 = 0x00; -/// Positive indirect load relocation. -pub const R_RL: u8 = 0x0c; -/// Positive load address relocation. Modifiable instruction. -pub const R_RLA: u8 = 0x0d; -/// Negative relocation. -pub const R_NEG: u8 = 0x01; -/// Relative to self relocation. -pub const R_REL: u8 = 0x02; -/// Relative to the TOC relocation. -pub const R_TOC: u8 = 0x03; -/// TOC relative indirect load relocation. -pub const R_TRL: u8 = 0x12; -/// Relative to the TOC or to the thread-local storage base relocation. -pub const R_TRLA: u8 = 0x13; -/// Global linkage-external TOC address relocation. -pub const R_GL: u8 = 0x05; -/// Local object TOC address relocation. -pub const R_TCL: u8 = 0x06; -/// A non-relocating relocation. -pub const R_REF: u8 = 0x0f; -/// Branch absolute relocation. References a non-modifiable instruction. -pub const R_BA: u8 = 0x08; -/// Branch relative to self relocation. References a non-modifiable instruction. -pub const R_BR: u8 = 0x0a; -/// Branch absolute relocation. References a modifiable instruction. -pub const R_RBA: u8 = 0x18; -/// Branch relative to self relocation. References a modifiable instruction. -pub const R_RBR: u8 = 0x1a; -/// General-dynamic reference to TLS symbol. -pub const R_TLS: u8 = 0x20; -/// Initial-exec reference to TLS symbol. -pub const R_TLS_IE: u8 = 0x21; -/// Local-dynamic reference to TLS symbol. -pub const R_TLS_LD: u8 = 0x22; -/// Local-exec reference to TLS symbol. -pub const R_TLS_LE: u8 = 0x23; -/// Module reference to TLS. -pub const R_TLSM: u8 = 0x24; -/// Module reference to the local TLS storage. -pub const R_TLSML: u8 = 0x25; -/// Relative to TOC upper. -pub const R_TOCU: u8 = 0x30; -/// Relative to TOC lower. -pub const R_TOCL: u8 = 0x31; - -unsafe_impl_pod!( -    FileHeader32, -    FileHeader64, -    AuxHeader32, -    AuxHeader64, -    SectionHeader32, -    SectionHeader64, -    SymbolBytes, -    Symbol32, -    Symbol64, -    FileAux32, -    FileAux64, -    CsectAux32, -    CsectAux64, -    FunAux32, -    FunAux64, -    ExpAux, -    BlockAux32, -    BlockAux64, -    StatAux, -    DwarfAux32, -    DwarfAux64, -    Rel32, -    Rel64, -);  | 
