aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/glibcelf.py1135
1 files changed, 1135 insertions, 0 deletions
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
new file mode 100644
index 0000000000..8f7d0ca184
--- /dev/null
+++ b/scripts/glibcelf.py
@@ -0,0 +1,1135 @@
+#!/usr/bin/python3
+# ELF support functionality for Python.
+# Copyright (C) 2022 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+"""Basic ELF parser.
+
+Use Image.readfile(path) to read an ELF file into memory and begin
+parsing it.
+
+"""
+
+import collections
+import enum
+import struct
+
+class _OpenIntEnum(enum.IntEnum):
+ """Integer enumeration that supports arbitrary int values."""
+ @classmethod
+ def _missing_(cls, value):
+ # See enum.IntFlag._create_pseudo_member_. This allows
+ # creating of enum constants with arbitrary integer values.
+ pseudo_member = int.__new__(cls, value)
+ pseudo_member._name_ = None
+ pseudo_member._value_ = value
+ return pseudo_member
+
+ def __repr__(self):
+ name = self._name_
+ if name is not None:
+ # The names have prefixes like SHT_, implying their type.
+ return name
+ return '{}({})'.format(self.__class__.__name__, self._value_)
+
+ def __str__(self):
+ name = self._name_
+ if name is not None:
+ return name
+ return str(self._value_)
+
+class ElfClass(_OpenIntEnum):
+ """ELF word size. Type of EI_CLASS values."""
+ ELFCLASSNONE = 0
+ ELFCLASS32 = 1
+ ELFCLASS64 = 2
+
+class ElfData(_OpenIntEnum):
+ """ELF endianess. Type of EI_DATA values."""
+ ELFDATANONE = 0
+ ELFDATA2LSB = 1
+ ELFDATA2MSB = 2
+
+class Machine(_OpenIntEnum):
+ """ELF machine type. Type of values in Ehdr.e_machine field."""
+ EM_NONE = 0
+ EM_M32 = 1
+ EM_SPARC = 2
+ EM_386 = 3
+ EM_68K = 4
+ EM_88K = 5
+ EM_IAMCU = 6
+ EM_860 = 7
+ EM_MIPS = 8
+ EM_S370 = 9
+ EM_MIPS_RS3_LE = 10
+ EM_PARISC = 15
+ EM_VPP500 = 17
+ EM_SPARC32PLUS = 18
+ EM_960 = 19
+ EM_PPC = 20
+ EM_PPC64 = 21
+ EM_S390 = 22
+ EM_SPU = 23
+ EM_V800 = 36
+ EM_FR20 = 37
+ EM_RH32 = 38
+ EM_RCE = 39
+ EM_ARM = 40
+ EM_FAKE_ALPHA = 41
+ EM_SH = 42
+ EM_SPARCV9 = 43
+ EM_TRICORE = 44
+ EM_ARC = 45
+ EM_H8_300 = 46
+ EM_H8_300H = 47
+ EM_H8S = 48
+ EM_H8_500 = 49
+ EM_IA_64 = 50
+ EM_MIPS_X = 51
+ EM_COLDFIRE = 52
+ EM_68HC12 = 53
+ EM_MMA = 54
+ EM_PCP = 55
+ EM_NCPU = 56
+ EM_NDR1 = 57
+ EM_STARCORE = 58
+ EM_ME16 = 59
+ EM_ST100 = 60
+ EM_TINYJ = 61
+ EM_X86_64 = 62
+ EM_PDSP = 63
+ EM_PDP10 = 64
+ EM_PDP11 = 65
+ EM_FX66 = 66
+ EM_ST9PLUS = 67
+ EM_ST7 = 68
+ EM_68HC16 = 69
+ EM_68HC11 = 70
+ EM_68HC08 = 71
+ EM_68HC05 = 72
+ EM_SVX = 73
+ EM_ST19 = 74
+ EM_VAX = 75
+ EM_CRIS = 76
+ EM_JAVELIN = 77
+ EM_FIREPATH = 78
+ EM_ZSP = 79
+ EM_MMIX = 80
+ EM_HUANY = 81
+ EM_PRISM = 82
+ EM_AVR = 83
+ EM_FR30 = 84
+ EM_D10V = 85
+ EM_D30V = 86
+ EM_V850 = 87
+ EM_M32R = 88
+ EM_MN10300 = 89
+ EM_MN10200 = 90
+ EM_PJ = 91
+ EM_OPENRISC = 92
+ EM_ARC_COMPACT = 93
+ EM_XTENSA = 94
+ EM_VIDEOCORE = 95
+ EM_TMM_GPP = 96
+ EM_NS32K = 97
+ EM_TPC = 98
+ EM_SNP1K = 99
+ EM_ST200 = 100
+ EM_IP2K = 101
+ EM_MAX = 102
+ EM_CR = 103
+ EM_F2MC16 = 104
+ EM_MSP430 = 105
+ EM_BLACKFIN = 106
+ EM_SE_C33 = 107
+ EM_SEP = 108
+ EM_ARCA = 109
+ EM_UNICORE = 110
+ EM_EXCESS = 111
+ EM_DXP = 112
+ EM_ALTERA_NIOS2 = 113
+ EM_CRX = 114
+ EM_XGATE = 115
+ EM_C166 = 116
+ EM_M16C = 117
+ EM_DSPIC30F = 118
+ EM_CE = 119
+ EM_M32C = 120
+ EM_TSK3000 = 131
+ EM_RS08 = 132
+ EM_SHARC = 133
+ EM_ECOG2 = 134
+ EM_SCORE7 = 135
+ EM_DSP24 = 136
+ EM_VIDEOCORE3 = 137
+ EM_LATTICEMICO32 = 138
+ EM_SE_C17 = 139
+ EM_TI_C6000 = 140
+ EM_TI_C2000 = 141
+ EM_TI_C5500 = 142
+ EM_TI_ARP32 = 143
+ EM_TI_PRU = 144
+ EM_MMDSP_PLUS = 160
+ EM_CYPRESS_M8C = 161
+ EM_R32C = 162
+ EM_TRIMEDIA = 163
+ EM_QDSP6 = 164
+ EM_8051 = 165
+ EM_STXP7X = 166
+ EM_NDS32 = 167
+ EM_ECOG1X = 168
+ EM_MAXQ30 = 169
+ EM_XIMO16 = 170
+ EM_MANIK = 171
+ EM_CRAYNV2 = 172
+ EM_RX = 173
+ EM_METAG = 174
+ EM_MCST_ELBRUS = 175
+ EM_ECOG16 = 176
+ EM_CR16 = 177
+ EM_ETPU = 178
+ EM_SLE9X = 179
+ EM_L10M = 180
+ EM_K10M = 181
+ EM_AARCH64 = 183
+ EM_AVR32 = 185
+ EM_STM8 = 186
+ EM_TILE64 = 187
+ EM_TILEPRO = 188
+ EM_MICROBLAZE = 189
+ EM_CUDA = 190
+ EM_TILEGX = 191
+ EM_CLOUDSHIELD = 192
+ EM_COREA_1ST = 193
+ EM_COREA_2ND = 194
+ EM_ARCV2 = 195
+ EM_OPEN8 = 196
+ EM_RL78 = 197
+ EM_VIDEOCORE5 = 198
+ EM_78KOR = 199
+ EM_56800EX = 200
+ EM_BA1 = 201
+ EM_BA2 = 202
+ EM_XCORE = 203
+ EM_MCHP_PIC = 204
+ EM_INTELGT = 205
+ EM_KM32 = 210
+ EM_KMX32 = 211
+ EM_EMX16 = 212
+ EM_EMX8 = 213
+ EM_KVARC = 214
+ EM_CDP = 215
+ EM_COGE = 216
+ EM_COOL = 217
+ EM_NORC = 218
+ EM_CSR_KALIMBA = 219
+ EM_Z80 = 220
+ EM_VISIUM = 221
+ EM_FT32 = 222
+ EM_MOXIE = 223
+ EM_AMDGPU = 224
+ EM_RISCV = 243
+ EM_BPF = 247
+ EM_CSKY = 252
+ EM_NUM = 253
+ EM_ALPHA = 0x9026
+
+class Et(_OpenIntEnum):
+ """ELF file type. Type of ET_* values and the Ehdr.e_type field."""
+ ET_NONE = 0
+ ET_REL = 1
+ ET_EXEC = 2
+ ET_DYN = 3
+ ET_CORE = 4
+
+class Shn(_OpenIntEnum):
+ """ELF reserved section indices."""
+ SHN_UNDEF = 0
+ SHN_BEFORE = 0xff00
+ SHN_AFTER = 0xff01
+ SHN_ABS = 0xfff1
+ SHN_COMMON = 0xfff2
+ SHN_XINDEX = 0xffff
+
+class ShnMIPS(enum.Enum):
+ """Supplemental SHN_* constants for EM_MIPS."""
+ SHN_MIPS_ACOMMON = 0xff00
+ SHN_MIPS_TEXT = 0xff01
+ SHN_MIPS_DATA = 0xff02
+ SHN_MIPS_SCOMMON = 0xff03
+ SHN_MIPS_SUNDEFINED = 0xff04
+
+class ShnPARISC(enum.Enum):
+ """Supplemental SHN_* constants for EM_PARISC."""
+ SHN_PARISC_ANSI_COMMON = 0xff00
+ SHN_PARISC_HUGE_COMMON = 0xff01
+
+class Sht(_OpenIntEnum):
+ """ELF section types. Type of SHT_* values."""
+ SHT_NULL = 0
+ SHT_PROGBITS = 1
+ SHT_SYMTAB = 2
+ SHT_STRTAB = 3
+ SHT_RELA = 4
+ SHT_HASH = 5
+ SHT_DYNAMIC = 6
+ SHT_NOTE = 7
+ SHT_NOBITS = 8
+ SHT_REL = 9
+ SHT_SHLIB = 10
+ SHT_DYNSYM = 11
+ SHT_INIT_ARRAY = 14
+ SHT_FINI_ARRAY = 15
+ SHT_PREINIT_ARRAY = 16
+ SHT_GROUP = 17
+ SHT_SYMTAB_SHNDX = 18
+ SHT_GNU_ATTRIBUTES = 0x6ffffff5
+ SHT_GNU_HASH = 0x6ffffff6
+ SHT_GNU_LIBLIST = 0x6ffffff7
+ SHT_CHECKSUM = 0x6ffffff8
+ SHT_SUNW_move = 0x6ffffffa
+ SHT_SUNW_COMDAT = 0x6ffffffb
+ SHT_SUNW_syminfo = 0x6ffffffc
+ SHT_GNU_verdef = 0x6ffffffd
+ SHT_GNU_verneed = 0x6ffffffe
+ SHT_GNU_versym = 0x6fffffff
+
+class ShtALPHA(enum.Enum):
+ """Supplemental SHT_* constants for EM_ALPHA."""
+ SHT_ALPHA_DEBUG = 0x70000001
+ SHT_ALPHA_REGINFO = 0x70000002
+
+class ShtARM(enum.Enum):
+ """Supplemental SHT_* constants for EM_ARM."""
+ SHT_ARM_EXIDX = 0x70000001
+ SHT_ARM_PREEMPTMAP = 0x70000002
+ SHT_ARM_ATTRIBUTES = 0x70000003
+
+class ShtCSKY(enum.Enum):
+ """Supplemental SHT_* constants for EM_CSKY."""
+ SHT_CSKY_ATTRIBUTES = 0x70000001
+
+class ShtIA_64(enum.Enum):
+ """Supplemental SHT_* constants for EM_IA_64."""
+ SHT_IA_64_EXT = 0x70000000
+ SHT_IA_64_UNWIND = 0x70000001
+
+class ShtMIPS(enum.Enum):
+ """Supplemental SHT_* constants for EM_MIPS."""
+ SHT_MIPS_LIBLIST = 0x70000000
+ SHT_MIPS_MSYM = 0x70000001
+ SHT_MIPS_CONFLICT = 0x70000002
+ SHT_MIPS_GPTAB = 0x70000003
+ SHT_MIPS_UCODE = 0x70000004
+ SHT_MIPS_DEBUG = 0x70000005
+ SHT_MIPS_REGINFO = 0x70000006
+ SHT_MIPS_PACKAGE = 0x70000007
+ SHT_MIPS_PACKSYM = 0x70000008
+ SHT_MIPS_RELD = 0x70000009
+ SHT_MIPS_IFACE = 0x7000000b
+ SHT_MIPS_CONTENT = 0x7000000c
+ SHT_MIPS_OPTIONS = 0x7000000d
+ SHT_MIPS_SHDR = 0x70000010
+ SHT_MIPS_FDESC = 0x70000011
+ SHT_MIPS_EXTSYM = 0x70000012
+ SHT_MIPS_DENSE = 0x70000013
+ SHT_MIPS_PDESC = 0x70000014
+ SHT_MIPS_LOCSYM = 0x70000015
+ SHT_MIPS_AUXSYM = 0x70000016
+ SHT_MIPS_OPTSYM = 0x70000017
+ SHT_MIPS_LOCSTR = 0x70000018
+ SHT_MIPS_LINE = 0x70000019
+ SHT_MIPS_RFDESC = 0x7000001a
+ SHT_MIPS_DELTASYM = 0x7000001b
+ SHT_MIPS_DELTAINST = 0x7000001c
+ SHT_MIPS_DELTACLASS = 0x7000001d
+ SHT_MIPS_DWARF = 0x7000001e
+ SHT_MIPS_DELTADECL = 0x7000001f
+ SHT_MIPS_SYMBOL_LIB = 0x70000020
+ SHT_MIPS_EVENTS = 0x70000021
+ SHT_MIPS_TRANSLATE = 0x70000022
+ SHT_MIPS_PIXIE = 0x70000023
+ SHT_MIPS_XLATE = 0x70000024
+ SHT_MIPS_XLATE_DEBUG = 0x70000025
+ SHT_MIPS_WHIRL = 0x70000026
+ SHT_MIPS_EH_REGION = 0x70000027
+ SHT_MIPS_XLATE_OLD = 0x70000028
+ SHT_MIPS_PDR_EXCEPTION = 0x70000029
+ SHT_MIPS_XHASH = 0x7000002b
+
+class ShtPARISC(enum.Enum):
+ """Supplemental SHT_* constants for EM_PARISC."""
+ SHT_PARISC_EXT = 0x70000000
+ SHT_PARISC_UNWIND = 0x70000001
+ SHT_PARISC_DOC = 0x70000002
+
+class Pf(enum.IntFlag):
+ """Program header flags. Type of Phdr.p_flags values."""
+ PF_X = 1
+ PF_W = 2
+ PF_R = 4
+
+class PfARM(enum.IntFlag):
+ """Supplemental PF_* flags for EM_ARM."""
+ PF_ARM_SB = 0x10000000
+ PF_ARM_PI = 0x20000000
+ PF_ARM_ABS = 0x40000000
+
+class PfPARISC(enum.IntFlag):
+ """Supplemental PF_* flags for EM_PARISC."""
+ PF_HP_PAGE_SIZE = 0x00100000
+ PF_HP_FAR_SHARED = 0x00200000
+ PF_HP_NEAR_SHARED = 0x00400000
+ PF_HP_CODE = 0x01000000
+ PF_HP_MODIFY = 0x02000000
+ PF_HP_LAZYSWAP = 0x04000000
+ PF_HP_SBP = 0x08000000
+
+class PfIA_64(enum.IntFlag):
+ """Supplemental PF_* flags for EM_IA_64."""
+ PF_IA_64_NORECOV = 0x80000000
+
+class PfMIPS(enum.IntFlag):
+ """Supplemental PF_* flags for EM_MIPS."""
+ PF_MIPS_LOCAL = 0x10000000
+
+class Shf(enum.IntFlag):
+ """Section flags. Type of Shdr.sh_type values."""
+ SHF_WRITE = 1 << 0
+ SHF_ALLOC = 1 << 1
+ SHF_EXECINSTR = 1 << 2
+ SHF_MERGE = 1 << 4
+ SHF_STRINGS = 1 << 5
+ SHF_INFO_LINK = 1 << 6
+ SHF_LINK_ORDER = 1 << 7
+ SHF_OS_NONCONFORMING = 256
+ SHF_GROUP = 1 << 9
+ SHF_TLS = 1 << 10
+ SHF_COMPRESSED = 1 << 11
+ SHF_GNU_RETAIN = 1 << 21
+ SHF_ORDERED = 1 << 30
+ SHF_EXCLUDE = 1 << 31
+
+class ShfALPHA(enum.IntFlag):
+ """Supplemental SHF_* constants for EM_ALPHA."""
+ SHF_ALPHA_GPREL = 0x10000000
+
+class ShfARM(enum.IntFlag):
+ """Supplemental SHF_* constants for EM_ARM."""
+ SHF_ARM_ENTRYSECT = 0x10000000
+ SHF_ARM_COMDEF = 0x80000000
+
+class ShfIA_64(enum.IntFlag):
+ """Supplemental SHF_* constants for EM_IA_64."""
+ SHF_IA_64_SHORT = 0x10000000
+ SHF_IA_64_NORECOV = 0x20000000
+
+class ShfMIPS(enum.IntFlag):
+ """Supplemental SHF_* constants for EM_MIPS."""
+ SHF_MIPS_GPREL = 0x10000000
+ SHF_MIPS_MERGE = 0x20000000
+ SHF_MIPS_ADDR = 0x40000000
+ SHF_MIPS_STRINGS = 0x80000000
+ SHF_MIPS_NOSTRIP = 0x08000000
+ SHF_MIPS_LOCAL = 0x04000000
+ SHF_MIPS_NAMES = 0x02000000
+ SHF_MIPS_NODUPE = 0x01000000
+
+class ShfPARISC(enum.IntFlag):
+ """Supplemental SHF_* constants for EM_PARISC."""
+ SHF_PARISC_SHORT = 0x20000000
+ SHF_PARISC_HUGE = 0x40000000
+ SHF_PARISC_SBP = 0x80000000
+
+class Stb(_OpenIntEnum):
+ """ELF symbol binding type."""
+ STB_LOCAL = 0
+ STB_GLOBAL = 1
+ STB_WEAK = 2
+ STB_GNU_UNIQUE = 10
+ STB_MIPS_SPLIT_COMMON = 13
+
+class Stt(_OpenIntEnum):
+ """ELF symbol type."""
+ STT_NOTYPE = 0
+ STT_OBJECT = 1
+ STT_FUNC = 2
+ STT_SECTION = 3
+ STT_FILE = 4
+ STT_COMMON = 5
+ STT_TLS = 6
+ STT_GNU_IFUNC = 10
+
+class SttARM(enum.Enum):
+ """Supplemental STT_* constants for EM_ARM."""
+ STT_ARM_TFUNC = 13
+ STT_ARM_16BIT = 15
+
+class SttPARISC(enum.Enum):
+ """Supplemental STT_* constants for EM_PARISC."""
+ STT_HP_OPAQUE = 11
+ STT_HP_STUB = 12
+ STT_PARISC_MILLICODE = 13
+
+class SttSPARC(enum.Enum):
+ """Supplemental STT_* constants for EM_SPARC."""
+ STT_SPARC_REGISTER = 13
+
+class SttX86_64(enum.Enum):
+ """Supplemental STT_* constants for EM_X86_64."""
+ SHT_X86_64_UNWIND = 0x70000001
+
+class Pt(_OpenIntEnum):
+ """ELF program header types. Type of Phdr.p_type."""
+ PT_NULL = 0
+ PT_LOAD = 1
+ PT_DYNAMIC = 2
+ PT_INTERP = 3
+ PT_NOTE = 4
+ PT_SHLIB = 5
+ PT_PHDR = 6
+ PT_TLS = 7
+ PT_NUM = 8
+ PT_GNU_EH_FRAME = 0x6474e550
+ PT_GNU_STACK = 0x6474e551
+ PT_GNU_RELRO = 0x6474e552
+ PT_GNU_PROPERTY = 0x6474e553
+ PT_SUNWBSS = 0x6ffffffa
+ PT_SUNWSTACK = 0x6ffffffb
+
+class PtARM(enum.Enum):
+ """Supplemental PT_* constants for EM_ARM."""
+ PT_ARM_EXIDX = 0x70000001
+
+class PtIA_64(enum.Enum):
+ """Supplemental PT_* constants for EM_IA_64."""
+ PT_IA_64_HP_OPT_ANOT = 0x60000012
+ PT_IA_64_HP_HSL_ANOT = 0x60000013
+ PT_IA_64_HP_STACK = 0x60000014
+ PT_IA_64_ARCHEXT = 0x70000000
+ PT_IA_64_UNWIND = 0x70000001
+
+class PtMIPS(enum.Enum):
+ """Supplemental PT_* constants for EM_MIPS."""
+ PT_MIPS_REGINFO = 0x70000000
+ PT_MIPS_RTPROC = 0x70000001
+ PT_MIPS_OPTIONS = 0x70000002
+ PT_MIPS_ABIFLAGS = 0x70000003
+
+class PtPARISC(enum.Enum):
+ """Supplemental PT_* constants for EM_PARISC."""
+ PT_HP_TLS = 0x60000000
+ PT_HP_CORE_NONE = 0x60000001
+ PT_HP_CORE_VERSION = 0x60000002
+ PT_HP_CORE_KERNEL = 0x60000003
+ PT_HP_CORE_COMM = 0x60000004
+ PT_HP_CORE_PROC = 0x60000005
+ PT_HP_CORE_LOADABLE = 0x60000006
+ PT_HP_CORE_STACK = 0x60000007
+ PT_HP_CORE_SHM = 0x60000008
+ PT_HP_CORE_MMF = 0x60000009
+ PT_HP_PARALLEL = 0x60000010
+ PT_HP_FASTBIND = 0x60000011
+ PT_HP_OPT_ANNOT = 0x60000012
+ PT_HP_HSL_ANNOT = 0x60000013
+ PT_HP_STACK = 0x60000014
+ PT_PARISC_ARCHEXT = 0x70000000
+ PT_PARISC_UNWIND = 0x70000001
+
+class Dt(_OpenIntEnum):
+ """ELF dynamic segment tags. Type of Dyn.d_val."""
+ DT_NULL = 0
+ DT_NEEDED = 1
+ DT_PLTRELSZ = 2
+ DT_PLTGOT = 3
+ DT_HASH = 4
+ DT_STRTAB = 5
+ DT_SYMTAB = 6
+ DT_RELA = 7
+ DT_RELASZ = 8
+ DT_RELAENT = 9
+ DT_STRSZ = 10
+ DT_SYMENT = 11
+ DT_INIT = 12
+ DT_FINI = 13
+ DT_SONAME = 14
+ DT_RPATH = 15
+ DT_SYMBOLIC = 16
+ DT_REL = 17
+ DT_RELSZ = 18
+ DT_RELENT = 19
+ DT_PLTREL = 20
+ DT_DEBUG = 21
+ DT_TEXTREL = 22
+ DT_JMPREL = 23
+ DT_BIND_NOW = 24
+ DT_INIT_ARRAY = 25
+ DT_FINI_ARRAY = 26
+ DT_INIT_ARRAYSZ = 27
+ DT_FINI_ARRAYSZ = 28
+ DT_RUNPATH = 29
+ DT_FLAGS = 30
+ DT_PREINIT_ARRAY = 32
+ DT_PREINIT_ARRAYSZ = 33
+ DT_SYMTAB_SHNDX = 34
+ DT_GNU_PRELINKED = 0x6ffffdf5
+ DT_GNU_CONFLICTSZ = 0x6ffffdf6
+ DT_GNU_LIBLISTSZ = 0x6ffffdf7
+ DT_CHECKSUM = 0x6ffffdf8
+ DT_PLTPADSZ = 0x6ffffdf9
+ DT_MOVEENT = 0x6ffffdfa
+ DT_MOVESZ = 0x6ffffdfb
+ DT_FEATURE_1 = 0x6ffffdfc
+ DT_POSFLAG_1 = 0x6ffffdfd
+ DT_SYMINSZ = 0x6ffffdfe
+ DT_SYMINENT = 0x6ffffdff
+ DT_GNU_HASH = 0x6ffffef5
+ DT_TLSDESC_PLT = 0x6ffffef6
+ DT_TLSDESC_GOT = 0x6ffffef7
+ DT_GNU_CONFLICT = 0x6ffffef8
+ DT_GNU_LIBLIST = 0x6ffffef9
+ DT_CONFIG = 0x6ffffefa
+ DT_DEPAUDIT = 0x6ffffefb
+ DT_AUDIT = 0x6ffffefc
+ DT_PLTPAD = 0x6ffffefd
+ DT_MOVETAB = 0x6ffffefe
+ DT_SYMINFO = 0x6ffffeff
+ DT_VERSYM = 0x6ffffff0
+ DT_RELACOUNT = 0x6ffffff9
+ DT_RELCOUNT = 0x6ffffffa
+ DT_FLAGS_1 = 0x6ffffffb
+ DT_VERDEF = 0x6ffffffc
+ DT_VERDEFNUM = 0x6ffffffd
+ DT_VERNEED = 0x6ffffffe
+ DT_VERNEEDNUM = 0x6fffffff
+ DT_AUXILIARY = 0x7ffffffd
+ DT_FILTER = 0x7fffffff
+
+class DtAARCH64(enum.Enum):
+ """Supplemental DT_* constants for EM_AARCH64."""
+ DT_AARCH64_BTI_PLT = 0x70000001
+ DT_AARCH64_PAC_PLT = 0x70000003
+ DT_AARCH64_VARIANT_PCS = 0x70000005
+
+class DtALPHA(enum.Enum):
+ """Supplemental DT_* constants for EM_ALPHA."""
+ DT_ALPHA_PLTRO = 0x70000000
+
+class DtALTERA_NIOS2(enum.Enum):
+ """Supplemental DT_* constants for EM_ALTERA_NIOS2."""
+ DT_NIOS2_GP = 0x70000002
+
+class DtIA_64(enum.Enum):
+ """Supplemental DT_* constants for EM_IA_64."""
+ DT_IA_64_PLT_RESERVE = 0x70000000
+
+class DtMIPS(enum.Enum):
+ """Supplemental DT_* constants for EM_MIPS."""
+ DT_MIPS_RLD_VERSION = 0x70000001
+ DT_MIPS_TIME_STAMP = 0x70000002
+ DT_MIPS_ICHECKSUM = 0x70000003
+ DT_MIPS_IVERSION = 0x70000004
+ DT_MIPS_FLAGS = 0x70000005
+ DT_MIPS_BASE_ADDRESS = 0x70000006
+ DT_MIPS_MSYM = 0x70000007
+ DT_MIPS_CONFLICT = 0x70000008
+ DT_MIPS_LIBLIST = 0x70000009
+ DT_MIPS_LOCAL_GOTNO = 0x7000000a
+ DT_MIPS_CONFLICTNO = 0x7000000b
+ DT_MIPS_LIBLISTNO = 0x70000010
+ DT_MIPS_SYMTABNO = 0x70000011
+ DT_MIPS_UNREFEXTNO = 0x70000012
+ DT_MIPS_GOTSYM = 0x70000013
+ DT_MIPS_HIPAGENO = 0x70000014
+ DT_MIPS_RLD_MAP = 0x70000016
+ DT_MIPS_DELTA_CLASS = 0x70000017
+ DT_MIPS_DELTA_CLASS_NO = 0x70000018
+ DT_MIPS_DELTA_INSTANCE = 0x70000019
+ DT_MIPS_DELTA_INSTANCE_NO = 0x7000001a
+ DT_MIPS_DELTA_RELOC = 0x7000001b
+ DT_MIPS_DELTA_RELOC_NO = 0x7000001c
+ DT_MIPS_DELTA_SYM = 0x7000001d
+ DT_MIPS_DELTA_SYM_NO = 0x7000001e
+ DT_MIPS_DELTA_CLASSSYM = 0x70000020
+ DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021
+ DT_MIPS_CXX_FLAGS = 0x70000022
+ DT_MIPS_PIXIE_INIT = 0x70000023
+ DT_MIPS_SYMBOL_LIB = 0x70000024
+ DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025
+ DT_MIPS_LOCAL_GOTIDX = 0x70000026
+ DT_MIPS_HIDDEN_GOTIDX = 0x70000027
+ DT_MIPS_PROTECTED_GOTIDX = 0x70000028
+ DT_MIPS_OPTIONS = 0x70000029
+ DT_MIPS_INTERFACE = 0x7000002a
+ DT_MIPS_DYNSTR_ALIGN = 0x7000002b
+ DT_MIPS_INTERFACE_SIZE = 0x7000002c
+ DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002d
+ DT_MIPS_PERF_SUFFIX = 0x7000002e
+ DT_MIPS_COMPACT_SIZE = 0x7000002f
+ DT_MIPS_GP_VALUE = 0x70000030
+ DT_MIPS_AUX_DYNAMIC = 0x70000031
+ DT_MIPS_PLTGOT = 0x70000032
+ DT_MIPS_RWPLT = 0x70000034
+ DT_MIPS_RLD_MAP_REL = 0x70000035
+ DT_MIPS_XHASH = 0x70000036
+
+class DtPPC(enum.Enum):
+ """Supplemental DT_* constants for EM_PPC."""
+ DT_PPC_GOT = 0x70000000
+ DT_PPC_OPT = 0x70000001
+
+class DtPPC64(enum.Enum):
+ """Supplemental DT_* constants for EM_PPC64."""
+ DT_PPC64_GLINK = 0x70000000
+ DT_PPC64_OPD = 0x70000001
+ DT_PPC64_OPDSZ = 0x70000002
+ DT_PPC64_OPT = 0x70000003
+
+class DtSPARC(enum.Enum):
+ """Supplemental DT_* constants for EM_SPARC."""
+ DT_SPARC_REGISTER = 0x70000001
+
+class StInfo:
+ """ELF symbol binding and type. Type of the Sym.st_info field."""
+ def __init__(self, arg0, arg1=None):
+ if isinstance(arg0, int) and arg1 is None:
+ self.bind = Stb(arg0 >> 4)
+ self.type = Stt(arg0 & 15)
+ else:
+ self.bind = Stb(arg0)
+ self.type = Stt(arg1)
+
+ def value(self):
+ """Returns the raw value for the bind/type combination."""
+ return (self.bind.value() << 4) | (self.type.value())
+
+# Type in an ELF file. Used for deserialization.
+_Layout = collections.namedtuple('_Layout', 'unpack size')
+
+def _define_layouts(baseclass: type, layout32: str, layout64: str,
+ types=None, fields32=None):
+ """Assign variants dict to baseclass.
+
+ The variants dict is indexed by (ElfClass, ElfData) pairs, and its
+ values are _Layout instances.
+
+ """
+ struct32 = struct.Struct(layout32)
+ struct64 = struct.Struct(layout64)
+
+ # Check that the struct formats yield the right number of components.
+ for s in (struct32, struct64):
+ example = s.unpack(b' ' * s.size)
+ if len(example) != len(baseclass._fields):
+ raise ValueError('{!r} yields wrong field count: {} != {}'.format(
+ s.format, len(example), len(baseclass._fields)))
+
+ # Check that field names in types are correct.
+ if types is None:
+ types = ()
+ for n in types:
+ if n not in baseclass._fields:
+ raise ValueError('{} does not have field {!r}'.format(
+ baseclass.__name__, n))
+
+ if fields32 is not None \
+ and set(fields32) != set(baseclass._fields):
+ raise ValueError('{!r} is not a permutation of the fields {!r}'.format(
+ fields32, baseclass._fields))
+
+ def unique_name(name, used_names = (set((baseclass.__name__,))
+ | set(baseclass._fields)
+ | {n.__name__
+ for n in (types or {}).values()})):
+ """Find a name that is not used for a class or field name."""
+ candidate = name
+ n = 0
+ while candidate in used_names:
+ n += 1
+ candidate = '{}{}'.format(name, n)
+ used_names.add(candidate)
+ return candidate
+
+ blob_name = unique_name('blob')
+ struct_unpack_name = unique_name('struct_unpack')
+ comps_name = unique_name('comps')
+
+ layouts = {}
+ for (bits, elfclass, layout, fields) in (
+ (32, ElfClass.ELFCLASS32, layout32, fields32),
+ (64, ElfClass.ELFCLASS64, layout64, None),
+ ):
+ for (elfdata, structprefix, funcsuffix) in (
+ (ElfData.ELFDATA2LSB, '<', 'LE'),
+ (ElfData.ELFDATA2MSB, '>', 'BE'),
+ ):
+ env = {
+ baseclass.__name__: baseclass,
+ struct_unpack_name: struct.unpack,
+ }
+
+ # Add the type converters.
+ if types:
+ for cls in types.values():
+ env[cls.__name__] = cls
+
+ funcname = ''.join(
+ ('unpack_', baseclass.__name__, str(bits), funcsuffix))
+
+ code = '''
+def {funcname}({blob_name}):
+'''.format(funcname=funcname, blob_name=blob_name)
+
+ indent = ' ' * 4
+ unpack_call = '{}({!r}, {})'.format(
+ struct_unpack_name, structprefix + layout, blob_name)
+ field_names = ', '.join(baseclass._fields)
+