Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/object/src/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 209 kB image not shown  

SSL elf.rs   Sprache: unbekannt

 
//! ELF definitions.
//!
//! These definitions are independent of read/write support, although we do implement
//! some traits useful for those.
//!
//! This module is the equivalent of /usr/include/elf.h, and is based heavily on it.

#![allow(missing_docs)]
#![allow(clippy::identity_op)]

use crate::endian::{Endian, U32Bytes, U64Bytes, I32, I64, U16, U32, U64};
use crate::pod::Pod;

/// The header at the start of every 32-bit ELF file.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FileHeader32<E: Endian> {
    /// Magic number and other information.
    pub e_ident: Ident,
    /// Object file type. One of the `ET_*` constants.
    pub e_type: U16<E>,
    /// Architecture. One of the `EM_*` constants.
    pub e_machine: U16<E>,
    /// Object file version. Must be `EV_CURRENT`.
    pub e_version: U32<E>,
    /// Entry point virtual address.
    pub e_entry: U32<E>,
    /// Program header table file offset.
    pub e_phoff: U32<E>,
    /// Section header table file offset.
    pub e_shoff: U32<E>,
    /// Processor-specific flags.
    ///
    /// A combination of the `EF_*` constants.
    pub e_flags: U32<E>,
    /// Size in bytes of this header.
    pub e_ehsize: U16<E>,
    /// Program header table entry size.
    pub e_phentsize: U16<E>,
    /// Program header table entry count.
    ///
    /// If the count is greater than or equal to `PN_XNUM` then this field is set to
    /// `PN_XNUM` and the count is stored in the `sh_info` field of section 0.
    pub e_phnum: U16<E>,
    /// Section header table entry size.
    pub e_shentsize: U16<E>,
    /// Section header table entry count.
    ///
    /// If the count is greater than or equal to `SHN_LORESERVE` then this field is set to
    /// `0` and the count is stored in the `sh_size` field of section 0.
    /// first section header.
    pub e_shnum: U16<E>,
    /// Section header string table index.
    ///
    /// If the index is greater than or equal to `SHN_LORESERVE` then this field is set to
    /// `SHN_XINDEX` and the index is stored in the `sh_link` field of section 0.
    pub e_shstrndx: U16<E>,
}

/// The header at the start of every 64-bit ELF file.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FileHeader64<E: Endian> {
    /// Magic number and other information.
    pub e_ident: Ident,
    /// Object file type. One of the `ET_*` constants.
    pub e_type: U16<E>,
    /// Architecture. One of the `EM_*` constants.
    pub e_machine: U16<E>,
    /// Object file version. Must be `EV_CURRENT`.
    pub e_version: U32<E>,
    /// Entry point virtual address.
    pub e_entry: U64<E>,
    /// Program header table file offset.
    pub e_phoff: U64<E>,
    /// Section header table file offset.
    pub e_shoff: U64<E>,
    /// Processor-specific flags.
    ///
    /// A combination of the `EF_*` constants.
    pub e_flags: U32<E>,
    /// Size in bytes of this header.
    pub e_ehsize: U16<E>,
    /// Program header table entry size.
    pub e_phentsize: U16<E>,
    /// Program header table entry count.
    ///
    /// If the count is greater than or equal to `PN_XNUM` then this field is set to
    /// `PN_XNUM` and the count is stored in the `sh_info` field of section 0.
    pub e_phnum: U16<E>,
    /// Section header table entry size.
    pub e_shentsize: U16<E>,
    /// Section header table entry count.
    ///
    /// If the count is greater than or equal to `SHN_LORESERVE` then this field is set to
    /// `0` and the count is stored in the `sh_size` field of section 0.
    /// first section header.
    pub e_shnum: U16<E>,
    /// Section header string table index.
    ///
    /// If the index is greater than or equal to `SHN_LORESERVE` then this field is set to
    /// `SHN_XINDEX` and the index is stored in the `sh_link` field of section 0.
    pub e_shstrndx: U16<E>,
}

/// Magic number and other information.
///
/// Contained in the file header.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Ident {
    /// Magic number. Must be `ELFMAG`.
    pub magic: [u8; 4],
    /// File class. One of the `ELFCLASS*` constants.
    pub class: u8,
    /// Data encoding. One of the `ELFDATA*` constants.
    pub data: u8,
    /// ELF version. Must be `EV_CURRENT`.
    pub version: u8,
    /// OS ABI identification. One of the `ELFOSABI*` constants.
    pub os_abi: u8,
    /// ABI version.
    ///
    /// The meaning of this field depends on the `os_abi` value.
    pub abi_version: u8,
    /// Padding bytes.
    pub padding: [u8; 7],
}

/// File identification bytes stored in `Ident::magic`.
pub const ELFMAG: [u8; 4] = [0x7f, b'E', b'L', b'F'];

// Values for `Ident::class`.
/// Invalid class.
pub const ELFCLASSNONE: u8 = 0;
/// 32-bit object.
pub const ELFCLASS32: u8 = 1;
/// 64-bit object.
pub const ELFCLASS64: u8 = 2;

// Values for `Ident::data`.
/// Invalid data encoding.
pub const ELFDATANONE: u8 = 0;
/// 2's complement, little endian.
pub const ELFDATA2LSB: u8 = 1;
/// 2's complement, big endian.
pub const ELFDATA2MSB: u8 = 2;

// Values for `Ident::os_abi`.
/// UNIX System V ABI.
pub const ELFOSABI_NONE: u8 = 0;
/// UNIX System V ABI.
///
/// Alias.
pub const ELFOSABI_SYSV: u8 = 0;
/// HP-UX.
pub const ELFOSABI_HPUX: u8 = 1;
/// NetBSD.
pub const ELFOSABI_NETBSD: u8 = 2;
/// Object uses GNU ELF extensions.
pub const ELFOSABI_GNU: u8 = 3;
/// Object uses GNU ELF extensions.
///
/// Compatibility alias.
pub const ELFOSABI_LINUX: u8 = ELFOSABI_GNU;
/// GNU/Hurd.
pub const ELFOSABI_HURD: u8 = 4;
/// Sun Solaris.
pub const ELFOSABI_SOLARIS: u8 = 6;
/// IBM AIX.
pub const ELFOSABI_AIX: u8 = 7;
/// SGI Irix.
pub const ELFOSABI_IRIX: u8 = 8;
/// FreeBSD.
pub const ELFOSABI_FREEBSD: u8 = 9;
/// Compaq TRU64 UNIX.
pub const ELFOSABI_TRU64: u8 = 10;
/// Novell Modesto.
pub const ELFOSABI_MODESTO: u8 = 11;
/// OpenBSD.
pub const ELFOSABI_OPENBSD: u8 = 12;
/// OpenVMS.
pub const ELFOSABI_OPENVMS: u8 = 13;
/// Hewlett-Packard Non-Stop Kernel.
pub const ELFOSABI_NSK: u8 = 14;
/// AROS
pub const ELFOSABI_AROS: u8 = 15;
/// FenixOS
pub const ELFOSABI_FENIXOS: u8 = 16;
/// Nuxi CloudABI
pub const ELFOSABI_CLOUDABI: u8 = 17;
/// ARM EABI.
pub const ELFOSABI_ARM_AEABI: u8 = 64;
/// ARM.
pub const ELFOSABI_ARM: u8 = 97;
/// Standalone (embedded) application.
pub const ELFOSABI_STANDALONE: u8 = 255;

// Values for `FileHeader*::e_type`.
/// No file type.
pub const ET_NONE: u16 = 0;
/// Relocatable file.
pub const ET_REL: u16 = 1;
/// Executable file.
pub const ET_EXEC: u16 = 2;
/// Shared object file.
pub const ET_DYN: u16 = 3;
/// Core file.
pub const ET_CORE: u16 = 4;
/// OS-specific range start.
pub const ET_LOOS: u16 = 0xfe00;
/// OS-specific range end.
pub const ET_HIOS: u16 = 0xfeff;
/// Processor-specific range start.
pub const ET_LOPROC: u16 = 0xff00;
/// Processor-specific range end.
pub const ET_HIPROC: u16 = 0xffff;

// Values for `FileHeader*::e_machine`.
/// No machine
pub const EM_NONE: u16 = 0;
/// AT&T WE 32100
pub const EM_M32: u16 = 1;
/// SUN SPARC
pub const EM_SPARC: u16 = 2;
/// Intel 80386
pub const EM_386: u16 = 3;
/// Motorola m68k family
pub const EM_68K: u16 = 4;
/// Motorola m88k family
pub const EM_88K: u16 = 5;
/// Intel MCU
pub const EM_IAMCU: u16 = 6;
/// Intel 80860
pub const EM_860: u16 = 7;
/// MIPS R3000 big-endian
pub const EM_MIPS: u16 = 8;
/// IBM System/370
pub const EM_S370: u16 = 9;
/// MIPS R3000 little-endian
pub const EM_MIPS_RS3_LE: u16 = 10;
/// HPPA
pub const EM_PARISC: u16 = 15;
/// Fujitsu VPP500
pub const EM_VPP500: u16 = 17;
/// Sun's "v8plus"
pub const EM_SPARC32PLUS: u16 = 18;
/// Intel 80960
pub const EM_960: u16 = 19;
/// PowerPC
pub const EM_PPC: u16 = 20;
/// PowerPC 64-bit
pub const EM_PPC64: u16 = 21;
/// IBM S390
pub const EM_S390: u16 = 22;
/// IBM SPU/SPC
pub const EM_SPU: u16 = 23;
/// NEC V800 series
pub const EM_V800: u16 = 36;
/// Fujitsu FR20
pub const EM_FR20: u16 = 37;
/// TRW RH-32
pub const EM_RH32: u16 = 38;
/// Motorola RCE
pub const EM_RCE: u16 = 39;
/// ARM
pub const EM_ARM: u16 = 40;
/// Digital Alpha
pub const EM_FAKE_ALPHA: u16 = 41;
/// Hitachi SH
pub const EM_SH: u16 = 42;
/// SPARC v9 64-bit
pub const EM_SPARCV9: u16 = 43;
/// Siemens Tricore
pub const EM_TRICORE: u16 = 44;
/// Argonaut RISC Core
pub const EM_ARC: u16 = 45;
/// Hitachi H8/300
pub const EM_H8_300: u16 = 46;
/// Hitachi H8/300H
pub const EM_H8_300H: u16 = 47;
/// Hitachi H8S
pub const EM_H8S: u16 = 48;
/// Hitachi H8/500
pub const EM_H8_500: u16 = 49;
/// Intel Merced
pub const EM_IA_64: u16 = 50;
/// Stanford MIPS-X
pub const EM_MIPS_X: u16 = 51;
/// Motorola Coldfire
pub const EM_COLDFIRE: u16 = 52;
/// Motorola M68HC12
pub const EM_68HC12: u16 = 53;
/// Fujitsu MMA Multimedia Accelerator
pub const EM_MMA: u16 = 54;
/// Siemens PCP
pub const EM_PCP: u16 = 55;
/// Sony nCPU embeeded RISC
pub const EM_NCPU: u16 = 56;
/// Denso NDR1 microprocessor
pub const EM_NDR1: u16 = 57;
/// Motorola Start*Core processor
pub const EM_STARCORE: u16 = 58;
/// Toyota ME16 processor
pub const EM_ME16: u16 = 59;
/// STMicroelectronic ST100 processor
pub const EM_ST100: u16 = 60;
/// Advanced Logic Corp. Tinyj emb.fam
pub const EM_TINYJ: u16 = 61;
/// AMD x86-64 architecture
pub const EM_X86_64: u16 = 62;
/// Sony DSP Processor
pub const EM_PDSP: u16 = 63;
/// Digital PDP-10
pub const EM_PDP10: u16 = 64;
/// Digital PDP-11
pub const EM_PDP11: u16 = 65;
/// Siemens FX66 microcontroller
pub const EM_FX66: u16 = 66;
/// STMicroelectronics ST9+ 8/16 mc
pub const EM_ST9PLUS: u16 = 67;
/// STmicroelectronics ST7 8 bit mc
pub const EM_ST7: u16 = 68;
/// Motorola MC68HC16 microcontroller
pub const EM_68HC16: u16 = 69;
/// Motorola MC68HC11 microcontroller
pub const EM_68HC11: u16 = 70;
/// Motorola MC68HC08 microcontroller
pub const EM_68HC08: u16 = 71;
/// Motorola MC68HC05 microcontroller
pub const EM_68HC05: u16 = 72;
/// Silicon Graphics SVx
pub const EM_SVX: u16 = 73;
/// STMicroelectronics ST19 8 bit mc
pub const EM_ST19: u16 = 74;
/// Digital VAX
pub const EM_VAX: u16 = 75;
/// Axis Communications 32-bit emb.proc
pub const EM_CRIS: u16 = 76;
/// Infineon Technologies 32-bit emb.proc
pub const EM_JAVELIN: u16 = 77;
/// Element 14 64-bit DSP Processor
pub const EM_FIREPATH: u16 = 78;
/// LSI Logic 16-bit DSP Processor
pub const EM_ZSP: u16 = 79;
/// Donald Knuth's educational 64-bit proc
pub const EM_MMIX: u16 = 80;
/// Harvard University machine-independent object files
pub const EM_HUANY: u16 = 81;
/// SiTera Prism
pub const EM_PRISM: u16 = 82;
/// Atmel AVR 8-bit microcontroller
pub const EM_AVR: u16 = 83;
/// Fujitsu FR30
pub const EM_FR30: u16 = 84;
/// Mitsubishi D10V
pub const EM_D10V: u16 = 85;
/// Mitsubishi D30V
pub const EM_D30V: u16 = 86;
/// NEC v850
pub const EM_V850: u16 = 87;
/// Mitsubishi M32R
pub const EM_M32R: u16 = 88;
/// Matsushita MN10300
pub const EM_MN10300: u16 = 89;
/// Matsushita MN10200
pub const EM_MN10200: u16 = 90;
/// picoJava
pub const EM_PJ: u16 = 91;
/// OpenRISC 32-bit embedded processor
pub const EM_OPENRISC: u16 = 92;
/// ARC International ARCompact
pub const EM_ARC_COMPACT: u16 = 93;
/// Tensilica Xtensa Architecture
pub const EM_XTENSA: u16 = 94;
/// Alphamosaic VideoCore
pub const EM_VIDEOCORE: u16 = 95;
/// Thompson Multimedia General Purpose Proc
pub const EM_TMM_GPP: u16 = 96;
/// National Semi. 32000
pub const EM_NS32K: u16 = 97;
/// Tenor Network TPC
pub const EM_TPC: u16 = 98;
/// Trebia SNP 1000
pub const EM_SNP1K: u16 = 99;
/// STMicroelectronics ST200
pub const EM_ST200: u16 = 100;
/// Ubicom IP2xxx
pub const EM_IP2K: u16 = 101;
/// MAX processor
pub const EM_MAX: u16 = 102;
/// National Semi. CompactRISC
pub const EM_CR: u16 = 103;
/// Fujitsu F2MC16
pub const EM_F2MC16: u16 = 104;
/// Texas Instruments msp430
pub const EM_MSP430: u16 = 105;
/// Analog Devices Blackfin DSP
pub const EM_BLACKFIN: u16 = 106;
/// Seiko Epson S1C33 family
pub const EM_SE_C33: u16 = 107;
/// Sharp embedded microprocessor
pub const EM_SEP: u16 = 108;
/// Arca RISC
pub const EM_ARCA: u16 = 109;
/// PKU-Unity & MPRC Peking Uni. mc series
pub const EM_UNICORE: u16 = 110;
/// eXcess configurable cpu
pub const EM_EXCESS: u16 = 111;
/// Icera Semi. Deep Execution Processor
pub const EM_DXP: u16 = 112;
/// Altera Nios II
pub const EM_ALTERA_NIOS2: u16 = 113;
/// National Semi. CompactRISC CRX
pub const EM_CRX: u16 = 114;
/// Motorola XGATE
pub const EM_XGATE: u16 = 115;
/// Infineon C16x/XC16x
pub const EM_C166: u16 = 116;
/// Renesas M16C
pub const EM_M16C: u16 = 117;
/// Microchip Technology dsPIC30F
pub const EM_DSPIC30F: u16 = 118;
/// Freescale Communication Engine RISC
pub const EM_CE: u16 = 119;
/// Renesas M32C
pub const EM_M32C: u16 = 120;
/// Altium TSK3000
pub const EM_TSK3000: u16 = 131;
/// Freescale RS08
pub const EM_RS08: u16 = 132;
/// Analog Devices SHARC family
pub const EM_SHARC: u16 = 133;
/// Cyan Technology eCOG2
pub const EM_ECOG2: u16 = 134;
/// Sunplus S+core7 RISC
pub const EM_SCORE7: u16 = 135;
/// New Japan Radio (NJR) 24-bit DSP
pub const EM_DSP24: u16 = 136;
/// Broadcom VideoCore III
pub const EM_VIDEOCORE3: u16 = 137;
/// RISC for Lattice FPGA
pub const EM_LATTICEMICO32: u16 = 138;
/// Seiko Epson C17
pub const EM_SE_C17: u16 = 139;
/// Texas Instruments TMS320C6000 DSP
pub const EM_TI_C6000: u16 = 140;
/// Texas Instruments TMS320C2000 DSP
pub const EM_TI_C2000: u16 = 141;
/// Texas Instruments TMS320C55x DSP
pub const EM_TI_C5500: u16 = 142;
/// Texas Instruments App. Specific RISC
pub const EM_TI_ARP32: u16 = 143;
/// Texas Instruments Prog. Realtime Unit
pub const EM_TI_PRU: u16 = 144;
/// STMicroelectronics 64bit VLIW DSP
pub const EM_MMDSP_PLUS: u16 = 160;
/// Cypress M8C
pub const EM_CYPRESS_M8C: u16 = 161;
/// Renesas R32C
pub const EM_R32C: u16 = 162;
/// NXP Semi. TriMedia
pub const EM_TRIMEDIA: u16 = 163;
/// QUALCOMM Hexagon
pub const EM_HEXAGON: u16 = 164;
/// Intel 8051 and variants
pub const EM_8051: u16 = 165;
/// STMicroelectronics STxP7x
pub const EM_STXP7X: u16 = 166;
/// Andes Tech. compact code emb. RISC
pub const EM_NDS32: u16 = 167;
/// Cyan Technology eCOG1X
pub const EM_ECOG1X: u16 = 168;
/// Dallas Semi. MAXQ30 mc
pub const EM_MAXQ30: u16 = 169;
/// New Japan Radio (NJR) 16-bit DSP
pub const EM_XIMO16: u16 = 170;
/// M2000 Reconfigurable RISC
pub const EM_MANIK: u16 = 171;
/// Cray NV2 vector architecture
pub const EM_CRAYNV2: u16 = 172;
/// Renesas RX
pub const EM_RX: u16 = 173;
/// Imagination Tech. META
pub const EM_METAG: u16 = 174;
/// MCST Elbrus
pub const EM_MCST_ELBRUS: u16 = 175;
/// Cyan Technology eCOG16
pub const EM_ECOG16: u16 = 176;
/// National Semi. CompactRISC CR16
pub const EM_CR16: u16 = 177;
/// Freescale Extended Time Processing Unit
pub const EM_ETPU: u16 = 178;
/// Infineon Tech. SLE9X
pub const EM_SLE9X: u16 = 179;
/// Intel L10M
pub const EM_L10M: u16 = 180;
/// Intel K10M
pub const EM_K10M: u16 = 181;
/// ARM AARCH64
pub const EM_AARCH64: u16 = 183;
/// Amtel 32-bit microprocessor
pub const EM_AVR32: u16 = 185;
/// STMicroelectronics STM8
pub const EM_STM8: u16 = 186;
/// Tileta TILE64
pub const EM_TILE64: u16 = 187;
/// Tilera TILEPro
pub const EM_TILEPRO: u16 = 188;
/// Xilinx MicroBlaze
pub const EM_MICROBLAZE: u16 = 189;
/// NVIDIA CUDA
pub const EM_CUDA: u16 = 190;
/// Tilera TILE-Gx
pub const EM_TILEGX: u16 = 191;
/// CloudShield
pub const EM_CLOUDSHIELD: u16 = 192;
/// KIPO-KAIST Core-A 1st gen.
pub const EM_COREA_1ST: u16 = 193;
/// KIPO-KAIST Core-A 2nd gen.
pub const EM_COREA_2ND: u16 = 194;
/// Synopsys ARCompact V2
pub const EM_ARC_COMPACT2: u16 = 195;
/// Open8 RISC
pub const EM_OPEN8: u16 = 196;
/// Renesas RL78
pub const EM_RL78: u16 = 197;
/// Broadcom VideoCore V
pub const EM_VIDEOCORE5: u16 = 198;
/// Renesas 78KOR
pub const EM_78KOR: u16 = 199;
/// Freescale 56800EX DSC
pub const EM_56800EX: u16 = 200;
/// Beyond BA1
pub const EM_BA1: u16 = 201;
/// Beyond BA2
pub const EM_BA2: u16 = 202;
/// XMOS xCORE
pub const EM_XCORE: u16 = 203;
/// Microchip 8-bit PIC(r)
pub const EM_MCHP_PIC: u16 = 204;
/// KM211 KM32
pub const EM_KM32: u16 = 210;
/// KM211 KMX32
pub const EM_KMX32: u16 = 211;
/// KM211 KMX16
pub const EM_EMX16: u16 = 212;
/// KM211 KMX8
pub const EM_EMX8: u16 = 213;
/// KM211 KVARC
pub const EM_KVARC: u16 = 214;
/// Paneve CDP
pub const EM_CDP: u16 = 215;
/// Cognitive Smart Memory Processor
pub const EM_COGE: u16 = 216;
/// Bluechip CoolEngine
pub const EM_COOL: u16 = 217;
/// Nanoradio Optimized RISC
pub const EM_NORC: u16 = 218;
/// CSR Kalimba
pub const EM_CSR_KALIMBA: u16 = 219;
/// Zilog Z80
pub const EM_Z80: u16 = 220;
/// Controls and Data Services VISIUMcore
pub const EM_VISIUM: u16 = 221;
/// FTDI Chip FT32
pub const EM_FT32: u16 = 222;
/// Moxie processor
pub const EM_MOXIE: u16 = 223;
/// AMD GPU
pub const EM_AMDGPU: u16 = 224;
/// RISC-V
pub const EM_RISCV: u16 = 243;
/// Linux BPF -- in-kernel virtual machine
pub const EM_BPF: u16 = 247;
/// C-SKY
pub const EM_CSKY: u16 = 252;
/// Loongson LoongArch
pub const EM_LOONGARCH: u16 = 258;
/// Solana Binary Format
pub const EM_SBF: u16 = 263;
/// Digital Alpha
pub const EM_ALPHA: u16 = 0x9026;

// Values for `FileHeader*::e_version` and `Ident::version`.
/// Invalid ELF version.
pub const EV_NONE: u8 = 0;
/// Current ELF version.
pub const EV_CURRENT: u8 = 1;

/// Section header.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct SectionHeader32<E: Endian> {
    /// Section name.
    ///
    /// This is an offset into the section header string table.
    pub sh_name: U32<E>,
    /// Section type. One of the `SHT_*` constants.
    pub sh_type: U32<E>,
    /// Section flags. A combination of the `SHF_*` constants.
    pub sh_flags: U32<E>,
    /// Section virtual address at execution.
    pub sh_addr: U32<E>,
    /// Section file offset.
    pub sh_offset: U32<E>,
    /// Section size in bytes.
    pub sh_size: U32<E>,
    /// Link to another section.
    ///
    /// The section relationship depends on the `sh_type` value.
    pub sh_link: U32<E>,
    /// Additional section information.
    ///
    /// The meaning of this field depends on the `sh_type` value.
    pub sh_info: U32<E>,
    /// Section alignment.
    pub sh_addralign: U32<E>,
    /// Entry size if the section holds a table.
    pub sh_entsize: U32<E>,
}

/// Section header.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct SectionHeader64<E: Endian> {
    /// Section name.
    ///
    /// This is an offset into the section header string table.
    pub sh_name: U32<E>,
    /// Section type. One of the `SHT_*` constants.
    pub sh_type: U32<E>,
    /// Section flags. A combination of the `SHF_*` constants.
    pub sh_flags: U64<E>,
    /// Section virtual address at execution.
    pub sh_addr: U64<E>,
    /// Section file offset.
    pub sh_offset: U64<E>,
    /// Section size in bytes.
    pub sh_size: U64<E>,
    /// Link to another section.
    ///
    /// The section relationship depends on the `sh_type` value.
    pub sh_link: U32<E>,
    /// Additional section information.
    ///
    /// The meaning of this field depends on the `sh_type` value.
    pub sh_info: U32<E>,
    /// Section alignment.
    pub sh_addralign: U64<E>,
    /// Entry size if the section holds a table.
    pub sh_entsize: U64<E>,
}

// Special values for section indices.
/// Undefined section.
pub const SHN_UNDEF: u16 = 0;
/// OS-specific range start.
/// Start of reserved section indices.
pub const SHN_LORESERVE: u16 = 0xff00;
/// Start of processor-specific section indices.
pub const SHN_LOPROC: u16 = 0xff00;
/// End of processor-specific section indices.
pub const SHN_HIPROC: u16 = 0xff1f;
/// Start of OS-specific section indices.
pub const SHN_LOOS: u16 = 0xff20;
/// End of OS-specific section indices.
pub const SHN_HIOS: u16 = 0xff3f;
/// Associated symbol is absolute.
pub const SHN_ABS: u16 = 0xfff1;
/// Associated symbol is common.
pub const SHN_COMMON: u16 = 0xfff2;
/// Section index is in the `SHT_SYMTAB_SHNDX` section.
pub const SHN_XINDEX: u16 = 0xffff;
/// End of reserved section indices.
pub const SHN_HIRESERVE: u16 = 0xffff;

// Values for `SectionHeader*::sh_type`.
/// Section header table entry is unused.
pub const SHT_NULL: u32 = 0;
/// Program data.
pub const SHT_PROGBITS: u32 = 1;
/// Symbol table.
pub const SHT_SYMTAB: u32 = 2;
/// String table.
pub const SHT_STRTAB: u32 = 3;
/// Relocation entries with explicit addends.
pub const SHT_RELA: u32 = 4;
/// Symbol hash table.
pub const SHT_HASH: u32 = 5;
/// Dynamic linking information.
pub const SHT_DYNAMIC: u32 = 6;
/// Notes.
pub const SHT_NOTE: u32 = 7;
/// Program space with no data (bss).
pub const SHT_NOBITS: u32 = 8;
/// Relocation entries without explicit addends.
pub const SHT_REL: u32 = 9;
/// Reserved section type.
pub const SHT_SHLIB: u32 = 10;
/// Dynamic linker symbol table.
pub const SHT_DYNSYM: u32 = 11;
/// Array of constructors.
pub const SHT_INIT_ARRAY: u32 = 14;
/// Array of destructors.
pub const SHT_FINI_ARRAY: u32 = 15;
/// Array of pre-constructors.
pub const SHT_PREINIT_ARRAY: u32 = 16;
/// Section group.
pub const SHT_GROUP: u32 = 17;
/// Extended section indices for a symbol table.
pub const SHT_SYMTAB_SHNDX: u32 = 18;
/// Start of OS-specific section types.
pub const SHT_LOOS: u32 = 0x6000_0000;
/// Object attributes.
pub const SHT_GNU_ATTRIBUTES: u32 = 0x6fff_fff5;
/// GNU-style hash table.
pub const SHT_GNU_HASH: u32 = 0x6fff_fff6;
/// Prelink library list
pub const SHT_GNU_LIBLIST: u32 = 0x6fff_fff7;
/// Checksum for DSO content.
pub const SHT_CHECKSUM: u32 = 0x6fff_fff8;
/// Sun-specific low bound.
pub const SHT_LOSUNW: u32 = 0x6fff_fffa;
#[allow(non_upper_case_globals)]
pub const SHT_SUNW_move: u32 = 0x6fff_fffa;
pub const SHT_SUNW_COMDAT: u32 = 0x6fff_fffb;
#[allow(non_upper_case_globals)]
pub const SHT_SUNW_syminfo: u32 = 0x6fff_fffc;
/// Version definition section.
#[allow(non_upper_case_globals)]
pub const SHT_GNU_VERDEF: u32 = 0x6fff_fffd;
/// Version needs section.
#[allow(non_upper_case_globals)]
pub const SHT_GNU_VERNEED: u32 = 0x6fff_fffe;
/// Version symbol table.
#[allow(non_upper_case_globals)]
pub const SHT_GNU_VERSYM: u32 = 0x6fff_ffff;
/// Sun-specific high bound.
pub const SHT_HISUNW: u32 = 0x6fff_ffff;
/// End of OS-specific section types.
pub const SHT_HIOS: u32 = 0x6fff_ffff;
/// Start of processor-specific section types.
pub const SHT_LOPROC: u32 = 0x7000_0000;
/// End of processor-specific section types.
pub const SHT_HIPROC: u32 = 0x7fff_ffff;
/// Start of application-specific section types.
pub const SHT_LOUSER: u32 = 0x8000_0000;
/// End of application-specific section types.
pub const SHT_HIUSER: u32 = 0x8fff_ffff;

// Values for `SectionHeader*::sh_flags`.
/// Section is writable.
pub const SHF_WRITE: u32 = 1 << 0;
/// Section occupies memory during execution.
pub const SHF_ALLOC: u32 = 1 << 1;
/// Section is executable.
pub const SHF_EXECINSTR: u32 = 1 << 2;
/// Section may be be merged to eliminate duplication.
pub const SHF_MERGE: u32 = 1 << 4;
/// Section contains nul-terminated strings.
pub const SHF_STRINGS: u32 = 1 << 5;
/// The `sh_info` field contains a section header table index.
pub const SHF_INFO_LINK: u32 = 1 << 6;
/// Section has special ordering requirements when combining sections.
pub const SHF_LINK_ORDER: u32 = 1 << 7;
/// Section requires special OS-specific handling.
pub const SHF_OS_NONCONFORMING: u32 = 1 << 8;
/// Section is a member of a group.
pub const SHF_GROUP: u32 = 1 << 9;
/// Section holds thread-local storage.
pub const SHF_TLS: u32 = 1 << 10;
/// Section is compressed.
///
/// Compressed sections begin with one of the `CompressionHeader*` headers.
pub const SHF_COMPRESSED: u32 = 1 << 11;
/// OS-specific section flags.
pub const SHF_MASKOS: u32 = 0x0ff0_0000;
/// Section should not be garbage collected by the linker.
pub const SHF_GNU_RETAIN: u32 = 1 << 21;
/// Mbind section.
pub const SHF_GNU_MBIND: u32 = 1 << 24;
/// Processor-specific section flags.
pub const SHF_MASKPROC: u32 = 0xf000_0000;
/// This section is excluded from the final executable or shared library.
pub const SHF_EXCLUDE: u32 = 0x8000_0000;

/// Section compression header.
///
/// Used when `SHF_COMPRESSED` is set.
///
/// Note: this type currently allows for misaligned headers, but that may be
/// changed in a future version.
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct CompressionHeader32<E: Endian> {
    /// Compression format. One of the `ELFCOMPRESS_*` values.
    pub ch_type: U32Bytes<E>,
    /// Uncompressed data size.
    pub ch_size: U32Bytes<E>,
    /// Uncompressed data alignment.
    pub ch_addralign: U32Bytes<E>,
}

/// Section compression header.
///
/// Used when `SHF_COMPRESSED` is set.
///
/// Note: this type currently allows for misaligned headers, but that may be
/// changed in a future version.
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct CompressionHeader64<E: Endian> {
    /// Compression format. One of the `ELFCOMPRESS_*` values.
    pub ch_type: U32Bytes<E>,
    /// Reserved.
    pub ch_reserved: U32Bytes<E>,
    /// Uncompressed data size.
    pub ch_size: U64Bytes<E>,
    /// Uncompressed data alignment.
    pub ch_addralign: U64Bytes<E>,
}

/// ZLIB/DEFLATE algorithm.
pub const ELFCOMPRESS_ZLIB: u32 = 1;
/// Zstandard algorithm.
pub const ELFCOMPRESS_ZSTD: u32 = 2;
/// Start of OS-specific compression types.
pub const ELFCOMPRESS_LOOS: u32 = 0x6000_0000;
/// End of OS-specific compression types.
pub const ELFCOMPRESS_HIOS: u32 = 0x6fff_ffff;
/// Start of processor-specific compression types.
pub const ELFCOMPRESS_LOPROC: u32 = 0x7000_0000;
/// End of processor-specific compression types.
pub const ELFCOMPRESS_HIPROC: u32 = 0x7fff_ffff;

// Values for the flag entry for section groups.
/// Mark group as COMDAT.
pub const GRP_COMDAT: u32 = 1;

/// Symbol table entry.
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct Sym32<E: Endian> {
    /// Symbol name.
    ///
    /// This is an offset into the symbol string table.
    pub st_name: U32<E>,
    /// Symbol value.
    pub st_value: U32<E>,
    /// Symbol size.
    pub st_size: U32<E>,
    /// Symbol type and binding.
    ///
    /// Use the `st_type` and `st_bind` methods to access this value.
    pub st_info: u8,
    /// Symbol visibility.
    ///
    /// Use the `st_visibility` method to access this value.
    pub st_other: u8,
    /// Section index or one of the `SHN_*` values.
    pub st_shndx: U16<E>,
}

impl<E: Endian> Sym32<E> {
    /// Get the `st_bind` component of the `st_info` field.
    #[inline]
    pub fn st_bind(&self) -> u8 {
        self.st_info >> 4
    }

    /// Get the `st_type` component of the `st_info` field.
    #[inline]
    pub fn st_type(&self) -> u8 {
        self.st_info & 0xf
    }

    /// Set the `st_info` field given the `st_bind` and `st_type` components.
    #[inline]
    pub fn set_st_info(&mut self, st_bind: u8, st_type: u8) {
        self.st_info = (st_bind << 4) + (st_type & 0xf);
    }

    /// Get the `st_visibility` component of the `st_info` field.
    #[inline]
    pub fn st_visibility(&self) -> u8 {
        self.st_other & 0x3
    }
}

/// Symbol table entry.
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct Sym64<E: Endian> {
    /// Symbol name.
    ///
    /// This is an offset into the symbol string table.
    pub st_name: U32<E>,
    /// Symbol type and binding.
    ///
    /// Use the `st_bind` and `st_type` methods to access this value.
    pub st_info: u8,
    /// Symbol visibility.
    ///
    /// Use the `st_visibility` method to access this value.
    pub st_other: u8,
    /// Section index or one of the `SHN_*` values.
    pub st_shndx: U16<E>,
    /// Symbol value.
    pub st_value: U64<E>,
    /// Symbol size.
    pub st_size: U64<E>,
}

impl<E: Endian> Sym64<E> {
    /// Get the `st_bind` component of the `st_info` field.
    #[inline]
    pub fn st_bind(&self) -> u8 {
        self.st_info >> 4
    }

    /// Get the `st_type` component of the `st_info` field.
    #[inline]
    pub fn st_type(&self) -> u8 {
        self.st_info & 0xf
    }

    /// Set the `st_info` field given the `st_bind` and `st_type` components.
    #[inline]
    pub fn set_st_info(&mut self, st_bind: u8, st_type: u8) {
        self.st_info = (st_bind << 4) + (st_type & 0xf);
    }

    /// Get the `st_visibility` component of the `st_info` field.
    #[inline]
    pub fn st_visibility(&self) -> u8 {
        self.st_other & 0x3
    }
}

/// Additional information about a `Sym32`.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Syminfo32<E: Endian> {
    /// Direct bindings, symbol bound to.
    pub si_boundto: U16<E>,
    /// Per symbol flags.
    pub si_flags: U16<E>,
}

/// Additional information about a `Sym64`.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Syminfo64<E: Endian> {
    /// Direct bindings, symbol bound to.
    pub si_boundto: U16<E>,
    /// Per symbol flags.
    pub si_flags: U16<E>,
}

// Values for `Syminfo*::si_boundto`.
/// Symbol bound to self
pub const SYMINFO_BT_SELF: u16 = 0xffff;
/// Symbol bound to parent
pub const SYMINFO_BT_PARENT: u16 = 0xfffe;
/// Beginning of reserved entries
pub const SYMINFO_BT_LOWRESERVE: u16 = 0xff00;

// Values for `Syminfo*::si_flags`.
/// Direct bound symbol
pub const SYMINFO_FLG_DIRECT: u16 = 0x0001;
/// Pass-thru symbol for translator
pub const SYMINFO_FLG_PASSTHRU: u16 = 0x0002;
/// Symbol is a copy-reloc
pub const SYMINFO_FLG_COPY: u16 = 0x0004;
/// Symbol bound to object to be lazy loaded
pub const SYMINFO_FLG_LAZYLOAD: u16 = 0x0008;

// Syminfo version values.
pub const SYMINFO_NONE: u16 = 0;
pub const SYMINFO_CURRENT: u16 = 1;
pub const SYMINFO_NUM: u16 = 2;

// Values for bind component of `Sym*::st_info`.
/// Local symbol.
pub const STB_LOCAL: u8 = 0;
/// Global symbol.
pub const STB_GLOBAL: u8 = 1;
/// Weak symbol.
pub const STB_WEAK: u8 = 2;
/// Start of OS-specific symbol binding.
pub const STB_LOOS: u8 = 10;
/// Unique symbol.
pub const STB_GNU_UNIQUE: u8 = 10;
/// End of OS-specific symbol binding.
pub const STB_HIOS: u8 = 12;
/// Start of processor-specific symbol binding.
pub const STB_LOPROC: u8 = 13;
/// End of processor-specific symbol binding.
pub const STB_HIPROC: u8 = 15;

// Values for type component of `Sym*::st_info`.
/// Symbol type is unspecified.
pub const STT_NOTYPE: u8 = 0;
/// Symbol is a data object.
pub const STT_OBJECT: u8 = 1;
/// Symbol is a code object.
pub const STT_FUNC: u8 = 2;
/// Symbol is associated with a section.
pub const STT_SECTION: u8 = 3;
/// Symbol's name is a file name.
pub const STT_FILE: u8 = 4;
/// Symbol is a common data object.
pub const STT_COMMON: u8 = 5;
/// Symbol is a thread-local storage object.
pub const STT_TLS: u8 = 6;
/// Start of OS-specific symbol types.
pub const STT_LOOS: u8 = 10;
/// Symbol is an indirect code object.
pub const STT_GNU_IFUNC: u8 = 10;
/// End of OS-specific symbol types.
pub const STT_HIOS: u8 = 12;
/// Start of processor-specific symbol types.
pub const STT_LOPROC: u8 = 13;
/// End of processor-specific symbol types.
pub const STT_HIPROC: u8 = 15;

// Values for visibility component of `Symbol*::st_other`.
/// Default symbol visibility rules.
pub const STV_DEFAULT: u8 = 0;
/// Processor specific hidden class.
pub const STV_INTERNAL: u8 = 1;
/// Symbol is not visible to other components.
pub const STV_HIDDEN: u8 = 2;
/// Symbol is visible to other components, but is not preemptible.
pub const STV_PROTECTED: u8 = 3;

/// Relocation table entry without explicit addend.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Rel32<E: Endian> {
    /// Relocation address.
    pub r_offset: U32<E>,
    /// Relocation type and symbol index.
    pub r_info: U32<E>,
}

impl<E: Endian> Rel32<E> {
    /// Get the `r_sym` component of the `r_info` field.
    #[inline]
    pub fn r_sym(&self, endian: E) -> u32 {
        self.r_info.get(endian) >> 8
    }

    /// Get the `r_type` component of the `r_info` field.
    #[inline]
    pub fn r_type(&self, endian: E) -> u32 {
        self.r_info.get(endian) & 0xff
    }

    /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
    pub fn r_info(endian: E, r_sym: u32, r_type: u8) -> U32<E> {
        U32::new(endian, (r_sym << 8) | u32::from(r_type))
    }

    /// Set the `r_info` field given the `r_sym` and `r_type` components.
    pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u8) {
        self.r_info = Self::r_info(endian, r_sym, r_type)
    }
}

/// Relocation table entry with explicit addend.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Rela32<E: Endian> {
    /// Relocation address.
    pub r_offset: U32<E>,
    /// Relocation type and symbol index.
    pub r_info: U32<E>,
    /// Explicit addend.
    pub r_addend: I32<E>,
}

impl<E: Endian> Rela32<E> {
    /// Get the `r_sym` component of the `r_info` field.
    #[inline]
    pub fn r_sym(&self, endian: E) -> u32 {
        self.r_info.get(endian) >> 8
    }

    /// Get the `r_type` component of the `r_info` field.
    #[inline]
    pub fn r_type(&self, endian: E) -> u32 {
        self.r_info.get(endian) & 0xff
    }

    /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
    pub fn r_info(endian: E, r_sym: u32, r_type: u8) -> U32<E> {
        U32::new(endian, (r_sym << 8) | u32::from(r_type))
    }

    /// Set the `r_info` field given the `r_sym` and `r_type` components.
    pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u8) {
        self.r_info = Self::r_info(endian, r_sym, r_type)
    }
}

impl<E: Endian> From<Rel32<E>> for Rela32<E> {
    fn from(rel: Rel32<E>) -> Self {
        Rela32 {
            r_offset: rel.r_offset,
            r_info: rel.r_info,
            r_addend: I32::default(),
        }
    }
}

/// Relocation table entry without explicit addend.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Rel64<E: Endian> {
    /// Relocation address.
    pub r_offset: U64<E>,
    /// Relocation type and symbol index.
    pub r_info: U64<E>,
}

impl<E: Endian> Rel64<E> {
    /// Get the `r_sym` component of the `r_info` field.
    #[inline]
    pub fn r_sym(&self, endian: E) -> u32 {
        (self.r_info.get(endian) >> 32) as u32
    }

    /// Get the `r_type` component of the `r_info` field.
    #[inline]
    pub fn r_type(&self, endian: E) -> u32 {
        (self.r_info.get(endian) & 0xffff_ffff) as u32
    }

    /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
    pub fn r_info(endian: E, r_sym: u32, r_type: u32) -> U64<E> {
        U64::new(endian, (u64::from(r_sym) << 32) | u64::from(r_type))
    }

    /// Set the `r_info` field given the `r_sym` and `r_type` components.
    pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u32) {
        self.r_info = Self::r_info(endian, r_sym, r_type)
    }
}

impl<E: Endian> From<Rel64<E>> for Rela64<E> {
    fn from(rel: Rel64<E>) -> Self {
        Rela64 {
            r_offset: rel.r_offset,
            r_info: rel.r_info,
            r_addend: I64::default(),
        }
    }
}

/// Relocation table entry with explicit addend.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Rela64<E: Endian> {
    /// Relocation address.
    pub r_offset: U64<E>,
    /// Relocation type and symbol index.
    pub r_info: U64<E>,
    /// Explicit addend.
    pub r_addend: I64<E>,
}

impl<E: Endian> Rela64<E> {
    pub(crate) fn get_r_info(&self, endian: E, is_mips64el: bool) -> u64 {
        let mut t = self.r_info.get(endian);
        if is_mips64el {
            t = (t << 32)
                | ((t >> 8) & 0xff000000)
                | ((t >> 24) & 0x00ff0000)
                | ((t >> 40) & 0x0000ff00)
                | ((t >> 56) & 0x000000ff);
        }
        t
    }

    /// Get the `r_sym` component of the `r_info` field.
    #[inline]
    pub fn r_sym(&self, endian: E, is_mips64el: bool) -> u32 {
        (self.get_r_info(endian, is_mips64el) >> 32) as u32
    }

    /// Get the `r_type` component of the `r_info` field.
    #[inline]
    pub fn r_type(&self, endian: E, is_mips64el: bool) -> u32 {
        (self.get_r_info(endian, is_mips64el) & 0xffff_ffff) as u32
    }

    /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
    pub fn r_info(endian: E, is_mips64el: bool, r_sym: u32, r_type: u32) -> U64<E> {
        let mut t = (u64::from(r_sym) << 32) | u64::from(r_type);
        if is_mips64el {
            t = (t >> 32)
                | ((t & 0xff000000) << 8)
                | ((t & 0x00ff0000) << 24)
                | ((t & 0x0000ff00) << 40)
                | ((t & 0x000000ff) << 56);
        }
        U64::new(endian, t)
    }

    /// Set the `r_info` field given the `r_sym` and `r_type` components.
    pub fn set_r_info(&mut self, endian: E, is_mips64el: bool, r_sym: u32, r_type: u32) {
        self.r_info = Self::r_info(endian, is_mips64el, r_sym, r_type);
    }
}

/// Program segment header.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ProgramHeader32<E: Endian> {
    /// Segment type. One of the `PT_*` constants.
    pub p_type: U32<E>,
    /// Segment file offset.
    pub p_offset: U32<E>,
    /// Segment virtual address.
    pub p_vaddr: U32<E>,
    /// Segment physical address.
    pub p_paddr: U32<E>,
    /// Segment size in the file.
    pub p_filesz: U32<E>,
    /// Segment size in memory.
    pub p_memsz: U32<E>,
    /// Segment flags. A combination of the `PF_*` constants.
    pub p_flags: U32<E>,
    /// Segment alignment.
    pub p_align: U32<E>,
}

/// Program segment header.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ProgramHeader64<E: Endian> {
    /// Segment type. One of the `PT_*` constants.
    pub p_type: U32<E>,
    /// Segment flags. A combination of the `PF_*` constants.
    pub p_flags: U32<E>,
    /// Segment file offset.
    pub p_offset: U64<E>,
    /// Segment virtual address.
    pub p_vaddr: U64<E>,
    /// Segment physical address.
    pub p_paddr: U64<E>,
    /// Segment size in the file.
    pub p_filesz: U64<E>,
    /// Segment size in memory.
    pub p_memsz: U64<E>,
    /// Segment alignment.
    pub p_align: U64<E>,
}

/// Special value for `FileHeader*::e_phnum`.
///
/// This indicates that the real number of program headers is too large to fit into e_phnum.
/// Instead the real value is in the field `sh_info` of section 0.
pub const PN_XNUM: u16 = 0xffff;

// Values for `ProgramHeader*::p_type`.
/// Program header table entry is unused.
pub const PT_NULL: u32 = 0;
/// Loadable program segment.
pub const PT_LOAD: u32 = 1;
/// Dynamic linking information.
pub const PT_DYNAMIC: u32 = 2;
/// Program interpreter.
pub const PT_INTERP: u32 = 3;
/// Auxiliary information.
pub const PT_NOTE: u32 = 4;
/// Reserved.
pub const PT_SHLIB: u32 = 5;
/// Segment contains the program header table.
pub const PT_PHDR: u32 = 6;
/// Thread-local storage segment.
pub const PT_TLS: u32 = 7;
/// Start of OS-specific segment types.
pub const PT_LOOS: u32 = 0x6000_0000;
/// GCC `.eh_frame_hdr` segment.
pub const PT_GNU_EH_FRAME: u32 = 0x6474_e550;
/// Indicates stack executability.
pub const PT_GNU_STACK: u32 = 0x6474_e551;
/// Read-only after relocation.
pub const PT_GNU_RELRO: u32 = 0x6474_e552;
/// Segment containing `.note.gnu.property` section.
pub const PT_GNU_PROPERTY: u32 = 0x6474_e553;
/// End of OS-specific segment types.
pub const PT_HIOS: u32 = 0x6fff_ffff;
/// Start of processor-specific segment types.
pub const PT_LOPROC: u32 = 0x7000_0000;
/// End of processor-specific segment types.
pub const PT_HIPROC: u32 = 0x7fff_ffff;

// Values for `ProgramHeader*::p_flags`.
/// Segment is executable.
pub const PF_X: u32 = 1 << 0;
/// Segment is writable.
pub const PF_W: u32 = 1 << 1;
/// Segment is readable.
pub const PF_R: u32 = 1 << 2;
/// OS-specific segment flags.
pub const PF_MASKOS: u32 = 0x0ff0_0000;
/// Processor-specific segment flags.
pub const PF_MASKPROC: u32 = 0xf000_0000;

/// Note name for core files.
pub const ELF_NOTE_CORE: &[u8] = b"CORE";
/// Note name for linux core files.
///
/// Notes in linux core files may also use `ELF_NOTE_CORE`.
pub const ELF_NOTE_LINUX: &[u8] = b"LINUX";

// Values for `NoteHeader*::n_type` in core files.
//
/// Contains copy of prstatus struct.
pub const NT_PRSTATUS: u32 = 1;
/// Contains copy of fpregset struct.
pub const NT_PRFPREG: u32 = 2;
/// Contains copy of fpregset struct.
pub const NT_FPREGSET: u32 = 2;
/// Contains copy of prpsinfo struct.
pub const NT_PRPSINFO: u32 = 3;
/// Contains copy of prxregset struct.
pub const NT_PRXREG: u32 = 4;
/// Contains copy of task structure.
pub const NT_TASKSTRUCT: u32 = 4;
/// String from sysinfo(SI_PLATFORM).
pub const NT_PLATFORM: u32 = 5;
/// Contains copy of auxv array.
pub const NT_AUXV: u32 = 6;
/// Contains copy of gwindows struct.
pub const NT_GWINDOWS: u32 = 7;
/// Contains copy of asrset struct.
pub const NT_ASRS: u32 = 8;
/// Contains copy of pstatus struct.
pub const NT_PSTATUS: u32 = 10;
/// Contains copy of psinfo struct.
pub const NT_PSINFO: u32 = 13;
/// Contains copy of prcred struct.
pub const NT_PRCRED: u32 = 14;
/// Contains copy of utsname struct.
pub const NT_UTSNAME: u32 = 15;
/// Contains copy of lwpstatus struct.
pub const NT_LWPSTATUS: u32 = 16;
/// Contains copy of lwpinfo struct.
pub const NT_LWPSINFO: u32 = 17;
/// Contains copy of fprxregset struct.
pub const NT_PRFPXREG: u32 = 20;
/// Contains copy of siginfo_t, size might increase.
pub const NT_SIGINFO: u32 = 0x5349_4749;
/// Contains information about mapped files.
pub const NT_FILE: u32 = 0x4649_4c45;
/// Contains copy of user_fxsr_struct.
pub const NT_PRXFPREG: u32 = 0x46e6_2b7f;
/// PowerPC Altivec/VMX registers.
pub const NT_PPC_VMX: u32 = 0x100;
/// PowerPC SPE/EVR registers.
pub const NT_PPC_SPE: u32 = 0x101;
/// PowerPC VSX registers.
pub const NT_PPC_VSX: u32 = 0x102;
/// Target Address Register.
pub const NT_PPC_TAR: u32 = 0x103;
/// Program Priority Register.
pub const NT_PPC_PPR: u32 = 0x104;
/// Data Stream Control Register.
pub const NT_PPC_DSCR: u32 = 0x105;
/// Event Based Branch Registers.
pub const NT_PPC_EBB: u32 = 0x106;
/// Performance Monitor Registers.
pub const NT_PPC_PMU: u32 = 0x107;
/// TM checkpointed GPR Registers.
pub const NT_PPC_TM_CGPR: u32 = 0x108;
/// TM checkpointed FPR Registers.
pub const NT_PPC_TM_CFPR: u32 = 0x109;
/// TM checkpointed VMX Registers.
pub const NT_PPC_TM_CVMX: u32 = 0x10a;
/// TM checkpointed VSX Registers.
pub const NT_PPC_TM_CVSX: u32 = 0x10b;
/// TM Special Purpose Registers.
pub const NT_PPC_TM_SPR: u32 = 0x10c;
/// TM checkpointed Target Address Register.
pub const NT_PPC_TM_CTAR: u32 = 0x10d;
/// TM checkpointed Program Priority Register.
pub const NT_PPC_TM_CPPR: u32 = 0x10e;
/// TM checkpointed Data Stream Control Register.
pub const NT_PPC_TM_CDSCR: u32 = 0x10f;
/// Memory Protection Keys registers.
pub const NT_PPC_PKEY: u32 = 0x110;
/// i386 TLS slots (struct user_desc).
pub const NT_386_TLS: u32 = 0x200;
/// x86 io permission bitmap (1=deny).
pub const NT_386_IOPERM: u32 = 0x201;
/// x86 extended state using xsave.
pub const NT_X86_XSTATE: u32 = 0x202;
/// s390 upper register halves.
pub const NT_S390_HIGH_GPRS: u32 = 0x300;
/// s390 timer register.
pub const NT_S390_TIMER: u32 = 0x301;
/// s390 TOD clock comparator register.
pub const NT_S390_TODCMP: u32 = 0x302;
/// s390 TOD programmable register.
pub const NT_S390_TODPREG: u32 = 0x303;
/// s390 control registers.
pub const NT_S390_CTRS: u32 = 0x304;
/// s390 prefix register.
pub const NT_S390_PREFIX: u32 = 0x305;
/// s390 breaking event address.
pub const NT_S390_LAST_BREAK: u32 = 0x306;
/// s390 system call restart data.
pub const NT_S390_SYSTEM_CALL: u32 = 0x307;
/// s390 transaction diagnostic block.
pub const NT_S390_TDB: u32 = 0x308;
/// s390 vector registers 0-15 upper half.
pub const NT_S390_VXRS_LOW: u32 = 0x309;
/// s390 vector registers 16-31.
pub const NT_S390_VXRS_HIGH: u32 = 0x30a;
/// s390 guarded storage registers.
pub const NT_S390_GS_CB: u32 = 0x30b;
/// s390 guarded storage broadcast control block.
pub const NT_S390_GS_BC: u32 = 0x30c;
/// s390 runtime instrumentation.
pub const NT_S390_RI_CB: u32 = 0x30d;
/// ARM VFP/NEON registers.
pub const NT_ARM_VFP: u32 = 0x400;
/// ARM TLS register.
pub const NT_ARM_TLS: u32 = 0x401;
/// ARM hardware breakpoint registers.
pub const NT_ARM_HW_BREAK: u32 = 0x402;
/// ARM hardware watchpoint registers.
pub const NT_ARM_HW_WATCH: u32 = 0x403;
/// ARM system call number.
pub const NT_ARM_SYSTEM_CALL: u32 = 0x404;
/// ARM Scalable Vector Extension registers.
pub const NT_ARM_SVE: u32 = 0x405;
/// Vmcore Device Dump Note.
pub const NT_VMCOREDD: u32 = 0x700;
/// MIPS DSP ASE registers.
pub const NT_MIPS_DSP: u32 = 0x800;
/// MIPS floating-point mode.
pub const NT_MIPS_FP_MODE: u32 = 0x801;

/// Note type for version string.
///
/// This note may appear in object files.
///
/// It must be handled as a special case because it has no descriptor, and instead
/// uses the note name as the version string.
pub const NT_VERSION: u32 = 1;

/// Dynamic section entry.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Dyn32<E: Endian> {
    /// Dynamic entry type.
    pub d_tag: U32<E>,
    /// Value (integer or address).
    pub d_val: U32<E>,
}

/// Dynamic section entry.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Dyn64<E: Endian> {
    /// Dynamic entry type.
    pub d_tag: U64<E>,
    /// Value (integer or address).
    pub d_val: U64<E>,
}

// Values for `Dyn*::d_tag`.

/// Marks end of dynamic section
pub const DT_NULL: u32 = 0;
/// Name of needed library
pub const DT_NEEDED: u32 = 1;
/// Size in bytes of PLT relocs
pub const DT_PLTRELSZ: u32 = 2;
/// Processor defined value
pub const DT_PLTGOT: u32 = 3;
/// Address of symbol hash table
pub const DT_HASH: u32 = 4;
/// Address of string table
pub const DT_STRTAB: u32 = 5;
/// Address of symbol table
pub const DT_SYMTAB: u32 = 6;
/// Address of Rela relocs
pub const DT_RELA: u32 = 7;
/// Total size of Rela relocs
pub const DT_RELASZ: u32 = 8;
/// Size of one Rela reloc
pub const DT_RELAENT: u32 = 9;
/// Size of string table
pub const DT_STRSZ: u32 = 10;
/// Size of one symbol table entry
pub const DT_SYMENT: u32 = 11;
/// Address of init function
pub const DT_INIT: u32 = 12;
/// Address of termination function
pub const DT_FINI: u32 = 13;
/// Name of shared object
pub const DT_SONAME: u32 = 14;
/// Library search path (deprecated)
pub const DT_RPATH: u32 = 15;
/// Start symbol search here
pub const DT_SYMBOLIC: u32 = 16;
/// Address of Rel relocs
pub const DT_REL: u32 = 17;
/// Total size of Rel relocs
pub const DT_RELSZ: u32 = 18;
/// Size of one Rel reloc
pub const DT_RELENT: u32 = 19;
/// Type of reloc in PLT
pub const DT_PLTREL: u32 = 20;
/// For debugging; unspecified
pub const DT_DEBUG: u32 = 21;
/// Reloc might modify .text
pub const DT_TEXTREL: u32 = 22;
/// Address of PLT relocs
pub const DT_JMPREL: u32 = 23;
/// Process relocations of object
pub const DT_BIND_NOW: u32 = 24;
/// Array with addresses of init fct
pub const DT_INIT_ARRAY: u32 = 25;
/// Array with addresses of fini fct
pub const DT_FINI_ARRAY: u32 = 26;
/// Size in bytes of DT_INIT_ARRAY
pub const DT_INIT_ARRAYSZ: u32 = 27;
/// Size in bytes of DT_FINI_ARRAY
pub const DT_FINI_ARRAYSZ: u32 = 28;
/// Library search path
pub const DT_RUNPATH: u32 = 29;
/// Flags for the object being loaded
pub const DT_FLAGS: u32 = 30;
/// Start of encoded range
pub const DT_ENCODING: u32 = 32;
/// Array with addresses of preinit fct
pub const DT_PREINIT_ARRAY: u32 = 32;
/// size in bytes of DT_PREINIT_ARRAY
pub const DT_PREINIT_ARRAYSZ: u32 = 33;
/// Address of SYMTAB_SHNDX section
pub const DT_SYMTAB_SHNDX: u32 = 34;
/// Start of OS-specific
pub const DT_LOOS: u32 = 0x6000_000d;
/// End of OS-specific
pub const DT_HIOS: u32 = 0x6fff_f000;
/// Start of processor-specific
pub const DT_LOPROC: u32 = 0x7000_0000;
/// End of processor-specific
pub const DT_HIPROC: u32 = 0x7fff_ffff;

// `DT_*` entries between `DT_VALRNGHI` & `DT_VALRNGLO` use `d_val` as a value.
pub const DT_VALRNGLO: u32 = 0x6fff_fd00;
/// Prelinking timestamp
pub const DT_GNU_PRELINKED: u32 = 0x6fff_fdf5;
/// Size of conflict section
pub const DT_GNU_CONFLICTSZ: u32 = 0x6fff_fdf6;
/// Size of library list
pub const DT_GNU_LIBLISTSZ: u32 = 0x6fff_fdf7;
pub const DT_CHECKSUM: u32 = 0x6fff_fdf8;
pub const DT_PLTPADSZ: u32 = 0x6fff_fdf9;
pub const DT_MOVEENT: u32 = 0x6fff_fdfa;
pub const DT_MOVESZ: u32 = 0x6fff_fdfb;
/// Feature selection (DTF_*).
pub const DT_FEATURE_1: u32 = 0x6fff_fdfc;
/// Flags for DT_* entries, affecting the following DT_* entry.
pub const DT_POSFLAG_1: u32 = 0x6fff_fdfd;
/// Size of syminfo table (in bytes)
pub const DT_SYMINSZ: u32 = 0x6fff_fdfe;
/// Entry size of syminfo
pub const DT_SYMINENT: u32 = 0x6fff_fdff;
pub const DT_VALRNGHI: u32 = 0x6fff_fdff;

// `DT_*` entries between `DT_ADDRRNGHI` & `DT_ADDRRNGLO` use `d_val` as an address.
//
// If any adjustment is made to the ELF object after it has been
// built these entries will need to be adjusted.
pub const DT_ADDRRNGLO: u32 = 0x6fff_fe00;
/// GNU-style hash table.
pub const DT_GNU_HASH: u32 = 0x6fff_fef5;
pub const DT_TLSDESC_PLT: u32 = 0x6fff_fef6;
pub const DT_TLSDESC_GOT: u32 = 0x6fff_fef7;
/// Start of conflict section
pub const DT_GNU_CONFLICT: u32 = 0x6fff_fef8;
/// Library list
pub const DT_GNU_LIBLIST: u32 = 0x6fff_fef9;
/// Configuration information.
pub const DT_CONFIG: u32 = 0x6fff_fefa;
/// Dependency auditing.
pub const DT_DEPAUDIT: u32 = 0x6fff_fefb;
/// Object auditing.
pub const DT_AUDIT: u32 = 0x6fff_fefc;
/// PLT padding.
pub const DT_PLTPAD: u32 = 0x6fff_fefd;
/// Move table.
pub const DT_MOVETAB: u32 = 0x6fff_fefe;
/// Syminfo table.
pub const DT_SYMINFO: u32 = 0x6fff_feff;
pub const DT_ADDRRNGHI: u32 = 0x6fff_feff;

// The versioning entry types.  The next are defined as part of the
// GNU extension.
pub const DT_VERSYM: u32 = 0x6fff_fff0;
pub const DT_RELACOUNT: u32 = 0x6fff_fff9;
pub const DT_RELCOUNT: u32 = 0x6fff_fffa;
/// State flags, see DF_1_* below.
pub const DT_FLAGS_1: u32 = 0x6fff_fffb;
/// Address of version definition table
pub const DT_VERDEF: u32 = 0x6fff_fffc;
/// Number of version definitions
pub const DT_VERDEFNUM: u32 = 0x6fff_fffd;
/// Address of table with needed versions
pub const DT_VERNEED: u32 = 0x6fff_fffe;
/// Number of needed versions
pub const DT_VERNEEDNUM: u32 = 0x6fff_ffff;

// Machine-independent extensions in the "processor-specific" range.
/// Shared object to load before self
pub const DT_AUXILIARY: u32 = 0x7fff_fffd;
/// Shared object to get values from
pub const DT_FILTER: u32 = 0x7fff_ffff;

// Values of `Dyn*::d_val` in the `DT_FLAGS` entry.
/// Object may use DF_ORIGIN
pub const DF_ORIGIN: u32 = 0x0000_0001;
/// Symbol resolutions starts here
pub const DF_SYMBOLIC: u32 = 0x0000_0002;
/// Object contains text relocations
pub const DF_TEXTREL: u32 = 0x0000_0004;
/// No lazy binding for this object
pub const DF_BIND_NOW: u32 = 0x0000_0008;
/// Module uses the static TLS model
pub const DF_STATIC_TLS: u32 = 0x0000_0010;

// Values of `Dyn*::d_val` in the `DT_FLAGS_1` entry.
/// Set RTLD_NOW for this object.
pub const DF_1_NOW: u32 = 0x0000_0001;
/// Set RTLD_GLOBAL for this object.
pub const DF_1_GLOBAL: u32 = 0x0000_0002;
/// Set RTLD_GROUP for this object.
pub const DF_1_GROUP: u32 = 0x0000_0004;
/// Set RTLD_NODELETE for this object.
pub const DF_1_NODELETE: u32 = 0x0000_0008;
/// Trigger filtee loading at runtime.
pub const DF_1_LOADFLTR: u32 = 0x0000_0010;
/// Set RTLD_INITFIRST for this object.
pub const DF_1_INITFIRST: u32 = 0x0000_0020;
/// Set RTLD_NOOPEN for this object.
pub const DF_1_NOOPEN: u32 = 0x0000_0040;
/// $ORIGIN must be handled.
pub const DF_1_ORIGIN: u32 = 0x0000_0080;
/// Direct binding enabled.
pub const DF_1_DIRECT: u32 = 0x0000_0100;
pub const DF_1_TRANS: u32 = 0x0000_0200;
/// Object is used to interpose.
pub const DF_1_INTERPOSE: u32 = 0x0000_0400;
/// Ignore default lib search path.
pub const DF_1_NODEFLIB: u32 = 0x0000_0800;
/// Object can't be dldump'ed.
pub const DF_1_NODUMP: u32 = 0x0000_1000;
/// Configuration alternative created.
pub const DF_1_CONFALT: u32 = 0x0000_2000;
/// Filtee terminates filters search.
pub const DF_1_ENDFILTEE: u32 = 0x0000_4000;
/// Disp reloc applied at build time.
pub const DF_1_DISPRELDNE: u32 = 0x0000_8000;
/// Disp reloc applied at run-time.
pub const DF_1_DISPRELPND: u32 = 0x0001_0000;
/// Object has no-direct binding.
pub const DF_1_NODIRECT: u32 = 0x0002_0000;
pub const DF_1_IGNMULDEF: u32 = 0x0004_0000;
pub const DF_1_NOKSYMS: u32 = 0x0008_0000;
pub const DF_1_NOHDR: u32 = 0x0010_0000;
/// Object is modified after built.
pub const DF_1_EDITED: u32 = 0x0020_0000;
pub const DF_1_NORELOC: u32 = 0x0040_0000;
/// Object has individual interposers.
pub const DF_1_SYMINTPOSE: u32 = 0x0080_0000;
/// Global auditing required.
pub const DF_1_GLOBAUDIT: u32 = 0x0100_0000;
/// Singleton symbols are used.
pub const DF_1_SINGLETON: u32 = 0x0200_0000;
pub const DF_1_STUB: u32 = 0x0400_0000;
pub const DF_1_PIE: u32 = 0x0800_0000;

/// Version symbol information
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Versym<E: Endian>(pub U16<E>);

/// Symbol is hidden.
pub const VERSYM_HIDDEN: u16 = 0x8000;
/// Symbol version index.
pub const VERSYM_VERSION: u16 = 0x7fff;

/// Version definition sections
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Verdef<E: Endian> {
    /// Version revision
    pub vd_version: U16<E>,
    /// Version information
    pub vd_flags: U16<E>,
    /// Version Index
    pub vd_ndx: U16<E>,
    /// Number of associated aux entries
    pub vd_cnt: U16<E>,
    /// Version name hash value
    pub vd_hash: U32<E>,
    /// Offset in bytes to verdaux array
    pub vd_aux: U32<E>,
    /// Offset in bytes to next verdef entry
    pub vd_next: U32<E>,
}

// Legal values for vd_version (version revision).
/// No version
pub const VER_DEF_NONE: u16 = 0;
/// Current version
pub const VER_DEF_CURRENT: u16 = 1;

// Legal values for vd_flags (version information flags).
/// Version definition of file itself
pub const VER_FLG_BASE: u16 = 0x1;
// Legal values for vd_flags and vna_flags (version information flags).
/// Weak version identifier
pub const VER_FLG_WEAK: u16 = 0x2;

// Versym symbol index values.
/// Symbol is local.
pub const VER_NDX_LOCAL: u16 = 0;
/// Symbol is global.
pub const VER_NDX_GLOBAL: u16 = 1;

/// Auxiliary version information.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Verdaux<E: Endian> {
    /// Version or dependency names
    pub vda_name: U32<E>,
    /// Offset in bytes to next verdaux
    pub vda_next: U32<E>,
}

/// Version dependency.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Verneed<E: Endian> {
    /// Version of structure
    pub vn_version: U16<E>,
    /// Number of associated aux entries
    pub vn_cnt: U16<E>,
    /// Offset of filename for this dependency
    pub vn_file: U32<E>,
    /// Offset in bytes to vernaux array
    pub vn_aux: U32<E>,
    /// Offset in bytes to next verneed entry
    pub vn_next: U32<E>,
}

// Legal values for vn_version (version revision).
/// No version
pub const VER_NEED_NONE: u16 = 0;
/// Current version
pub const VER_NEED_CURRENT: u16 = 1;

/// Auxiliary needed version information.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Vernaux<E: Endian> {
    /// Hash value of dependency name
    pub vna_hash: U32<E>,
    /// Dependency specific information
    pub vna_flags: U16<E>,
    /// Version Index
    pub vna_other: U16<E>,
    /// Dependency name string offset
    pub vna_name: U32<E>,
    /// Offset in bytes to next vernaux entry
    pub vna_next: U32<E>,
}

// TODO: Elf*_auxv_t, AT_*

/// Note section entry header.
///
/// A note consists of a header followed by a variable length name and descriptor.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct NoteHeader32<E: Endian> {
    /// Length of the note's name.
    ///
    /// Some known names are defined by the `ELF_NOTE_*` constants.
    pub n_namesz: U32<E>,
    /// Length of the note's descriptor.
    ///
    /// The content of the descriptor depends on the note name and type.
    pub n_descsz: U32<E>,
    /// Type of the note.
    ///
    /// One of the `NT_*` constants. The note name determines which
    /// `NT_*` constants are valid.
    pub n_type: U32<E>,
}

/// Note section entry header.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct NoteHeader64<E: Endian> {
    /// Length of the note's name.
    ///
    /// Some known names are defined by the `ELF_NOTE_*` constants.
    pub n_namesz: U32<E>,
    /// Length of the note's descriptor.
    ///
    /// The content of the descriptor depends on the note name and type.
    pub n_descsz: U32<E>,
    /// Type of the note.
    ///
    /// One of the `NT_*` constants. The note name determines which
    /// `NT_*` constants are valid.
    pub n_type: U32<E>,
}

/// Solaris entries in the note section have this name.
pub const ELF_NOTE_SOLARIS: &[u8] = b"SUNW Solaris";

// Values for `n_type` when the name is `ELF_NOTE_SOLARIS`.
/// Desired pagesize for the binary.
pub const NT_SOLARIS_PAGESIZE_HINT: u32 = 1;

/// GNU entries in the note section have this name.
pub const ELF_NOTE_GNU: &[u8] = b"GNU";

/// Go entries in the note section have this name.
// See https://go-review.googlesource.com/9520 and https://go-review.googlesource.com/10704.
pub const ELF_NOTE_GO: &[u8] = b"Go";

// Note types for `ELF_NOTE_GNU`.

/// ABI information.
///
/// The descriptor consists of words:
/// - word 0: OS descriptor
/// - word 1: major version of the ABI
/// - word 2: minor version of the ABI
/// - word 3: subminor version of the ABI
pub const NT_GNU_ABI_TAG: u32 = 1;

/// OS descriptor for `NT_GNU_ABI_TAG`.
pub const ELF_NOTE_OS_LINUX: u32 = 0;
/// OS descriptor for `NT_GNU_ABI_TAG`.
pub const ELF_NOTE_OS_GNU: u32 = 1;
/// OS descriptor for `NT_GNU_ABI_TAG`.
pub const ELF_NOTE_OS_SOLARIS2: u32 = 2;
/// OS descriptor for `NT_GNU_ABI_TAG`.
pub const ELF_NOTE_OS_FREEBSD: u32 = 3;

/// Synthetic hwcap information.
///
/// The descriptor begins with two words:
/// - word 0: number of entries
/// - word 1: bitmask of enabled entries
///
/// Then follow variable-length entries, one byte followed by a
/// '\0'-terminated hwcap name string.  The byte gives the bit
/// number to test if enabled, (1U << bit) & bitmask.  */
pub const NT_GNU_HWCAP: u32 = 2;

/// Build ID bits as generated by `ld --build-id`.
///
/// The descriptor consists of any nonzero number of bytes.
pub const NT_GNU_BUILD_ID: u32 = 3;

/// Build ID bits as generated by Go's gc compiler.
///
/// The descriptor consists of any nonzero number of bytes.
// See https://go-review.googlesource.com/10707.
pub const NT_GO_BUILD_ID: u32 = 4;

/// Version note generated by GNU gold containing a version string.
pub const NT_GNU_GOLD_VERSION: u32 = 4;

/// Program property.
pub const NT_GNU_PROPERTY_TYPE_0: u32 = 5;

// Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0).

/// Stack size.
pub const GNU_PROPERTY_STACK_SIZE: u32 = 1;
/// No copy relocation on protected data symbol.
pub const GNU_PROPERTY_NO_COPY_ON_PROTECTED: u32 = 2;

// A 4-byte unsigned integer property: A bit is set if it is set in all
// relocatable inputs.
pub const GNU_PROPERTY_UINT32_AND_LO: u32 = 0xb0000000;
pub const GNU_PROPERTY_UINT32_AND_HI: u32 = 0xb0007fff;

// A 4-byte unsigned integer property: A bit is set if it is set in any
// relocatable inputs.
pub const GNU_PROPERTY_UINT32_OR_LO: u32 = 0xb0008000;
pub const GNU_PROPERTY_UINT32_OR_HI: u32 = 0xb000ffff;

/// The needed properties by the object file.  */
pub const GNU_PROPERTY_1_NEEDED: u32 = GNU_PROPERTY_UINT32_OR_LO;

/// Set if the object file requires canonical function pointers and
/// cannot be used with copy relocation.
pub const GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS: u32 = 1 << 0;

/// Processor-specific semantics, lo
pub const GNU_PROPERTY_LOPROC: u32 = 0xc0000000;
/// Processor-specific semantics, hi
pub const GNU_PROPERTY_HIPROC: u32 = 0xdfffffff;
/// Application-specific semantics, lo
pub const GNU_PROPERTY_LOUSER: u32 = 0xe0000000;
/// Application-specific semantics, hi
pub const GNU_PROPERTY_HIUSER: u32 = 0xffffffff;

/// AArch64 specific GNU properties.
pub const GNU_PROPERTY_AARCH64_FEATURE_1_AND: u32 = 0xc0000000;
pub const GNU_PROPERTY_AARCH64_FEATURE_PAUTH: u32 = 0xc0000001;

pub const GNU_PROPERTY_AARCH64_FEATURE_1_BTI: u32 = 1 << 0;
pub const GNU_PROPERTY_AARCH64_FEATURE_1_PAC: u32 = 1 << 1;

// A 4-byte unsigned integer property: A bit is set if it is set in all
// relocatable inputs.
pub const GNU_PROPERTY_X86_UINT32_AND_LO: u32 = 0xc0000002;
pub const GNU_PROPERTY_X86_UINT32_AND_HI: u32 = 0xc0007fff;

// A 4-byte unsigned integer property: A bit is set if it is set in any
// relocatable inputs.
pub const GNU_PROPERTY_X86_UINT32_OR_LO: u32 = 0xc0008000;
pub const GNU_PROPERTY_X86_UINT32_OR_HI: u32 = 0xc000ffff;

// A 4-byte unsigned integer property: A bit is set if it is set in any
// relocatable inputs and the property is present in all relocatable
// inputs.
pub const GNU_PROPERTY_X86_UINT32_OR_AND_LO: u32 = 0xc0010000;
pub const GNU_PROPERTY_X86_UINT32_OR_AND_HI: u32 = 0xc0017fff;

/// The x86 instruction sets indicated by the corresponding bits are
/// used in program.  Their support in the hardware is optional.
pub const GNU_PROPERTY_X86_ISA_1_USED: u32 = 0xc0010002;
/// The x86 instruction sets indicated by the corresponding bits are
/// used in program and they must be supported by the hardware.
pub const GNU_PROPERTY_X86_ISA_1_NEEDED: u32 = 0xc0008002;
/// X86 processor-specific features used in program.
pub const GNU_PROPERTY_X86_FEATURE_1_AND: u32 = 0xc0000002;

/// GNU_PROPERTY_X86_ISA_1_BASELINE: CMOV, CX8 (cmpxchg8b), FPU (fld),
/// MMX, OSFXSR (fxsave), SCE (syscall), SSE and SSE2.
pub const GNU_PROPERTY_X86_ISA_1_BASELINE: u32 = 1 << 0;
/// GNU_PROPERTY_X86_ISA_1_V2: GNU_PROPERTY_X86_ISA_1_BASELINE,
/// CMPXCHG16B (cmpxchg16b), LAHF-SAHF (lahf), POPCNT (popcnt), SSE3,
/// SSSE3, SSE4.1 and SSE4.2.
pub const GNU_PROPERTY_X86_ISA_1_V2: u32 = 1 << 1;
/// GNU_PROPERTY_X86_ISA_1_V3: GNU_PROPERTY_X86_ISA_1_V2, AVX, AVX2, BMI1,
/// BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE.
pub const GNU_PROPERTY_X86_ISA_1_V3: u32 = 1 << 2;
/// GNU_PROPERTY_X86_ISA_1_V4: GNU_PROPERTY_X86_ISA_1_V3, AVX512F,
/// AVX512BW, AVX512CD, AVX512DQ and AVX512VL.
pub const GNU_PROPERTY_X86_ISA_1_V4: u32 = 1 << 3;

/// This indicates that all executable sections are compatible with IBT.
pub const GNU_PROPERTY_X86_FEATURE_1_IBT: u32 = 1 << 0;
/// This indicates that all executable sections are compatible with SHSTK.
pub const GNU_PROPERTY_X86_FEATURE_1_SHSTK: u32 = 1 << 1;

// TODO: Elf*_Move

/// Header of `SHT_HASH` section.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct HashHeader<E: Endian> {
    /// The number of hash buckets.
    pub bucket_count: U32<E>,
    /// The number of chain values.
    pub chain_count: U32<E>,
    // Array of hash bucket start indices.
    // buckets: U32<E>[bucket_count]
    // Array of hash chain links. An index of 0 terminates the chain.
    // chains: U32<E>[chain_count]
}

/// Calculate the SysV hash for a symbol name.
///
/// Used for `SHT_HASH`.
pub fn hash(name: &[u8]) -> u32 {
    let mut hash = 0u32;
    for byte in name {
        hash = hash.wrapping_mul(16).wrapping_add(u32::from(*byte));
        hash ^= (hash >> 24) & 0xf0;
    }
    hash & 0xfff_ffff
}

/// Header of `SHT_GNU_HASH` section.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct GnuHashHeader<E: Endian> {
    /// The number of hash buckets.
    pub bucket_count: U32<E>,
    /// The symbol table index of the first symbol in the hash.
    pub symbol_base: U32<E>,
    /// The number of words in the bloom filter.
    ///
    /// Must be a non-zero power of 2.
    pub bloom_count: U32<E>,
    /// The bit shift count for the bloom filter.
    pub bloom_shift: U32<E>,
    // Array of bloom filter words.
    // bloom_filters: U32<E>[bloom_count] or U64<E>[bloom_count]
    // Array of hash bucket start indices.
    // buckets: U32<E>[bucket_count]
    // Array of hash values, one for each symbol starting at symbol_base.
    // values: U32<E>[symbol_count]
}

/// Calculate the GNU hash for a symbol name.
///
/// Used for `SHT_GNU_HASH`.
pub fn gnu_hash(name: &[u8]) -> u32 {
    let mut hash = 5381u32;
    for byte in name {
        hash = hash.wrapping_mul(33).wrapping_add(u32::from(*byte));
    }
    hash
}

// Motorola 68k specific definitions.

// m68k values for `Rel*::r_type`.

/// No reloc
pub const R_68K_NONE: u32 = 0;
/// Direct 32 bit
pub const R_68K_32: u32 = 1;
/// Direct 16 bit
pub const R_68K_16: u32 = 2;
/// Direct 8 bit
pub const R_68K_8: u32 = 3;
/// PC relative 32 bit
pub const R_68K_PC32: u32 = 4;
/// PC relative 16 bit
pub const R_68K_PC16: u32 = 5;
/// PC relative 8 bit
pub const R_68K_PC8: u32 = 6;
/// 32 bit PC relative GOT entry
pub const R_68K_GOT32: u32 = 7;
/// 16 bit PC relative GOT entry
pub const R_68K_GOT16: u32 = 8;
/// 8 bit PC relative GOT entry
pub const R_68K_GOT8: u32 = 9;
/// 32 bit GOT offset
pub const R_68K_GOT32O: u32 = 10;
/// 16 bit GOT offset
pub const R_68K_GOT16O: u32 = 11;
/// 8 bit GOT offset
pub const R_68K_GOT8O: u32 = 12;
/// 32 bit PC relative PLT address
pub const R_68K_PLT32: u32 = 13;
/// 16 bit PC relative PLT address
pub const R_68K_PLT16: u32 = 14;
/// 8 bit PC relative PLT address
pub const R_68K_PLT8: u32 = 15;
/// 32 bit PLT offset
pub const R_68K_PLT32O: u32 = 16;
/// 16 bit PLT offset
pub const R_68K_PLT16O: u32 = 17;
/// 8 bit PLT offset
pub const R_68K_PLT8O: u32 = 18;
/// Copy symbol at runtime
pub const R_68K_COPY: u32 = 19;
/// Create GOT entry
pub const R_68K_GLOB_DAT: u32 = 20;
/// Create PLT entry
--> --------------------

--> maximum size reached

--> --------------------

[ Verzeichnis aufwärts0.40unsichere Verbindung  Übersetzung europäischer Sprachen durch Browser  ]