From 9835e2ae736235810b4ea1c162ca5e65c547e770 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:50 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/object/src/common.rs | 26 +- vendor/object/src/elf.rs | 807 ++++----------------------- vendor/object/src/endian.rs | 60 ++ vendor/object/src/lib.rs | 21 +- vendor/object/src/macho.rs | 58 +- vendor/object/src/pe.rs | 86 +-- vendor/object/src/read/any.rs | 132 ++--- vendor/object/src/read/coff/comdat.rs | 96 +++- vendor/object/src/read/coff/file.rs | 219 ++++++-- vendor/object/src/read/coff/relocation.rs | 25 +- vendor/object/src/read/coff/section.rs | 98 +++- vendor/object/src/read/coff/symbol.rs | 364 +++++++----- vendor/object/src/read/elf/attributes.rs | 303 ++++++++++ vendor/object/src/read/elf/comdat.rs | 2 - vendor/object/src/read/elf/file.rs | 25 + vendor/object/src/read/elf/hash.rs | 4 +- vendor/object/src/read/elf/mod.rs | 3 + vendor/object/src/read/elf/note.rs | 90 ++- vendor/object/src/read/elf/section.rs | 112 +++- vendor/object/src/read/elf/segment.rs | 1 - vendor/object/src/read/elf/symbol.rs | 5 +- vendor/object/src/read/elf/version.rs | 4 +- vendor/object/src/read/macho/dyld_cache.rs | 2 +- vendor/object/src/read/macho/file.rs | 2 +- vendor/object/src/read/macho/load_command.rs | 22 +- vendor/object/src/read/macho/relocation.rs | 17 +- vendor/object/src/read/macho/section.rs | 9 +- vendor/object/src/read/macho/segment.rs | 8 +- vendor/object/src/read/macho/symbol.rs | 2 +- vendor/object/src/read/mod.rs | 39 +- vendor/object/src/read/pe/data_directory.rs | 2 +- vendor/object/src/read/pe/file.rs | 4 +- vendor/object/src/read/pe/resource.rs | 2 +- vendor/object/src/read/pe/rich.rs | 2 +- vendor/object/src/read/pe/section.rs | 2 - vendor/object/src/read/read_cache.rs | 5 +- vendor/object/src/read/read_ref.rs | 2 +- vendor/object/src/read/traits.rs | 4 +- vendor/object/src/read/util.rs | 42 ++ vendor/object/src/read/wasm.rs | 447 ++++++++------- vendor/object/src/read/xcoff/comdat.rs | 1 - vendor/object/src/read/xcoff/relocation.rs | 1 - vendor/object/src/read/xcoff/section.rs | 7 +- vendor/object/src/read/xcoff/segment.rs | 2 - vendor/object/src/read/xcoff/symbol.rs | 121 +++- vendor/object/src/write/coff.rs | 52 +- vendor/object/src/write/elf/object.rs | 115 +++- vendor/object/src/write/elf/writer.rs | 196 ++++++- vendor/object/src/write/macho.rs | 198 +++++-- vendor/object/src/write/mod.rs | 63 ++- vendor/object/src/write/string.rs | 2 +- vendor/object/src/write/util.rs | 50 ++ vendor/object/src/write/xcoff.rs | 556 ++++++++++++++++++ vendor/object/src/xcoff.rs | 2 +- 54 files changed, 2968 insertions(+), 1552 deletions(-) create mode 100644 vendor/object/src/read/elf/attributes.rs create mode 100644 vendor/object/src/write/xcoff.rs (limited to 'vendor/object/src') diff --git a/vendor/object/src/common.rs b/vendor/object/src/common.rs index cb009c0f9..7d789a71d 100644 --- a/vendor/object/src/common.rs +++ b/vendor/object/src/common.rs @@ -27,6 +27,7 @@ pub enum Architecture { Sbf, Sparc64, Wasm32, + Wasm64, Xtensa, } @@ -58,6 +59,7 @@ impl Architecture { Architecture::Sbf => Some(AddressSize::U64), Architecture::Sparc64 => Some(AddressSize::U64), Architecture::Wasm32 => Some(AddressSize::U32), + Architecture::Wasm64 => Some(AddressSize::U64), Architecture::Xtensa => Some(AddressSize::U32), } } @@ -122,6 +124,11 @@ pub enum SectionKind { /// /// 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` @@ -450,7 +457,7 @@ pub enum SectionFlags { /// Symbol flags that are specific to each file format. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] -pub enum SymbolFlags
{ +pub enum SymbolFlags { /// No symbol flags. None, /// ELF symbol flags. @@ -472,4 +479,21 @@ pub enum SymbolFlags
{ /// `Number` field in the auxiliary symbol for the section. associative_section: Option
, }, + /// 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, + }, } diff --git a/vendor/object/src/elf.rs b/vendor/object/src/elf.rs index edbfd9e3d..202b3a2cc 100644 --- a/vendor/object/src/elf.rs +++ b/vendor/object/src/elf.rs @@ -5,6 +5,7 @@ //! //! 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}; @@ -721,11 +722,10 @@ pub const SHT_GNU_LIBLIST: u32 = 0x6fff_fff7; pub const SHT_CHECKSUM: u32 = 0x6fff_fff8; /// Sun-specific low bound. pub const SHT_LOSUNW: u32 = 0x6fff_fffa; -#[allow(missing_docs, non_upper_case_globals)] +#[allow(non_upper_case_globals)] pub const SHT_SUNW_move: u32 = 0x6fff_fffa; -#[allow(missing_docs)] pub const SHT_SUNW_COMDAT: u32 = 0x6fff_fffb; -#[allow(missing_docs, non_upper_case_globals)] +#[allow(non_upper_case_globals)] pub const SHT_SUNW_syminfo: u32 = 0x6fff_fffc; /// Version definition section. #[allow(non_upper_case_globals)] @@ -819,6 +819,8 @@ pub struct CompressionHeader64 { /// 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. @@ -971,11 +973,8 @@ pub const SYMINFO_FLG_COPY: u16 = 0x0004; pub const SYMINFO_FLG_LAZYLOAD: u16 = 0x0008; // Syminfo version values. -#[allow(missing_docs)] pub const SYMINFO_NONE: u16 = 0; -#[allow(missing_docs)] pub const SYMINFO_CURRENT: u16 = 1; -#[allow(missing_docs)] pub const SYMINFO_NUM: u16 = 2; // Values for bind component of `Sym*::st_info`. @@ -1287,6 +1286,8 @@ pub const PT_GNU_EH_FRAME: u32 = 0x6474_e550; 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. @@ -1552,7 +1553,6 @@ pub const DT_LOPROC: u32 = 0x7000_0000; pub const DT_HIPROC: u32 = 0x7fff_ffff; // `DT_*` entries between `DT_VALRNGHI` & `DT_VALRNGLO` use `d_val` as a value. -#[allow(missing_docs)] pub const DT_VALRNGLO: u32 = 0x6fff_fd00; /// Prelinking timestamp pub const DT_GNU_PRELINKED: u32 = 0x6fff_fdf5; @@ -1560,13 +1560,9 @@ pub const DT_GNU_PRELINKED: u32 = 0x6fff_fdf5; pub const DT_GNU_CONFLICTSZ: u32 = 0x6fff_fdf6; /// Size of library list pub const DT_GNU_LIBLISTSZ: u32 = 0x6fff_fdf7; -#[allow(missing_docs)] pub const DT_CHECKSUM: u32 = 0x6fff_fdf8; -#[allow(missing_docs)] pub const DT_PLTPADSZ: u32 = 0x6fff_fdf9; -#[allow(missing_docs)] pub const DT_MOVEENT: u32 = 0x6fff_fdfa; -#[allow(missing_docs)] pub const DT_MOVESZ: u32 = 0x6fff_fdfb; /// Feature selection (DTF_*). pub const DT_FEATURE_1: u32 = 0x6fff_fdfc; @@ -1576,20 +1572,16 @@ pub const DT_POSFLAG_1: u32 = 0x6fff_fdfd; pub const DT_SYMINSZ: u32 = 0x6fff_fdfe; /// Entry size of syminfo pub const DT_SYMINENT: u32 = 0x6fff_fdff; -#[allow(missing_docs)] 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. -#[allow(missing_docs)] pub const DT_ADDRRNGLO: u32 = 0x6fff_fe00; /// GNU-style hash table. pub const DT_GNU_HASH: u32 = 0x6fff_fef5; -#[allow(missing_docs)] pub const DT_TLSDESC_PLT: u32 = 0x6fff_fef6; -#[allow(missing_docs)] pub const DT_TLSDESC_GOT: u32 = 0x6fff_fef7; /// Start of conflict section pub const DT_GNU_CONFLICT: u32 = 0x6fff_fef8; @@ -1607,16 +1599,12 @@ pub const DT_PLTPAD: u32 = 0x6fff_fefd; pub const DT_MOVETAB: u32 = 0x6fff_fefe; /// Syminfo table. pub const DT_SYMINFO: u32 = 0x6fff_feff; -#[allow(missing_docs)] pub const DT_ADDRRNGHI: u32 = 0x6fff_feff; // The versioning entry types. The next are defined as part of the // GNU extension. -#[allow(missing_docs)] pub const DT_VERSYM: u32 = 0x6fff_fff0; -#[allow(missing_docs)] pub const DT_RELACOUNT: u32 = 0x6fff_fff9; -#[allow(missing_docs)] pub const DT_RELCOUNT: u32 = 0x6fff_fffa; /// State flags, see DF_1_* below. pub const DT_FLAGS_1: u32 = 0x6fff_fffb; @@ -1666,7 +1654,6 @@ pub const DF_1_NOOPEN: u32 = 0x0000_0040; pub const DF_1_ORIGIN: u32 = 0x0000_0080; /// Direct binding enabled. pub const DF_1_DIRECT: u32 = 0x0000_0100; -#[allow(missing_docs)] pub const DF_1_TRANS: u32 = 0x0000_0200; /// Object is used to interpose. pub const DF_1_INTERPOSE: u32 = 0x0000_0400; @@ -1684,15 +1671,11 @@ pub const DF_1_DISPRELDNE: u32 = 0x0000_8000; pub const DF_1_DISPRELPND: u32 = 0x0001_0000; /// Object has no-direct binding. pub const DF_1_NODIRECT: u32 = 0x0002_0000; -#[allow(missing_docs)] pub const DF_1_IGNMULDEF: u32 = 0x0004_0000; -#[allow(missing_docs)] pub const DF_1_NOKSYMS: u32 = 0x0008_0000; -#[allow(missing_docs)] pub const DF_1_NOHDR: u32 = 0x0010_0000; /// Object is modified after built. pub const DF_1_EDITED: u32 = 0x0020_0000; -#[allow(missing_docs)] pub const DF_1_NORELOC: u32 = 0x0040_0000; /// Object has individual interposers. pub const DF_1_SYMINTPOSE: u32 = 0x0080_0000; @@ -1700,9 +1683,7 @@ pub const DF_1_SYMINTPOSE: u32 = 0x0080_0000; pub const DF_1_GLOBAUDIT: u32 = 0x0100_0000; /// Singleton symbols are used. pub const DF_1_SINGLETON: u32 = 0x0200_0000; -#[allow(missing_docs)] pub const DF_1_STUB: u32 = 0x0400_0000; -#[allow(missing_docs)] pub const DF_1_PIE: u32 = 0x0800_0000; /// Version symbol information @@ -1895,7 +1876,89 @@ pub const NT_GNU_GOLD_VERSION: u32 = 4; /// Program property. pub const NT_GNU_PROPERTY_TYPE_0: u32 = 5; -// TODO: GNU_PROPERTY_* +// 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_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. @@ -2142,17 +2205,12 @@ pub const STT_SPARC_REGISTER: u8 = 13; // SPARC values for `FileHeader64::e_flags`. -#[allow(missing_docs)] pub const EF_SPARCV9_MM: u32 = 3; -#[allow(missing_docs)] pub const EF_SPARCV9_TSO: u32 = 0; -#[allow(missing_docs)] pub const EF_SPARCV9_PSO: u32 = 1; -#[allow(missing_docs)] pub const EF_SPARCV9_RMO: u32 = 2; /// little endian data pub const EF_SPARC_LEDATA: u32 = 0x80_0000; -#[allow(missing_docs)] pub const EF_SPARC_EXT_MASK: u32 = 0xFF_FF00; /// generic V8+ features pub const EF_SPARC_32PLUS: u32 = 0x00_0100; @@ -2280,86 +2338,47 @@ pub const R_SPARC_REGISTER: u32 = 53; pub const R_SPARC_UA64: u32 = 54; /// Direct 16 bit unaligned pub const R_SPARC_UA16: u32 = 55; -#[allow(missing_docs)] pub const R_SPARC_TLS_GD_HI22: u32 = 56; -#[allow(missing_docs)] pub const R_SPARC_TLS_GD_LO10: u32 = 57; -#[allow(missing_docs)] pub const R_SPARC_TLS_GD_ADD: u32 = 58; -#[allow(missing_docs)] pub const R_SPARC_TLS_GD_CALL: u32 = 59; -#[allow(missing_docs)] pub const R_SPARC_TLS_LDM_HI22: u32 = 60; -#[allow(missing_docs)] pub const R_SPARC_TLS_LDM_LO10: u32 = 61; -#[allow(missing_docs)] pub const R_SPARC_TLS_LDM_ADD: u32 = 62; -#[allow(missing_docs)] pub const R_SPARC_TLS_LDM_CALL: u32 = 63; -#[allow(missing_docs)] pub const R_SPARC_TLS_LDO_HIX22: u32 = 64; -#[allow(missing_docs)] pub const R_SPARC_TLS_LDO_LOX10: u32 = 65; -#[allow(missing_docs)] pub const R_SPARC_TLS_LDO_ADD: u32 = 66; -#[allow(missing_docs)] pub const R_SPARC_TLS_IE_HI22: u32 = 67; -#[allow(missing_docs)] pub const R_SPARC_TLS_IE_LO10: u32 = 68; -#[allow(missing_docs)] pub const R_SPARC_TLS_IE_LD: u32 = 69; -#[allow(missing_docs)] pub const R_SPARC_TLS_IE_LDX: u32 = 70; -#[allow(missing_docs)] pub const R_SPARC_TLS_IE_ADD: u32 = 71; -#[allow(missing_docs)] pub const R_SPARC_TLS_LE_HIX22: u32 = 72; -#[allow(missing_docs)] pub const R_SPARC_TLS_LE_LOX10: u32 = 73; -#[allow(missing_docs)] pub const R_SPARC_TLS_DTPMOD32: u32 = 74; -#[allow(missing_docs)] pub const R_SPARC_TLS_DTPMOD64: u32 = 75; -#[allow(missing_docs)] pub const R_SPARC_TLS_DTPOFF32: u32 = 76; -#[allow(missing_docs)] pub const R_SPARC_TLS_DTPOFF64: u32 = 77; -#[allow(missing_docs)] pub const R_SPARC_TLS_TPOFF32: u32 = 78; -#[allow(missing_docs)] pub const R_SPARC_TLS_TPOFF64: u32 = 79; -#[allow(missing_docs)] pub const R_SPARC_GOTDATA_HIX22: u32 = 80; -#[allow(missing_docs)] pub const R_SPARC_GOTDATA_LOX10: u32 = 81; -#[allow(missing_docs)] pub const R_SPARC_GOTDATA_OP_HIX22: u32 = 82; -#[allow(missing_docs)] pub const R_SPARC_GOTDATA_OP_LOX10: u32 = 83; -#[allow(missing_docs)] pub const R_SPARC_GOTDATA_OP: u32 = 84; -#[allow(missing_docs)] pub const R_SPARC_H34: u32 = 85; -#[allow(missing_docs)] pub const R_SPARC_SIZE32: u32 = 86; -#[allow(missing_docs)] pub const R_SPARC_SIZE64: u32 = 87; -#[allow(missing_docs)] pub const R_SPARC_WDISP10: u32 = 88; -#[allow(missing_docs)] pub const R_SPARC_JMP_IREL: u32 = 248; -#[allow(missing_docs)] pub const R_SPARC_IRELATIVE: u32 = 249; -#[allow(missing_docs)] pub const R_SPARC_GNU_VTINHERIT: u32 = 250; -#[allow(missing_docs)] pub const R_SPARC_GNU_VTENTRY: u32 = 251; -#[allow(missing_docs)] pub const R_SPARC_REV32: u32 = 252; // Sparc64 values for `Dyn32::d_tag`. -#[allow(missing_docs)] pub const DT_SPARC_REGISTER: u32 = 0x7000_0001; // MIPS R3000 specific definitions. @@ -2372,13 +2391,9 @@ pub const EF_MIPS_NOREORDER: u32 = 1; pub const EF_MIPS_PIC: u32 = 2; /// Uses PIC calling sequence. pub const EF_MIPS_CPIC: u32 = 4; -#[allow(missing_docs)] pub const EF_MIPS_XGOT: u32 = 8; -#[allow(missing_docs)] pub const EF_MIPS_64BIT_WHIRL: u32 = 16; -#[allow(missing_docs)] pub const EF_MIPS_ABI2: u32 = 32; -#[allow(missing_docs)] pub const EF_MIPS_ABI_ON32: u32 = 64; /// Uses FP64 (12 callee-saved). pub const EF_MIPS_FP64: u32 = 512; @@ -2440,7 +2455,6 @@ pub const SHN_MIPS_SUNDEFINED: u16 = 0xff04; /// Shared objects used in link. pub const SHT_MIPS_LIBLIST: u32 = 0x7000_0000; -#[allow(missing_docs)] pub const SHT_MIPS_MSYM: u32 = 0x7000_0001; /// Conflicting symbols. pub const SHT_MIPS_CONFLICT: u32 = 0x7000_0002; @@ -2452,99 +2466,61 @@ pub const SHT_MIPS_UCODE: u32 = 0x7000_0004; pub const SHT_MIPS_DEBUG: u32 = 0x7000_0005; /// Register usage information. pub const SHT_MIPS_REGINFO: u32 = 0x7000_0006; -#[allow(missing_docs)] pub const SHT_MIPS_PACKAGE: u32 = 0x7000_0007; -#[allow(missing_docs)] pub const SHT_MIPS_PACKSYM: u32 = 0x7000_0008; -#[allow(missing_docs)] pub const SHT_MIPS_RELD: u32 = 0x7000_0009; -#[allow(missing_docs)] pub const SHT_MIPS_IFACE: u32 = 0x7000_000b; -#[allow(missing_docs)] pub const SHT_MIPS_CONTENT: u32 = 0x7000_000c; /// Miscellaneous options. pub const SHT_MIPS_OPTIONS: u32 = 0x7000_000d; -#[allow(missing_docs)] pub const SHT_MIPS_SHDR: u32 = 0x7000_0010; -#[allow(missing_docs)] pub const SHT_MIPS_FDESC: u32 = 0x7000_0011; -#[allow(missing_docs)] pub const SHT_MIPS_EXTSYM: u32 = 0x7000_0012; -#[allow(missing_docs)] pub const SHT_MIPS_DENSE: u32 = 0x7000_0013; -#[allow(missing_docs)] pub const SHT_MIPS_PDESC: u32 = 0x7000_0014; -#[allow(missing_docs)] pub const SHT_MIPS_LOCSYM: u32 = 0x7000_0015; -#[allow(missing_docs)] pub const SHT_MIPS_AUXSYM: u32 = 0x7000_0016; -#[allow(missing_docs)] pub const SHT_MIPS_OPTSYM: u32 = 0x7000_0017; -#[allow(missing_docs)] pub const SHT_MIPS_LOCSTR: u32 = 0x7000_0018; -#[allow(missing_docs)] pub const SHT_MIPS_LINE: u32 = 0x7000_0019; -#[allow(missing_docs)] pub const SHT_MIPS_RFDESC: u32 = 0x7000_001a; -#[allow(missing_docs)] pub const SHT_MIPS_DELTASYM: u32 = 0x7000_001b; -#[allow(missing_docs)] pub const SHT_MIPS_DELTAINST: u32 = 0x7000_001c; -#[allow(missing_docs)] pub const SHT_MIPS_DELTACLASS: u32 = 0x7000_001d; /// DWARF debugging information. pub const SHT_MIPS_DWARF: u32 = 0x7000_001e; -#[allow(missing_docs)] pub const SHT_MIPS_DELTADECL: u32 = 0x7000_001f; -#[allow(missing_docs)] pub const SHT_MIPS_SYMBOL_LIB: u32 = 0x7000_0020; /// Event section. pub const SHT_MIPS_EVENTS: u32 = 0x7000_0021; -#[allow(missing_docs)] pub const SHT_MIPS_TRANSLATE: u32 = 0x7000_0022; -#[allow(missing_docs)] pub const SHT_MIPS_PIXIE: u32 = 0x7000_0023; -#[allow(missing_docs)] pub const SHT_MIPS_XLATE: u32 = 0x7000_0024; -#[allow(missing_docs)] pub const SHT_MIPS_XLATE_DEBUG: u32 = 0x7000_0025; -#[allow(missing_docs)] pub const SHT_MIPS_WHIRL: u32 = 0x7000_0026; -#[allow(missing_docs)] pub const SHT_MIPS_EH_REGION: u32 = 0x7000_0027; -#[allow(missing_docs)] pub const SHT_MIPS_XLATE_OLD: u32 = 0x7000_0028; -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const SHF_MIPS_MERGE: u32 = 0x2000_0000; -#[allow(missing_docs)] pub const SHF_MIPS_ADDR: u32 = 0x4000_0000; -#[allow(missing_docs)] pub const SHF_MIPS_STRINGS: u32 = 0x8000_0000; -#[allow(missing_docs)] pub const SHF_MIPS_NOSTRIP: u32 = 0x0800_0000; -#[allow(missing_docs)] pub const SHF_MIPS_LOCAL: u32 = 0x0400_0000; -#[allow(missing_docs)] pub const SHF_MIPS_NAMES: u32 = 0x0200_0000; -#[allow(missing_docs)] pub const SHF_MIPS_NODUPE: u32 = 0x0100_0000; // MIPS values for `Sym32::st_other`. -#[allow(missing_docs)] 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'. -#[allow(missing_docs)] pub const STB_MIPS_SPLIT_COMMON: u8 = 13; // Entries found in sections of type `SHT_MIPS_GPTAB`. @@ -2584,20 +2560,14 @@ pub const OEX_PAGE0: u32 = 0x10000; pub const OEX_SMM: u32 = 0x20000; /// Force floating point debug mode? pub const OEX_FPDBUG: u32 = 0x40000; -#[allow(missing_docs)] pub const OEX_PRECISEFP: u32 = OEX_FPDBUG; /// Dismiss invalid address faults? pub const OEX_DISMISS: u32 = 0x80000; -#[allow(missing_docs)] pub const OEX_FPU_INVAL: u32 = 0x10; -#[allow(missing_docs)] pub const OEX_FPU_DIV0: u32 = 0x08; -#[allow(missing_docs)] pub const OEX_FPU_OFLO: u32 = 0x04; -#[allow(missing_docs)] pub const OEX_FPU_UFLO: u32 = 0x02; -#[allow(missing_docs)] pub const OEX_FPU_INEX: u32 = 0x01; // Masks for `Elf_Options::info` for an `ODK_HWPATCH` entry. */ @@ -2610,11 +2580,8 @@ pub const OHW_R5KEOP: u32 = 0x4; /// R5000 cvt.\[ds\].l bug. clean=1. pub const OHW_R5KCVTL: u32 = 0x8; -#[allow(missing_docs)] pub const OPAD_PREFIX: u32 = 0x1; -#[allow(missing_docs)] pub const OPAD_POSTFIX: u32 = 0x2; -#[allow(missing_docs)] pub const OPAD_SYMBOL: u32 = 0x4; // Entries found in sections of type `SHT_MIPS_OPTIONS`. @@ -2623,9 +2590,7 @@ pub const OPAD_SYMBOL: u32 = 0x4; // Masks for `ElfOptions::info` for `ODK_HWAND` and `ODK_HWOR` entries. -#[allow(missing_docs)] pub const OHWA0_R4KEOP_CHECKED: u32 = 0x0000_0001; -#[allow(missing_docs)] pub const OHWA1_R4KEOP_CLEAN: u32 = 0x0000_0002; // MIPS values for `Rel*::r_type`. @@ -2657,49 +2622,27 @@ pub const R_MIPS_CALL16: u32 = 11; /// GP relative 32 bit pub const R_MIPS_GPREL32: u32 = 12; -#[allow(missing_docs)] pub const R_MIPS_SHIFT5: u32 = 16; -#[allow(missing_docs)] pub const R_MIPS_SHIFT6: u32 = 17; -#[allow(missing_docs)] pub const R_MIPS_64: u32 = 18; -#[allow(missing_docs)] pub const R_MIPS_GOT_DISP: u32 = 19; -#[allow(missing_docs)] pub const R_MIPS_GOT_PAGE: u32 = 20; -#[allow(missing_docs)] pub const R_MIPS_GOT_OFST: u32 = 21; -#[allow(missing_docs)] pub const R_MIPS_GOT_HI16: u32 = 22; -#[allow(missing_docs)] pub const R_MIPS_GOT_LO16: u32 = 23; -#[allow(missing_docs)] pub const R_MIPS_SUB: u32 = 24; -#[allow(missing_docs)] pub const R_MIPS_INSERT_A: u32 = 25; -#[allow(missing_docs)] pub const R_MIPS_INSERT_B: u32 = 26; -#[allow(missing_docs)] pub const R_MIPS_DELETE: u32 = 27; -#[allow(missing_docs)] pub const R_MIPS_HIGHER: u32 = 28; -#[allow(missing_docs)] pub const R_MIPS_HIGHEST: u32 = 29; -#[allow(missing_docs)] pub const R_MIPS_CALL_HI16: u32 = 30; -#[allow(missing_docs)] pub const R_MIPS_CALL_LO16: u32 = 31; -#[allow(missing_docs)] pub const R_MIPS_SCN_DISP: u32 = 32; -#[allow(missing_docs)] pub const R_MIPS_REL16: u32 = 33; -#[allow(missing_docs)] pub const R_MIPS_ADD_IMMEDIATE: u32 = 34; -#[allow(missing_docs)] pub const R_MIPS_PJUMP: u32 = 35; -#[allow(missing_docs)] pub const R_MIPS_RELGOT: u32 = 36; -#[allow(missing_docs)] pub const R_MIPS_JALR: u32 = 37; /// Module number 32 bit pub const R_MIPS_TLS_DTPMOD32: u32 = 38; @@ -2727,11 +2670,8 @@ pub const R_MIPS_TLS_TPREL64: u32 = 48; pub const R_MIPS_TLS_TPREL_HI16: u32 = 49; /// TP-relative offset, low 16 bits pub const R_MIPS_TLS_TPREL_LO16: u32 = 50; -#[allow(missing_docs)] pub const R_MIPS_GLOB_DAT: u32 = 51; -#[allow(missing_docs)] pub const R_MIPS_COPY: u32 = 126; -#[allow(missing_docs)] pub const R_MIPS_JUMP_SLOT: u32 = 127; // MIPS values for `ProgramHeader32::p_type`. @@ -2740,14 +2680,12 @@ pub const R_MIPS_JUMP_SLOT: u32 = 127; pub const PT_MIPS_REGINFO: u32 = 0x7000_0000; /// Runtime procedure table. pub const PT_MIPS_RTPROC: u32 = 0x7000_0001; -#[allow(missing_docs)] 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`. -#[allow(missing_docs)] pub const PF_MIPS_LOCAL: u32 = 0x1000_0000; // MIPS values for `Dyn32::d_tag`. @@ -2764,7 +2702,6 @@ pub const DT_MIPS_IVERSION: u32 = 0x7000_0004; pub const DT_MIPS_FLAGS: u32 = 0x7000_0005; /// Base address pub const DT_MIPS_BASE_ADDRESS: u32 = 0x7000_0006; -#[allow(missing_docs)] pub const DT_MIPS_MSYM: u32 = 0x7000_0007; /// Address of CONFLICT section pub const DT_MIPS_CONFLICT: u32 = 0x7000_0008; @@ -2808,23 +2745,16 @@ pub const DT_MIPS_DELTA_CLASSSYM: u32 = 0x7000_0020; pub const DT_MIPS_DELTA_CLASSSYM_NO: u32 = 0x7000_0021; /// Flags indicating for C++ flavor. pub const DT_MIPS_CXX_FLAGS: u32 = 0x7000_0022; -#[allow(missing_docs)] pub const DT_MIPS_PIXIE_INIT: u32 = 0x7000_0023; -#[allow(missing_docs)] pub const DT_MIPS_SYMBOL_LIB: u32 = 0x7000_0024; -#[allow(missing_docs)] pub const DT_MIPS_LOCALPAGE_GOTIDX: u32 = 0x7000_0025; -#[allow(missing_docs)] pub const DT_MIPS_LOCAL_GOTIDX: u32 = 0x7000_0026; -#[allow(missing_docs)] pub const DT_MIPS_HIDDEN_GOTIDX: u32 = 0x7000_0027; -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const DT_MIPS_DYNSTR_ALIGN: u32 = 0x7000_002b; /// Size of the .interface section. pub const DT_MIPS_INTERFACE_SIZE: u32 = 0x7000_002c; @@ -2855,29 +2785,17 @@ pub const RHF_QUICKSTART: u32 = 1 << 0; pub const RHF_NOTPOT: u32 = 1 << 1; /// Ignore LD_LIBRARY_PATH pub const RHF_NO_LIBRARY_REPLACEMENT: u32 = 1 << 2; -#[allow(missing_docs)] pub const RHF_NO_MOVE: u32 = 1 << 3; -#[allow(missing_docs)] pub const RHF_SGI_ONLY: u32 = 1 << 4; -#[allow(missing_docs)] pub const RHF_GUARANTEE_INIT: u32 = 1 << 5; -#[allow(missing_docs)] pub const RHF_DELTA_C_PLUS_PLUS: u32 = 1 << 6; -#[allow(missing_docs)] pub const RHF_GUARANTEE_START_INIT: u32 = 1 << 7; -#[allow(missing_docs)] pub const RHF_PIXIE: u32 = 1 << 8; -#[allow(missing_docs)] pub const RHF_DEFAULT_DELAY_LOAD: u32 = 1 << 9; -#[allow(missing_docs)] pub const RHF_REQUICKSTART: u32 = 1 << 10; -#[allow(missing_docs)] pub const RHF_REQUICKSTARTED: u32 = 1 << 11; -#[allow(missing_docs)] pub const RHF_CORD: u32 = 1 << 12; -#[allow(missing_docs)] pub const RHF_NO_UNRES_UNDEF: u32 = 1 << 13; -#[allow(missing_docs)] pub const RHF_RLD_ORDER_SAFE: u32 = 1 << 14; // Entries found in sections of type `SHT_MIPS_LIBLIST`. @@ -2886,19 +2804,14 @@ pub const RHF_RLD_ORDER_SAFE: u32 = 1 << 14; // Values for `Lib*::l_flags`. -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const LL_REQUIRE_MINOR: u32 = 1 << 2; -#[allow(missing_docs)] pub const LL_EXPORTS: u32 = 1 << 3; -#[allow(missing_docs)] pub const LL_DELAY_LOAD: u32 = 1 << 4; -#[allow(missing_docs)] pub const LL_DELTA: u32 = 1 << 5; // TODO: MIPS ABI flags @@ -2933,7 +2846,7 @@ pub const EFA_PARISC_2_0: u32 = 0x0214; // PA-RISC values for `Sym*::st_shndx`. -/// Section for tenatively declared symbols in ANSI C. +/// 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; @@ -2961,9 +2874,7 @@ pub const SHF_PARISC_SBP: u32 = 0x8000_0000; /// Millicode function entry point. pub const STT_PARISC_MILLICODE: u8 = 13; -#[allow(missing_docs)] pub const STT_HP_OPAQUE: u8 = STT_LOOS + 0x1; -#[allow(missing_docs)] pub const STT_HP_STUB: u8 = STT_LOOS + 0x2; // PA-RISC values for `Rel*::r_type`. @@ -3102,7 +3013,6 @@ pub const R_PARISC_LTOFF_FPTR16F: u32 = 125; pub const R_PARISC_LTOFF_FPTR16WF: u32 = 126; /// 16 bits LT-rel. function ptr. pub const R_PARISC_LTOFF_FPTR16DF: u32 = 127; -#[allow(missing_docs)] pub const R_PARISC_LORESERVE: u32 = 128; /// Copy relocation. pub const R_PARISC_COPY: u32 = 128; @@ -3146,9 +3056,7 @@ pub const R_PARISC_LTOFF_TP16F: u32 = 229; pub const R_PARISC_LTOFF_TP16WF: u32 = 230; /// 16 bits LT-TP-rel. address. pub const R_PARISC_LTOFF_TP16DF: u32 = 231; -#[allow(missing_docs)] pub const R_PARISC_GNU_VTENTRY: u32 = 232; -#[allow(missing_docs)] pub const R_PARISC_GNU_VTINHERIT: u32 = 233; /// GD 21-bit left. pub const R_PARISC_TLS_GD21L: u32 = 234; @@ -3174,77 +3082,45 @@ pub const R_PARISC_TLS_DTPMOD64: u32 = 243; pub const R_PARISC_TLS_DTPOFF32: u32 = 244; /// DTP offset 32-bit. pub const R_PARISC_TLS_DTPOFF64: u32 = 245; -#[allow(missing_docs)] pub const R_PARISC_TLS_LE21L: u32 = R_PARISC_TPREL21L; -#[allow(missing_docs)] pub const R_PARISC_TLS_LE14R: u32 = R_PARISC_TPREL14R; -#[allow(missing_docs)] pub const R_PARISC_TLS_IE21L: u32 = R_PARISC_LTOFF_TP21L; -#[allow(missing_docs)] pub const R_PARISC_TLS_IE14R: u32 = R_PARISC_LTOFF_TP14R; -#[allow(missing_docs)] pub const R_PARISC_TLS_TPREL32: u32 = R_PARISC_TPREL32; -#[allow(missing_docs)] pub const R_PARISC_TLS_TPREL64: u32 = R_PARISC_TPREL64; -#[allow(missing_docs)] pub const R_PARISC_HIRESERVE: u32 = 255; // PA-RISC values for `ProgramHeader*::p_type`. -#[allow(missing_docs)] pub const PT_HP_TLS: u32 = PT_LOOS + 0x0; -#[allow(missing_docs)] pub const PT_HP_CORE_NONE: u32 = PT_LOOS + 0x1; -#[allow(missing_docs)] pub const PT_HP_CORE_VERSION: u32 = PT_LOOS + 0x2; -#[allow(missing_docs)] pub const PT_HP_CORE_KERNEL: u32 = PT_LOOS + 0x3; -#[allow(missing_docs)] pub const PT_HP_CORE_COMM: u32 = PT_LOOS + 0x4; -#[allow(missing_docs)] pub const PT_HP_CORE_PROC: u32 = PT_LOOS + 0x5; -#[allow(missing_docs)] pub const PT_HP_CORE_LOADABLE: u32 = PT_LOOS + 0x6; -#[allow(missing_docs)] pub const PT_HP_CORE_STACK: u32 = PT_LOOS + 0x7; -#[allow(missing_docs)] pub const PT_HP_CORE_SHM: u32 = PT_LOOS + 0x8; -#[allow(missing_docs)] pub const PT_HP_CORE_MMF: u32 = PT_LOOS + 0x9; -#[allow(missing_docs)] pub const PT_HP_PARALLEL: u32 = PT_LOOS + 0x10; -#[allow(missing_docs)] pub const PT_HP_FASTBIND: u32 = PT_LOOS + 0x11; -#[allow(missing_docs)] pub const PT_HP_OPT_ANNOT: u32 = PT_LOOS + 0x12; -#[allow(missing_docs)] pub const PT_HP_HSL_ANNOT: u32 = PT_LOOS + 0x13; -#[allow(missing_docs)] pub const PT_HP_STACK: u32 = PT_LOOS + 0x14; -#[allow(missing_docs)] pub const PT_PARISC_ARCHEXT: u32 = 0x7000_0000; -#[allow(missing_docs)] pub const PT_PARISC_UNWIND: u32 = 0x7000_0001; // PA-RISC values for `ProgramHeader*::p_flags`. -#[allow(missing_docs)] pub const PF_PARISC_SBP: u32 = 0x0800_0000; -#[allow(missing_docs)] pub const PF_HP_PAGE_SIZE: u32 = 0x0010_0000; -#[allow(missing_docs)] pub const PF_HP_FAR_SHARED: u32 = 0x0020_0000; -#[allow(missing_docs)] pub const PF_HP_NEAR_SHARED: u32 = 0x0040_0000; -#[allow(missing_docs)] pub const PF_HP_CODE: u32 = 0x0100_0000; -#[allow(missing_docs)] pub const PF_HP_MODIFY: u32 = 0x0200_0000; -#[allow(missing_docs)] pub const PF_HP_LAZYSWAP: u32 = 0x0400_0000; -#[allow(missing_docs)] pub const PF_HP_SBP: u32 = 0x0800_0000; // Alpha specific definitions. @@ -3259,14 +3135,11 @@ pub const EF_ALPHA_CANRELAX: u32 = 2; // Alpha values for `SectionHeader64::sh_type`. // These two are primerily concerned with ECOFF debugging info. -#[allow(missing_docs)] pub const SHT_ALPHA_DEBUG: u32 = 0x7000_0001; -#[allow(missing_docs)] pub const SHT_ALPHA_REGINFO: u32 = 0x7000_0002; // Alpha values for `SectionHeader64::sh_flags`. -#[allow(missing_docs)] pub const SHF_ALPHA_GPREL: u32 = 0x1000_0000; // Alpha values for `Sym64::st_other`. @@ -3315,51 +3188,30 @@ pub const R_ALPHA_GLOB_DAT: u32 = 25; pub const R_ALPHA_JMP_SLOT: u32 = 26; /// Adjust by program base pub const R_ALPHA_RELATIVE: u32 = 27; -#[allow(missing_docs)] pub const R_ALPHA_TLS_GD_HI: u32 = 28; -#[allow(missing_docs)] pub const R_ALPHA_TLSGD: u32 = 29; -#[allow(missing_docs)] pub const R_ALPHA_TLS_LDM: u32 = 30; -#[allow(missing_docs)] pub const R_ALPHA_DTPMOD64: u32 = 31; -#[allow(missing_docs)] pub const R_ALPHA_GOTDTPREL: u32 = 32; -#[allow(missing_docs)] pub const R_ALPHA_DTPREL64: u32 = 33; -#[allow(missing_docs)] pub const R_ALPHA_DTPRELHI: u32 = 34; -#[allow(missing_docs)] pub const R_ALPHA_DTPRELLO: u32 = 35; -#[allow(missing_docs)] pub const R_ALPHA_DTPREL16: u32 = 36; -#[allow(missing_docs)] pub const R_ALPHA_GOTTPREL: u32 = 37; -#[allow(missing_docs)] pub const R_ALPHA_TPREL64: u32 = 38; -#[allow(missing_docs)] pub const R_ALPHA_TPRELHI: u32 = 39; -#[allow(missing_docs)] pub const R_ALPHA_TPRELLO: u32 = 40; -#[allow(missing_docs)] pub const R_ALPHA_TPREL16: u32 = 41; // Magic values of the `R_ALPHA_LITUSE` relocation addend. -#[allow(missing_docs)] pub const LITUSE_ALPHA_ADDR: u32 = 0; -#[allow(missing_docs)] pub const LITUSE_ALPHA_BASE: u32 = 1; -#[allow(missing_docs)] pub const LITUSE_ALPHA_BYTOFF: u32 = 2; -#[allow(missing_docs)] pub const LITUSE_ALPHA_JSR: u32 = 3; -#[allow(missing_docs)] pub const LITUSE_ALPHA_TLS_GD: u32 = 4; -#[allow(missing_docs)] pub const LITUSE_ALPHA_TLS_LDM: u32 = 5; // Alpha values for `Dyn64::d_tag`. -#[allow(missing_docs)] pub const DT_ALPHA_PLTRO: u32 = DT_LOPROC + 0; // PowerPC specific declarations. @@ -3375,7 +3227,6 @@ pub const EF_PPC_RELOCATABLE: u32 = 0x0001_0000; pub const EF_PPC_RELOCATABLE_LIB: u32 = 0x0000_8000; // PowerPC values for `Rel*::r_type` defined by the ABIs. -#[allow(missing_docs)] pub const R_PPC_NONE: u32 = 0; /// 32bit absolute address pub const R_PPC_ADDR32: u32 = 1; @@ -3391,63 +3242,36 @@ pub const R_PPC_ADDR16_HI: u32 = 5; pub const R_PPC_ADDR16_HA: u32 = 6; /// 16bit address, 2 bits ignored pub const R_PPC_ADDR14: u32 = 7; -#[allow(missing_docs)] pub const R_PPC_ADDR14_BRTAKEN: u32 = 8; -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const R_PPC_REL14_BRTAKEN: u32 = 12; -#[allow(missing_docs)] pub const R_PPC_REL14_BRNTAKEN: u32 = 13; -#[allow(missing_docs)] pub const R_PPC_GOT16: u32 = 14; -#[allow(missing_docs)] pub const R_PPC_GOT16_LO: u32 = 15; -#[allow(missing_docs)] pub const R_PPC_GOT16_HI: u32 = 16; -#[allow(missing_docs)] pub const R_PPC_GOT16_HA: u32 = 17; -#[allow(missing_docs)] pub const R_PPC_PLTREL24: u32 = 18; -#[allow(missing_docs)] pub const R_PPC_COPY: u32 = 19; -#[allow(missing_docs)] pub const R_PPC_GLOB_DAT: u32 = 20; -#[allow(missing_docs)] pub const R_PPC_JMP_SLOT: u32 = 21; -#[allow(missing_docs)] pub const R_PPC_RELATIVE: u32 = 22; -#[allow(missing_docs)] pub const R_PPC_LOCAL24PC: u32 = 23; -#[allow(missing_docs)] pub const R_PPC_UADDR32: u32 = 24; -#[allow(missing_docs)] pub const R_PPC_UADDR16: u32 = 25; -#[allow(missing_docs)] pub const R_PPC_REL32: u32 = 26; -#[allow(missing_docs)] pub const R_PPC_PLT32: u32 = 27; -#[allow(missing_docs)] pub const R_PPC_PLTREL32: u32 = 28; -#[allow(missing_docs)] pub const R_PPC_PLT16_LO: u32 = 29; -#[allow(missing_docs)] pub const R_PPC_PLT16_HI: u32 = 30; -#[allow(missing_docs)] pub const R_PPC_PLT16_HA: u32 = 31; -#[allow(missing_docs)] pub const R_PPC_SDAREL16: u32 = 32; -#[allow(missing_docs)] pub const R_PPC_SECTOFF: u32 = 33; -#[allow(missing_docs)] pub const R_PPC_SECTOFF_LO: u32 = 34; -#[allow(missing_docs)] pub const R_PPC_SECTOFF_HI: u32 = 35; -#[allow(missing_docs)] pub const R_PPC_SECTOFF_HA: u32 = 36; // PowerPC values for `Rel*::r_type` defined for the TLS access ABI. @@ -3513,35 +3337,21 @@ pub const R_PPC_TLSGD: u32 = 95; pub const R_PPC_TLSLD: u32 = 96; // PowerPC values for `Rel*::r_type` from the Embedded ELF ABI. -#[allow(missing_docs)] pub const R_PPC_EMB_NADDR32: u32 = 101; -#[allow(missing_docs)] pub const R_PPC_EMB_NADDR16: u32 = 102; -#[allow(missing_docs)] pub const R_PPC_EMB_NADDR16_LO: u32 = 103; -#[allow(missing_docs)] pub const R_PPC_EMB_NADDR16_HI: u32 = 104; -#[allow(missing_docs)] pub const R_PPC_EMB_NADDR16_HA: u32 = 105; -#[allow(missing_docs)] pub const R_PPC_EMB_SDAI16: u32 = 106; -#[allow(missing_docs)] pub const R_PPC_EMB_SDA2I16: u32 = 107; -#[allow(missing_docs)] pub const R_PPC_EMB_SDA2REL: u32 = 108; /// 16 bit offset in SDA pub const R_PPC_EMB_SDA21: u32 = 109; -#[allow(missing_docs)] pub const R_PPC_EMB_MRKREF: u32 = 110; -#[allow(missing_docs)] pub const R_PPC_EMB_RELSEC16: u32 = 111; -#[allow(missing_docs)] pub const R_PPC_EMB_RELST_LO: u32 = 112; -#[allow(missing_docs)] pub const R_PPC_EMB_RELST_HI: u32 = 113; -#[allow(missing_docs)] pub const R_PPC_EMB_RELST_HA: u32 = 114; -#[allow(missing_docs)] pub const R_PPC_EMB_BIT_FLD: u32 = 115; /// 16 bit relative offset in SDA pub const R_PPC_EMB_RELSDA: u32 = 116; @@ -3578,17 +3388,13 @@ pub const R_PPC_REL16_HA: u32 = 252; pub const R_PPC_TOC16: u32 = 255; // PowerPC specific values for `Dyn*::d_tag`. -#[allow(missing_docs)] pub const DT_PPC_GOT: u32 = DT_LOPROC + 0; -#[allow(missing_docs)] pub const DT_PPC_OPT: u32 = DT_LOPROC + 1; // PowerPC specific values for the `DT_PPC_OPT` entry. -#[allow(missing_docs)] pub const PPC_OPT_TLS: u32 = 1; // PowerPC64 values for `Rel*::r_type` defined by the ABIs. -#[allow(missing_docs)] pub const R_PPC64_NONE: u32 = R_PPC_NONE; /// 32bit absolute address pub const R_PPC64_ADDR32: u32 = R_PPC_ADDR32; @@ -3604,60 +3410,36 @@ pub const R_PPC64_ADDR16_HI: u32 = R_PPC_ADDR16_HI; pub const R_PPC64_ADDR16_HA: u32 = R_PPC_ADDR16_HA; /// 16bit address, word aligned pub const R_PPC64_ADDR14: u32 = R_PPC_ADDR14; -#[allow(missing_docs)] pub const R_PPC64_ADDR14_BRTAKEN: u32 = R_PPC_ADDR14_BRTAKEN; -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const R_PPC64_REL14_BRTAKEN: u32 = R_PPC_REL14_BRTAKEN; -#[allow(missing_docs)] pub const R_PPC64_REL14_BRNTAKEN: u32 = R_PPC_REL14_BRNTAKEN; -#[allow(missing_docs)] pub const R_PPC64_GOT16: u32 = R_PPC_GOT16; -#[allow(missing_docs)] pub const R_PPC64_GOT16_LO: u32 = R_PPC_GOT16_LO; -#[allow(missing_docs)] pub const R_PPC64_GOT16_HI: u32 = R_PPC_GOT16_HI; -#[allow(missing_docs)] pub const R_PPC64_GOT16_HA: u32 = R_PPC_GOT16_HA; -#[allow(missing_docs)] pub const R_PPC64_COPY: u32 = R_PPC_COPY; -#[allow(missing_docs)] pub const R_PPC64_GLOB_DAT: u32 = R_PPC_GLOB_DAT; -#[allow(missing_docs)] pub const R_PPC64_JMP_SLOT: u32 = R_PPC_JMP_SLOT; -#[allow(missing_docs)] pub const R_PPC64_RELATIVE: u32 = R_PPC_RELATIVE; -#[allow(missing_docs)] pub const R_PPC64_UADDR32: u32 = R_PPC_UADDR32; -#[allow(missing_docs)] pub const R_PPC64_UADDR16: u32 = R_PPC_UADDR16; -#[allow(missing_docs)] pub const R_PPC64_REL32: u32 = R_PPC_REL32; -#[allow(missing_docs)] pub const R_PPC64_PLT32: u32 = R_PPC_PLT32; -#[allow(missing_docs)] pub const R_PPC64_PLTREL32: u32 = R_PPC_PLTREL32; -#[allow(missing_docs)] pub const R_PPC64_PLT16_LO: u32 = R_PPC_PLT16_LO; -#[allow(missing_docs)] pub const R_PPC64_PLT16_HI: u32 = R_PPC_PLT16_HI; -#[allow(missing_docs)] pub const R_PPC64_PLT16_HA: u32 = R_PPC_PLT16_HA; -#[allow(missing_docs)] pub const R_PPC64_SECTOFF: u32 = R_PPC_SECTOFF; -#[allow(missing_docs)] pub const R_PPC64_SECTOFF_LO: u32 = R_PPC_SECTOFF_LO; -#[allow(missing_docs)] pub const R_PPC64_SECTOFF_HI: u32 = R_PPC_SECTOFF_HI; -#[allow(missing_docs)] pub const R_PPC64_SECTOFF_HA: u32 = R_PPC_SECTOFF_HA; /// word30 (S + A - P) >> 2 pub const R_PPC64_ADDR30: u32 = 37; @@ -3810,24 +3592,16 @@ pub const R_PPC64_TLSLD: u32 = 108; pub const R_PPC64_TOCSAVE: u32 = 109; // Added when HA and HI relocs were changed to report overflows. -#[allow(missing_docs)] pub const R_PPC64_ADDR16_HIGH: u32 = 110; -#[allow(missing_docs)] pub const R_PPC64_ADDR16_HIGHA: u32 = 111; -#[allow(missing_docs)] pub const R_PPC64_TPREL16_HIGH: u32 = 112; -#[allow(missing_docs)] pub const R_PPC64_TPREL16_HIGHA: u32 = 113; -#[allow(missing_docs)] pub const R_PPC64_DTPREL16_HIGH: u32 = 114; -#[allow(missing_docs)] pub const R_PPC64_DTPREL16_HIGHA: u32 = 115; /// GNU extension to support local ifunc. -#[allow(missing_docs)] pub const R_PPC64_JMP_IREL: u32 = 247; /// GNU extension to support local ifunc. -#[allow(missing_docs)] pub const R_PPC64_IRELATIVE: u32 = 248; /// half16 (sym+add-.) pub const R_PPC64_REL16: u32 = 249; @@ -3847,55 +3621,35 @@ pub const R_PPC64_REL16_HA: u32 = 252; pub const EF_PPC64_ABI: u32 = 3; // PowerPC64 values for `Dyn64::d_tag. -#[allow(missing_docs)] pub const DT_PPC64_GLINK: u32 = DT_LOPROC + 0; -#[allow(missing_docs)] pub const DT_PPC64_OPD: u32 = DT_LOPROC + 1; -#[allow(missing_docs)] pub const DT_PPC64_OPDSZ: u32 = DT_LOPROC + 2; -#[allow(missing_docs)] pub const DT_PPC64_OPT: u32 = DT_LOPROC + 3; // PowerPC64 bits for `DT_PPC64_OPT` entry. -#[allow(missing_docs)] pub const PPC64_OPT_TLS: u32 = 1; -#[allow(missing_docs)] pub const PPC64_OPT_MULTI_TOC: u32 = 2; -#[allow(missing_docs)] pub const PPC64_OPT_LOCALENTRY: u32 = 4; // PowerPC64 values for `Sym64::st_other. -#[allow(missing_docs)] pub const STO_PPC64_LOCAL_BIT: u8 = 5; -#[allow(missing_docs)] pub const STO_PPC64_LOCAL_MASK: u8 = 7 << STO_PPC64_LOCAL_BIT; // ARM specific declarations. // ARM values for `FileHeader*::e_flags`. -#[allow(missing_docs)] pub const EF_ARM_RELEXEC: u32 = 0x01; -#[allow(missing_docs)] pub const EF_ARM_HASENTRY: u32 = 0x02; -#[allow(missing_docs)] pub const EF_ARM_INTERWORK: u32 = 0x04; -#[allow(missing_docs)] pub const EF_ARM_APCS_26: u32 = 0x08; -#[allow(missing_docs)] pub const EF_ARM_APCS_FLOAT: u32 = 0x10; -#[allow(missing_docs)] pub const EF_ARM_PIC: u32 = 0x20; /// 8-bit structure alignment is in use pub const EF_ARM_ALIGN8: u32 = 0x40; -#[allow(missing_docs)] pub const EF_ARM_NEW_ABI: u32 = 0x80; -#[allow(missing_docs)] pub const EF_ARM_OLD_ABI: u32 = 0x100; -#[allow(missing_docs)] pub const EF_ARM_SOFT_FLOAT: u32 = 0x200; -#[allow(missing_docs)] pub const EF_ARM_VFP_FLOAT: u32 = 0x400; -#[allow(missing_docs)] pub const EF_ARM_MAVERICK_FLOAT: u32 = 0x800; /// NB conflicts with EF_ARM_SOFT_FLOAT @@ -3905,32 +3659,20 @@ 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. -#[allow(missing_docs)] pub const EF_ARM_SYMSARESORTED: u32 = 0x04; -#[allow(missing_docs)] pub const EF_ARM_DYNSYMSUSESEGIDX: u32 = 0x08; -#[allow(missing_docs)] pub const EF_ARM_MAPSYMSFIRST: u32 = 0x10; // Constants defined in AAELF. -#[allow(missing_docs)] pub const EF_ARM_BE8: u32 = 0x0080_0000; -#[allow(missing_docs)] pub const EF_ARM_LE8: u32 = 0x0040_0000; -#[allow(missing_docs)] pub const EF_ARM_EABIMASK: u32 = 0xff00_0000; -#[allow(missing_docs)] pub const EF_ARM_EABI_UNKNOWN: u32 = 0x0000_0000; -#[allow(missing_docs)] pub const EF_ARM_EABI_VER1: u32 = 0x0100_0000; -#[allow(missing_docs)] pub const EF_ARM_EABI_VER2: u32 = 0x0200_0000; -#[allow(missing_docs)] pub const EF_ARM_EABI_VER3: u32 = 0x0300_0000; -#[allow(missing_docs)] pub const EF_ARM_EABI_VER4: u32 = 0x0400_0000; -#[allow(missing_docs)] pub const EF_ARM_EABI_VER5: u32 = 0x0500_0000; // ARM Thumb values for `st_type` component of `Sym*::st_info`. @@ -4247,118 +3989,65 @@ pub const EF_AVR_ARCH: u32 = 0x7F; /// for the relocations so that linker relaxation is possible. pub const EF_AVR_LINKRELAX_PREPARED: u32 = 0x80; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR1: u32 = 1; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR2: u32 = 2; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR25: u32 = 25; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR3: u32 = 3; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR31: u32 = 31; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR35: u32 = 35; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR4: u32 = 4; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR5: u32 = 5; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR51: u32 = 51; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVR6: u32 = 6; -#[allow(missing_docs)] pub const EF_AVR_ARCH_AVRTINY: u32 = 100; -#[allow(missing_docs)] pub const EF_AVR_ARCH_XMEGA1: u32 = 101; -#[allow(missing_docs)] pub const EF_AVR_ARCH_XMEGA2: u32 = 102; -#[allow(missing_docs)] pub const EF_AVR_ARCH_XMEGA3: u32 = 103; -#[allow(missing_docs)] pub const EF_AVR_ARCH_XMEGA4: u32 = 104; -#[allow(missing_docs)] pub const EF_AVR_ARCH_XMEGA5: u32 = 105; -#[allow(missing_docs)] pub const EF_AVR_ARCH_XMEGA6: u32 = 106; -#[allow(missing_docs)] pub const EF_AVR_ARCH_XMEGA7: u32 = 107; // AVR values for `Rel*::r_type`. -#[allow(missing_docs)] pub const R_AVR_NONE: u32 = 0; /// Direct 32 bit pub const R_AVR_32: u32 = 1; -#[allow(missing_docs)] pub const R_AVR_7_PCREL: u32 = 2; -#[allow(missing_docs)] pub const R_AVR_13_PCREL: u32 = 3; /// Direct 16 bit pub const R_AVR_16: u32 = 4; -#[allow(missing_docs)] pub const R_AVR_16_PM: u32 = 5; -#[allow(missing_docs)] pub const R_AVR_LO8_LDI: u32 = 6; -#[allow(missing_docs)] pub const R_AVR_HI8_LDI: u32 = 7; -#[allow(missing_docs)] pub const R_AVR_HH8_LDI: u32 = 8; -#[allow(missing_docs)] pub const R_AVR_LO8_LDI_NEG: u32 = 9; -#[allow(missing_docs)] pub const R_AVR_HI8_LDI_NEG: u32 = 10; -#[allow(missing_docs)] pub const R_AVR_HH8_LDI_NEG: u32 = 11; -#[allow(missing_docs)] pub const R_AVR_LO8_LDI_PM: u32 = 12; -#[allow(missing_docs)] pub const R_AVR_HI8_LDI_PM: u32 = 13; -#[allow(missing_docs)] pub const R_AVR_HH8_LDI_PM: u32 = 14; -#[allow(missing_docs)] pub const R_AVR_LO8_LDI_PM_NEG: u32 = 15; -#[allow(missing_docs)] pub const R_AVR_HI8_LDI_PM_NEG: u32 = 16; -#[allow(missing_docs)] pub const R_AVR_HH8_LDI_PM_NEG: u32 = 17; -#[allow(missing_docs)] pub const R_AVR_CALL: u32 = 18; -#[allow(missing_docs)] pub const R_AVR_LDI: u32 = 19; -#[allow(missing_docs)] pub const R_AVR_6: u32 = 20; -#[allow(missing_docs)] pub const R_AVR_6_ADIW: u32 = 21; -#[allow(missing_docs)] pub const R_AVR_MS8_LDI: u32 = 22; -#[allow(missing_docs)] pub const R_AVR_MS8_LDI_NEG: u32 = 23; -#[allow(missing_docs)] pub const R_AVR_LO8_LDI_GS: u32 = 24; -#[allow(missing_docs)] pub const R_AVR_HI8_LDI_GS: u32 = 25; -#[allow(missing_docs)] pub const R_AVR_8: u32 = 26; -#[allow(missing_docs)] pub const R_AVR_8_LO8: u32 = 27; -#[allow(missing_docs)] pub const R_AVR_8_HI8: u32 = 28; -#[allow(missing_docs)] pub const R_AVR_8_HLO8: u32 = 29; -#[allow(missing_docs)] pub const R_AVR_DIFF8: u32 = 30; -#[allow(missing_docs)] pub const R_AVR_DIFF16: u32 = 31; -#[allow(missing_docs)] pub const R_AVR_DIFF32: u32 = 32; -#[allow(missing_docs)] pub const R_AVR_LDS_STS_16: u32 = 33; -#[allow(missing_docs)] pub const R_AVR_PORT6: u32 = 34; -#[allow(missing_docs)] pub const R_AVR_PORT5: u32 = 35; -#[allow(missing_docs)] pub const R_AVR_32_PCREL: u32 = 36; // MSP430 values for `Rel*::r_type`. @@ -4383,7 +4072,6 @@ pub const R_ARM_PC24: u32 = 1; pub const R_ARM_ABS32: u32 = 2; /// PC relative 32 bit pub const R_ARM_REL32: u32 = 3; -#[allow(missing_docs)] pub const R_ARM_PC13: u32 = 4; /// Direct 16 bit pub const R_ARM_ABS16: u32 = 5; @@ -4393,13 +4081,11 @@ pub const R_ARM_ABS12: u32 = 6; pub const R_ARM_THM_ABS5: u32 = 7; /// Direct 8 bit pub const R_ARM_ABS8: u32 = 8; -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const R_ARM_AMP_VCALL9: u32 = 12; /// Obsolete static relocation. pub const R_ARM_SWI24: u32 = 13; @@ -4453,13 +4139,10 @@ pub const R_ARM_LDR_SBREL_11_0: u32 = 35; pub const R_ARM_ALU_SBREL_19_12: u32 = 36; /// Deprecated, prog. base relative. pub const R_ARM_ALU_SBREL_27_20: u32 = 37; -#[allow(missing_docs)] pub const R_ARM_TARGET1: u32 = 38; /// Program base relative. pub const R_ARM_SBREL31: u32 = 39; -#[allow(missing_docs)] pub const R_ARM_V4BX: u32 = 40; -#[allow(missing_docs)] pub const R_ARM_TARGET2: u32 = 41; /// 32 bit PC relative. pub const R_ARM_PREL31: u32 = 42; @@ -4557,15 +4240,11 @@ pub const R_ARM_THM_MOVW_BREL_NC: u32 = 87; 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; -#[allow(missing_docs)] pub const R_ARM_TLS_GOTDESC: u32 = 90; -#[allow(missing_docs)] pub const R_ARM_TLS_CALL: u32 = 91; /// TLS relaxation. pub const R_ARM_TLS_DESCSEQ: u32 = 92; -#[allow(missing_docs)] pub const R_ARM_THM_TLS_CALL: u32 = 93; -#[allow(missing_docs)] pub const R_ARM_PLT32_ABS: u32 = 94; /// GOT entry. pub const R_ARM_GOT_ABS: u32 = 95; @@ -4575,11 +4254,8 @@ pub const R_ARM_GOT_PREL: u32 = 96; 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; -#[allow(missing_docs)] pub const R_ARM_GOTRELAX: u32 = 99; -#[allow(missing_docs)] pub const R_ARM_GNU_VTENTRY: u32 = 100; -#[allow(missing_docs)] pub const R_ARM_GNU_VTINHERIT: u32 = 101; /// PC relative & 0xFFE (Thumb16 B). pub const R_ARM_THM_PC11: u32 = 102; @@ -4603,29 +4279,18 @@ pub const R_ARM_TLS_LE12: u32 = 110; pub const R_ARM_TLS_IE12GP: u32 = 111; /// Obsolete. pub const R_ARM_ME_TOO: u32 = 128; -#[allow(missing_docs)] pub const R_ARM_THM_TLS_DESCSEQ: u32 = 129; -#[allow(missing_docs)] pub const R_ARM_THM_TLS_DESCSEQ16: u32 = 129; -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const R_ARM_IRELATIVE: u32 = 160; -#[allow(missing_docs)] pub const R_ARM_RXPC25: u32 = 249; -#[allow(missing_docs)] pub const R_ARM_RSBREL32: u32 = 250; -#[allow(missing_docs)] pub const R_ARM_THM_RPC22: u32 = 251; -#[allow(missing_docs)] pub const R_ARM_RREL32: u32 = 252; -#[allow(missing_docs)] pub const R_ARM_RABS22: u32 = 253; -#[allow(missing_docs)] pub const R_ARM_RPC24: u32 = 254; -#[allow(missing_docs)] pub const R_ARM_RBASE: u32 = 255; // C-SKY values for `Rel*::r_type`. @@ -4725,32 +4390,20 @@ pub const R_CKCORE_PLT_IMM18BY4: u32 = 49; pub const R_CKCORE_PCREL_IMM7BY4: u32 = 50; /// 32 bit offset to TLS block pub const R_CKCORE_TLS_LE32: u32 = 51; -#[allow(missing_docs)] pub const R_CKCORE_TLS_IE32: u32 = 52; -#[allow(missing_docs)] pub const R_CKCORE_TLS_GD32: u32 = 53; -#[allow(missing_docs)] pub const R_CKCORE_TLS_LDM32: u32 = 54; -#[allow(missing_docs)] pub const R_CKCORE_TLS_LDO32: u32 = 55; -#[allow(missing_docs)] pub const R_CKCORE_TLS_DTPMOD32: u32 = 56; -#[allow(missing_docs)] pub const R_CKCORE_TLS_DTPOFF32: u32 = 57; -#[allow(missing_docs)] pub const R_CKCORE_TLS_TPOFF32: u32 = 58; // C-SKY values for `FileHeader*::e_flags`. -#[allow(missing_docs)] pub const EF_CSKY_ABIMASK: u32 = 0xF000_0000; -#[allow(missing_docs)] pub const EF_CSKY_OTHER: u32 = 0x0FFF_0000; -#[allow(missing_docs)] pub const EF_CSKY_PROCESSOR: u32 = 0x0000_FFFF; -#[allow(missing_docs)] pub const EF_CSKY_ABIV1: u32 = 0x1000_0000; -#[allow(missing_docs)] pub const EF_CSKY_ABIV2: u32 = 0x2000_0000; // C-SKY values for `SectionHeader*::sh_type`. @@ -4772,11 +4425,8 @@ pub const EF_IA_64_ARCH: u32 = 0xff00_0000; pub const PT_IA_64_ARCHEXT: u32 = PT_LOPROC + 0; /// ia64 unwind bits pub const PT_IA_64_UNWIND: u32 = PT_LOPROC + 1; -#[allow(missing_docs)] pub const PT_IA_64_HP_OPT_ANOT: u32 = PT_LOOS + 0x12; -#[allow(missing_docs)] pub const PT_IA_64_HP_HSL_ANOT: u32 = PT_LOOS + 0x13; -#[allow(missing_docs)] pub const PT_IA_64_HP_STACK: u32 = PT_LOOS + 0x14; // IA-64 values for `ProgramHeader64::p_flags`. @@ -4796,7 +4446,6 @@ pub const SHF_IA_64_SHORT: u32 = 0x1000_0000; pub const SHF_IA_64_NORECOV: u32 = 0x2000_0000; // IA-64 values for `Dyn64::d_tag`. -#[allow(missing_docs)] pub const DT_IA_64_PLT_RESERVE: u32 = DT_LOPROC + 0; // IA-64 values for `Rel*::r_type`. @@ -4966,125 +4615,66 @@ pub const R_IA64_LTOFF_DTPREL22: u32 = 0xba; // SH specific declarations. // SH values `FileHeader*::e_flags`. -#[allow(missing_docs)] pub const EF_SH_MACH_MASK: u32 = 0x1f; -#[allow(missing_docs)] pub const EF_SH_UNKNOWN: u32 = 0x0; -#[allow(missing_docs)] pub const EF_SH1: u32 = 0x1; -#[allow(missing_docs)] pub const EF_SH2: u32 = 0x2; -#[allow(missing_docs)] pub const EF_SH3: u32 = 0x3; -#[allow(missing_docs)] pub const EF_SH_DSP: u32 = 0x4; -#[allow(missing_docs)] pub const EF_SH3_DSP: u32 = 0x5; -#[allow(missing_docs)] pub const EF_SH4AL_DSP: u32 = 0x6; -#[allow(missing_docs)] pub const EF_SH3E: u32 = 0x8; -#[allow(missing_docs)] pub const EF_SH4: u32 = 0x9; -#[allow(missing_docs)] pub const EF_SH2E: u32 = 0xb; -#[allow(missing_docs)] pub const EF_SH4A: u32 = 0xc; -#[allow(missing_docs)] pub const EF_SH2A: u32 = 0xd; -#[allow(missing_docs)] pub const EF_SH4_NOFPU: u32 = 0x10; -#[allow(missing_docs)] pub const EF_SH4A_NOFPU: u32 = 0x11; -#[allow(missing_docs)] pub const EF_SH4_NOMMU_NOFPU: u32 = 0x12; -#[allow(missing_docs)] pub const EF_SH2A_NOFPU: u32 = 0x13; -#[allow(missing_docs)] pub const EF_SH3_NOMMU: u32 = 0x14; -#[allow(missing_docs)] pub const EF_SH2A_SH4_NOFPU: u32 = 0x15; -#[allow(missing_docs)] pub const EF_SH2A_SH3_NOFPU: u32 = 0x16; -#[allow(missing_docs)] pub const EF_SH2A_SH4: u32 = 0x17; -#[allow(missing_docs)] pub const EF_SH2A_SH3E: u32 = 0x18; // SH values `Rel*::r_type`. -#[allow(missing_docs)] pub const R_SH_NONE: u32 = 0; -#[allow(missing_docs)] pub const R_SH_DIR32: u32 = 1; -#[allow(missing_docs)] pub const R_SH_REL32: u32 = 2; -#[allow(missing_docs)] pub const R_SH_DIR8WPN: u32 = 3; -#[allow(missing_docs)] pub const R_SH_IND12W: u32 = 4; -#[allow(missing_docs)] pub const R_SH_DIR8WPL: u32 = 5; -#[allow(missing_docs)] pub const R_SH_DIR8WPZ: u32 = 6; -#[allow(missing_docs)] pub const R_SH_DIR8BP: u32 = 7; -#[allow(missing_docs)] pub const R_SH_DIR8W: u32 = 8; -#[allow(missing_docs)] pub const R_SH_DIR8L: u32 = 9; -#[allow(missing_docs)] pub const R_SH_SWITCH16: u32 = 25; -#[allow(missing_docs)] pub const R_SH_SWITCH32: u32 = 26; -#[allow(missing_docs)] pub const R_SH_USES: u32 = 27; -#[allow(missing_docs)] pub const R_SH_COUNT: u32 = 28; -#[allow(missing_docs)] pub const R_SH_ALIGN: u32 = 29; -#[allow(missing_docs)] pub const R_SH_CODE: u32 = 30; -#[allow(missing_docs)] pub const R_SH_DATA: u32 = 31; -#[allow(missing_docs)] pub const R_SH_LABEL: u32 = 32; -#[allow(missing_docs)] pub const R_SH_SWITCH8: u32 = 33; -#[allow(missing_docs)] pub const R_SH_GNU_VTINHERIT: u32 = 34; -#[allow(missing_docs)] pub const R_SH_GNU_VTENTRY: u32 = 35; -#[allow(missing_docs)] pub const R_SH_TLS_GD_32: u32 = 144; -#[allow(missing_docs)] pub const R_SH_TLS_LD_32: u32 = 145; -#[allow(missing_docs)] pub const R_SH_TLS_LDO_32: u32 = 146; -#[allow(missing_docs)] pub const R_SH_TLS_IE_32: u32 = 147; -#[allow(missing_docs)] pub const R_SH_TLS_LE_32: u32 = 148; -#[allow(missing_docs)] pub const R_SH_TLS_DTPMOD32: u32 = 149; -#[allow(missing_docs)] pub const R_SH_TLS_DTPOFF32: u32 = 150; -#[allow(missing_docs)] pub const R_SH_TLS_TPOFF32: u32 = 151; -#[allow(missing_docs)] pub const R_SH_GOT32: u32 = 160; -#[allow(missing_docs)] pub const R_SH_PLT32: u32 = 161; -#[allow(missing_docs)] pub const R_SH_COPY: u32 = 162; -#[allow(missing_docs)] pub const R_SH_GLOB_DAT: u32 = 163; -#[allow(missing_docs)] pub const R_SH_JMP_SLOT: u32 = 164; -#[allow(missing_docs)] pub const R_SH_RELATIVE: u32 = 165; -#[allow(missing_docs)] pub const R_SH_GOTOFF: u32 = 166; -#[allow(missing_docs)] pub const R_SH_GOTPC: u32 = 167; // S/390 specific definitions. @@ -5222,45 +4812,25 @@ pub const R_390_TLS_GOTIE20: u32 = 60; pub const R_390_IRELATIVE: u32 = 61; // CRIS values `Rel*::r_type`. -#[allow(missing_docs)] pub const R_CRIS_NONE: u32 = 0; -#[allow(missing_docs)] pub const R_CRIS_8: u32 = 1; -#[allow(missing_docs)] pub const R_CRIS_16: u32 = 2; -#[allow(missing_docs)] pub const R_CRIS_32: u32 = 3; -#[allow(missing_docs)] pub const R_CRIS_8_PCREL: u32 = 4; -#[allow(missing_docs)] pub const R_CRIS_16_PCREL: u32 = 5; -#[allow(missing_docs)] pub const R_CRIS_32_PCREL: u32 = 6; -#[allow(missing_docs)] pub const R_CRIS_GNU_VTINHERIT: u32 = 7; -#[allow(missing_docs)] pub const R_CRIS_GNU_VTENTRY: u32 = 8; -#[allow(missing_docs)] pub const R_CRIS_COPY: u32 = 9; -#[allow(missing_docs)] pub const R_CRIS_GLOB_DAT: u32 = 10; -#[allow(missing_docs)] pub const R_CRIS_JUMP_SLOT: u32 = 11; -#[allow(missing_docs)] pub const R_CRIS_RELATIVE: u32 = 12; -#[allow(missing_docs)] pub const R_CRIS_16_GOT: u32 = 13; -#[allow(missing_docs)] pub const R_CRIS_32_GOT: u32 = 14; -#[allow(missing_docs)] pub const R_CRIS_16_GOTPLT: u32 = 15; -#[allow(missing_docs)] pub const R_CRIS_32_GOTPLT: u32 = 16; -#[allow(missing_docs)] pub const R_CRIS_32_GOTREL: u32 = 17; -#[allow(missing_docs)] pub const R_CRIS_32_PLT_GOTREL: u32 = 18; -#[allow(missing_docs)] pub const R_CRIS_32_PLT_PCREL: u32 = 19; // AMD x86-64 values `Rel*::r_type`. @@ -5448,9 +5018,7 @@ pub const R_M32R_HI16_SLO: u32 = 8; pub const R_M32R_LO16: u32 = 9; /// 16 bit offset in SDA. pub const R_M32R_SDA16: u32 = 10; -#[allow(missing_docs)] pub const R_M32R_GNU_VTINHERIT: u32 = 11; -#[allow(missing_docs)] pub const R_M32R_GNU_VTENTRY: u32 = 12; // M32R values `Rela32::r_type`. /// Direct 16 bit. @@ -5473,9 +5041,7 @@ pub const R_M32R_HI16_SLO_RELA: u32 = 40; pub const R_M32R_LO16_RELA: u32 = 41; /// 16 bit offset in SDA pub const R_M32R_SDA16_RELA: u32 = 42; -#[allow(missing_docs)] pub const R_M32R_RELA_GNU_VTINHERIT: u32 = 43; -#[allow(missing_docs)] pub const R_M32R_RELA_GNU_VTENTRY: u32 = 44; /// PC relative 32 bit. pub const R_M32R_REL32: u32 = 45; @@ -6109,271 +5675,154 @@ pub const R_TILEGX_GNU_VTINHERIT: u32 = 128; pub const R_TILEGX_GNU_VTENTRY: u32 = 129; // RISC-V values `FileHeader*::e_flags`. -#[allow(missing_docs)] pub const EF_RISCV_RVC: u32 = 0x0001; -#[allow(missing_docs)] pub const EF_RISCV_FLOAT_ABI: u32 = 0x0006; -#[allow(missing_docs)] pub const EF_RISCV_FLOAT_ABI_SOFT: u32 = 0x0000; -#[allow(missing_docs)] pub const EF_RISCV_FLOAT_ABI_SINGLE: u32 = 0x0002; -#[allow(missing_docs)] pub const EF_RISCV_FLOAT_ABI_DOUBLE: u32 = 0x0004; -#[allow(missing_docs)] 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`. -#[allow(missing_docs)] pub const R_RISCV_NONE: u32 = 0; -#[allow(missing_docs)] pub const R_RISCV_32: u32 = 1; -#[allow(missing_docs)] pub const R_RISCV_64: u32 = 2; -#[allow(missing_docs)] pub const R_RISCV_RELATIVE: u32 = 3; -#[allow(missing_docs)] pub const R_RISCV_COPY: u32 = 4; -#[allow(missing_docs)] pub const R_RISCV_JUMP_SLOT: u32 = 5; -#[allow(missing_docs)] pub const R_RISCV_TLS_DTPMOD32: u32 = 6; -#[allow(missing_docs)] pub const R_RISCV_TLS_DTPMOD64: u32 = 7; -#[allow(missing_docs)] pub const R_RISCV_TLS_DTPREL32: u32 = 8; -#[allow(missing_docs)] pub const R_RISCV_TLS_DTPREL64: u32 = 9; -#[allow(missing_docs)] pub const R_RISCV_TLS_TPREL32: u32 = 10; -#[allow(missing_docs)] pub const R_RISCV_TLS_TPREL64: u32 = 11; -#[allow(missing_docs)] pub const R_RISCV_BRANCH: u32 = 16; -#[allow(missing_docs)] pub const R_RISCV_JAL: u32 = 17; -#[allow(missing_docs)] pub const R_RISCV_CALL: u32 = 18; -#[allow(missing_docs)] pub const R_RISCV_CALL_PLT: u32 = 19; -#[allow(missing_docs)] pub const R_RISCV_GOT_HI20: u32 = 20; -#[allow(missing_docs)] pub const R_RISCV_TLS_GOT_HI20: u32 = 21; -#[allow(missing_docs)] pub const R_RISCV_TLS_GD_HI20: u32 = 22; -#[allow(missing_docs)] pub const R_RISCV_PCREL_HI20: u32 = 23; -#[allow(missing_docs)] pub const R_RISCV_PCREL_LO12_I: u32 = 24; -#[allow(missing_docs)] pub const R_RISCV_PCREL_LO12_S: u32 = 25; -#[allow(missing_docs)] pub const R_RISCV_HI20: u32 = 26; -#[allow(missing_docs)] pub const R_RISCV_LO12_I: u32 = 27; -#[allow(missing_docs)] pub const R_RISCV_LO12_S: u32 = 28; -#[allow(missing_docs)] pub const R_RISCV_TPREL_HI20: u32 = 29; -#[allow(missing_docs)] pub const R_RISCV_TPREL_LO12_I: u32 = 30; -#[allow(missing_docs)] pub const R_RISCV_TPREL_LO12_S: u32 = 31; -#[allow(missing_docs)] pub const R_RISCV_TPREL_ADD: u32 = 32; -#[allow(missing_docs)] pub const R_RISCV_ADD8: u32 = 33; -#[allow(missing_docs)] pub const R_RISCV_ADD16: u32 = 34; -#[allow(missing_docs)] pub const R_RISCV_ADD32: u32 = 35; -#[allow(missing_docs)] pub const R_RISCV_ADD64: u32 = 36; -#[allow(missing_docs)] pub const R_RISCV_SUB8: u32 = 37; -#[allow(missing_docs)] pub const R_RISCV_SUB16: u32 = 38; -#[allow(missing_docs)] pub const R_RISCV_SUB32: u32 = 39; -#[allow(missing_docs)] pub const R_RISCV_SUB64: u32 = 40; -#[allow(missing_docs)] pub const R_RISCV_GNU_VTINHERIT: u32 = 41; -#[allow(missing_docs)] pub const R_RISCV_GNU_VTENTRY: u32 = 42; -#[allow(missing_docs)] pub const R_RISCV_ALIGN: u32 = 43; -#[allow(missing_docs)] pub const R_RISCV_RVC_BRANCH: u32 = 44; -#[allow(missing_docs)] pub const R_RISCV_RVC_JUMP: u32 = 45; -#[allow(missing_docs)] pub const R_RISCV_RVC_LUI: u32 = 46; -#[allow(missing_docs)] pub const R_RISCV_GPREL_I: u32 = 47; -#[allow(missing_docs)] pub const R_RISCV_GPREL_S: u32 = 48; -#[allow(missing_docs)] pub const R_RISCV_TPREL_I: u32 = 49; -#[allow(missing_docs)] pub const R_RISCV_TPREL_S: u32 = 50; -#[allow(missing_docs)] pub const R_RISCV_RELAX: u32 = 51; -#[allow(missing_docs)] pub const R_RISCV_SUB6: u32 = 52; -#[allow(missing_docs)] pub const R_RISCV_SET6: u32 = 53; -#[allow(missing_docs)] pub const R_RISCV_SET8: u32 = 54; -#[allow(missing_docs)] pub const R_RISCV_SET16: u32 = 55; -#[allow(missing_docs)] pub const R_RISCV_SET32: u32 = 56; -#[allow(missing_docs)] pub const R_RISCV_32_PCREL: u32 = 57; // BPF values `Rel*::r_type`. /// No reloc pub const R_BPF_NONE: u32 = 0; -#[allow(missing_docs)] pub const R_BPF_64_64: u32 = 1; -#[allow(missing_docs)] pub const R_BPF_64_32: u32 = 10; // SBF values `Rel*::r_type`. /// No reloc pub const R_SBF_NONE: u32 = 0; -#[allow(missing_docs)] pub const R_SBF_64_64: u32 = 1; -#[allow(missing_docs)] pub const R_SBF_64_32: u32 = 10; // Imagination Meta values `Rel*::r_type`. -#[allow(missing_docs)] pub const R_METAG_HIADDR16: u32 = 0; -#[allow(missing_docs)] 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; -#[allow(missing_docs)] pub const R_METAG_RELBRANCH: u32 = 4; -#[allow(missing_docs)] pub const R_METAG_GETSETOFF: u32 = 5; -// Backward compatability -#[allow(missing_docs)] +// Backward compatibility pub const R_METAG_REG32OP1: u32 = 6; -#[allow(missing_docs)] pub const R_METAG_REG32OP2: u32 = 7; -#[allow(missing_docs)] pub const R_METAG_REG32OP3: u32 = 8; -#[allow(missing_docs)] pub const R_METAG_REG16OP1: u32 = 9; -#[allow(missing_docs)] pub const R_METAG_REG16OP2: u32 = 10; -#[allow(missing_docs)] pub const R_METAG_REG16OP3: u32 = 11; -#[allow(missing_docs)] pub const R_METAG_REG32OP4: u32 = 12; -#[allow(missing_docs)] pub const R_METAG_HIOG: u32 = 13; -#[allow(missing_docs)] pub const R_METAG_LOOG: u32 = 14; -#[allow(missing_docs)] pub const R_METAG_REL8: u32 = 15; -#[allow(missing_docs)] pub const R_METAG_REL16: u32 = 16; -#[allow(missing_docs)] pub const R_METAG_GNU_VTINHERIT: u32 = 30; -#[allow(missing_docs)] pub const R_METAG_GNU_VTENTRY: u32 = 31; // PIC relocations -#[allow(missing_docs)] pub const R_METAG_HI16_GOTOFF: u32 = 32; -#[allow(missing_docs)] pub const R_METAG_LO16_GOTOFF: u32 = 33; -#[allow(missing_docs)] pub const R_METAG_GETSET_GOTOFF: u32 = 34; -#[allow(missing_docs)] pub const R_METAG_GETSET_GOT: u32 = 35; -#[allow(missing_docs)] pub const R_METAG_HI16_GOTPC: u32 = 36; -#[allow(missing_docs)] pub const R_METAG_LO16_GOTPC: u32 = 37; -#[allow(missing_docs)] pub const R_METAG_HI16_PLT: u32 = 38; -#[allow(missing_docs)] pub const R_METAG_LO16_PLT: u32 = 39; -#[allow(missing_docs)] pub const R_METAG_RELBRANCH_PLT: u32 = 40; -#[allow(missing_docs)] pub const R_METAG_GOTOFF: u32 = 41; -#[allow(missing_docs)] pub const R_METAG_PLT: u32 = 42; -#[allow(missing_docs)] pub const R_METAG_COPY: u32 = 43; -#[allow(missing_docs)] pub const R_METAG_JMP_SLOT: u32 = 44; -#[allow(missing_docs)] pub const R_METAG_RELATIVE: u32 = 45; -#[allow(missing_docs)] pub const R_METAG_GLOB_DAT: u32 = 46; // TLS relocations -#[allow(missing_docs)] pub const R_METAG_TLS_GD: u32 = 47; -#[allow(missing_docs)] pub const R_METAG_TLS_LDM: u32 = 48; -#[allow(missing_docs)] pub const R_METAG_TLS_LDO_HI16: u32 = 49; -#[allow(missing_docs)] pub const R_METAG_TLS_LDO_LO16: u32 = 50; -#[allow(missing_docs)] pub const R_METAG_TLS_LDO: u32 = 51; -#[allow(missing_docs)] pub const R_METAG_TLS_IE: u32 = 52; -#[allow(missing_docs)] pub const R_METAG_TLS_IENONPIC: u32 = 53; -#[allow(missing_docs)] pub const R_METAG_TLS_IENONPIC_HI16: u32 = 54; -#[allow(missing_docs)] pub const R_METAG_TLS_IENONPIC_LO16: u32 = 55; -#[allow(missing_docs)] pub const R_METAG_TLS_TPOFF: u32 = 56; -#[allow(missing_docs)] pub const R_METAG_TLS_DTPMOD: u32 = 57; -#[allow(missing_docs)] pub const R_METAG_TLS_DTPOFF: u32 = 58; -#[allow(missing_docs)] pub const R_METAG_TLS_LE: u32 = 59; -#[allow(missing_docs)] pub const R_METAG_TLS_LE_HI16: u32 = 60; -#[allow(missing_docs)] pub const R_METAG_TLS_LE_LO16: u32 = 61; // NDS32 values `Rel*::r_type`. -#[allow(missing_docs)] pub const R_NDS32_NONE: u32 = 0; -#[allow(missing_docs)] pub const R_NDS32_32_RELA: u32 = 20; -#[allow(missing_docs)] pub const R_NDS32_COPY: u32 = 39; -#[allow(missing_docs)] pub const R_NDS32_GLOB_DAT: u32 = 40; -#[allow(missing_docs)] pub const R_NDS32_JMP_SLOT: u32 = 41; -#[allow(missing_docs)] pub const R_NDS32_RELATIVE: u32 = 42; -#[allow(missing_docs)] pub const R_NDS32_TLS_TPOFF: u32 = 102; -#[allow(missing_docs)] pub const R_NDS32_TLS_DESC: u32 = 119; // LoongArch values `FileHeader*::e_flags`. @@ -6597,129 +6046,75 @@ pub const R_LARCH_32_PCREL: u32 = 99; pub const R_LARCH_RELAX: u32 = 100; // Xtensa values Rel*::r_type`. -#[allow(missing_docs)] pub const R_XTENSA_NONE: u32 = 0; -#[allow(missing_docs)] pub const R_XTENSA_32: u32 = 1; -#[allow(missing_docs)] pub const R_XTENSA_RTLD: u32 = 2; -#[allow(missing_docs)] pub const R_XTENSA_GLOB_DAT: u32 = 3; -#[allow(missing_docs)] pub const R_XTENSA_JMP_SLOT: u32 = 4; -#[allow(missing_docs)] pub const R_XTENSA_RELATIVE: u32 = 5; -#[allow(missing_docs)] pub const R_XTENSA_PLT: u32 = 6; -#[allow(missing_docs)] pub const R_XTENSA_OP0: u32 = 8; -#[allow(missing_docs)] pub const R_XTENSA_OP1: u32 = 9; -#[allow(missing_docs)] pub const R_XTENSA_OP2: u32 = 10; -#[allow(missing_docs)] pub const R_XTENSA_ASM_EXPAND: u32 = 11; -#[allow(missing_docs)] pub const R_XTENSA_ASM_SIMPLIFY: u32 = 12; -#[allow(missing_docs)] pub const R_XTENSA_32_PCREL: u32 = 14; -#[allow(missing_docs)] pub const R_XTENSA_GNU_VTINHERIT: u32 = 15; -#[allow(missing_docs)] pub const R_XTENSA_GNU_VTENTRY: u32 = 16; -#[allow(missing_docs)] pub const R_XTENSA_DIFF8: u32 = 17; -#[allow(missing_docs)] pub const R_XTENSA_DIFF16: u32 = 18; -#[allow(missing_docs)] pub const R_XTENSA_DIFF32: u32 = 19; -#[allow(missing_docs)] pub const R_XTENSA_SLOT0_OP: u32 = 20; -#[allow(missing_docs)] pub const R_XTENSA_SLOT1_OP: u32 = 21; -#[allow(missing_docs)] pub const R_XTENSA_SLOT2_OP: u32 = 22; -#[allow(missing_docs)] pub const R_XTENSA_SLOT3_OP: u32 = 23; -#[allow(missing_docs)] pub const R_XTENSA_SLOT4_OP: u32 = 24; -#[allow(missing_docs)] pub const R_XTENSA_SLOT5_OP: u32 = 25; -#[allow(missing_docs)] pub const R_XTENSA_SLOT6_OP: u32 = 26; -#[allow(missing_docs)] pub const R_XTENSA_SLOT7_OP: u32 = 27; -#[allow(missing_docs)] pub const R_XTENSA_SLOT8_OP: u32 = 28; -#[allow(missing_docs)] pub const R_XTENSA_SLOT9_OP: u32 = 29; -#[allow(missing_docs)] pub const R_XTENSA_SLOT10_OP: u32 = 30; -#[allow(missing_docs)] pub const R_XTENSA_SLOT11_OP: u32 = 31; -#[allow(missing_docs)] pub const R_XTENSA_SLOT12_OP: u32 = 32; -#[allow(missing_docs)] pub const R_XTENSA_SLOT13_OP: u32 = 33; -#[allow(missing_docs)] pub const R_XTENSA_SLOT14_OP: u32 = 34; -#[allow(missing_docs)] pub const R_XTENSA_SLOT0_ALT: u32 = 35; -#[allow(missing_docs)] pub const R_XTENSA_SLOT1_ALT: u32 = 36; -#[allow(missing_docs)] pub const R_XTENSA_SLOT2_ALT: u32 = 37; -#[allow(missing_docs)] pub const R_XTENSA_SLOT3_ALT: u32 = 38; -#[allow(missing_docs)] pub const R_XTENSA_SLOT4_ALT: u32 = 39; -#[allow(missing_docs)] pub const R_XTENSA_SLOT5_ALT: u32 = 40; -#[allow(missing_docs)] pub const R_XTENSA_SLOT6_ALT: u32 = 41; -#[allow(missing_docs)] pub const R_XTENSA_SLOT7_ALT: u32 = 42; -#[allow(missing_docs)] pub const R_XTENSA_SLOT8_ALT: u32 = 43; -#[allow(missing_docs)] pub const R_XTENSA_SLOT9_ALT: u32 = 44; -#[allow(missing_docs)] pub const R_XTENSA_SLOT10_ALT: u32 = 45; -#[allow(missing_docs)] pub const R_XTENSA_SLOT11_ALT: u32 = 46; -#[allow(missing_docs)] pub const R_XTENSA_SLOT12_ALT: u32 = 47; -#[allow(missing_docs)] pub const R_XTENSA_SLOT13_ALT: u32 = 48; -#[allow(missing_docs)] pub const R_XTENSA_SLOT14_ALT: u32 = 49; -#[allow(missing_docs)] pub const R_XTENSA_TLSDESC_FN: u32 = 50; -#[allow(missing_docs)] pub const R_XTENSA_TLSDESC_ARG: u32 = 51; -#[allow(missing_docs)] pub const R_XTENSA_TLS_DTPOFF: u32 = 52; -#[allow(missing_docs)] pub const R_XTENSA_TLS_TPOFF: u32 = 53; -#[allow(missing_docs)] pub const R_XTENSA_TLS_FUNC: u32 = 54; -#[allow(missing_docs)] pub const R_XTENSA_TLS_ARG: u32 = 55; -#[allow(missing_docs)] pub const R_XTENSA_TLS_CALL: u32 = 56; -#[allow(missing_docs)] pub const R_XTENSA_PDIFF8: u32 = 57; -#[allow(missing_docs)] pub const R_XTENSA_PDIFF16: u32 = 58; -#[allow(missing_docs)] pub const R_XTENSA_PDIFF32: u32 = 59; -#[allow(missing_docs)] pub const R_XTENSA_NDIFF8: u32 = 60; -#[allow(missing_docs)] pub const R_XTENSA_NDIFF16: u32 = 61; -#[allow(missing_docs)] 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, diff --git a/vendor/object/src/endian.rs b/vendor/object/src/endian.rs index 1287aa654..e4a36ba13 100644 --- a/vendor/object/src/endian.rs +++ b/vendor/object/src/endian.rs @@ -402,6 +402,11 @@ mod aligned { pub struct U16(u16, PhantomData); impl U16 { + /// 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) @@ -424,6 +429,11 @@ mod aligned { pub struct U32(u32, PhantomData); impl U32 { + /// 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) @@ -444,6 +454,11 @@ mod aligned { pub struct U64(u64, PhantomData); impl U64 { + /// 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) @@ -464,6 +479,11 @@ mod aligned { pub struct I16(i16, PhantomData); impl I16 { + /// 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) @@ -484,6 +504,11 @@ mod aligned { pub struct I32(i32, PhantomData); impl I32 { + /// 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) @@ -504,6 +529,11 @@ mod aligned { pub struct I64(i64, PhantomData); impl I64 { + /// 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) @@ -590,6 +620,11 @@ pub type I64 = I64Bytes; pub struct U16Bytes([u8; 2], PhantomData); impl U16Bytes { + /// 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) @@ -612,6 +647,11 @@ impl U16Bytes { pub struct U32Bytes([u8; 4], PhantomData); impl U32Bytes { + /// 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) @@ -634,6 +674,11 @@ impl U32Bytes { pub struct U64Bytes([u8; 8], PhantomData); impl U64Bytes { + /// 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) @@ -656,6 +701,11 @@ impl U64Bytes { pub struct I16Bytes([u8; 2], PhantomData); impl I16Bytes { + /// 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) @@ -678,6 +728,11 @@ impl I16Bytes { pub struct I32Bytes([u8; 4], PhantomData); impl I32Bytes { + /// 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) @@ -700,6 +755,11 @@ impl I32Bytes { pub struct I64Bytes([u8; 8], PhantomData); impl I64Bytes { + /// 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) diff --git a/vendor/object/src/lib.rs b/vendor/object/src/lib.rs index 40f17c017..e17802c4f 100644 --- a/vendor/object/src/lib.rs +++ b/vendor/object/src/lib.rs @@ -1,20 +1,22 @@ //! # `object` //! //! The `object` crate provides a unified interface to working with object files -//! across platforms. It supports reading object files and executable files, -//! and writing object files and some executable 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), [archive]. +//! 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 [pod] and [endian]. //! //! ## Unified read API //! -//! The [read::Object] trait defines the unified interace. This trait is implemented +//! The [read::Object] trait defines the unified interface. This trait is implemented //! by [read::File], which allows reading any file format, as well as implementations //! for each file format: [ELF](read::elf::ElfFile), [Mach-O](read::macho::MachOFile), -//! [COFF](read::coff::CoffFile), [PE](read::pe::PeFile), [Wasm](read::wasm::WasmFile). +//! [COFF](read::coff::CoffFile), [PE](read::pe::PeFile), [Wasm](read::wasm::WasmFile), +//! [XCOFF](read::xcoff::XcoffFile). //! //! ## Low level read API //! @@ -24,7 +26,8 @@ //! //! ## Unified write API //! -//! [write::Object] allows building a COFF/ELF/Mach-O object and then writing it out. +//! [write::Object] allows building a COFF/ELF/Mach-O/XCOFF relocatable object file and +//! then writing it out. //! //! ## Low level executable writers //! @@ -55,6 +58,7 @@ #![deny(missing_docs)] #![deny(missing_debug_implementations)] #![no_std] +#![warn(rust_2018_idioms)] // Style. #![allow(clippy::collapsible_if)] #![allow(clippy::comparison_chain)] @@ -65,17 +69,12 @@ #![allow(clippy::should_implement_trait)] // Unit errors are converted to other types by callers. #![allow(clippy::result_unit_err)] -// Clippy is wrong. -#![allow(clippy::transmute_ptr_to_ptr)] // Worse readability sometimes. #![allow(clippy::collapsible_else_if)] #[cfg(feature = "cargo-all")] compile_error!("'--all-features' is not supported; use '--features all' instead"); -#[cfg(all(feature = "xcoff", not(feature = "unstable")))] -compile_error!("'xcoff` is an unstable feature; enable 'unstable' as well"); - #[cfg(any(feature = "read_core", feature = "write_core"))] #[allow(unused_imports)] #[macro_use] diff --git a/vendor/object/src/macho.rs b/vendor/object/src/macho.rs index 86a5bf626..3cd38e0ee 100644 --- a/vendor/object/src/macho.rs +++ b/vendor/object/src/macho.rs @@ -100,10 +100,10 @@ pub const CPU_SUBTYPE_UVAXIII: u32 = 12; * * The subtype definitions here are unusual for historical reasons. * NeXT used to consider 68030 code as generic 68000 code. For - * backwards compatability: + * backwards compatibility: * * CPU_SUBTYPE_MC68030 symbol has been preserved for source code - * compatability. + * compatibility. * * CPU_SUBTYPE_MC680x0_ALL has been defined to be the same * subtype as CPU_SUBTYPE_MC68030 for binary comatability. @@ -394,7 +394,7 @@ pub struct DyldSubCacheInfo { /* * This header file describes the structures of the file format for "fat" - * architecture specific file (wrapper design). At the begining of the file + * 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 @@ -576,7 +576,7 @@ pub const MH_FILESET: u32 = 0xc; 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 staticly link edited again +/// 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; @@ -590,7 +590,7 @@ pub const MH_LAZY_INIT: u32 = 0x40; 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 defintions of symbols in its sub-images so the two-level namespace hints can always be used. +/// 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; @@ -1142,7 +1142,7 @@ pub const SEG_LINKINFO: &str = "__LINKINFO"; /// the unix stack segment pub const SEG_UNIXSTACK: &str = "__UNIXSTACK"; -/// the segment for the self (dyld) modifing code stubs that has read, write and execute permissions +/// the segment for the self (dyld) modifying code stubs that has read, write and execute permissions pub const SEG_IMPORT: &str = "__IMPORT"; /* @@ -1181,7 +1181,7 @@ pub struct FvmlibCommand { } /* - * Dynamicly linked shared libraries are identified by two things. The + * 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 @@ -1265,7 +1265,7 @@ pub struct SubClientCommand { * 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 - * staticly linking when -twolevel_namespace is in effect a twolevel namespace + * 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 @@ -1289,7 +1289,7 @@ pub struct SubUmbrellaCommand { * 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 - * staticly linking when -twolevel_namespace is in effect a twolevel namespace + * 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 @@ -1630,7 +1630,7 @@ pub struct DysymtabCommand { /* * 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 staticly link edited address). + * from it statically link edited address). */ /// offset to local relocation entries pub locreloff: U32, @@ -1640,7 +1640,7 @@ pub struct DysymtabCommand { /* * An indirect symbol table entry is simply a 32bit index into the symbol table - * to the symbol that the pointer or stub is refering to. Unless it is for a + * 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. @@ -2025,7 +2025,7 @@ pub struct DyldInfoCommand { * * 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 initialzed to the same value can be + * like for runs of pointers initialized to the same value can be * encoded in a few bytes. */ /// file offset to binding info @@ -2486,7 +2486,7 @@ 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 dynamicly bound object (dynamic shared libraries, bundles). + * 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; @@ -2561,9 +2561,9 @@ 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 coalesed sections. + * is only supported for symbols in coalesced sections. */ -/// coalesed symbol is a weak definition +/// coalesced symbol is a weak definition pub const N_WEAK_DEF: u16 = 0x0080; /* @@ -2575,7 +2575,7 @@ 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 defintion of a Thumb function. + * a definition of a Thumb function. */ /// symbol is a Thumb function (ARM) pub const N_ARM_THUMB_DEF: u16 = 0x0008; @@ -2619,7 +2619,7 @@ pub const N_ALT_ENTRY: u16 = 0x0200; * * 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 - * refering to. + * referring to. */ /// global symbol: name,,NO_SECT,type,0 pub const N_GSYM: u8 = 0x20; @@ -2840,7 +2840,7 @@ pub const R_ABS: u8 = 0; /* * 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 expresion is outside the + * 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 @@ -2851,7 +2851,7 @@ pub const R_ABS: u8 = 0; * there is a non-zero offset added to a symbol. The "external" and "local" * relocation entries remain unchanged. * - * The implemention is quite messy given the compatibility with the existing + * 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 @@ -2882,7 +2882,7 @@ pub struct ScatteredRelocationInfo { pub r_length: u8, /// was relocated pc relative already pub r_pcrel: bool, - /// the value the item to be relocated is refering to (without any offset added) + /// the value the item to be relocated is referring to (without any offset added) pub r_value: u32, } @@ -2904,7 +2904,7 @@ impl ScatteredRelocationInfo { /* * Relocation types used in a generic implementation. Relocation entries for - * normal things use the generic relocation as discribed above and their r_type + * 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 @@ -2920,7 +2920,7 @@ impl ScatteredRelocationInfo { * 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 discribed above +/// 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; @@ -2935,13 +2935,13 @@ pub const GENERIC_RELOC_TLV: u8 = 5; /* * Relocation types used in the arm implementation. Relocation entries for - * things other than instructions use the same generic relocation as discribed + * things other than instructions use the same generic relocation as described * in 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 preformed on. + * indicates the 32 bit instruction that the relocation is to be performed on. */ -/// generic relocation as discribed above +/// 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; @@ -3027,10 +3027,10 @@ pub const ARM64_RELOC_AUTHENTICATED_POINTER: u8 = 11; /* * Relocation types used in the ppc implementation. Relocation entries for - * things other than instructions use the same generic relocation as discribed + * 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 preformed on. + * 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. * @@ -3040,7 +3040,7 @@ pub const ARM64_RELOC_AUTHENTICATED_POINTER: u8 = 11; * the value of the Y-bit if the sign of the displacement changes for non-branch * always conditions. */ -/// generic relocation as discribed above +/// 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; @@ -3053,7 +3053,7 @@ 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 extened first. This means if bit 15 of the low 16 bits is +/// 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 diff --git a/vendor/object/src/pe.rs b/vendor/object/src/pe.rs index 00105adac..bac101ea0 100644 --- a/vendor/object/src/pe.rs +++ b/vendor/object/src/pe.rs @@ -7,7 +7,9 @@ #![allow(missing_docs)] -use crate::endian::{LittleEndian as LE, U16Bytes, U32Bytes, I32, U16, U32, U64}; +use core::convert::TryInto; + +use crate::endian::{I32Bytes, LittleEndian as LE, U16Bytes, U32Bytes, I32, U16, U32, U64}; use crate::pod::Pod; /// MZ @@ -274,7 +276,7 @@ pub const IMAGE_SIZEOF_FILE_HEADER: usize = 20; 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 nunbers stripped from file. +/// 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; @@ -589,16 +591,33 @@ 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)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(C)] -pub struct Guid { - pub data1: U32, - pub data2: U16, - pub data3: U16, - pub data4: [u8; 8], +pub struct Guid(pub [u8; 16]); + +impl Guid { + #[inline] + pub fn data1(self) -> U32 { + U32::from_bytes(self.0[0..4].try_into().unwrap()) + } + + #[inline] + pub fn data2(self) -> U16 { + U16::from_bytes(self.0[4..6].try_into().unwrap()) + } + + #[inline] + pub fn data3(self) -> U16 { + 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 type ClsId = Guid; +pub use Guid as ClsId; /// Non-COFF Object file header #[derive(Debug, Clone, Copy)] @@ -641,6 +660,11 @@ pub struct AnonObjectHeaderV2 { pub meta_data_offset: U32, } +/// 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 { @@ -654,7 +678,7 @@ pub struct AnonObjectHeaderBigobj { /// Actual machine - IMAGE_FILE_MACHINE_xxx pub machine: U16, pub time_date_stamp: U32, - /// {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8} + /// Must be `ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID`. pub class_id: ClsId, /// Size of data that follows the header pub size_of_data: U32, @@ -756,7 +780,7 @@ pub const IMAGE_SCN_ALIGN_MASK: u32 = 0x00F0_0000; 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 cachable. +/// 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; @@ -805,7 +829,7 @@ 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, - pub section_number: U32Bytes, + pub section_number: I32Bytes, pub typ: U16Bytes, pub storage_class: u8, pub number_of_aux_symbols: u8, @@ -823,11 +847,11 @@ pub struct ImageSymbolExBytes(pub [u8; IMAGE_SIZEOF_SYMBOL_EX]); // defined. Otherwise, section numbers have the following meanings: /// Symbol is undefined or is common. -pub const IMAGE_SYM_UNDEFINED: u16 = 0; +pub const IMAGE_SYM_UNDEFINED: i32 = 0; /// Symbol is an absolute value. -pub const IMAGE_SYM_ABSOLUTE: u16 = 0xffff; +pub const IMAGE_SYM_ABSOLUTE: i32 = -1; /// Symbol is a special debug item. -pub const IMAGE_SYM_DEBUG: u16 = 0xfffe; +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; @@ -913,30 +937,6 @@ pub const N_TSHIFT: usize = 2; pub const IMAGE_SYM_DTYPE_SHIFT: usize = N_BTSHFT; -impl ImageSymbol { - #[inline] - pub fn base_type(&self) -> u16 { - self.typ.get(LE) & N_BTMASK - } - - #[inline] - pub fn derived_type(&self) -> u16 { - (self.typ.get(LE) & N_TMASK) >> N_BTSHFT - } -} - -impl ImageSymbolEx { - #[inline] - pub fn base_type(&self) -> u16 { - self.typ.get(LE) & N_BTMASK - } - - #[inline] - pub fn derived_type(&self) -> u16 { - (self.typ.get(LE) & N_TMASK) >> N_BTSHFT - } -} - // // Auxiliary entry format. // @@ -1095,7 +1095,7 @@ 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 referemce (used for >32k TLS) +/// 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; @@ -2010,7 +2010,7 @@ pub const IMAGE_DELAYLOAD_RVA_BASED: u32 = 0x8000_0000; // // 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 consistant with the syntax of the .RC file and the .RES file. +// This is consistent with the syntax of the .RC file and the .RES file. // #[derive(Debug, Clone, Copy)] @@ -2560,7 +2560,7 @@ pub struct ImageRuntimeFunctionEntry { } // -// Sofware enclave information +// Software enclave information // pub const IMAGE_ENCLAVE_LONG_ID_LENGTH: usize = 32; @@ -2754,7 +2754,7 @@ pub struct ImageFunctionEntry64 { // 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 accessable. This header is followed by +// 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 diff --git a/vendor/object/src/read/any.rs b/vendor/object/src/read/any.rs index c390b21b6..342ad75fd 100644 --- a/vendor/object/src/read/any.rs +++ b/vendor/object/src/read/any.rs @@ -32,6 +32,8 @@ macro_rules! with_inner { 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")] @@ -59,6 +61,8 @@ macro_rules! with_inner_mut { 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")] @@ -87,6 +91,8 @@ macro_rules! map_inner { 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")] @@ -115,6 +121,8 @@ macro_rules! map_inner_option { 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")] @@ -142,6 +150,8 @@ macro_rules! map_inner_option_mut { 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")] @@ -170,6 +180,8 @@ macro_rules! next_inner { 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")] @@ -204,6 +216,8 @@ pub struct File<'data, R: ReadRef<'data> = &'data [u8]> { enum FileInternal<'data, R: ReadRef<'data>> { #[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")] @@ -244,6 +258,8 @@ impl<'data, R: ReadRef<'data>> File<'data, R> { FileKind::Pe64 => FileInternal::Pe64(pe::PeFile64::parse(data)?), #[cfg(feature = "coff")] FileKind::Coff => FileInternal::Coff(coff::CoffFile::parse(data)?), + #[cfg(feature = "coff")] + FileKind::CoffBig => FileInternal::CoffBig(coff::CoffBigFile::parse(data)?), #[cfg(feature = "xcoff")] FileKind::Xcoff32 => FileInternal::Xcoff32(xcoff::XcoffFile32::parse(data)?), #[cfg(feature = "xcoff")] @@ -275,7 +291,7 @@ impl<'data, R: ReadRef<'data>> File<'data, R> { pub fn format(&self) -> BinaryFormat { match self.inner { #[cfg(feature = "coff")] - FileInternal::Coff(_) => BinaryFormat::Coff, + FileInternal::Coff(_) | FileInternal::CoffBig(_) => BinaryFormat::Coff, #[cfg(feature = "elf")] FileInternal::Elf32(_) | FileInternal::Elf64(_) => BinaryFormat::Elf, #[cfg(feature = "macho")] @@ -457,7 +473,7 @@ where } #[inline] - fn pdb_info(&self) -> Result> { + fn pdb_info(&self) -> Result>> { with_inner!(self.inner, FileInternal, |x| x.pdb_info()) } @@ -476,20 +492,16 @@ where /// An iterator over the segments of a `File`. #[derive(Debug)] -pub struct SegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +pub struct SegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { inner: SegmentIteratorInternal<'data, 'file, R>, } #[derive(Debug)] -enum SegmentIteratorInternal<'data, 'file, R: ReadRef<'data>> -where - 'data: 'file, -{ +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")] @@ -520,20 +532,16 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for SegmentIterator<'data, 'file, } /// A segment of a `File`. -pub struct Segment<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +pub struct Segment<'data, 'file, R: ReadRef<'data> = &'data [u8]> { inner: SegmentInternal<'data, 'file, R>, } #[derive(Debug)] -enum SegmentInternal<'data, 'file, R: ReadRef<'data>> -where - 'data: 'file, -{ +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")] @@ -615,21 +623,17 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'f /// An iterator of the sections of a `File`. #[derive(Debug)] -pub struct SectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +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>> -where - 'data: 'file, -{ +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")] @@ -660,19 +664,15 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionIterator<'data, 'file, } /// A Section of a File -pub struct Section<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +pub struct Section<'data, 'file, R: ReadRef<'data> = &'data [u8]> { inner: SectionInternal<'data, 'file, R>, } -enum SectionInternal<'data, 'file, R: ReadRef<'data>> -where - 'data: 'file, -{ +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")] @@ -795,20 +795,16 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'f /// An iterator of the COMDAT section groups of a `File`. #[derive(Debug)] -pub struct ComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +pub struct ComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { inner: ComdatIteratorInternal<'data, 'file, R>, } #[derive(Debug)] -enum ComdatIteratorInternal<'data, 'file, R: ReadRef<'data>> -where - 'data: 'file, -{ +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")] @@ -839,19 +835,15 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatIterator<'data, 'file, } /// A COMDAT section group of a `File`. -pub struct Comdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +pub struct Comdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> { inner: ComdatInternal<'data, 'file, R>, } -enum ComdatInternal<'data, 'file, R: ReadRef<'data>> -where - 'data: 'file, -{ +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")] @@ -917,20 +909,16 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for Comdat<'data, 'fil /// An iterator over COMDAT section entries. #[derive(Debug)] -pub struct ComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +pub struct ComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { inner: ComdatSectionIteratorInternal<'data, 'file, R>, } #[derive(Debug)] -enum ComdatSectionIteratorInternal<'data, 'file, R: ReadRef<'data>> -where - 'data: 'file, -{ +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")] @@ -963,7 +951,6 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatSectionIterator<'data, #[derive(Debug)] pub struct SymbolTable<'data, 'file, R = &'data [u8]> where - 'data: 'file, R: ReadRef<'data>, { inner: SymbolTableInternal<'data, 'file, R>, @@ -972,11 +959,12 @@ where #[derive(Debug)] enum SymbolTableInternal<'data, 'file, R> where - 'data: 'file, R: ReadRef<'data>, { #[cfg(feature = "coff")] Coff((coff::CoffSymbolTable<'data, 'file, R>, PhantomData)), + #[cfg(feature = "coff")] + CoffBig((coff::CoffBigSymbolTable<'data, 'file, R>, PhantomData)), #[cfg(feature = "elf")] Elf32( ( @@ -1047,7 +1035,6 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> for SymbolTable<' #[derive(Debug)] pub struct SymbolIterator<'data, 'file, R = &'data [u8]> where - 'data: 'file, R: ReadRef<'data>, { inner: SymbolIteratorInternal<'data, 'file, R>, @@ -1056,11 +1043,12 @@ where #[derive(Debug)] enum SymbolIteratorInternal<'data, 'file, R> where - 'data: 'file, R: ReadRef<'data>, { #[cfg(feature = "coff")] Coff((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData)), + #[cfg(feature = "coff")] + CoffBig((coff::CoffBigSymbolIterator<'data, 'file, R>, PhantomData)), #[cfg(feature = "elf")] Elf32( ( @@ -1125,7 +1113,6 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file, /// A symbol table entry. pub struct Symbol<'data, 'file, R = &'data [u8]> where - 'data: 'file, R: ReadRef<'data>, { inner: SymbolInternal<'data, 'file, R>, @@ -1133,11 +1120,12 @@ where enum SymbolInternal<'data, 'file, R> where - 'data: 'file, R: ReadRef<'data>, { #[cfg(feature = "coff")] Coff((coff::CoffSymbol<'data, 'file, R>, PhantomData)), + #[cfg(feature = "coff")] + CoffBig((coff::CoffBigSymbol<'data, 'file, R>, PhantomData)), #[cfg(feature = "elf")] Elf32( ( @@ -1252,7 +1240,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'fil with_inner!(self.inner, SymbolInternal, |x| x.0.is_local()) } - fn flags(&self) -> SymbolFlags { + fn flags(&self) -> SymbolFlags { with_inner!(self.inner, SymbolInternal, |x| x.0.flags()) } } @@ -1261,7 +1249,6 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'fil #[derive(Debug)] pub struct DynamicRelocationIterator<'data, 'file, R = &'data [u8]> where - 'data: 'file, R: ReadRef<'data>, { inner: DynamicRelocationIteratorInternal<'data, 'file, R>, @@ -1270,7 +1257,6 @@ where #[derive(Debug)] enum DynamicRelocationIteratorInternal<'data, 'file, R> where - 'data: 'file, R: ReadRef<'data>, { #[cfg(feature = "elf")] @@ -1298,20 +1284,16 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for DynamicRelocationIterator<'da /// An iterator over section relocation entries. #[derive(Debug)] -pub struct SectionRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> -where - 'data: 'file, -{ +pub struct SectionRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { inner: SectionRelocationIteratorInternal<'data, 'file, R>, } #[derive(Debug)] -enum SectionRelocationIteratorInternal<'data, 'file, R: ReadRef<'data>> -where - 'data: 'file, -{ +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")] diff --git a/vendor/object/src/read/coff/comdat.rs b/vendor/object/src/read/coff/comdat.rs index 3be69ecc2..22e061a23 100644 --- a/vendor/object/src/read/coff/comdat.rs +++ b/vendor/object/src/read/coff/comdat.rs @@ -6,23 +6,34 @@ use crate::read::{ self, ComdatKind, ObjectComdat, ReadError, ReadRef, Result, SectionIndex, SymbolIndex, }; -use super::CoffFile; +use super::{CoffFile, CoffHeader, ImageSymbol}; + +/// An iterator over the COMDAT section groups of a `CoffBigFile`. +pub type CoffBigComdatIterator<'data, 'file, R = &'data [u8]> = + CoffComdatIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; /// An iterator over the COMDAT section groups of a `CoffFile`. #[derive(Debug)] -pub struct CoffComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - pub(super) file: &'file CoffFile<'data, R>, +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>> Iterator for CoffComdatIterator<'data, 'file, R> { - type Item = CoffComdat<'data, 'file, R>; +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 { loop { let index = self.index; let symbol = self.file.common.symbols.symbol(index).ok()?; - self.index += 1 + symbol.number_of_aux_symbols as usize; + self.index += 1 + symbol.number_of_aux_symbols() as usize; if let Some(comdat) = CoffComdat::parse(self.file, symbol, index) { return Some(comdat); } @@ -30,21 +41,30 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffComdatIterator<'data, 'fi } } +/// A COMDAT section group of a `CoffBigFile`. +pub type CoffBigComdat<'data, 'file, R = &'data [u8]> = + CoffComdat<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// A COMDAT section group of a `CoffFile`. #[derive(Debug)] -pub struct CoffComdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - file: &'file CoffFile<'data, R>, +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 pe::ImageSymbol, + symbol: &'data Coff::ImageSymbol, selection: u8, } -impl<'data, 'file, R: ReadRef<'data>> CoffComdat<'data, 'file, R> { +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffComdat<'data, 'file, R, Coff> { fn parse( - file: &'file CoffFile<'data, R>, - section_symbol: &'data pe::ImageSymbol, + file: &'file CoffFile<'data, R, Coff>, + section_symbol: &'data Coff::ImageSymbol, index: usize, - ) -> Option> { + ) -> Option> { // Must be a section symbol. if !section_symbol.has_aux_section() { return None; @@ -60,11 +80,11 @@ impl<'data, 'file, R: ReadRef<'data>> CoffComdat<'data, 'file, R> { // Find the COMDAT symbol. let mut symbol_index = index; let mut symbol = section_symbol; - let section_number = section_symbol.section_number.get(LE); + let section_number = section_symbol.section_number(); loop { - symbol_index += 1 + symbol.number_of_aux_symbols as usize; + symbol_index += 1 + symbol.number_of_aux_symbols() as usize; symbol = file.common.symbols.symbol(symbol_index).ok()?; - if section_number == symbol.section_number.get(LE) { + if section_number == symbol.section_number() { break; } } @@ -78,10 +98,15 @@ impl<'data, 'file, R: ReadRef<'data>> CoffComdat<'data, 'file, R> { } } -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for CoffComdat<'data, 'file, R> {} +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed + for CoffComdat<'data, 'file, R, Coff> +{ +} -impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for CoffComdat<'data, 'file, R> { - type SectionIterator = CoffComdatSectionIterator<'data, 'file, R>; +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 { @@ -119,21 +144,32 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for CoffComdat<'data, fn sections(&self) -> Self::SectionIterator { CoffComdatSectionIterator { file: self.file, - section_number: self.symbol.section_number.get(LE), + section_number: self.symbol.section_number(), index: 0, } } } +/// An iterator over the sections in a COMDAT section group of a `CoffBigFile`. +pub type CoffBigComdatSectionIterator<'data, 'file, R = &'data [u8]> = + CoffComdatSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// An iterator over the sections in a COMDAT section group of a `CoffFile`. #[derive(Debug)] -pub struct CoffComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - file: &'file CoffFile<'data, R>, - section_number: u16, +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>> Iterator for CoffComdatSectionIterator<'data, 'file, R> { +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator + for CoffComdatSectionIterator<'data, 'file, R, Coff> +{ type Item = SectionIndex; fn next(&mut self) -> Option { @@ -142,19 +178,23 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffComdatSectionIterator<'da loop { let index = self.index; let symbol = self.file.common.symbols.symbol(index).ok()?; - self.index += 1 + symbol.number_of_aux_symbols as usize; + 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.get(LE); + let section_number = symbol.section_number(); let aux = self.file.common.symbols.aux_section(index).ok()?; if aux.selection == pe::IMAGE_COMDAT_SELECT_ASSOCIATIVE { - // TODO: use high_number for bigobj - if aux.number.get(LE) == self.section_number { + 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 { diff --git a/vendor/object/src/read/coff/file.rs b/vendor/object/src/read/coff/file.rs index c6cc9f846..4219f8f02 100644 --- a/vendor/object/src/read/coff/file.rs +++ b/vendor/object/src/read/coff/file.rs @@ -1,39 +1,43 @@ use alloc::vec::Vec; +use core::fmt::Debug; use crate::read::{ self, Architecture, Export, FileFlags, Import, NoDynamicRelocationIterator, Object, ObjectKind, ObjectSection, ReadError, ReadRef, Result, SectionIndex, SymbolIndex, }; -use crate::{pe, LittleEndian as LE}; +use crate::{pe, LittleEndian as LE, Pod}; use super::{ CoffComdat, CoffComdatIterator, CoffSection, CoffSectionIterator, CoffSegment, - CoffSegmentIterator, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, SectionTable, - SymbolTable, + CoffSegmentIterator, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, ImageSymbol, + SectionTable, SymbolTable, }; /// The common parts of `PeFile` and `CoffFile`. #[derive(Debug)] -pub(crate) struct CoffCommon<'data, R: ReadRef<'data>> { +pub(crate) struct CoffCommon<'data, R: ReadRef<'data>, Coff: CoffHeader = pe::ImageFileHeader> { pub(crate) sections: SectionTable<'data>, - // TODO: ImageSymbolExBytes - pub(crate) symbols: SymbolTable<'data, R>, + pub(crate) symbols: SymbolTable<'data, R, Coff>, pub(crate) image_base: u64, } +/// A COFF bigobj object file with 32-bit section numbers. +pub type CoffBigFile<'data, R = &'data [u8]> = CoffFile<'data, R, pe::AnonObjectHeaderBigobj>; + /// A COFF object file. #[derive(Debug)] -pub struct CoffFile<'data, R: ReadRef<'data> = &'data [u8]> { - pub(super) header: &'data pe::ImageFileHeader, - pub(super) common: CoffCommon<'data, R>, +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>> CoffFile<'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 { let mut offset = 0; - let header = pe::ImageFileHeader::parse(data, &mut offset)?; + let header = Coff::parse(data, &mut offset)?; let sections = header.sections(data, offset)?; let symbols = header.symbols(data)?; @@ -49,26 +53,30 @@ impl<'data, R: ReadRef<'data>> CoffFile<'data, R> { } } -impl<'data, R: ReadRef<'data>> read::private::Sealed for CoffFile<'data, R> {} +impl<'data, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed + for CoffFile<'data, R, Coff> +{ +} -impl<'data, 'file, R> Object<'data, 'file> for CoffFile<'data, R> +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>; - type SegmentIterator = CoffSegmentIterator<'data, 'file, R>; - type Section = CoffSection<'data, 'file, R>; - type SectionIterator = CoffSectionIterator<'data, 'file, R>; - type Comdat = CoffComdat<'data, 'file, R>; - type ComdatIterator = CoffComdatIterator<'data, 'file, R>; - type Symbol = CoffSymbol<'data, 'file, R>; - type SymbolIterator = CoffSymbolIterator<'data, 'file, R>; - type SymbolTable = CoffSymbolTable<'data, 'file, R>; + 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.get(LE) { + match self.header.machine() { pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm, pe::IMAGE_FILE_MACHINE_ARM64 => Architecture::Aarch64, pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386, @@ -92,7 +100,7 @@ where ObjectKind::Relocatable } - fn segments(&'file self) -> CoffSegmentIterator<'data, 'file, R> { + fn segments(&'file self) -> CoffSegmentIterator<'data, 'file, R, Coff> { CoffSegmentIterator { file: self, iter: self.common.sections.iter(), @@ -102,12 +110,15 @@ where fn section_by_name_bytes( &'file self, section_name: &[u8], - ) -> Option> { + ) -> Option> { self.sections() .find(|section| section.name_bytes() == Ok(section_name)) } - fn section_by_index(&'file self, index: SectionIndex) -> Result> { + fn section_by_index( + &'file self, + index: SectionIndex, + ) -> Result> { let section = self.common.sections.section(index.0)?; Ok(CoffSection { file: self, @@ -116,21 +127,24 @@ where }) } - fn sections(&'file self) -> CoffSectionIterator<'data, 'file, R> { + 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> { + fn comdats(&'file self) -> CoffComdatIterator<'data, 'file, R, Coff> { CoffComdatIterator { file: self, index: 0, } } - fn symbol_by_index(&'file self, index: SymbolIndex) -> Result> { + fn symbol_by_index( + &'file self, + index: SymbolIndex, + ) -> Result> { let symbol = self.common.symbols.symbol(index.0)?; Ok(CoffSymbol { file: &self.common, @@ -139,7 +153,7 @@ where }) } - fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> { + fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R, Coff> { CoffSymbolIterator { file: &self.common, index: 0, @@ -147,11 +161,11 @@ where } #[inline] - fn symbol_table(&'file self) -> Option> { + fn symbol_table(&'file self) -> Option> { Some(CoffSymbolTable { file: &self.common }) } - fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> { + fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R, Coff> { CoffSymbolIterator { file: &self.common, // Hack: don't return any. @@ -160,7 +174,7 @@ where } #[inline] - fn dynamic_symbol_table(&'file self) -> Option> { + fn dynamic_symbol_table(&'file self) -> Option> { None } @@ -196,37 +210,51 @@ where fn flags(&self) -> FileFlags { FileFlags::Coff { - characteristics: self.header.characteristics.get(LE), + characteristics: self.header.characteristics(), } } } -impl pe::ImageFileHeader { +/// Read the `class_id` field from an anon object header. +/// +/// This can be used to determine the format of the header. +pub fn anon_object_class_id<'data, R: ReadRef<'data>>(data: R) -> Result { + let header = data + .read_at::(0) + .read_error("Invalid anon object header size or alignment")?; + Ok(header.class_id) +} + +/// A trait for generic access to `ImageFileHeader` and `AnonObjectHeaderBigobj`. +#[allow(missing_docs)] +pub trait CoffHeader: Debug + Pod { + type ImageSymbol: ImageSymbol; + type ImageSymbolBytes: Debug + Pod; + + /// Return true if this type is `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. - pub fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self> { - let header = data - .read::(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) - } + 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] - pub fn sections<'data, R: ReadRef<'data>>( + fn sections<'data, R: ReadRef<'data>>( &self, data: R, offset: u64, @@ -238,10 +266,99 @@ impl pe::ImageFileHeader { /// /// `data` must be the entire file data. #[inline] - pub fn symbols<'data, R: ReadRef<'data>>( + fn symbols<'data, R: ReadRef<'data>>( &self, data: R, - ) -> read::Result> { + ) -> read::Result> { 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::(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::(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/relocation.rs b/vendor/object/src/read/coff/relocation.rs index 9a1fcb618..44d2c68d0 100644 --- a/vendor/object/src/read/coff/relocation.rs +++ b/vendor/object/src/read/coff/relocation.rs @@ -7,20 +7,31 @@ use crate::read::{ ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, SymbolIndex, }; -use super::CoffFile; +use super::{CoffFile, CoffHeader}; + +/// An iterator over the relocations in a `CoffBigSection`. +pub type CoffBigRelocationIterator<'data, 'file, R = &'data [u8]> = + CoffRelocationIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; /// An iterator over the relocations in a `CoffSection`. -pub struct CoffRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - pub(super) file: &'file CoffFile<'data, R>, +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>> Iterator for CoffRelocationIterator<'data, 'file, R> { +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.iter.next().map(|relocation| { - let (kind, size, addend) = match self.file.header.machine.get(LE) { + 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), @@ -84,7 +95,9 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffRelocationIterator<'data, } } -impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for CoffRelocationIterator<'data, 'file, R> { +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 index 731e37ca8..75804034b 100644 --- a/vendor/object/src/read/coff/section.rs +++ b/vendor/object/src/read/coff/section.rs @@ -9,7 +9,7 @@ use crate::read::{ ReadRef, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags, }; -use super::{CoffFile, CoffRelocationIterator}; +use super::{CoffFile, CoffHeader, CoffRelocationIterator}; /// The table of section headers in a COFF or PE file. #[derive(Debug, Default, Clone, Copy)] @@ -22,13 +22,13 @@ impl<'data> SectionTable<'data> { /// /// `data` must be the entire file data. /// `offset` must be after the optional file header. - pub fn parse>( - header: &pe::ImageFileHeader, + pub fn parse>( + header: &Coff, data: R, offset: u64, ) -> Result { let sections = data - .read_slice_at(offset, header.number_of_sections.get(LE).into()) + .read_slice_at(offset, header.number_of_sections() as usize) .read_error("Invalid COFF/PE section headers")?; Ok(SectionTable { sections }) } @@ -104,15 +104,26 @@ impl<'data> SectionTable<'data> { } } +/// An iterator over the loadable sections of a `CoffBigFile`. +pub type CoffBigSegmentIterator<'data, 'file, R = &'data [u8]> = + CoffSegmentIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// An iterator over the loadable sections of a `CoffFile`. #[derive(Debug)] -pub struct CoffSegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - pub(super) file: &'file CoffFile<'data, R>, +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>> Iterator for CoffSegmentIterator<'data, 'file, R> { - type Item = CoffSegment<'data, 'file, R>; +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.iter.next().map(|section| CoffSegment { @@ -122,14 +133,23 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffSegmentIterator<'data, 'f } } +/// A loadable section of a `CoffBigFile`. +pub type CoffBigSegment<'data, 'file, R = &'data [u8]> = + CoffSegment<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// A loadable section of a `CoffFile`. #[derive(Debug)] -pub struct CoffSegment<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - pub(super) file: &'file CoffFile<'data, R>, +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>> CoffSegment<'data, 'file, R> { +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) @@ -137,9 +157,14 @@ impl<'data, 'file, R: ReadRef<'data>> CoffSegment<'data, 'file, R> { } } -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for CoffSegment<'data, 'file, R> {} +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed + for CoffSegment<'data, 'file, R, Coff> +{ +} -impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for CoffSegment<'data, 'file, R> { +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)) @@ -197,15 +222,26 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for CoffSegment<'data } } +/// An iterator over the sections of a `CoffBigFile`. +pub type CoffBigSectionIterator<'data, 'file, R = &'data [u8]> = + CoffSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// An iterator over the sections of a `CoffFile`. #[derive(Debug)] -pub struct CoffSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - pub(super) file: &'file CoffFile<'data, R>, +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>, } -impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffSectionIterator<'data, 'file, R> { - type Item = CoffSection<'data, 'file, R>; +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.iter.next().map(|(index, section)| CoffSection { @@ -216,15 +252,24 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffSectionIterator<'data, 'f } } +/// A section of a `CoffBigFile`. +pub type CoffBigSection<'data, 'file, R = &'data [u8]> = + CoffSection<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// A section of a `CoffFile`. #[derive(Debug)] -pub struct CoffSection<'data, 'file, R: ReadRef<'data> = &'data [u8]> { - pub(super) file: &'file CoffFile<'data, R>, +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>> CoffSection<'data, 'file, R> { +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) @@ -232,10 +277,15 @@ impl<'data, 'file, R: ReadRef<'data>> CoffSection<'data, 'file, R> { } } -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for CoffSection<'data, 'file, R> {} +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed + for CoffSection<'data, 'file, R, Coff> +{ +} -impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for CoffSection<'data, 'file, R> { - type RelocationIterator = CoffRelocationIterator<'data, 'file, R>; +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 { @@ -315,7 +365,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for CoffSection<'data self.section.kind() } - fn relocations(&self) -> CoffRelocationIterator<'data, 'file, R> { + fn relocations(&self) -> CoffRelocationIterator<'data, 'file, R, Coff> { let relocations = self.section.coff_relocations(self.file.data).unwrap_or(&[]); CoffRelocationIterator { file: self.file, diff --git a/vendor/object/src/read/coff/symbol.rs b/vendor/object/src/read/coff/symbol.rs index 217e38fca..e95468d7e 100644 --- a/vendor/object/src/read/coff/symbol.rs +++ b/vendor/object/src/read/coff/symbol.rs @@ -1,12 +1,13 @@ use alloc::fmt; use alloc::vec::Vec; use core::convert::TryInto; +use core::fmt::Debug; use core::str; -use super::{CoffCommon, SectionTable}; +use super::{CoffCommon, CoffHeader, SectionTable}; use crate::endian::{LittleEndian as LE, U32Bytes}; use crate::pe; -use crate::pod::{bytes_of_slice, Pod}; +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, @@ -17,15 +18,16 @@ use crate::read::{ /// /// Also includes the string table used for the symbol names. #[derive(Debug)] -pub struct SymbolTable<'data, R = &'data [u8]> +pub struct SymbolTable<'data, R = &'data [u8], Coff = pe::ImageFileHeader> where R: ReadRef<'data>, + Coff: CoffHeader, { - symbols: &'data [pe::ImageSymbolBytes], + symbols: &'data [Coff::ImageSymbolBytes], strings: StringTable<'data, R>, } -impl<'data, R: ReadRef<'data>> Default for SymbolTable<'data, R> { +impl<'data, R: ReadRef<'data>, Coff: CoffHeader> Default for SymbolTable<'data, R, Coff> { fn default() -> Self { Self { symbols: &[], @@ -34,14 +36,14 @@ impl<'data, R: ReadRef<'data>> Default for SymbolTable<'data, R> { } } -impl<'data, R: ReadRef<'data>> SymbolTable<'data, R> { +impl<'data, R: ReadRef<'data>, Coff: CoffHeader> SymbolTable<'data, R, Coff> { /// Read the symbol table. - pub fn parse(header: &pe::ImageFileHeader, data: R) -> Result { + pub fn parse(header: &Coff, data: R) -> Result { // The symbol table may not be present. - let mut offset = header.pointer_to_symbol_table.get(LE).into(); + 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.get(LE) as usize) + .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. @@ -84,7 +86,7 @@ impl<'data, R: ReadRef<'data>> SymbolTable<'data, R> { /// Iterate over the symbols. #[inline] - pub fn iter<'table>(&'table self) -> SymbolIterator<'data, 'table, R> { + pub fn iter<'table>(&'table self) -> SymbolIterator<'data, 'table, R, Coff> { SymbolIterator { symbols: self, index: 0, @@ -93,8 +95,8 @@ impl<'data, R: ReadRef<'data>> SymbolTable<'data, R> { /// Return the symbol table entry at the given index. #[inline] - pub fn symbol(&self, index: usize) -> Result<&'data pe::ImageSymbol> { - self.get::(index, 0) + pub fn symbol(&self, index: usize) -> Result<&'data Coff::ImageSymbol> { + self.get::(index, 0) } /// Return the auxiliary function symbol for the symbol table entry at the given index. @@ -136,13 +138,13 @@ impl<'data, R: ReadRef<'data>> SymbolTable<'data, R> { .checked_add(offset) .and_then(|x| self.symbols.get(x)) .read_error("Invalid COFF symbol index")?; - Bytes(&bytes.0[..]) + 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 Option>( + pub fn map Option>( &self, f: F, ) -> SymbolMap { @@ -163,109 +165,52 @@ impl<'data, R: ReadRef<'data>> SymbolTable<'data, R> { /// /// Yields the index and symbol structure for each symbol. #[derive(Debug)] -pub struct SymbolIterator<'data, 'table, R = &'data [u8]> +pub struct SymbolIterator<'data, 'table, R = &'data [u8], Coff = pe::ImageFileHeader> where R: ReadRef<'data>, + Coff: CoffHeader, { - symbols: &'table SymbolTable<'data, R>, + symbols: &'table SymbolTable<'data, R, Coff>, index: usize, } -impl<'data, 'table, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'table, R> { - type Item = (usize, &'data pe::ImageSymbol); +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 { let index = self.index; let symbol = self.symbols.symbol(index).ok()?; - self.index += 1 + symbol.number_of_aux_symbols as usize; + self.index += 1 + symbol.number_of_aux_symbols() as usize; Some((index, symbol)) } } -impl pe::ImageSymbol { - /// Parse a COFF symbol name. - /// - /// `strings` must be the string table used for symbol names. - pub fn name<'data, R: ReadRef<'data>>( - &'data self, - strings: StringTable<'data, R>, - ) -> Result<&'data [u8]> { - if self.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(self.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', &self.name) { - Some(end) => &self.name[..end], - None => &self.name[..], - }) - } - } - - /// Return the symbol address. - /// - /// This takes into account the image base and the section address. - pub fn address(&self, image_base: u64, sections: &SectionTable) -> Result { - let section_number = self.section_number.get(LE) as usize; - let section = sections.section(section_number)?; - let virtual_address = u64::from(section.virtual_address.get(LE)); - let value = u64::from(self.value.get(LE)); - Ok(image_base + virtual_address + value) - } - - /// Return true if the symbol is a definition of a function or data object. - pub fn is_definition(&self) -> bool { - let section_number = self.section_number.get(LE); - if section_number == pe::IMAGE_SYM_UNDEFINED { - return false; - } - match self.storage_class { - pe::IMAGE_SYM_CLASS_STATIC => { - // Exclude section symbols. - !(self.value.get(LE) == 0 && self.number_of_aux_symbols > 0) - } - pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => true, - _ => false, - } - } - - /// Return true if the symbol has an auxiliary file name. - pub 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. - pub 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. - pub fn has_aux_section(&self) -> bool { - self.number_of_aux_symbols > 0 - && self.storage_class == pe::IMAGE_SYM_CLASS_STATIC - && self.value.get(LE) == 0 - } -} +/// A symbol table of a `CoffBigFile`. +pub type CoffBigSymbolTable<'data, 'file, R = &'data [u8]> = + CoffSymbolTable<'data, 'file, R, pe::AnonObjectHeaderBigobj>; /// A symbol table of a `CoffFile`. #[derive(Debug, Clone, Copy)] -pub struct CoffSymbolTable<'data, 'file, R = &'data [u8]> +pub struct CoffSymbolTable<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> where R: ReadRef<'data>, + Coff: CoffHeader, { - pub(crate) file: &'file CoffCommon<'data, R>, + pub(crate) file: &'file CoffCommon<'data, R, Coff>, } -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for CoffSymbolTable<'data, 'file, R> {} +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed + for CoffSymbolTable<'data, 'file, R, Coff> +{ +} -impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> - for CoffSymbolTable<'data, 'file, R> +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbolTable<'data> + for CoffSymbolTable<'data, 'file, R, Coff> { - type Symbol = CoffSymbol<'data, 'file, R>; - type SymbolIterator = CoffSymbolIterator<'data, 'file, R>; + type Symbol = CoffSymbol<'data, 'file, R, Coff>; + type SymbolIterator = CoffSymbolIterator<'data, 'file, R, Coff>; fn symbols(&self) -> Self::SymbolIterator { CoffSymbolIterator { @@ -284,28 +229,37 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> } } +/// An iterator over the symbols of a `CoffBigFile`. +pub type CoffBigSymbolIterator<'data, 'file, R = &'data [u8]> = + CoffSymbolIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// An iterator over the symbols of a `CoffFile`. -pub struct CoffSymbolIterator<'data, 'file, R = &'data [u8]> +pub struct CoffSymbolIterator<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> where R: ReadRef<'data>, + Coff: CoffHeader, { - pub(crate) file: &'file CoffCommon<'data, R>, + pub(crate) file: &'file CoffCommon<'data, R, Coff>, pub(crate) index: usize, } -impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for CoffSymbolIterator<'data, 'file, R> { +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>> Iterator for CoffSymbolIterator<'data, 'file, R> { - type Item = CoffSymbol<'data, 'file, R>; +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 { let index = self.index; let symbol = self.file.symbols.symbol(index).ok()?; - self.index += 1 + symbol.number_of_aux_symbols as usize; + self.index += 1 + symbol.number_of_aux_symbols() as usize; Some(CoffSymbol { file: self.file, index: SymbolIndex(index), @@ -314,28 +268,38 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffSymbolIterator<'data, 'fi } } +/// A symbol of a `CoffBigFile`. +pub type CoffBigSymbol<'data, 'file, R = &'data [u8]> = + CoffSymbol<'data, 'file, R, pe::AnonObjectHeaderBigobj>; + /// A symbol of a `CoffFile`. #[derive(Debug, Clone, Copy)] -pub struct CoffSymbol<'data, 'file, R = &'data [u8]> +pub struct CoffSymbol<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> where R: ReadRef<'data>, + Coff: CoffHeader, { - pub(crate) file: &'file CoffCommon<'data, R>, + pub(crate) file: &'file CoffCommon<'data, R, Coff>, pub(crate) index: SymbolIndex, - pub(crate) symbol: &'data pe::ImageSymbol, + pub(crate) symbol: &'data Coff::ImageSymbol, } -impl<'data, 'file, R: ReadRef<'data>> CoffSymbol<'data, 'file, R> { +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 pe::ImageSymbol { + pub fn raw_symbol(&self) -> &'data Coff::ImageSymbol { self.symbol } } -impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for CoffSymbol<'data, 'file, R> {} +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed + for CoffSymbol<'data, 'file, R, Coff> +{ +} -impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, 'file, R> { +impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbol<'data> + for CoffSymbol<'data, 'file, R, Coff> +{ #[inline] fn index(&self) -> SymbolIndex { self.index @@ -345,7 +309,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, if self.symbol.has_aux_file_name() { self.file .symbols - .aux_file_name(self.index.0, self.symbol.number_of_aux_symbols) + .aux_file_name(self.index.0, self.symbol.number_of_aux_symbols()) } else { self.symbol.name(self.file.symbols.strings()) } @@ -360,12 +324,12 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, fn address(&self) -> u64 { // Only return an address for storage classes that we know use an address. - match self.symbol.storage_class { + 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.get(LE) == pe::IMAGE_SYM_UNDEFINED { + if self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED { // Undefined or common data, neither of which have an address. return 0; } @@ -378,7 +342,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, } fn size(&self) -> u64 { - match self.symbol.storage_class { + 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() { @@ -392,10 +356,10 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, } } pe::IMAGE_SYM_CLASS_EXTERNAL => { - if self.symbol.section_number.get(LE) == pe::IMAGE_SYM_UNDEFINED { + 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.get(LE)) + 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) { @@ -418,9 +382,9 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, } else { SymbolKind::Data }; - match self.symbol.storage_class { + match self.symbol.storage_class() { pe::IMAGE_SYM_CLASS_STATIC => { - if self.symbol.value.get(LE) == 0 && self.symbol.number_of_aux_symbols > 0 { + if self.symbol.value() == 0 && self.symbol.number_of_aux_symbols() > 0 { SymbolKind::Section } else { derived_kind @@ -435,10 +399,10 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, } fn section(&self) -> SymbolSection { - match self.symbol.section_number.get(LE) { + match self.symbol.section_number() { pe::IMAGE_SYM_UNDEFINED => { - if self.symbol.storage_class == pe::IMAGE_SYM_CLASS_EXTERNAL - && self.symbol.value.get(LE) == 0 + if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL + && self.symbol.value() == 0 { SymbolSection::Undefined } else { @@ -447,22 +411,22 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, } pe::IMAGE_SYM_ABSOLUTE => SymbolSection::Absolute, pe::IMAGE_SYM_DEBUG => { - if self.symbol.storage_class == pe::IMAGE_SYM_CLASS_FILE { + if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_FILE { SymbolSection::None } else { SymbolSection::Unknown } } - index if index > 0 => SymbolSection::Section(SectionIndex(index.into())), + 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.get(LE) == pe::IMAGE_SYM_UNDEFINED - && self.symbol.value.get(LE) == 0 + self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL + && self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED + && self.symbol.value() == 0 } #[inline] @@ -472,19 +436,19 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, #[inline] fn is_common(&self) -> bool { - self.symbol.storage_class == pe::IMAGE_SYM_CLASS_EXTERNAL - && self.symbol.section_number.get(LE) == pe::IMAGE_SYM_UNDEFINED - && self.symbol.value.get(LE) != 0 + 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 + self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL } #[inline] fn scope(&self) -> SymbolScope { - match self.symbol.storage_class { + match self.symbol.storage_class() { pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => { // TODO: determine if symbol is exported SymbolScope::Linkage @@ -495,7 +459,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, #[inline] fn is_global(&self) -> bool { - match self.symbol.storage_class { + match self.symbol.storage_class() { pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => true, _ => false, } @@ -506,17 +470,20 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, !self.is_global() } - fn flags(&self) -> SymbolFlags { + fn flags(&self) -> SymbolFlags { if self.symbol.has_aux_section() { if let Ok(aux) = self.file.symbols.aux_section(self.index.0) { - // TODO: use high_number for bigobj - let number = aux.number.get(LE) as usize; + 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)) + Some(SectionIndex(number as usize)) }, }; } @@ -524,3 +491,136 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for CoffSymbol<'data, SymbolFlags::None } } + +/// A trait for generic access to `ImageSymbol` and `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 { + 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 { + let section_number = self.section_number(); + if section_number == pe::IMAGE_SYM_UNDEFINED { + return false; + } + match self.storage_class() { + pe::IMAGE_SYM_CLASS_STATIC => { + // Exclude section symbols. + !(self.value() == 0 && self.number_of_aux_symbols() > 0) + } + 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.value() == 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 new file mode 100644 index 000000000..6ec535d72 --- /dev/null +++ b/vendor/object/src/read/elf/attributes.rs @@ -0,0 +1,303 @@ +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 subsections. +#[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 { + let mut data = Bytes(data); + + // Skip the version field that is one byte long. + let version = *data + .read::() + .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> { + // 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 over the subsections in an ELF attributes section. +#[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>> { + 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>> { + // First read the subsection length. + let mut data = self.data; + let length = data + .read::>() + .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 ELF attributes section. +/// +/// A subsection is identified by a vendor name. It contains a series of sub-subsections. +#[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 over the sub-subsections in an ELF attributes section. +#[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>> { + 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>> { + // The format of a sub-section looks like this: + // + // * + // | * 0 * + // | * 0 * + let mut data = self.data; + let tag = *data + .read::() + .read_error("ELF attributes subsection is too short")?; + let length = data + .read::>() + .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 ELF attributes section. +/// +/// 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 a sub-subsection in an ELF attributes section. +#[derive(Debug, Clone)] +pub struct AttributeIndexIterator<'data> { + data: Bytes<'data>, +} + +impl<'data> AttributeIndexIterator<'data> { + /// Parse the next index. + pub fn next(&mut self) -> Result> { + 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 a sub-subsection in an ELF attributes section. +/// +/// 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> { + 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 { + 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 index 7cee85bb4..1a2f2f44a 100644 --- a/vendor/object/src/read/elf/comdat.rs +++ b/vendor/object/src/read/elf/comdat.rs @@ -18,7 +18,6 @@ pub type ElfComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> #[derive(Debug)] pub struct ElfComdatIterator<'data, 'file, Elf, R = &'data [u8]> where - 'data: 'file, Elf: FileHeader, R: ReadRef<'data>, { @@ -140,7 +139,6 @@ pub type ElfComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'dat #[derive(Debug)] pub struct ElfComdatSectionIterator<'data, 'file, Elf, R = &'data [u8]> where - 'data: 'file, Elf: FileHeader, R: ReadRef<'data>, { diff --git a/vendor/object/src/read/elf/file.rs b/vendor/object/src/read/elf/file.rs index 259da7906..aac66e7cc 100644 --- a/vendor/object/src/read/elf/file.rs +++ b/vendor/object/src/read/elf/file.rs @@ -456,6 +456,15 @@ pub trait FileHeader: Debug + Pod { /// 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 `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; @@ -724,6 +733,14 @@ impl FileHeader for elf::FileHeader32 { false } + #[inline] + fn is_type_64_sized() -> bool + where + Self: Sized, + { + false + } + #[inline] fn e_ident(&self) -> &elf::Ident { &self.e_ident @@ -813,6 +830,14 @@ impl FileHeader for elf::FileHeader64 { true } + #[inline] + fn is_type_64_sized() -> bool + where + Self: Sized, + { + true + } + #[inline] fn e_ident(&self) -> &elf::Ident { &self.e_ident diff --git a/vendor/object/src/read/elf/hash.rs b/vendor/object/src/read/elf/hash.rs index aa1039ac1..aadbb9208 100644 --- a/vendor/object/src/read/elf/hash.rs +++ b/vendor/object/src/read/elf/hash.rs @@ -45,7 +45,7 @@ impl<'data, Elf: FileHeader> HashTable<'data, Elf> { endian: Elf::Endian, name: &[u8], hash: u32, - version: Option<&Version>, + version: Option<&Version<'_>>, symbols: &SymbolTable<'data, Elf, R>, versions: &VersionTable<'data, Elf>, ) -> Option<(usize, &'data Elf::Sym)> { @@ -160,7 +160,7 @@ impl<'data, Elf: FileHeader> GnuHashTable<'data, Elf> { endian: Elf::Endian, name: &[u8], hash: u32, - version: Option<&Version>, + version: Option<&Version<'_>>, symbols: &SymbolTable<'data, Elf, R>, versions: &VersionTable<'data, Elf>, ) -> Option<(usize, &'data Elf::Sym)> { diff --git a/vendor/object/src/read/elf/mod.rs b/vendor/object/src/read/elf/mod.rs index 5b7d7f9f7..07db6cd66 100644 --- a/vendor/object/src/read/elf/mod.rs +++ b/vendor/object/src/read/elf/mod.rs @@ -37,3 +37,6 @@ 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 index 34024dbb8..fc5aa7753 100644 --- a/vendor/object/src/read/elf/note.rs +++ b/vendor/object/src/read/elf/note.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; use core::mem; use crate::elf; -use crate::endian; +use crate::endian::{self, U32}; use crate::pod::Pod; use crate::read::util; use crate::read::{self, Bytes, Error, ReadError}; @@ -24,12 +24,15 @@ 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(super) fn new( - endian: Elf::Endian, - align: Elf::Word, - data: &'data [u8], - ) -> read::Result { + pub fn new(endian: Elf::Endian, align: Elf::Word, data: &'data [u8]) -> read::Result { let align = match align.into() { 0u64..=4 => 4, 8 => 8, @@ -134,6 +137,24 @@ impl<'data, Elf: FileHeader> Note<'data, Elf> { pub fn desc(&self) -> &'data [u8] { self.desc } + + /// Return an iterator for properties if this note's type is `NT_GNU_PROPERTY_TYPE_0`. + pub fn gnu_properties( + &self, + endian: Elf::Endian, + ) -> Option> { + 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 `NoteHeader32` and `NoteHeader64`. @@ -183,3 +204,60 @@ impl NoteHeader for elf::NoteHeader64 { self.n_type.get(endian) } } + +/// An iterator over the properties in a `NT_GNU_PROPERTY_TYPE_0` note. +#[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>> { + let mut data = self.data; + if data.is_empty() { + return Ok(None); + } + + (|| -> Result<_, ()> { + let pr_type = data.read_at::>(0)?.get(self.endian); + let pr_datasz = data.read_at::>(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 `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(&self, endian: E) -> read::Result { + Bytes(self.pr_data) + .read_at::>(0) + .read_error("Invalid ELF GNU property data") + .map(|val| val.get(endian)) + } +} diff --git a/vendor/object/src/read/elf/section.rs b/vendor/object/src/read/elf/section.rs index 3f8a08216..df08f9e3e 100644 --- a/vendor/object/src/read/elf/section.rs +++ b/vendor/object/src/read/elf/section.rs @@ -10,8 +10,9 @@ use crate::read::{ }; use super::{ - CompressionHeader, ElfFile, ElfSectionRelocationIterator, FileHeader, GnuHashTable, HashTable, - NoteIterator, RelocationSections, SymbolTable, VerdefIterator, VerneedIterator, VersionTable, + AttributesSection, CompressionHeader, ElfFile, ElfSectionRelocationIterator, FileHeader, + GnuHashTable, HashTable, NoteIterator, RelocationSections, SymbolTable, VerdefIterator, + VerneedIterator, VersionTable, }; /// The table of section headers in an ELF file. @@ -362,7 +363,6 @@ pub type ElfSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> = #[derive(Debug)] pub struct ElfSection<'data, 'file, Elf, R = &'data [u8]> where - 'data: 'file, Elf: FileHeader, R: ReadRef<'data>, { @@ -380,32 +380,24 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSection<'data, 'file, fn maybe_compressed(&self) -> read::Result> { let endian = self.file.endian; - if (self.section.sh_flags(endian).into() & u64::from(elf::SHF_COMPRESSED)) == 0 { - return Ok(None); - } - let (section_offset, section_size) = self - .section - .file_range(endian) - .read_error("Invalid ELF compressed section type")?; - let mut offset = section_offset; - let header = self - .file - .data - .read::(&mut offset) - .read_error("Invalid ELF compressed section offset")?; - if header.ch_type(endian) != elf::ELFCOMPRESS_ZLIB { - return Err(Error("Unsupported ELF compression type")); + 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) } - let uncompressed_size = header.ch_size(endian).into(); - let compressed_size = section_size - .checked_sub(offset - section_offset) - .read_error("Invalid ELF compressed section size")?; - Ok(Some(CompressedFileRange { - format: CompressionFormat::Zlib, - offset, - compressed_size, - uncompressed_size, - })) } /// Try GNU-style "ZLIB" header decompression. @@ -975,6 +967,70 @@ pub trait SectionHeader: Debug + Pod { 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>> { + 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> { + 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 ::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::<::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 SectionHeader for elf::SectionHeader32 { diff --git a/vendor/object/src/read/elf/segment.rs b/vendor/object/src/read/elf/segment.rs index 445893c8d..3972731ec 100644 --- a/vendor/object/src/read/elf/segment.rs +++ b/vendor/object/src/read/elf/segment.rs @@ -57,7 +57,6 @@ pub type ElfSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> = #[derive(Debug)] pub struct ElfSegment<'data, 'file, Elf, R = &'data [u8]> where - 'data: 'file, Elf: FileHeader, R: ReadRef<'data>, { diff --git a/vendor/object/src/read/elf/symbol.rs b/vendor/object/src/read/elf/symbol.rs index 5d8d29f27..ac1095705 100644 --- a/vendor/object/src/read/elf/symbol.rs +++ b/vendor/object/src/read/elf/symbol.rs @@ -208,7 +208,6 @@ pub type ElfSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> = #[derive(Debug, Clone, Copy)] pub struct ElfSymbolTable<'data, 'file, Elf, R = &'data [u8]> where - 'data: 'file, Elf: FileHeader, R: ReadRef<'data>, { @@ -256,7 +255,6 @@ pub type ElfSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> /// An iterator over the symbols of an `ElfFile`. pub struct ElfSymbolIterator<'data, 'file, Elf, R = &'data [u8]> where - 'data: 'file, Elf: FileHeader, R: ReadRef<'data>, { @@ -302,7 +300,6 @@ pub type ElfSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> = #[derive(Debug, Clone, Copy)] pub struct ElfSymbol<'data, 'file, Elf, R = &'data [u8]> where - 'data: 'file, Elf: FileHeader, R: ReadRef<'data>, { @@ -430,7 +427,7 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } #[inline] - fn flags(&self) -> SymbolFlags { + fn flags(&self) -> SymbolFlags { SymbolFlags::Elf { st_info: self.symbol.st_info(), st_other: self.symbol.st_other(), diff --git a/vendor/object/src/read/elf/version.rs b/vendor/object/src/read/elf/version.rs index 6d80ba1e3..cc87bbef1 100644 --- a/vendor/object/src/read/elf/version.rs +++ b/vendor/object/src/read/elf/version.rs @@ -183,12 +183,12 @@ impl<'data, Elf: FileHeader> VersionTable<'data, Elf> { .map(Some) } - /// Return true if the given symbol index satisifies the requirements of `need`. + /// 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 { + 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, diff --git a/vendor/object/src/read/macho/dyld_cache.rs b/vendor/object/src/read/macho/dyld_cache.rs index 0839ded7d..68f27f549 100644 --- a/vendor/object/src/read/macho/dyld_cache.rs +++ b/vendor/object/src/read/macho/dyld_cache.rs @@ -191,7 +191,7 @@ where /// 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 alway succeed. + // 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) } diff --git a/vendor/object/src/read/macho/file.rs b/vendor/object/src/read/macho/file.rs index ab8c05757..368c28bbd 100644 --- a/vendor/object/src/read/macho/file.rs +++ b/vendor/object/src/read/macho/file.rs @@ -192,6 +192,7 @@ where 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, @@ -531,7 +532,6 @@ pub type MachOComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'d #[derive(Debug)] pub struct MachOComdatSectionIterator<'data, 'file, Mach, R = &'data [u8]> where - 'data: 'file, Mach: MachHeader, R: ReadRef<'data>, { diff --git a/vendor/object/src/read/macho/load_command.rs b/vendor/object/src/read/macho/load_command.rs index 10daf4ed1..e9af89d8b 100644 --- a/vendor/object/src/read/macho/load_command.rs +++ b/vendor/object/src/read/macho/load_command.rs @@ -1,10 +1,11 @@ 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, ReadError, ReadRef, Result, StringTable}; +use crate::read::{Bytes, Error, ReadError, ReadRef, Result, StringTable}; /// An iterator over the load commands of a `MachHeader`. #[derive(Debug, Default, Clone, Copy)] @@ -34,6 +35,9 @@ impl<'data, E: Endian> LoadCommandIterator<'data, E> { .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::>() { + return Err(Error("Invalid Mach-O load command size")); + } let data = self .data .read_bytes(cmdsize) @@ -351,3 +355,19 @@ impl macho::SymtabCommand { 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/relocation.rs b/vendor/object/src/read/macho/relocation.rs index 5dd7df896..18e22ef70 100644 --- a/vendor/object/src/read/macho/relocation.rs +++ b/vendor/object/src/read/macho/relocation.rs @@ -19,7 +19,6 @@ pub type MachORelocationIterator64<'data, 'file, Endian = Endianness, R = &'data /// An iterator over the relocations in a `MachOSection`. pub struct MachORelocationIterator<'data, 'file, Mach, R = &'data [u8]> where - 'data: 'file, Mach: MachHeader, R: ReadRef<'data>, { @@ -54,13 +53,15 @@ where relative: reloc.r_pcrel, }, }, - macho::CPU_TYPE_ARM64 => match (reloc.r_type, reloc.r_pcrel) { - (macho::ARM64_RELOC_UNSIGNED, 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, + _ => 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 { diff --git a/vendor/object/src/read/macho/section.rs b/vendor/object/src/read/macho/section.rs index 9e71aa8fd..f43a5b83d 100644 --- a/vendor/object/src/read/macho/section.rs +++ b/vendor/object/src/read/macho/section.rs @@ -21,7 +21,6 @@ pub type MachOSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u /// An iterator over the sections of a `MachOFile`. pub struct MachOSectionIterator<'data, 'file, Mach, R = &'data [u8]> where - 'data: 'file, Mach: MachHeader, R: ReadRef<'data>, { @@ -66,7 +65,6 @@ pub type MachOSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> = #[derive(Debug)] pub struct MachOSection<'data, 'file, Mach, R = &'data [u8]> where - 'data: 'file, Mach: MachHeader, R: ReadRef<'data>, { @@ -120,7 +118,12 @@ where #[inline] fn align(&self) -> u64 { - 1 << self.internal.section.align(self.file.endian) + let align = self.internal.section.align(self.file.endian); + if align < 64 { + 1 << align + } else { + 0 + } } #[inline] diff --git a/vendor/object/src/read/macho/segment.rs b/vendor/object/src/read/macho/segment.rs index c7eaa6fff..01037e1dd 100644 --- a/vendor/object/src/read/macho/segment.rs +++ b/vendor/object/src/read/macho/segment.rs @@ -19,7 +19,6 @@ pub type MachOSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u #[derive(Debug)] pub struct MachOSegmentIterator<'data, 'file, Mach, R = &'data [u8]> where - 'data: 'file, Mach: MachHeader, R: ReadRef<'data>, { @@ -53,7 +52,6 @@ pub type MachOSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> = #[derive(Debug)] pub struct MachOSegment<'data, 'file, Mach, R = &'data [u8]> where - 'data: 'file, Mach: MachHeader, R: ReadRef<'data>, { @@ -160,7 +158,7 @@ pub trait Segment: Debug + Pod { type Endian: endian::Endian; type Section: Section; - fn from_command(command: LoadCommandData) -> Result>; + fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result>; fn cmd(&self, endian: Self::Endian) -> u32; fn cmdsize(&self, endian: Self::Endian) -> u32; @@ -219,7 +217,7 @@ impl Segment for macho::SegmentCommand32 { type Endian = Endian; type Section = macho::Section32; - fn from_command(command: LoadCommandData) -> Result> { + fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result> { command.segment_32() } @@ -263,7 +261,7 @@ impl Segment for macho::SegmentCommand64 { type Endian = Endian; type Section = macho::Section64; - fn from_command(command: LoadCommandData) -> Result> { + fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result> { command.segment_64() } diff --git a/vendor/object/src/read/macho/symbol.rs b/vendor/object/src/read/macho/symbol.rs index e102c5d0b..ef8852145 100644 --- a/vendor/object/src/read/macho/symbol.rs +++ b/vendor/object/src/read/macho/symbol.rs @@ -388,7 +388,7 @@ where } #[inline] - fn flags(&self) -> SymbolFlags { + fn flags(&self) -> SymbolFlags { let n_desc = self.nlist.n_desc(self.file.endian); SymbolFlags::MachO { n_desc } } diff --git a/vendor/object/src/read/mod.rs b/vendor/object/src/read/mod.rs index 91a5c05a5..0a450359f 100644 --- a/vendor/object/src/read/mod.rs +++ b/vendor/object/src/read/mod.rs @@ -70,7 +70,7 @@ pub struct Error(&'static str); impl fmt::Display for Error { #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.0) } } @@ -151,6 +151,11 @@ pub enum FileKind { /// A COFF object file. #[cfg(feature = "coff")] Coff, + /// A COFF bigobj object file. + /// + /// This supports a larger number of sections. + #[cfg(feature = "coff")] + CoffBig, /// A dyld cache file containing Mach-O images. #[cfg(feature = "macho")] DyldCache, @@ -226,7 +231,7 @@ impl FileKind { #[cfg(feature = "wasm")] [0x00, b'a', b's', b'm', ..] => FileKind::Wasm, #[cfg(feature = "pe")] - [b'M', b'Z', ..] => { + [b'M', b'Z', ..] if offset == 0 => { match pe::optional_header_magic(data) { Ok(crate::pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC) => { FileKind::Pe32 @@ -247,6 +252,13 @@ impl FileKind { | [0x4c, 0x01, ..] // COFF x86-64 | [0x64, 0x86, ..] => FileKind::Coff, + #[cfg(feature = "coff")] + [0x00, 0x00, 0xff, 0xff, 0x02, 0x00, ..] if 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")] @@ -620,6 +632,10 @@ pub enum CompressionFormat { /// /// 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. @@ -719,6 +735,25 @@ impl<'data> CompressedData<'data> { .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 index f5d98774e..0e10244bf 100644 --- a/vendor/object/src/read/pe/data_directory.rs +++ b/vendor/object/src/read/pe/data_directory.rs @@ -178,7 +178,7 @@ impl pe::ImageDataDirectory { /// 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<'data>(&self, sections: &SectionTable<'data>) -> Result<(u32, u32)> { + 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")?; diff --git a/vendor/object/src/read/pe/file.rs b/vendor/object/src/read/pe/file.rs index 8dd85131a..0f8ce9f25 100644 --- a/vendor/object/src/read/pe/file.rs +++ b/vendor/object/src/read/pe/file.rs @@ -80,7 +80,7 @@ where } /// Returns information about the rich header of this file (if any). - pub fn rich_header_info(&self) -> Option { + pub fn rich_header_info(&self) -> Option> { RichHeaderInfo::parse(self.data, self.dos_header.nt_headers_offset().into()) } @@ -298,7 +298,7 @@ where Ok(exports) } - fn pdb_info(&self) -> Result> { + fn pdb_info(&self) -> Result>> { let data_dir = match self.data_directory(pe::IMAGE_DIRECTORY_ENTRY_DEBUG) { Some(data_dir) => data_dir, None => return Ok(None), diff --git a/vendor/object/src/read/pe/resource.rs b/vendor/object/src/read/pe/resource.rs index e667f0d98..646eaefaa 100644 --- a/vendor/object/src/read/pe/resource.rs +++ b/vendor/object/src/read/pe/resource.rs @@ -143,7 +143,7 @@ pub struct ResourceName { impl ResourceName { /// Converts to a `String`. - pub fn to_string_lossy(&self, directory: ResourceDirectory) -> Result { + pub fn to_string_lossy(&self, directory: ResourceDirectory<'_>) -> Result { let d = self.data(directory)?.iter().map(|c| c.get(LE)); Ok(char::decode_utf16(d) diff --git a/vendor/object/src/read/pe/rich.rs b/vendor/object/src/read/pe/rich.rs index 687dfc995..33dd039c9 100644 --- a/vendor/object/src/read/pe/rich.rs +++ b/vendor/object/src/read/pe/rich.rs @@ -77,7 +77,7 @@ impl<'data> RichHeaderInfo<'data> { } } -/// Find the offset of the first occurence of needle in the data. +/// 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 { diff --git a/vendor/object/src/read/pe/section.rs b/vendor/object/src/read/pe/section.rs index 439d42dac..2880e401f 100644 --- a/vendor/object/src/read/pe/section.rs +++ b/vendor/object/src/read/pe/section.rs @@ -143,7 +143,6 @@ pub type PeSectionIterator64<'data, 'file, R = &'data [u8]> = #[derive(Debug)] pub struct PeSectionIterator<'data, 'file, Pe, R = &'data [u8]> where - 'data: 'file, Pe: ImageNtHeaders, R: ReadRef<'data>, { @@ -178,7 +177,6 @@ pub type PeSection64<'data, 'file, R = &'data [u8]> = #[derive(Debug)] pub struct PeSection<'data, 'file, Pe, R = &'data [u8]> where - 'data: 'file, Pe: ImageNtHeaders, R: ReadRef<'data>, { diff --git a/vendor/object/src/read/read_cache.rs b/vendor/object/src/read/read_cache.rs index 19a98a44d..dfce1e1b1 100644 --- a/vendor/object/src/read/read_cache.rs +++ b/vendor/object/src/read/read_cache.rs @@ -77,10 +77,7 @@ impl<'a, R: Read + Seek> ReadRef<'a> for &'a ReadCache { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { let size = size.try_into().map_err(|_| ())?; - cache - .read - .seek(SeekFrom::Start(offset as u64)) - .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) diff --git a/vendor/object/src/read/read_ref.rs b/vendor/object/src/read/read_ref.rs index 2f547a4e2..a9b425221 100644 --- a/vendor/object/src/read/read_ref.rs +++ b/vendor/object/src/read/read_ref.rs @@ -67,7 +67,7 @@ pub trait ReadRef<'a>: Clone + Copy { /// 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 satisified. Alternatively, only use this method with + /// 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(self, offset: &mut u64) -> Result<&'a T> { let size = mem::size_of::().try_into().map_err(|_| ())?; diff --git a/vendor/object/src/read/traits.rs b/vendor/object/src/read/traits.rs index f1a473e0a..d35b0b0ca 100644 --- a/vendor/object/src/read/traits.rs +++ b/vendor/object/src/read/traits.rs @@ -210,7 +210,7 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// The filename and GUID from the PE CodeView section #[inline] - fn pdb_info(&self) -> Result> { + fn pdb_info(&self) -> Result>> { Ok(None) } @@ -452,7 +452,7 @@ pub trait ObjectSymbol<'data>: read::private::Sealed { fn is_local(&self) -> bool; /// Symbol flags that are specific to each file format. - fn flags(&self) -> SymbolFlags; + fn flags(&self) -> SymbolFlags; } /// An iterator for files that don't have dynamic relocations. diff --git a/vendor/object/src/read/util.rs b/vendor/object/src/read/util.rs index 842bd6ca1..7c3c65ec9 100644 --- a/vendor/object/src/read/util.rs +++ b/vendor/object/src/read/util.rs @@ -165,6 +165,48 @@ impl<'data> Bytes<'data> { self.skip(offset)?; self.read_string() } + + /// Read an unsigned LEB128 number. + pub fn read_uleb128(&mut self) -> Result { + let mut result = 0; + let mut shift = 0; + + loop { + let byte = *self.read::()?; + 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 { + let mut result = 0; + let mut shift = 0; + + loop { + let byte = *self.read::()?; + 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`. diff --git a/vendor/object/src/read/wasm.rs b/vendor/object/src/read/wasm.rs index 0113f5971..b950ef2b2 100644 --- a/vendor/object/src/read/wasm.rs +++ b/vendor/object/src/read/wasm.rs @@ -6,6 +6,7 @@ use alloc::boxed::Box; use alloc::vec::Vec; use core::marker::PhantomData; +use core::ops::Range; use core::{slice, str}; use wasmparser as wp; @@ -17,27 +18,33 @@ use crate::read::{ SymbolScope, SymbolSection, }; -const SECTION_CUSTOM: usize = 0; -const SECTION_TYPE: usize = 1; -const SECTION_IMPORT: usize = 2; -const SECTION_FUNCTION: usize = 3; -const SECTION_TABLE: usize = 4; -const SECTION_MEMORY: usize = 5; -const SECTION_GLOBAL: usize = 6; -const SECTION_EXPORT: usize = 7; -const SECTION_START: usize = 8; -const SECTION_ELEMENT: usize = 9; -const SECTION_CODE: usize = 10; -const SECTION_DATA: usize = 11; -const SECTION_DATA_COUNT: usize = 12; +#[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 = SECTION_DATA_COUNT; +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>, + sections: Vec>, // Indices into `sections` of sections with a non-zero id. id_sections: Box<[Option; MAX_SECTION_ID + 1]>, // Whether the file has DWARF information. @@ -49,6 +56,13 @@ pub struct WasmFile<'data, R = &'data [u8]> { marker: PhantomData, } +#[derive(Debug)] +struct SectionHeader<'data> { + id: SectionId, + range: Range, + name: &'data str, +} + #[derive(Clone)] enum LocalFunctionKind { Unknown, @@ -67,9 +81,11 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { pub fn parse(data: R) -> Result { let len = data.len().read_error("Unknown Wasm file size")?; let data = data.read_bytes_at(0, len).read_error("Wasm read failed")?; - let module = wp::ModuleReader::new(data).read_error("Invalid Wasm header")?; + 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, @@ -90,18 +106,23 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { 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 section in module { - let section = section.read_error("Invalid Wasm section header")?; + for payload in parser { + let payload = payload.read_error("Invalid Wasm section header")?; - match section.code { - wp::SectionCode::Import => { + 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 - .get_import_section_reader() - .read_error("Couldn't read header of the import section")? - { + for import in section { let import = import.read_error("Couldn't read an import item")?; let module_name = import.module; @@ -118,17 +139,20 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { } let kind = match import.ty { - wp::ImportSectionEntryType::Function(_) => { + wp::TypeRef::Func(_) => { imported_funcs_count += 1; SymbolKind::Text } - wp::ImportSectionEntryType::Table(_) - | wp::ImportSectionEntryType::Memory(_) - | wp::ImportSectionEntryType::Global(_) => SymbolKind::Data, + 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.field, + name: import.name, address: 0, size: 0, kind, @@ -137,28 +161,49 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { }); } } - wp::SectionCode::Function => { - local_func_kinds = vec![ - LocalFunctionKind::Unknown; - section - .get_function_section_reader() - .read_error("Couldn't read header of the function section")? - .get_count() as usize - ]; + 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::SectionCode::Export => { + 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 - .get_export_section_reader() - .read_error("Couldn't read header of the export section")? - { + for export in section { let export = export.read_error("Couldn't read an export item")?; let (kind, section_idx) = match export.kind { - wp::ExternalKind::Function => { + wp::ExternalKind::Func => { if let Some(local_func_id) = export.index.checked_sub(imported_funcs_count) { @@ -175,133 +220,149 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { }; symbol_ids.push(file.symbols.len() as u32); } - (SymbolKind::Text, SECTION_CODE) + (SymbolKind::Text, SectionId::Code) } wp::ExternalKind::Table | wp::ExternalKind::Memory - | wp::ExternalKind::Global => (SymbolKind::Data, SECTION_DATA), + | 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.field, - address: 0, + name: export.name, + address, size: 0, kind, - section: SymbolSection::Section(SectionIndex(section_idx)), + section: SymbolSection::Section(SectionIndex(section_idx as usize)), scope: SymbolScope::Dynamic, }); } } - wp::SectionCode::Start => { - entry_func_id = Some( - section - .get_start_section_content() - .read_error("Couldn't read contents of the start section")?, - ); + wp::Payload::StartSection { func, range, .. } => { + file.add_section(SectionId::Start, range, ""); + entry_func_id = Some(func); } - wp::SectionCode::Code => { + 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; - for (i, (body, local_func_kind)) in section - .get_code_section_reader() - .read_error("Couldn't read header of the code section")? - .into_iter() - .zip(&mut local_func_kinds) - .enumerate() - { - let body = body.read_error("Couldn't read a function body")?; - let range = body.range(); - - let address = range.start as u64 - section.range().start as u64; - let size = (range.end - range.start) as u64; - - if entry_func_id == Some(i as u32) { - file.entry = address; - } + let range = body.range(); - 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(SECTION_CODE)), - 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; - } + 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!(), } + _ => unreachable!(), } } - wp::SectionCode::Custom { - kind: wp::CustomSectionKind::Name, - .. - } => { - for name in section - .get_name_section_reader() - .read_error("Couldn't read header of the name section")? - { - // 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)) = name { - let mut name_map = name.get_map().read_error( - "Couldn't read header of the function name subsection", - )?; - for _ in 0..name_map.get_count() { - let naming = name_map - .read() - .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] + 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) { - file.symbols[symbol_id as usize].name = naming.name; + 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; } } - wp::SectionCode::Custom { name, .. } if name.starts_with(".debug_") => { - file.has_debug_symbols = true; - } _ => {} } - - let id = section_code_to_id(section.code); - file.id_sections[id] = Some(file.sections.len()); - - file.sections.push(section); } Ok(file) } + + fn add_section(&mut self, id: SectionId, range: Range, 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> Object<'data, 'file> for WasmFile<'data, R> +impl<'data, 'file, R: ReadRef<'data>> Object<'data, 'file> for WasmFile<'data, R> where 'data: 'file, R: 'file, @@ -319,7 +380,11 @@ where #[inline] fn architecture(&self) -> Architecture { - Architecture::Wasm32 + if self.has_memory64 { + Architecture::Wasm64 + } else { + Architecture::Wasm32 + } } #[inline] @@ -329,7 +394,7 @@ where #[inline] fn is_64(&self) -> bool { - false + self.has_memory64 } fn kind(&self) -> ObjectKind { @@ -358,15 +423,15 @@ where .read_error("Invalid Wasm section index")?; let section = self.sections.get(id_section).unwrap(); Ok(WasmSection { + file: self, section, - marker: PhantomData, }) } fn sections(&'file self) -> Self::SectionIterator { WasmSectionIterator { + file: self, sections: self.sections.iter(), - marker: PhantomData, } } @@ -513,8 +578,8 @@ impl<'data, 'file, R> ObjectSegment<'data> for WasmSegment<'data, 'file, R> { /// An iterator over the sections of a `WasmFile`. #[derive(Debug)] pub struct WasmSectionIterator<'data, 'file, R = &'data [u8]> { - sections: slice::Iter<'file, wp::Section<'data>>, - marker: PhantomData, + file: &'file WasmFile<'data, R>, + sections: slice::Iter<'file, SectionHeader<'data>>, } impl<'data, 'file, R> Iterator for WasmSectionIterator<'data, 'file, R> { @@ -523,8 +588,8 @@ impl<'data, 'file, R> Iterator for WasmSectionIterator<'data, 'file, R> { fn next(&mut self) -> Option { let section = self.sections.next()?; Some(WasmSection { + file: self.file, section, - marker: PhantomData, }) } } @@ -532,20 +597,20 @@ impl<'data, 'file, R> Iterator for WasmSectionIterator<'data, 'file, R> { /// A section of a `WasmFile`. #[derive(Debug)] pub struct WasmSection<'data, 'file, R = &'data [u8]> { - section: &'file wp::Section<'data>, - marker: PhantomData, + 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> ObjectSection<'data> 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(section_code_to_id(self.section.code)) + SectionIndex(self.section.id as usize) } #[inline] @@ -555,7 +620,7 @@ impl<'data, 'file, R> ObjectSection<'data> for WasmSection<'data, 'file, R> { #[inline] fn size(&self) -> u64 { - let range = self.section.range(); + let range = &self.section.range; (range.end - range.start) as u64 } @@ -566,16 +631,17 @@ impl<'data, 'file, R> ObjectSection<'data> for WasmSection<'data, 'file, R> { #[inline] fn file_range(&self) -> Option<(u64, u64)> { - let range = self.section.range(); + let range = &self.section.range; Some((range.start as _, range.end as _)) } #[inline] fn data(&self) -> Result<&'data [u8]> { - let mut reader = self.section.get_binary_reader(); - // TODO: raise a feature request upstream to be able - // to get remaining slice from a BinaryReader directly. - Ok(reader.read_bytes(reader.bytes_remaining()).unwrap()) + 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> { @@ -599,20 +665,20 @@ impl<'data, 'file, R> ObjectSection<'data> for WasmSection<'data, 'file, R> { #[inline] fn name(&self) -> Result<&str> { - Ok(match self.section.code { - wp::SectionCode::Custom { name, .. } => name, - wp::SectionCode::Type => "", - wp::SectionCode::Import => "", - wp::SectionCode::Function => "", - wp::SectionCode::Table => "", - wp::SectionCode::Memory => "", - wp::SectionCode::Global => "", - wp::SectionCode::Export => "", - wp::SectionCode::Start => "", - wp::SectionCode::Element => "", - wp::SectionCode::Code => "", - wp::SectionCode::Data => "", - wp::SectionCode::DataCount => "", + Ok(match self.section.id { + SectionId::Custom => self.section.name, + SectionId::Type => "", + SectionId::Import => "", + SectionId::Function => "", + SectionId::Table => "
", + SectionId::Memory => "", + SectionId::Global => "", + SectionId::Export => "", + SectionId::Start => "", + SectionId::Element => "", + SectionId::Code => "", + SectionId::Data => "", + SectionId::DataCount => "", }) } @@ -628,25 +694,23 @@ impl<'data, 'file, R> ObjectSection<'data> for WasmSection<'data, 'file, R> { #[inline] fn kind(&self) -> SectionKind { - match self.section.code { - wp::SectionCode::Custom { kind, .. } => match kind { - wp::CustomSectionKind::Reloc | wp::CustomSectionKind::Linking => { - SectionKind::Linker - } + match self.section.id { + SectionId::Custom => match self.section.name { + "reloc." | "linking" => SectionKind::Linker, _ => SectionKind::Other, }, - wp::SectionCode::Type => SectionKind::Metadata, - wp::SectionCode::Import => SectionKind::Linker, - wp::SectionCode::Function => SectionKind::Metadata, - wp::SectionCode::Table => SectionKind::UninitializedData, - wp::SectionCode::Memory => SectionKind::UninitializedData, - wp::SectionCode::Global => SectionKind::Data, - wp::SectionCode::Export => SectionKind::Linker, - wp::SectionCode::Start => SectionKind::Linker, - wp::SectionCode::Element => SectionKind::Data, - wp::SectionCode::Code => SectionKind::Text, - wp::SectionCode::Data => SectionKind::Data, - wp::SectionCode::DataCount => SectionKind::UninitializedData, + 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, } } @@ -717,10 +781,7 @@ impl<'data, 'file, R> ObjectComdat<'data> for WasmComdat<'data, 'file, R> { /// An iterator over the sections in a COMDAT section group of a `WasmFile`. #[derive(Debug)] -pub struct WasmComdatSectionIterator<'data, 'file, R = &'data [u8]> -where - 'data: 'file, -{ +pub struct WasmComdatSectionIterator<'data, 'file, R = &'data [u8]> { #[allow(unused)] file: &'file WasmFile<'data, R>, } @@ -869,7 +930,7 @@ impl<'data, 'file> ObjectSymbol<'data> for WasmSymbol<'data, 'file> { } #[inline] - fn flags(&self) -> SymbolFlags { + fn flags(&self) -> SymbolFlags { SymbolFlags::None } } @@ -888,21 +949,3 @@ impl<'data, 'file, R> Iterator for WasmRelocationIterator<'data, 'file, R> { None } } - -fn section_code_to_id(code: wp::SectionCode) -> usize { - match code { - wp::SectionCode::Custom { .. } => SECTION_CUSTOM, - wp::SectionCode::Type => SECTION_TYPE, - wp::SectionCode::Import => SECTION_IMPORT, - wp::SectionCode::Function => SECTION_FUNCTION, - wp::SectionCode::Table => SECTION_TABLE, - wp::SectionCode::Memory => SECTION_MEMORY, - wp::SectionCode::Global => SECTION_GLOBAL, - wp::SectionCode::Export => SECTION_EXPORT, - wp::SectionCode::Start => SECTION_START, - wp::SectionCode::Element => SECTION_ELEMENT, - wp::SectionCode::Code => SECTION_CODE, - wp::SectionCode::Data => SECTION_DATA, - wp::SectionCode::DataCount => SECTION_DATA_COUNT, - } -} diff --git a/vendor/object/src/read/xcoff/comdat.rs b/vendor/object/src/read/xcoff/comdat.rs index eeed2f54d..2b23d1dba 100644 --- a/vendor/object/src/read/xcoff/comdat.rs +++ b/vendor/object/src/read/xcoff/comdat.rs @@ -109,7 +109,6 @@ pub type XcoffComdatSectionIterator64<'data, 'file, R = &'data [u8]> = #[derive(Debug)] pub struct XcoffComdatSectionIterator<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { diff --git a/vendor/object/src/read/xcoff/relocation.rs b/vendor/object/src/read/xcoff/relocation.rs index 8107a2e82..78c6acfc7 100644 --- a/vendor/object/src/read/xcoff/relocation.rs +++ b/vendor/object/src/read/xcoff/relocation.rs @@ -19,7 +19,6 @@ pub type XcoffRelocationIterator64<'data, 'file, R = &'data [u8]> = /// An iterator over the relocations in a `XcoffSection`. pub struct XcoffRelocationIterator<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { diff --git a/vendor/object/src/read/xcoff/section.rs b/vendor/object/src/read/xcoff/section.rs index 0944e10c8..77453fcd2 100644 --- a/vendor/object/src/read/xcoff/section.rs +++ b/vendor/object/src/read/xcoff/section.rs @@ -36,7 +36,7 @@ where fn next(&mut self) -> Option { self.iter.next().map(|(index, section)| XcoffSection { - index: SectionIndex(index), + index: SectionIndex(index + 1), file: self.file, section, }) @@ -54,7 +54,6 @@ pub type XcoffSection64<'data, 'file, R = &'data [u8]> = #[derive(Debug)] pub struct XcoffSection<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { @@ -252,9 +251,11 @@ where } /// 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) + .get(index.0.wrapping_sub(1)) .read_error("Invalid XCOFF section index") } } diff --git a/vendor/object/src/read/xcoff/segment.rs b/vendor/object/src/read/xcoff/segment.rs index 49969438d..7eca72367 100644 --- a/vendor/object/src/read/xcoff/segment.rs +++ b/vendor/object/src/read/xcoff/segment.rs @@ -19,7 +19,6 @@ pub type XcoffSegmentIterator64<'data, 'file, R = &'data [u8]> = #[derive(Debug)] pub struct XcoffSegmentIterator<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { @@ -50,7 +49,6 @@ pub type XcoffSegment64<'data, 'file, R = &'data [u8]> = #[derive(Debug)] pub struct XcoffSegment<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { diff --git a/vendor/object/src/read/xcoff/symbol.rs b/vendor/object/src/read/xcoff/symbol.rs index 6738ad171..7ce215fac 100644 --- a/vendor/object/src/read/xcoff/symbol.rs +++ b/vendor/object/src/read/xcoff/symbol.rs @@ -5,9 +5,9 @@ use core::marker::PhantomData; use core::str; use crate::endian::{BigEndian as BE, U32Bytes}; -use crate::pod::Pod; +use crate::pod::{bytes_of, Pod}; use crate::read::util::StringTable; -use crate::{bytes_of, xcoff, Object, ObjectSection, SectionKind}; +use crate::xcoff; use crate::read::{ self, Bytes, Error, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex, @@ -95,10 +95,10 @@ where self.get::(index, 0) } - /// Return the file auxiliary symbol. - pub fn aux_file(&self, index: usize) -> Result<&'data Xcoff::FileAux> { + /// 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::(index, 1)?; + let aux_file = self.get::(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.")); @@ -145,7 +145,6 @@ pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> = #[derive(Debug, Clone, Copy)] pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { @@ -193,7 +192,6 @@ pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> = /// An iterator over the symbols of an `XcoffFile`. pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { @@ -240,7 +238,6 @@ pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> = #[derive(Debug, Clone, Copy)] pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]> where - 'data: 'file, Xcoff: FileHeader, R: ReadRef<'data>, { @@ -264,7 +261,14 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } fn name_bytes(&self) -> Result<&'data [u8]> { - self.symbol.name(self.symbols.strings) + 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> { @@ -283,7 +287,8 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> | xcoff::C_HIDEXT | xcoff::C_FCN | xcoff::C_BLOCK - | xcoff::C_STAT => self.symbol.n_value().into(), + | xcoff::C_STAT + | xcoff::C_INFO => self.symbol.n_value().into(), _ => 0, } } @@ -300,32 +305,46 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> { let sym_type = aux_csect.sym_type() & 0x07; if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM { - aux_csect.x_scnlen() - } else { - 0 + return aux_csect.x_scnlen(); } - } else { - 0 } - } else { - 0 } + 0 } fn kind(&self) -> SymbolKind { + if self.symbol.has_aux_csect() { + if let Ok(aux_csect) = self + .file + .symbols + .aux_csect(self.index.0, self.symbol.n_numaux() as usize) + { + let sym_type = aux_csect.sym_type() & 0x07; + if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM { + return match aux_csect.x_smclas() { + xcoff::XMC_PR | xcoff::XMC_GL => SymbolKind::Text, + xcoff::XMC_RO | xcoff::XMC_RW | xcoff::XMC_TD | xcoff::XMC_BS => { + SymbolKind::Data + } + xcoff::XMC_TL | xcoff::XMC_UL => SymbolKind::Tls, + xcoff::XMC_DS | xcoff::XMC_TC0 | xcoff::XMC_TC => { + // `Metadata` might be a better kind for these if we had it. + SymbolKind::Data + } + _ => SymbolKind::Unknown, + }; + } else if sym_type == xcoff::XTY_LD { + // A function entry point. Neither `Text` nor `Label` are a good fit for this. + return SymbolKind::Text; + } else if sym_type == xcoff::XTY_ER { + return SymbolKind::Unknown; + } + } + } match self.symbol.n_sclass() { - xcoff::C_FILE => SymbolKind::File, xcoff::C_NULL => SymbolKind::Null, - _ => self - .file - .section_by_index(SectionIndex((self.symbol.n_scnum() - 1) as usize)) - .map(|section| match section.kind() { - SectionKind::Data | SectionKind::UninitializedData => SymbolKind::Data, - SectionKind::UninitializedTls | SectionKind::Tls => SymbolKind::Tls, - SectionKind::Text => SymbolKind::Text, - _ => SymbolKind::Unknown, - }) - .unwrap_or(SymbolKind::Unknown), + xcoff::C_FILE => SymbolKind::File, + _ => SymbolKind::Unknown, } } @@ -407,8 +426,29 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } #[inline] - fn flags(&self) -> SymbolFlags { - SymbolFlags::None + fn flags(&self) -> SymbolFlags { + let mut x_smtyp = 0; + let mut x_smclas = 0; + let mut containing_csect = None; + if self.symbol.has_aux_csect() { + if let Ok(aux_csect) = self + .file + .symbols + .aux_csect(self.index.0, self.symbol.n_numaux() as usize) + { + x_smtyp = aux_csect.x_smtyp(); + x_smclas = aux_csect.x_smclas(); + if x_smtyp == xcoff::XTY_LD { + containing_csect = Some(SymbolIndex(aux_csect.x_scnlen() as usize)) + } + } + } + SymbolFlags::Xcoff { + n_sclass: self.symbol.n_sclass(), + x_smtyp, + x_smclas, + containing_csect, + } } } @@ -536,6 +576,27 @@ pub trait FileAux: Debug + Pod { fn x_fname(&self) -> &[u8; 8]; fn x_ftype(&self) -> u8; fn x_auxtype(&self) -> Option; + + /// Parse the x_fname field, which may be an inline string or a string table offset. + fn fname<'data, R: ReadRef<'data>>( + &'data self, + strings: StringTable<'data, R>, + ) -> Result<&'data [u8]> { + let x_fname = self.x_fname(); + if x_fname[0] == 0 { + // If the name starts with 0 then the last 4 bytes are a string table offset. + let offset = u32::from_be_bytes(x_fname[4..8].try_into().unwrap()); + strings + .get(offset) + .read_error("Invalid XCOFF symbol name offset") + } else { + // The name is inline and padded with nulls. + Ok(match memchr::memchr(b'\0', x_fname) { + Some(end) => &x_fname[..end], + None => x_fname, + }) + } + } } impl FileAux for xcoff::FileAux64 { diff --git a/vendor/object/src/write/coff.rs b/vendor/object/src/write/coff.rs index c7489d3d6..d2f7ccc64 100644 --- a/vendor/object/src/write/coff.rs +++ b/vendor/object/src/write/coff.rs @@ -37,29 +37,41 @@ impl<'a> Object<'a> { pub(crate) fn coff_section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match section { - StandardSection::Text => (&[], &b".text"[..], SectionKind::Text), - StandardSection::Data => (&[], &b".data"[..], SectionKind::Data), + 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), - StandardSection::UninitializedData => { - (&[], &b".bss"[..], SectionKind::UninitializedData) - } + | 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), + StandardSection::Tls => (&[], &b".tls$"[..], SectionKind::Data, SectionFlags::None), StandardSection::UninitializedTls => { // Unsupported section. - (&[], &[], SectionKind::UninitializedTls) + (&[], &[], SectionKind::UninitializedTls, SectionFlags::None) } StandardSection::TlsVariables => { // Unsupported section. - (&[], &[], SectionKind::TlsVariables) + (&[], &[], SectionKind::TlsVariables, SectionFlags::None) } StandardSection::Common => { // Unsupported section. - (&[], &[], SectionKind::Common) + (&[], &[], SectionKind::Common, SectionFlags::None) + } + StandardSection::GnuProperty => { + // Unsupported section. + (&[], &[], SectionKind::Note, SectionFlags::None) } } } @@ -265,7 +277,7 @@ impl<'a> Object<'a> { symtab_count += 1; match symbol.kind { SymbolKind::File => { - // Name goes in auxilary symbol records. + // Name goes in auxiliary symbol records. let aux_count = (symbol.name.len() + coff::IMAGE_SIZEOF_SYMBOL - 1) / coff::IMAGE_SIZEOF_SYMBOL; symbol_offsets[index].aux_count = aux_count as u8; @@ -355,7 +367,9 @@ impl<'a> Object<'a> { | coff::IMAGE_SCN_MEM_READ | coff::IMAGE_SCN_MEM_WRITE } - SectionKind::ReadOnlyData | SectionKind::ReadOnlyString => { + SectionKind::ReadOnlyData + | SectionKind::ReadOnlyDataWithRel + | SectionKind::ReadOnlyString => { coff::IMAGE_SCN_CNT_INITIALIZED_DATA | coff::IMAGE_SCN_MEM_READ } SectionKind::Debug | SectionKind::Other | SectionKind::OtherString => { @@ -573,11 +587,11 @@ impl<'a> Object<'a> { let section_number = match symbol.section { SymbolSection::None => { debug_assert_eq!(symbol.kind, SymbolKind::File); - coff::IMAGE_SYM_DEBUG + coff::IMAGE_SYM_DEBUG as u16 } - SymbolSection::Undefined => coff::IMAGE_SYM_UNDEFINED, - SymbolSection::Absolute => coff::IMAGE_SYM_ABSOLUTE, - SymbolSection::Common => coff::IMAGE_SYM_UNDEFINED, + 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 { @@ -587,7 +601,7 @@ impl<'a> Object<'a> { }; let storage_class = match symbol.kind { SymbolKind::File => { - // Name goes in auxilary symbol records. + // Name goes in auxiliary symbol records. name = b".file"; coff::IMAGE_SYM_CLASS_FILE } @@ -640,7 +654,7 @@ impl<'a> Object<'a> { let mut coff_symbol = coff::ImageSymbol { name: [0; 8], value: U32Bytes::new(LE, value), - section_number: U16Bytes::new(LE, section_number as u16), + section_number: U16Bytes::new(LE, section_number), typ: U16Bytes::new(LE, typ), storage_class, number_of_aux_symbols, diff --git a/vendor/object/src/write/elf/object.rs b/vendor/object/src/write/elf/object.rs index 068ada6bd..8b9eadaf8 100644 --- a/vendor/object/src/write/elf/object.rs +++ b/vendor/object/src/write/elf/object.rs @@ -1,10 +1,10 @@ use alloc::vec::Vec; -use crate::elf; 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 { @@ -27,33 +27,88 @@ struct SymbolOffsets { str_id: Option, } +// 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) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match section { - StandardSection::Text => (&[], &b".text"[..], SectionKind::Text), - StandardSection::Data => (&[], &b".data"[..], SectionKind::Data), - StandardSection::ReadOnlyData | StandardSection::ReadOnlyString => { - (&[], &b".rodata"[..], SectionKind::ReadOnlyData) - } - StandardSection::ReadOnlyDataWithRel => (&[], b".data.rel.ro", SectionKind::Data), - StandardSection::UninitializedData => { - (&[], &b".bss"[..], SectionKind::UninitializedData) - } - StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls), - StandardSection::UninitializedTls => { - (&[], &b".tbss"[..], SectionKind::UninitializedTls) - } + 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) + (&[], &[], SectionKind::TlsVariables, SectionFlags::None) } StandardSection::Common => { // Unsupported section. - (&[], &[], SectionKind::Common) + (&[], &[], SectionKind::Common, SectionFlags::None) } + StandardSection::GnuProperty => ( + &[], + &b".note.gnu.property"[..], + SectionKind::Note, + SectionFlags::Elf { + sh_flags: u64::from(elf::SHF_ALLOC), + }, + ), } } @@ -151,6 +206,13 @@ impl<'a> Object<'a> { } } + 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()?; @@ -174,11 +236,7 @@ impl<'a> Object<'a> { .collect(); // Start calculating offsets of everything. - let is_64 = match self.architecture.address_size().unwrap() { - AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false, - AddressSize::U64 => true, - }; - let mut writer = Writer::new(self.endian, is_64, buffer); + let mut writer = Writer::new(self.endian, self.elf_is_64(), buffer); writer.reserve_file_header(); // Calculate size of section data. @@ -321,12 +379,9 @@ impl<'a> Object<'a> { } } for (index, section) in self.sections.iter().enumerate() { - let len = section.data.len(); - if len != 0 { - writer.write_align(section.align as usize); - debug_assert_eq!(section_offsets[index].offset, writer.len()); - writer.write(§ion.data); - } + writer.write_align(section.align as usize); + debug_assert_eq!(section_offsets[index].offset, writer.len()); + writer.write(§ion.data); } // Write symbols. @@ -767,7 +822,9 @@ impl<'a> Object<'a> { } else { match section.kind { SectionKind::Text => elf::SHF_ALLOC | elf::SHF_EXECINSTR, - SectionKind::Data => elf::SHF_ALLOC | elf::SHF_WRITE, + 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, diff --git a/vendor/object/src/write/elf/writer.rs b/vendor/object/src/write/elf/writer.rs index 3c9d85a12..975092496 100644 --- a/vendor/object/src/write/elf/writer.rs +++ b/vendor/object/src/write/elf/writer.rs @@ -5,6 +5,7 @@ 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}; @@ -113,6 +114,10 @@ pub struct Writer<'a> { gnu_verneed_count: u16, gnu_verneed_remaining: u16, gnu_vernaux_remaining: u16, + + gnu_attributes_str_id: Option, + gnu_attributes_offset: usize, + gnu_attributes_size: usize, } impl<'a> Writer<'a> { @@ -198,6 +203,10 @@ impl<'a> Writer<'a> { 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, } } @@ -216,10 +225,9 @@ impl<'a> Writer<'a> { /// /// Returns the aligned offset of the start of the range. pub fn reserve(&mut self, len: usize, align_start: usize) -> usize { - if len == 0 { - return self.len; + if align_start > 1 { + self.len = util::align(self.len, align_start); } - self.len = util::align(self.len, align_start); let offset = self.len; self.len += len; offset @@ -227,7 +235,9 @@ impl<'a> Writer<'a> { /// Write alignment padding bytes. pub fn write_align(&mut self, align_start: usize) { - util::write_align(self.buffer, align_start); + if align_start > 1 { + util::write_align(self.buffer, align_start); + } } /// Write data. @@ -1735,6 +1745,54 @@ impl<'a> Writer<'a> { }); } + /// 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. @@ -1857,6 +1915,136 @@ impl<'a> Writer<'a> { 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, + 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 { + debug_assert_eq!(self.subsection_offset, 0); + debug_assert_eq!(self.subsubsection_offset, 0); + self.data + } } /// Native endian version of [`elf::FileHeader64`]. diff --git a/vendor/object/src/write/macho.rs b/vendor/object/src/write/macho.rs index 8ef722fae..0e082b69d 100644 --- a/vendor/object/src/write/macho.rs +++ b/vendor/object/src/write/macho.rs @@ -22,6 +22,42 @@ struct SymbolOffsets { str_id: Option, } +/// 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::>(); + debug_assert!(sz <= u32::MAX as usize); + sz as u32 + } +} + +// Public methods. +impl<'a> Object<'a> { + /// 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 { @@ -44,38 +80,72 @@ impl<'a> Object<'a> { pub(crate) fn macho_section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match section { - StandardSection::Text => (&b"__TEXT"[..], &b"__text"[..], SectionKind::Text), - StandardSection::Data => (&b"__DATA"[..], &b"__data"[..], SectionKind::Data), - StandardSection::ReadOnlyData => { - (&b"__TEXT"[..], &b"__const"[..], SectionKind::ReadOnlyData) - } - StandardSection::ReadOnlyDataWithRel => { - (&b"__DATA"[..], &b"__const"[..], SectionKind::ReadOnlyData) - } + 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::Tls => (&b"__DATA"[..], &b"__thread_data"[..], SectionKind::Tls), 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), + StandardSection::Common => ( + &b"__DATA"[..], + &b"__common"[..], + SectionKind::Common, + SectionFlags::None, + ), + StandardSection::GnuProperty => { + // Unsupported section. + (&[], &[], SectionKind::Note, SectionFlags::None) + } } } @@ -211,6 +281,12 @@ impl<'a> Object<'a> { let mut ncmds = 0; let command_offset = offset; + let build_version_offset = offset; + if let Some(version) = &self.macho_build_version { + offset += version.cmdsize() as usize; + ncmds += 1; + } + // Calculate size of segment command and section headers. let segment_command_offset = offset; let segment_command_len = @@ -271,16 +347,8 @@ impl<'a> Object<'a> { // // Since we don't actually emit the symbol kind, we validate it here too. match symbol.kind { - SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls => {} + SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls | SymbolKind::Unknown => {} SymbolKind::File | SymbolKind::Section => continue, - SymbolKind::Unknown => { - if symbol.section != SymbolSection::Undefined { - return Err(Error(format!( - "defined symbol `{}` with unknown kind", - symbol.name().unwrap_or(""), - ))); - } - } SymbolKind::Null | SymbolKind::Label => { return Err(Error(format!( "unimplemented symbol `{}` kind {:?}", @@ -330,6 +398,9 @@ impl<'a> Object<'a> { let (cputype, cpusubtype) = match self.architecture { Architecture::Arm => (macho::CPU_TYPE_ARM, macho::CPU_SUBTYPE_ARM_ALL), Architecture::Aarch64 => (macho::CPU_TYPE_ARM64, macho::CPU_SUBTYPE_ARM64_ALL), + Architecture::Aarch64_Ilp32 => { + (macho::CPU_TYPE_ARM64_32, macho::CPU_SUBTYPE_ARM64_32_V8) + } Architecture::I386 => (macho::CPU_TYPE_X86, macho::CPU_SUBTYPE_I386_ALL), Architecture::X86_64 => (macho::CPU_TYPE_X86_64, macho::CPU_SUBTYPE_X86_64_ALL), Architecture::PowerPc => (macho::CPU_TYPE_POWERPC, macho::CPU_SUBTYPE_POWERPC_ALL), @@ -358,6 +429,18 @@ impl<'a> Object<'a> { }, ); + 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 segment command. debug_assert_eq!(segment_command_offset, buffer.len()); macho.write_segment_command( @@ -406,7 +489,7 @@ impl<'a> Object<'a> { macho::S_ATTR_PURE_INSTRUCTIONS | macho::S_ATTR_SOME_INSTRUCTIONS } SectionKind::Data => 0, - SectionKind::ReadOnlyData => 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, @@ -592,39 +675,48 @@ impl<'a> Object<'a> { return Err(Error(format!("unimplemented relocation {:?}", reloc))); } }, - Architecture::Aarch64 => match (reloc.kind, reloc.encoding, reloc.addend) { - (RelocationKind::Absolute, RelocationEncoding::Generic, 0) => { - (false, macho::ARM64_RELOC_UNSIGNED) - } - (RelocationKind::Relative, RelocationEncoding::AArch64Call, 0) => { - (true, macho::ARM64_RELOC_BRANCH26) - } - // Non-zero addend, so we have to encode the addend separately - (RelocationKind::Relative, RelocationEncoding::AArch64Call, value) => { - // first emit the BR26 relocation - let reloc_info = macho::RelocationInfo { - r_address: reloc.offset as u32, - r_symbolnum, - r_pcrel: true, - r_length, - r_extern: true, - r_type: macho::ARM64_RELOC_BRANCH26, - }; - buffer.write(&reloc_info.relocation(endian)); - - // set up a separate relocation for the addend - r_symbolnum = value as u32; - (false, macho::ARM64_RELOC_ADDEND) - } - ( - RelocationKind::MachO { value, relative }, - RelocationEncoding::Generic, - 0, - ) => (relative, value), - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); + Architecture::Aarch64 | Architecture::Aarch64_Ilp32 => { + match (reloc.kind, reloc.encoding, reloc.addend) { + (RelocationKind::Absolute, RelocationEncoding::Generic, 0) => { + (false, macho::ARM64_RELOC_UNSIGNED) + } + (RelocationKind::Relative, RelocationEncoding::AArch64Call, 0) => { + (true, macho::ARM64_RELOC_BRANCH26) + } + // Non-zero addend, so we have to encode the addend separately + ( + RelocationKind::Relative, + RelocationEncoding::AArch64Call, + value, + ) => { + // first emit the BR26 relocation + let reloc_info = macho::RelocationInfo { + r_address: reloc.offset as u32, + r_symbolnum, + r_pcrel: true, + r_length, + r_extern: true, + r_type: macho::ARM64_RELOC_BRANCH26, + }; + buffer.write(&reloc_info.relocation(endian)); + + // set up a separate relocation for the addend + r_symbolnum = value as u32; + (false, macho::ARM64_RELOC_ADDEND) + } + ( + RelocationKind::MachO { value, relative }, + RelocationEncoding::Generic, + 0, + ) => (relative, value), + _ => { + return Err(Error(format!( + "unimplemented relocation {:?}", + reloc + ))); + } } - }, + } _ => { if let RelocationKind::MachO { value, relative } = reloc.kind { (relative, value) diff --git a/vendor/object/src/write/mod.rs b/vendor/object/src/write/mod.rs index aa4980b1e..711ff16d2 100644 --- a/vendor/object/src/write/mod.rs +++ b/vendor/object/src/write/mod.rs @@ -25,10 +25,15 @@ 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; @@ -41,7 +46,7 @@ pub struct Error(String); impl fmt::Display for Error { #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.0) } } @@ -52,7 +57,7 @@ impl error::Error for Error {} /// The result type used within the write module. pub type Result = result::Result; -/// A writable object file. +/// A writable relocatable object file. #[derive(Debug)] pub struct Object<'a> { format: BinaryFormat, @@ -70,6 +75,8 @@ pub struct Object<'a> { pub mangling: Mangling, /// Mach-O "_tlv_bootstrap" symbol. tlv_bootstrap: Option, + #[cfg(feature = "macho")] + macho_build_version: Option, } impl<'a> Object<'a> { @@ -88,6 +95,8 @@ impl<'a> Object<'a> { flags: FileFlags::None, mangling: Mangling::default(format, architecture), tlv_bootstrap: None, + #[cfg(feature = "macho")] + macho_build_version: None, } } @@ -171,8 +180,10 @@ impl<'a> Object<'a> { .get(§ion) .cloned() .unwrap_or_else(|| { - let (segment, name, kind) = self.section_info(section); - self.add_section(segment.to_vec(), name.to_vec(), kind) + 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 }) } @@ -197,7 +208,7 @@ impl<'a> Object<'a> { let section = &self.sections[id.0]; for standard_section in StandardSection::all() { if !self.standard_sections.contains_key(standard_section) { - let (segment, name, kind) = self.section_info(*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); } @@ -210,7 +221,7 @@ impl<'a> Object<'a> { fn section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match self.format { #[cfg(feature = "coff")] BinaryFormat::Coff => self.coff_section_info(section), @@ -218,6 +229,8 @@ impl<'a> Object<'a> { 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!(), } } @@ -234,8 +247,10 @@ impl<'a> Object<'a> { self.set_subsections_via_symbols(); self.section_id(section) } else { - let (segment, name, kind) = self.subsection_info(section, name); - self.add_section(segment.to_vec(), name, kind) + 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) @@ -243,7 +258,7 @@ impl<'a> Object<'a> { fn has_subsections_via_symbols(&self) -> bool { match self.format { - BinaryFormat::Coff | BinaryFormat::Elf => false, + BinaryFormat::Coff | BinaryFormat::Elf | BinaryFormat::Xcoff => false, BinaryFormat::MachO => true, _ => unimplemented!(), } @@ -261,10 +276,10 @@ impl<'a> Object<'a> { &self, section: StandardSection, value: &[u8], - ) -> (&'static [u8], Vec, SectionKind) { - let (segment, section, kind) = self.section_info(section); + ) -> (&'static [u8], Vec, SectionKind, SectionFlags) { + let (segment, section, kind, flags) = self.section_info(section); let name = self.subsection_name(section, value); - (segment, name, kind) + (segment, name, kind, flags) } #[allow(unused_variables)] @@ -506,6 +521,8 @@ impl<'a> Object<'a> { 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 { @@ -574,6 +591,8 @@ impl<'a> Object<'a> { 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!(), } } @@ -607,6 +626,8 @@ pub enum StandardSection { TlsVariables, /// Common data. Only supported for Mach-O. Common, + /// Notes for GNU properties. Only supported for ELF. + GnuProperty, } impl StandardSection { @@ -615,15 +636,15 @@ impl StandardSection { match self { StandardSection::Text => SectionKind::Text, StandardSection::Data => SectionKind::Data, - StandardSection::ReadOnlyData | StandardSection::ReadOnlyDataWithRel => { - SectionKind::ReadOnlyData - } + 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, } } @@ -640,6 +661,7 @@ impl StandardSection { StandardSection::UninitializedTls, StandardSection::TlsVariables, StandardSection::Common, + StandardSection::GnuProperty, ] } } @@ -718,7 +740,7 @@ impl<'a> Section<'a> { offset as u64 } - /// Append unitialized data to a section. + /// 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 { @@ -733,7 +755,7 @@ impl<'a> Section<'a> { self.size = offset; } self.size += size; - offset as u64 + offset } /// Returns the section as-built so far. @@ -807,7 +829,7 @@ pub struct Symbol { /// The section containing the symbol. pub section: SymbolSection, /// Symbol flags that are specific to each file format. - pub flags: SymbolFlags, + pub flags: SymbolFlags, } impl Symbol { @@ -894,6 +916,8 @@ pub enum Mangling { Elf, /// Mach-O symbol mangling. MachO, + /// Xcoff symbol mangling. + Xcoff, } impl Mangling { @@ -904,6 +928,7 @@ impl Mangling { (BinaryFormat::Coff, _) => Mangling::Coff, (BinaryFormat::Elf, _) => Mangling::Elf, (BinaryFormat::MachO, _) => Mangling::MachO, + (BinaryFormat::Xcoff, _) => Mangling::Xcoff, _ => Mangling::None, } } @@ -911,7 +936,7 @@ impl Mangling { /// Return the prefix to use for global symbols. pub fn global_prefix(self) -> Option { match self { - Mangling::None | Mangling::Elf | Mangling::Coff => None, + Mangling::None | Mangling::Elf | Mangling::Coff | Mangling::Xcoff => None, Mangling::CoffI386 | Mangling::MachO => Some(b'_'), } } diff --git a/vendor/object/src/write/string.rs b/vendor/object/src/write/string.rs index 3bdfcccaa..b23274a0a 100644 --- a/vendor/object/src/write/string.rs +++ b/vendor/object/src/write/string.rs @@ -5,7 +5,7 @@ type IndexSet = indexmap::IndexSet; #[cfg(not(feature = "std"))] type IndexSet = indexmap::IndexSet; -/// An identifer for an entry in a string table. +/// An identifier for an entry in a string table. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct StringId(usize); diff --git a/vendor/object/src/write/util.rs b/vendor/object/src/write/util.rs index 51bc3515f..b05b14d92 100644 --- a/vendor/object/src/write/util.rs +++ b/vendor/object/src/write/util.rs @@ -164,6 +164,56 @@ impl<'a> BytesMut for &'a mut [u8] { } } +/// 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, 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, 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) } diff --git a/vendor/object/src/write/xcoff.rs b/vendor/object/src/write/xcoff.rs new file mode 100644 index 000000000..6c9a80384 --- /dev/null +++ b/vendor/object/src/write/xcoff.rs @@ -0,0 +1,556 @@ +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, + 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, mut 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::(), + mem::size_of::(), + mem::size_of::(), + mem::size_of::(), + ) + } else { + ( + mem::size_of::(), + mem::size_of::(), + mem::size_of::(), + mem::size_of::(), + ) + }; + + // 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 index 4724f8ef8..038698926 100644 --- a/vendor/object/src/xcoff.rs +++ b/vendor/object/src/xcoff.rs @@ -770,7 +770,7 @@ pub struct DwarfAux64 { pub x_nreloc: U64, /// Reserved. pub pad: u8, - /// Contains _AUX_SECT; Type of Auxillary entry. + /// Contains _AUX_SECT; Type of Auxiliary entry. pub x_auxtype: u8, } -- cgit v1.2.3