Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  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

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

[ Dauer der Verarbeitung: 0.37 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge