elf: Define DT_RELR related macros and types
[glibc.git] / scripts / glibcelf.py
blobf847b36c55c15b8a6e4dcb1805b660c2730253c0
1 #!/usr/bin/python3
2 # ELF support functionality for Python.
3 # Copyright (C) 2022 Free Software Foundation, Inc.
4 # This file is part of the GNU C Library.
6 # The GNU C Library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # The GNU C Library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with the GNU C Library; if not, see
18 # <https://www.gnu.org/licenses/>.
20 """Basic ELF parser.
22 Use Image.readfile(path) to read an ELF file into memory and begin
23 parsing it.
25 """
27 import collections
28 import enum
29 import struct
31 if not hasattr(enum, 'IntFlag'):
32 import sys
33 sys.stdout.write(
34 'warning: glibcelf.py needs Python 3.6 for enum support\n')
35 sys.exit(77)
37 class _OpenIntEnum(enum.IntEnum):
38 """Integer enumeration that supports arbitrary int values."""
39 @classmethod
40 def _missing_(cls, value):
41 # See enum.IntFlag._create_pseudo_member_. This allows
42 # creating of enum constants with arbitrary integer values.
43 pseudo_member = int.__new__(cls, value)
44 pseudo_member._name_ = None
45 pseudo_member._value_ = value
46 return pseudo_member
48 def __repr__(self):
49 name = self._name_
50 if name is not None:
51 # The names have prefixes like SHT_, implying their type.
52 return name
53 return '{}({})'.format(self.__class__.__name__, self._value_)
55 def __str__(self):
56 name = self._name_
57 if name is not None:
58 return name
59 return str(self._value_)
61 class ElfClass(_OpenIntEnum):
62 """ELF word size. Type of EI_CLASS values."""
63 ELFCLASSNONE = 0
64 ELFCLASS32 = 1
65 ELFCLASS64 = 2
67 class ElfData(_OpenIntEnum):
68 """ELF endianess. Type of EI_DATA values."""
69 ELFDATANONE = 0
70 ELFDATA2LSB = 1
71 ELFDATA2MSB = 2
73 class Machine(_OpenIntEnum):
74 """ELF machine type. Type of values in Ehdr.e_machine field."""
75 EM_NONE = 0
76 EM_M32 = 1
77 EM_SPARC = 2
78 EM_386 = 3
79 EM_68K = 4
80 EM_88K = 5
81 EM_IAMCU = 6
82 EM_860 = 7
83 EM_MIPS = 8
84 EM_S370 = 9
85 EM_MIPS_RS3_LE = 10
86 EM_PARISC = 15
87 EM_VPP500 = 17
88 EM_SPARC32PLUS = 18
89 EM_960 = 19
90 EM_PPC = 20
91 EM_PPC64 = 21
92 EM_S390 = 22
93 EM_SPU = 23
94 EM_V800 = 36
95 EM_FR20 = 37
96 EM_RH32 = 38
97 EM_RCE = 39
98 EM_ARM = 40
99 EM_FAKE_ALPHA = 41
100 EM_SH = 42
101 EM_SPARCV9 = 43
102 EM_TRICORE = 44
103 EM_ARC = 45
104 EM_H8_300 = 46
105 EM_H8_300H = 47
106 EM_H8S = 48
107 EM_H8_500 = 49
108 EM_IA_64 = 50
109 EM_MIPS_X = 51
110 EM_COLDFIRE = 52
111 EM_68HC12 = 53
112 EM_MMA = 54
113 EM_PCP = 55
114 EM_NCPU = 56
115 EM_NDR1 = 57
116 EM_STARCORE = 58
117 EM_ME16 = 59
118 EM_ST100 = 60
119 EM_TINYJ = 61
120 EM_X86_64 = 62
121 EM_PDSP = 63
122 EM_PDP10 = 64
123 EM_PDP11 = 65
124 EM_FX66 = 66
125 EM_ST9PLUS = 67
126 EM_ST7 = 68
127 EM_68HC16 = 69
128 EM_68HC11 = 70
129 EM_68HC08 = 71
130 EM_68HC05 = 72
131 EM_SVX = 73
132 EM_ST19 = 74
133 EM_VAX = 75
134 EM_CRIS = 76
135 EM_JAVELIN = 77
136 EM_FIREPATH = 78
137 EM_ZSP = 79
138 EM_MMIX = 80
139 EM_HUANY = 81
140 EM_PRISM = 82
141 EM_AVR = 83
142 EM_FR30 = 84
143 EM_D10V = 85
144 EM_D30V = 86
145 EM_V850 = 87
146 EM_M32R = 88
147 EM_MN10300 = 89
148 EM_MN10200 = 90
149 EM_PJ = 91
150 EM_OPENRISC = 92
151 EM_ARC_COMPACT = 93
152 EM_XTENSA = 94
153 EM_VIDEOCORE = 95
154 EM_TMM_GPP = 96
155 EM_NS32K = 97
156 EM_TPC = 98
157 EM_SNP1K = 99
158 EM_ST200 = 100
159 EM_IP2K = 101
160 EM_MAX = 102
161 EM_CR = 103
162 EM_F2MC16 = 104
163 EM_MSP430 = 105
164 EM_BLACKFIN = 106
165 EM_SE_C33 = 107
166 EM_SEP = 108
167 EM_ARCA = 109
168 EM_UNICORE = 110
169 EM_EXCESS = 111
170 EM_DXP = 112
171 EM_ALTERA_NIOS2 = 113
172 EM_CRX = 114
173 EM_XGATE = 115
174 EM_C166 = 116
175 EM_M16C = 117
176 EM_DSPIC30F = 118
177 EM_CE = 119
178 EM_M32C = 120
179 EM_TSK3000 = 131
180 EM_RS08 = 132
181 EM_SHARC = 133
182 EM_ECOG2 = 134
183 EM_SCORE7 = 135
184 EM_DSP24 = 136
185 EM_VIDEOCORE3 = 137
186 EM_LATTICEMICO32 = 138
187 EM_SE_C17 = 139
188 EM_TI_C6000 = 140
189 EM_TI_C2000 = 141
190 EM_TI_C5500 = 142
191 EM_TI_ARP32 = 143
192 EM_TI_PRU = 144
193 EM_MMDSP_PLUS = 160
194 EM_CYPRESS_M8C = 161
195 EM_R32C = 162
196 EM_TRIMEDIA = 163
197 EM_QDSP6 = 164
198 EM_8051 = 165
199 EM_STXP7X = 166
200 EM_NDS32 = 167
201 EM_ECOG1X = 168
202 EM_MAXQ30 = 169
203 EM_XIMO16 = 170
204 EM_MANIK = 171
205 EM_CRAYNV2 = 172
206 EM_RX = 173
207 EM_METAG = 174
208 EM_MCST_ELBRUS = 175
209 EM_ECOG16 = 176
210 EM_CR16 = 177
211 EM_ETPU = 178
212 EM_SLE9X = 179
213 EM_L10M = 180
214 EM_K10M = 181
215 EM_AARCH64 = 183
216 EM_AVR32 = 185
217 EM_STM8 = 186
218 EM_TILE64 = 187
219 EM_TILEPRO = 188
220 EM_MICROBLAZE = 189
221 EM_CUDA = 190
222 EM_TILEGX = 191
223 EM_CLOUDSHIELD = 192
224 EM_COREA_1ST = 193
225 EM_COREA_2ND = 194
226 EM_ARCV2 = 195
227 EM_OPEN8 = 196
228 EM_RL78 = 197
229 EM_VIDEOCORE5 = 198
230 EM_78KOR = 199
231 EM_56800EX = 200
232 EM_BA1 = 201
233 EM_BA2 = 202
234 EM_XCORE = 203
235 EM_MCHP_PIC = 204
236 EM_INTELGT = 205
237 EM_KM32 = 210
238 EM_KMX32 = 211
239 EM_EMX16 = 212
240 EM_EMX8 = 213
241 EM_KVARC = 214
242 EM_CDP = 215
243 EM_COGE = 216
244 EM_COOL = 217
245 EM_NORC = 218
246 EM_CSR_KALIMBA = 219
247 EM_Z80 = 220
248 EM_VISIUM = 221
249 EM_FT32 = 222
250 EM_MOXIE = 223
251 EM_AMDGPU = 224
252 EM_RISCV = 243
253 EM_BPF = 247
254 EM_CSKY = 252
255 EM_NUM = 253
256 EM_ALPHA = 0x9026
258 class Et(_OpenIntEnum):
259 """ELF file type. Type of ET_* values and the Ehdr.e_type field."""
260 ET_NONE = 0
261 ET_REL = 1
262 ET_EXEC = 2
263 ET_DYN = 3
264 ET_CORE = 4
266 class Shn(_OpenIntEnum):
267 """ELF reserved section indices."""
268 SHN_UNDEF = 0
269 SHN_BEFORE = 0xff00
270 SHN_AFTER = 0xff01
271 SHN_ABS = 0xfff1
272 SHN_COMMON = 0xfff2
273 SHN_XINDEX = 0xffff
275 class ShnMIPS(enum.Enum):
276 """Supplemental SHN_* constants for EM_MIPS."""
277 SHN_MIPS_ACOMMON = 0xff00
278 SHN_MIPS_TEXT = 0xff01
279 SHN_MIPS_DATA = 0xff02
280 SHN_MIPS_SCOMMON = 0xff03
281 SHN_MIPS_SUNDEFINED = 0xff04
283 class ShnPARISC(enum.Enum):
284 """Supplemental SHN_* constants for EM_PARISC."""
285 SHN_PARISC_ANSI_COMMON = 0xff00
286 SHN_PARISC_HUGE_COMMON = 0xff01
288 class Sht(_OpenIntEnum):
289 """ELF section types. Type of SHT_* values."""
290 SHT_NULL = 0
291 SHT_PROGBITS = 1
292 SHT_SYMTAB = 2
293 SHT_STRTAB = 3
294 SHT_RELA = 4
295 SHT_HASH = 5
296 SHT_DYNAMIC = 6
297 SHT_NOTE = 7
298 SHT_NOBITS = 8
299 SHT_REL = 9
300 SHT_SHLIB = 10
301 SHT_DYNSYM = 11
302 SHT_INIT_ARRAY = 14
303 SHT_FINI_ARRAY = 15
304 SHT_PREINIT_ARRAY = 16
305 SHT_GROUP = 17
306 SHT_SYMTAB_SHNDX = 18
307 SHT_RELR = 19
308 SHT_GNU_ATTRIBUTES = 0x6ffffff5
309 SHT_GNU_HASH = 0x6ffffff6
310 SHT_GNU_LIBLIST = 0x6ffffff7
311 SHT_CHECKSUM = 0x6ffffff8
312 SHT_SUNW_move = 0x6ffffffa
313 SHT_SUNW_COMDAT = 0x6ffffffb
314 SHT_SUNW_syminfo = 0x6ffffffc
315 SHT_GNU_verdef = 0x6ffffffd
316 SHT_GNU_verneed = 0x6ffffffe
317 SHT_GNU_versym = 0x6fffffff
319 class ShtALPHA(enum.Enum):
320 """Supplemental SHT_* constants for EM_ALPHA."""
321 SHT_ALPHA_DEBUG = 0x70000001
322 SHT_ALPHA_REGINFO = 0x70000002
324 class ShtARM(enum.Enum):
325 """Supplemental SHT_* constants for EM_ARM."""
326 SHT_ARM_EXIDX = 0x70000001
327 SHT_ARM_PREEMPTMAP = 0x70000002
328 SHT_ARM_ATTRIBUTES = 0x70000003
330 class ShtCSKY(enum.Enum):
331 """Supplemental SHT_* constants for EM_CSKY."""
332 SHT_CSKY_ATTRIBUTES = 0x70000001
334 class ShtIA_64(enum.Enum):
335 """Supplemental SHT_* constants for EM_IA_64."""
336 SHT_IA_64_EXT = 0x70000000
337 SHT_IA_64_UNWIND = 0x70000001
339 class ShtMIPS(enum.Enum):
340 """Supplemental SHT_* constants for EM_MIPS."""
341 SHT_MIPS_LIBLIST = 0x70000000
342 SHT_MIPS_MSYM = 0x70000001
343 SHT_MIPS_CONFLICT = 0x70000002
344 SHT_MIPS_GPTAB = 0x70000003
345 SHT_MIPS_UCODE = 0x70000004
346 SHT_MIPS_DEBUG = 0x70000005
347 SHT_MIPS_REGINFO = 0x70000006
348 SHT_MIPS_PACKAGE = 0x70000007
349 SHT_MIPS_PACKSYM = 0x70000008
350 SHT_MIPS_RELD = 0x70000009
351 SHT_MIPS_IFACE = 0x7000000b
352 SHT_MIPS_CONTENT = 0x7000000c
353 SHT_MIPS_OPTIONS = 0x7000000d
354 SHT_MIPS_SHDR = 0x70000010
355 SHT_MIPS_FDESC = 0x70000011
356 SHT_MIPS_EXTSYM = 0x70000012
357 SHT_MIPS_DENSE = 0x70000013
358 SHT_MIPS_PDESC = 0x70000014
359 SHT_MIPS_LOCSYM = 0x70000015
360 SHT_MIPS_AUXSYM = 0x70000016
361 SHT_MIPS_OPTSYM = 0x70000017
362 SHT_MIPS_LOCSTR = 0x70000018
363 SHT_MIPS_LINE = 0x70000019
364 SHT_MIPS_RFDESC = 0x7000001a
365 SHT_MIPS_DELTASYM = 0x7000001b
366 SHT_MIPS_DELTAINST = 0x7000001c
367 SHT_MIPS_DELTACLASS = 0x7000001d
368 SHT_MIPS_DWARF = 0x7000001e
369 SHT_MIPS_DELTADECL = 0x7000001f
370 SHT_MIPS_SYMBOL_LIB = 0x70000020
371 SHT_MIPS_EVENTS = 0x70000021
372 SHT_MIPS_TRANSLATE = 0x70000022
373 SHT_MIPS_PIXIE = 0x70000023
374 SHT_MIPS_XLATE = 0x70000024
375 SHT_MIPS_XLATE_DEBUG = 0x70000025
376 SHT_MIPS_WHIRL = 0x70000026
377 SHT_MIPS_EH_REGION = 0x70000027
378 SHT_MIPS_XLATE_OLD = 0x70000028
379 SHT_MIPS_PDR_EXCEPTION = 0x70000029
380 SHT_MIPS_XHASH = 0x7000002b
382 class ShtPARISC(enum.Enum):
383 """Supplemental SHT_* constants for EM_PARISC."""
384 SHT_PARISC_EXT = 0x70000000
385 SHT_PARISC_UNWIND = 0x70000001
386 SHT_PARISC_DOC = 0x70000002
388 class Pf(enum.IntFlag):
389 """Program header flags. Type of Phdr.p_flags values."""
390 PF_X = 1
391 PF_W = 2
392 PF_R = 4
394 class PfARM(enum.IntFlag):
395 """Supplemental PF_* flags for EM_ARM."""
396 PF_ARM_SB = 0x10000000
397 PF_ARM_PI = 0x20000000
398 PF_ARM_ABS = 0x40000000
400 class PfPARISC(enum.IntFlag):
401 """Supplemental PF_* flags for EM_PARISC."""
402 PF_HP_PAGE_SIZE = 0x00100000
403 PF_HP_FAR_SHARED = 0x00200000
404 PF_HP_NEAR_SHARED = 0x00400000
405 PF_HP_CODE = 0x01000000
406 PF_HP_MODIFY = 0x02000000
407 PF_HP_LAZYSWAP = 0x04000000
408 PF_HP_SBP = 0x08000000
410 class PfIA_64(enum.IntFlag):
411 """Supplemental PF_* flags for EM_IA_64."""
412 PF_IA_64_NORECOV = 0x80000000
414 class PfMIPS(enum.IntFlag):
415 """Supplemental PF_* flags for EM_MIPS."""
416 PF_MIPS_LOCAL = 0x10000000
418 class Shf(enum.IntFlag):
419 """Section flags. Type of Shdr.sh_type values."""
420 SHF_WRITE = 1 << 0
421 SHF_ALLOC = 1 << 1
422 SHF_EXECINSTR = 1 << 2
423 SHF_MERGE = 1 << 4
424 SHF_STRINGS = 1 << 5
425 SHF_INFO_LINK = 1 << 6
426 SHF_LINK_ORDER = 1 << 7
427 SHF_OS_NONCONFORMING = 256
428 SHF_GROUP = 1 << 9
429 SHF_TLS = 1 << 10
430 SHF_COMPRESSED = 1 << 11
431 SHF_GNU_RETAIN = 1 << 21
432 SHF_ORDERED = 1 << 30
433 SHF_EXCLUDE = 1 << 31
435 class ShfALPHA(enum.IntFlag):
436 """Supplemental SHF_* constants for EM_ALPHA."""
437 SHF_ALPHA_GPREL = 0x10000000
439 class ShfARM(enum.IntFlag):
440 """Supplemental SHF_* constants for EM_ARM."""
441 SHF_ARM_ENTRYSECT = 0x10000000
442 SHF_ARM_COMDEF = 0x80000000
444 class ShfIA_64(enum.IntFlag):
445 """Supplemental SHF_* constants for EM_IA_64."""
446 SHF_IA_64_SHORT = 0x10000000
447 SHF_IA_64_NORECOV = 0x20000000
449 class ShfMIPS(enum.IntFlag):
450 """Supplemental SHF_* constants for EM_MIPS."""
451 SHF_MIPS_GPREL = 0x10000000
452 SHF_MIPS_MERGE = 0x20000000
453 SHF_MIPS_ADDR = 0x40000000
454 SHF_MIPS_STRINGS = 0x80000000
455 SHF_MIPS_NOSTRIP = 0x08000000
456 SHF_MIPS_LOCAL = 0x04000000
457 SHF_MIPS_NAMES = 0x02000000
458 SHF_MIPS_NODUPE = 0x01000000
460 class ShfPARISC(enum.IntFlag):
461 """Supplemental SHF_* constants for EM_PARISC."""
462 SHF_PARISC_SHORT = 0x20000000
463 SHF_PARISC_HUGE = 0x40000000
464 SHF_PARISC_SBP = 0x80000000
466 class Stb(_OpenIntEnum):
467 """ELF symbol binding type."""
468 STB_LOCAL = 0
469 STB_GLOBAL = 1
470 STB_WEAK = 2
471 STB_GNU_UNIQUE = 10
472 STB_MIPS_SPLIT_COMMON = 13
474 class Stt(_OpenIntEnum):
475 """ELF symbol type."""
476 STT_NOTYPE = 0
477 STT_OBJECT = 1
478 STT_FUNC = 2
479 STT_SECTION = 3
480 STT_FILE = 4
481 STT_COMMON = 5
482 STT_TLS = 6
483 STT_GNU_IFUNC = 10
485 class SttARM(enum.Enum):
486 """Supplemental STT_* constants for EM_ARM."""
487 STT_ARM_TFUNC = 13
488 STT_ARM_16BIT = 15
490 class SttPARISC(enum.Enum):
491 """Supplemental STT_* constants for EM_PARISC."""
492 STT_HP_OPAQUE = 11
493 STT_HP_STUB = 12
494 STT_PARISC_MILLICODE = 13
496 class SttSPARC(enum.Enum):
497 """Supplemental STT_* constants for EM_SPARC."""
498 STT_SPARC_REGISTER = 13
500 class SttX86_64(enum.Enum):
501 """Supplemental STT_* constants for EM_X86_64."""
502 SHT_X86_64_UNWIND = 0x70000001
504 class Pt(_OpenIntEnum):
505 """ELF program header types. Type of Phdr.p_type."""
506 PT_NULL = 0
507 PT_LOAD = 1
508 PT_DYNAMIC = 2
509 PT_INTERP = 3
510 PT_NOTE = 4
511 PT_SHLIB = 5
512 PT_PHDR = 6
513 PT_TLS = 7
514 PT_NUM = 8
515 PT_GNU_EH_FRAME = 0x6474e550
516 PT_GNU_STACK = 0x6474e551
517 PT_GNU_RELRO = 0x6474e552
518 PT_GNU_PROPERTY = 0x6474e553
519 PT_SUNWBSS = 0x6ffffffa
520 PT_SUNWSTACK = 0x6ffffffb
522 class PtARM(enum.Enum):
523 """Supplemental PT_* constants for EM_ARM."""
524 PT_ARM_EXIDX = 0x70000001
526 class PtIA_64(enum.Enum):
527 """Supplemental PT_* constants for EM_IA_64."""
528 PT_IA_64_HP_OPT_ANOT = 0x60000012
529 PT_IA_64_HP_HSL_ANOT = 0x60000013
530 PT_IA_64_HP_STACK = 0x60000014
531 PT_IA_64_ARCHEXT = 0x70000000
532 PT_IA_64_UNWIND = 0x70000001
534 class PtMIPS(enum.Enum):
535 """Supplemental PT_* constants for EM_MIPS."""
536 PT_MIPS_REGINFO = 0x70000000
537 PT_MIPS_RTPROC = 0x70000001
538 PT_MIPS_OPTIONS = 0x70000002
539 PT_MIPS_ABIFLAGS = 0x70000003
541 class PtPARISC(enum.Enum):
542 """Supplemental PT_* constants for EM_PARISC."""
543 PT_HP_TLS = 0x60000000
544 PT_HP_CORE_NONE = 0x60000001
545 PT_HP_CORE_VERSION = 0x60000002
546 PT_HP_CORE_KERNEL = 0x60000003
547 PT_HP_CORE_COMM = 0x60000004
548 PT_HP_CORE_PROC = 0x60000005
549 PT_HP_CORE_LOADABLE = 0x60000006
550 PT_HP_CORE_STACK = 0x60000007
551 PT_HP_CORE_SHM = 0x60000008
552 PT_HP_CORE_MMF = 0x60000009
553 PT_HP_PARALLEL = 0x60000010
554 PT_HP_FASTBIND = 0x60000011
555 PT_HP_OPT_ANNOT = 0x60000012
556 PT_HP_HSL_ANNOT = 0x60000013
557 PT_HP_STACK = 0x60000014
558 PT_PARISC_ARCHEXT = 0x70000000
559 PT_PARISC_UNWIND = 0x70000001
561 class Dt(_OpenIntEnum):
562 """ELF dynamic segment tags. Type of Dyn.d_val."""
563 DT_NULL = 0
564 DT_NEEDED = 1
565 DT_PLTRELSZ = 2
566 DT_PLTGOT = 3
567 DT_HASH = 4
568 DT_STRTAB = 5
569 DT_SYMTAB = 6
570 DT_RELA = 7
571 DT_RELASZ = 8
572 DT_RELAENT = 9
573 DT_STRSZ = 10
574 DT_SYMENT = 11
575 DT_INIT = 12
576 DT_FINI = 13
577 DT_SONAME = 14
578 DT_RPATH = 15
579 DT_SYMBOLIC = 16
580 DT_REL = 17
581 DT_RELSZ = 18
582 DT_RELENT = 19
583 DT_PLTREL = 20
584 DT_DEBUG = 21
585 DT_TEXTREL = 22
586 DT_JMPREL = 23
587 DT_BIND_NOW = 24
588 DT_INIT_ARRAY = 25
589 DT_FINI_ARRAY = 26
590 DT_INIT_ARRAYSZ = 27
591 DT_FINI_ARRAYSZ = 28
592 DT_RUNPATH = 29
593 DT_FLAGS = 30
594 DT_PREINIT_ARRAY = 32
595 DT_PREINIT_ARRAYSZ = 33
596 DT_SYMTAB_SHNDX = 34
597 DT_RELRSZ = 35
598 DT_RELR = 36
599 DT_RELRENT = 37
600 DT_GNU_PRELINKED = 0x6ffffdf5
601 DT_GNU_CONFLICTSZ = 0x6ffffdf6
602 DT_GNU_LIBLISTSZ = 0x6ffffdf7
603 DT_CHECKSUM = 0x6ffffdf8
604 DT_PLTPADSZ = 0x6ffffdf9
605 DT_MOVEENT = 0x6ffffdfa
606 DT_MOVESZ = 0x6ffffdfb
607 DT_FEATURE_1 = 0x6ffffdfc
608 DT_POSFLAG_1 = 0x6ffffdfd
609 DT_SYMINSZ = 0x6ffffdfe
610 DT_SYMINENT = 0x6ffffdff
611 DT_GNU_HASH = 0x6ffffef5
612 DT_TLSDESC_PLT = 0x6ffffef6
613 DT_TLSDESC_GOT = 0x6ffffef7
614 DT_GNU_CONFLICT = 0x6ffffef8
615 DT_GNU_LIBLIST = 0x6ffffef9
616 DT_CONFIG = 0x6ffffefa
617 DT_DEPAUDIT = 0x6ffffefb
618 DT_AUDIT = 0x6ffffefc
619 DT_PLTPAD = 0x6ffffefd
620 DT_MOVETAB = 0x6ffffefe
621 DT_SYMINFO = 0x6ffffeff
622 DT_VERSYM = 0x6ffffff0
623 DT_RELACOUNT = 0x6ffffff9
624 DT_RELCOUNT = 0x6ffffffa
625 DT_FLAGS_1 = 0x6ffffffb
626 DT_VERDEF = 0x6ffffffc
627 DT_VERDEFNUM = 0x6ffffffd
628 DT_VERNEED = 0x6ffffffe
629 DT_VERNEEDNUM = 0x6fffffff
630 DT_AUXILIARY = 0x7ffffffd
631 DT_FILTER = 0x7fffffff
633 class DtAARCH64(enum.Enum):
634 """Supplemental DT_* constants for EM_AARCH64."""
635 DT_AARCH64_BTI_PLT = 0x70000001
636 DT_AARCH64_PAC_PLT = 0x70000003
637 DT_AARCH64_VARIANT_PCS = 0x70000005
639 class DtALPHA(enum.Enum):
640 """Supplemental DT_* constants for EM_ALPHA."""
641 DT_ALPHA_PLTRO = 0x70000000
643 class DtALTERA_NIOS2(enum.Enum):
644 """Supplemental DT_* constants for EM_ALTERA_NIOS2."""
645 DT_NIOS2_GP = 0x70000002
647 class DtIA_64(enum.Enum):
648 """Supplemental DT_* constants for EM_IA_64."""
649 DT_IA_64_PLT_RESERVE = 0x70000000
651 class DtMIPS(enum.Enum):
652 """Supplemental DT_* constants for EM_MIPS."""
653 DT_MIPS_RLD_VERSION = 0x70000001
654 DT_MIPS_TIME_STAMP = 0x70000002
655 DT_MIPS_ICHECKSUM = 0x70000003
656 DT_MIPS_IVERSION = 0x70000004
657 DT_MIPS_FLAGS = 0x70000005
658 DT_MIPS_BASE_ADDRESS = 0x70000006
659 DT_MIPS_MSYM = 0x70000007
660 DT_MIPS_CONFLICT = 0x70000008
661 DT_MIPS_LIBLIST = 0x70000009
662 DT_MIPS_LOCAL_GOTNO = 0x7000000a
663 DT_MIPS_CONFLICTNO = 0x7000000b
664 DT_MIPS_LIBLISTNO = 0x70000010
665 DT_MIPS_SYMTABNO = 0x70000011
666 DT_MIPS_UNREFEXTNO = 0x70000012
667 DT_MIPS_GOTSYM = 0x70000013
668 DT_MIPS_HIPAGENO = 0x70000014
669 DT_MIPS_RLD_MAP = 0x70000016
670 DT_MIPS_DELTA_CLASS = 0x70000017
671 DT_MIPS_DELTA_CLASS_NO = 0x70000018
672 DT_MIPS_DELTA_INSTANCE = 0x70000019
673 DT_MIPS_DELTA_INSTANCE_NO = 0x7000001a
674 DT_MIPS_DELTA_RELOC = 0x7000001b
675 DT_MIPS_DELTA_RELOC_NO = 0x7000001c
676 DT_MIPS_DELTA_SYM = 0x7000001d
677 DT_MIPS_DELTA_SYM_NO = 0x7000001e
678 DT_MIPS_DELTA_CLASSSYM = 0x70000020
679 DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021
680 DT_MIPS_CXX_FLAGS = 0x70000022
681 DT_MIPS_PIXIE_INIT = 0x70000023
682 DT_MIPS_SYMBOL_LIB = 0x70000024
683 DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025
684 DT_MIPS_LOCAL_GOTIDX = 0x70000026
685 DT_MIPS_HIDDEN_GOTIDX = 0x70000027
686 DT_MIPS_PROTECTED_GOTIDX = 0x70000028
687 DT_MIPS_OPTIONS = 0x70000029
688 DT_MIPS_INTERFACE = 0x7000002a
689 DT_MIPS_DYNSTR_ALIGN = 0x7000002b
690 DT_MIPS_INTERFACE_SIZE = 0x7000002c
691 DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002d
692 DT_MIPS_PERF_SUFFIX = 0x7000002e
693 DT_MIPS_COMPACT_SIZE = 0x7000002f
694 DT_MIPS_GP_VALUE = 0x70000030
695 DT_MIPS_AUX_DYNAMIC = 0x70000031
696 DT_MIPS_PLTGOT = 0x70000032
697 DT_MIPS_RWPLT = 0x70000034
698 DT_MIPS_RLD_MAP_REL = 0x70000035
699 DT_MIPS_XHASH = 0x70000036
701 class DtPPC(enum.Enum):
702 """Supplemental DT_* constants for EM_PPC."""
703 DT_PPC_GOT = 0x70000000
704 DT_PPC_OPT = 0x70000001
706 class DtPPC64(enum.Enum):
707 """Supplemental DT_* constants for EM_PPC64."""
708 DT_PPC64_GLINK = 0x70000000
709 DT_PPC64_OPD = 0x70000001
710 DT_PPC64_OPDSZ = 0x70000002
711 DT_PPC64_OPT = 0x70000003
713 class DtSPARC(enum.Enum):
714 """Supplemental DT_* constants for EM_SPARC."""
715 DT_SPARC_REGISTER = 0x70000001
717 class StInfo:
718 """ELF symbol binding and type. Type of the Sym.st_info field."""
719 def __init__(self, arg0, arg1=None):
720 if isinstance(arg0, int) and arg1 is None:
721 self.bind = Stb(arg0 >> 4)
722 self.type = Stt(arg0 & 15)
723 else:
724 self.bind = Stb(arg0)
725 self.type = Stt(arg1)
727 def value(self):
728 """Returns the raw value for the bind/type combination."""
729 return (self.bind.value() << 4) | (self.type.value())
731 # Type in an ELF file. Used for deserialization.
732 _Layout = collections.namedtuple('_Layout', 'unpack size')
734 def _define_layouts(baseclass: type, layout32: str, layout64: str,
735 types=None, fields32=None):
736 """Assign variants dict to baseclass.
738 The variants dict is indexed by (ElfClass, ElfData) pairs, and its
739 values are _Layout instances.
742 struct32 = struct.Struct(layout32)
743 struct64 = struct.Struct(layout64)
745 # Check that the struct formats yield the right number of components.
746 for s in (struct32, struct64):
747 example = s.unpack(b' ' * s.size)
748 if len(example) != len(baseclass._fields):
749 raise ValueError('{!r} yields wrong field count: {} != {}'.format(
750 s.format, len(example), len(baseclass._fields)))
752 # Check that field names in types are correct.
753 if types is None:
754 types = ()
755 for n in types:
756 if n not in baseclass._fields:
757 raise ValueError('{} does not have field {!r}'.format(
758 baseclass.__name__, n))
760 if fields32 is not None \
761 and set(fields32) != set(baseclass._fields):
762 raise ValueError('{!r} is not a permutation of the fields {!r}'.format(
763 fields32, baseclass._fields))
765 def unique_name(name, used_names = (set((baseclass.__name__,))
766 | set(baseclass._fields)
767 | {n.__name__
768 for n in (types or {}).values()})):
769 """Find a name that is not used for a class or field name."""
770 candidate = name
771 n = 0
772 while candidate in used_names:
773 n += 1
774 candidate = '{}{}'.format(name, n)
775 used_names.add(candidate)
776 return candidate
778 blob_name = unique_name('blob')
779 struct_unpack_name = unique_name('struct_unpack')
780 comps_name = unique_name('comps')
782 layouts = {}
783 for (bits, elfclass, layout, fields) in (
784 (32, ElfClass.ELFCLASS32, layout32, fields32),
785 (64, ElfClass.ELFCLASS64, layout64, None),
787 for (elfdata, structprefix, funcsuffix) in (
788 (ElfData.ELFDATA2LSB, '<', 'LE'),
789 (ElfData.ELFDATA2MSB, '>', 'BE'),
791 env = {
792 baseclass.__name__: baseclass,
793 struct_unpack_name: struct.unpack,
796 # Add the type converters.
797 if types:
798 for cls in types.values():
799 env[cls.__name__] = cls
801 funcname = ''.join(
802 ('unpack_', baseclass.__name__, str(bits), funcsuffix))
804 code = '''
805 def {funcname}({blob_name}):
806 '''.format(funcname=funcname, blob_name=blob_name)
808 indent = ' ' * 4
809 unpack_call = '{}({!r}, {})'.format(
810 struct_unpack_name, structprefix + layout, blob_name)
811 field_names = ', '.join(baseclass._fields)
812 if types is None and fields is None:
813 code += '{}return {}({})\n'.format(
814 indent, baseclass.__name__, unpack_call)
815 else:
816 # Destructuring tuple assignment.
817 if fields is None:
818 code += '{}{} = {}\n'.format(
819 indent, field_names, unpack_call)
820 else:
821 # Use custom field order.
822 code += '{}{} = {}\n'.format(
823 indent, ', '.join(fields), unpack_call)
825 # Perform the type conversions.
826 for n in baseclass._fields:
827 if n in types:
828 code += '{}{} = {}({})\n'.format(
829 indent, n, types[n].__name__, n)
830 # Create the named tuple.
831 code += '{}return {}({})\n'.format(
832 indent, baseclass.__name__, field_names)
834 exec(code, env)
835 layouts[(elfclass, elfdata)] = _Layout(
836 env[funcname], struct.calcsize(layout))
837 baseclass.layouts = layouts
840 # Corresponds to EI_* indices into Elf*_Ehdr.e_indent.
841 class Ident(collections.namedtuple('Ident',
842 'ei_mag ei_class ei_data ei_version ei_osabi ei_abiversion ei_pad')):
844 def __new__(cls, *args):
845 """Construct an object from a blob or its constituent fields."""
846 if len(args) == 1:
847 return cls.unpack(args[0])
848 return cls.__base__.__new__(cls, *args)
850 @staticmethod
851 def unpack(blob: memoryview) -> 'Ident':
852 """Parse raws data into a tuple."""
853 ei_mag, ei_class, ei_data, ei_version, ei_osabi, ei_abiversion, \
854 ei_pad = struct.unpack('4s5B7s', blob)
855 return Ident(ei_mag, ElfClass(ei_class), ElfData(ei_data),
856 ei_version, ei_osabi, ei_abiversion, ei_pad)
857 size = 16
859 # Corresponds to Elf32_Ehdr and Elf64_Ehdr.
860 Ehdr = collections.namedtuple('Ehdr',
861 'e_ident e_type e_machine e_version e_entry e_phoff e_shoff e_flags'
862 + ' e_ehsize e_phentsize e_phnum e_shentsize e_shnum e_shstrndx')
863 _define_layouts(Ehdr,
864 layout32='16s2H5I6H',
865 layout64='16s2HI3QI6H',
866 types=dict(e_ident=Ident,
867 e_machine=Machine,
868 e_type=Et,
869 e_shstrndx=Shn))
871 # Corresponds to Elf32_Phdr and Elf64_Pdhr. Order follows the latter.
872 Phdr = collections.namedtuple('Phdr',
873 'p_type p_flags p_offset p_vaddr p_paddr p_filesz p_memsz p_align')
874 _define_layouts(Phdr,
875 layout32='8I',
876 fields32=('p_type', 'p_offset', 'p_vaddr', 'p_paddr',
877 'p_filesz', 'p_memsz', 'p_flags', 'p_align'),
878 layout64='2I6Q',
879 types=dict(p_type=Pt, p_flags=Pf))
882 # Corresponds to Elf32_Shdr and Elf64_Shdr.
883 class Shdr(collections.namedtuple('Shdr',
884 'sh_name sh_type sh_flags sh_addr sh_offset sh_size sh_link sh_info'
885 + ' sh_addralign sh_entsize')):
886 def resolve(self, strtab: 'StringTable') -> 'Shdr':
887 """Resolve sh_name using a string table."""
888 return self.__class__(strtab.get(self[0]), *self[1:])
889 _define_layouts(Shdr,
890 layout32='10I',
891 layout64='2I4Q2I2Q',
892 types=dict(sh_type=Sht,
893 sh_flags=Shf,
894 sh_link=Shn))
896 # Corresponds to Elf32_Dyn and Elf64_Dyn. The nesting through the
897 # d_un union is skipped, and d_ptr is missing (its representation in
898 # Python would be identical to d_val).
899 Dyn = collections.namedtuple('Dyn', 'd_tag d_val')
900 _define_layouts(Dyn,
901 layout32='2i',
902 layout64='2q',
903 types=dict(d_tag=Dt))
905 # Corresponds to Elf32_Sym and Elf64_Sym.
906 class Sym(collections.namedtuple('Sym',
907 'st_name st_info st_other st_shndx st_value st_size')):
908 def resolve(self, strtab: 'StringTable') -> 'Sym':
909 """Resolve st_name using a string table."""
910 return self.__class__(strtab.get(self[0]), *self[1:])
911 _define_layouts(Sym,
912 layout32='3I2BH',
913 layout64='I2BH2Q',
914 fields32=('st_name', 'st_value', 'st_size', 'st_info',
915 'st_other', 'st_shndx'),
916 types=dict(st_shndx=Shn,
917 st_info=StInfo))
919 # Corresponds to Elf32_Rel and Elf64_Rel.
920 Rel = collections.namedtuple('Rel', 'r_offset r_info')
921 _define_layouts(Rel,
922 layout32='2I',
923 layout64='2Q')
925 # Corresponds to Elf32_Rel and Elf64_Rel.
926 Rela = collections.namedtuple('Rela', 'r_offset r_info r_addend')
927 _define_layouts(Rela,
928 layout32='3I',
929 layout64='3Q')
931 class StringTable:
932 """ELF string table."""
933 def __init__(self, blob):
934 """Create a new string table backed by the data in the blob.
936 blob: a memoryview-like object
939 self.blob = blob
941 def get(self, index) -> bytes:
942 """Returns the null-terminated byte string at the index."""
943 blob = self.blob
944 endindex = index
945 while True:
946 if blob[endindex] == 0:
947 return bytes(blob[index:endindex])
948 endindex += 1
950 class Image:
951 """ELF image parser."""
952 def __init__(self, image):
953 """Create an ELF image from binary image data.
955 image: a memoryview-like object that supports efficient range
956 subscripting.
959 self.image = image
960 ident = self.read(Ident, 0)
961 classdata = (ident.ei_class, ident.ei_data)
962 # Set self.Ehdr etc. to the subtypes with the right parsers.
963 for typ in (Ehdr, Phdr, Shdr, Dyn, Sym, Rel, Rela):
964 setattr(self, typ.__name__, typ.layouts.get(classdata, None))
966 if self.Ehdr is not None:
967 self.ehdr = self.read(self.Ehdr, 0)
968 self._shdr_num = self._compute_shdr_num()
969 else:
970 self.ehdr = None
971 self._shdr_num = 0
973 self._section = {}
974 self._stringtab = {}
976 if self._shdr_num > 0:
977 self._shdr_strtab = self._find_shdr_strtab()
978 else:
979 self._shdr_strtab = None
981 @staticmethod
982 def readfile(path: str) -> 'Image':
983 """Reads the ELF file at the specified path."""
984 with open(path, 'rb') as inp:
985 return Image(memoryview(inp.read()))
987 def _compute_shdr_num(self) -> int:
988 """Computes the actual number of section headers."""
989 shnum = self.ehdr.e_shnum
990 if shnum == 0:
991 if self.ehdr.e_shoff == 0 or self.ehdr.e_shentsize == 0:
992 # No section headers.
993 return 0
994 # Otherwise the extension mechanism is used (which may be
995 # needed because e_shnum is just 16 bits).
996 return self.read(self.Shdr, self.ehdr.e_shoff).sh_size
997 return shnum
999 def _find_shdr_strtab(self) -> StringTable:
1000 """Finds the section header string table (maybe via extensions)."""
1001 shstrndx = self.ehdr.e_shstrndx
1002 if shstrndx == Shn.SHN_XINDEX:
1003 shstrndx = self.read(self.Shdr, self.ehdr.e_shoff).sh_link
1004 return self._find_stringtab(shstrndx)
1006 def read(self, typ: type, offset:int ):
1007 """Reads an object at a specific offset.
1009 The type must have been enhanced using _define_variants.
1012 return typ.unpack(self.image[offset: offset + typ.size])
1014 def phdrs(self) -> Phdr:
1015 """Generator iterating over the program headers."""
1016 if self.ehdr is None:
1017 return
1018 size = self.ehdr.e_phentsize
1019 if size != self.Phdr.size:
1020 raise ValueError('Unexpected Phdr size in ELF header: {} != {}'
1021 .format(size, self.Phdr.size))
1023 offset = self.ehdr.e_phoff
1024 for _ in range(self.ehdr.e_phnum):
1025 yield self.read(self.Phdr, offset)
1026 offset += size
1028 def shdrs(self, resolve: bool=True) -> Shdr:
1029 """Generator iterating over the section headers.
1031 If resolve, section names are automatically translated
1032 using the section header string table.
1035 if self._shdr_num == 0:
1036 return
1038 size = self.ehdr.e_shentsize
1039 if size != self.Shdr.size:
1040 raise ValueError('Unexpected Shdr size in ELF header: {} != {}'
1041 .format(size, self.Shdr.size))
1043 offset = self.ehdr.e_shoff
1044 for _ in range(self._shdr_num):
1045 shdr = self.read(self.Shdr, offset)
1046 if resolve:
1047 shdr = shdr.resolve(self._shdr_strtab)
1048 yield shdr
1049 offset += size
1051 def dynamic(self) -> Dyn:
1052 """Generator iterating over the dynamic segment."""
1053 for phdr in self.phdrs():
1054 if phdr.p_type == Pt.PT_DYNAMIC:
1055 # Pick the first dynamic segment, like the loader.
1056 if phdr.p_filesz == 0:
1057 # Probably separated debuginfo.
1058 return
1059 offset = phdr.p_offset
1060 end = offset + phdr.p_memsz
1061 size = self.Dyn.size
1062 while True:
1063 next_offset = offset + size
1064 if next_offset > end:
1065 raise ValueError(
1066 'Dynamic segment size {} is not a multiple of Dyn size {}'.format(
1067 phdr.p_memsz, size))
1068 yield self.read(self.Dyn, offset)
1069 if next_offset == end:
1070 return
1071 offset = next_offset
1073 def syms(self, shdr: Shdr, resolve: bool=True) -> Sym:
1074 """A generator iterating over a symbol table.
1076 If resolve, symbol names are automatically translated using
1077 the string table for the symbol table.
1080 assert shdr.sh_type == Sht.SHT_SYMTAB
1081 size = shdr.sh_entsize
1082 if size != self.Sym.size:
1083 raise ValueError('Invalid symbol table entry size {}'.format(size))
1084 offset = shdr.sh_offset
1085 end = shdr.sh_offset + shdr.sh_size
1086 if resolve:
1087 strtab = self._find_stringtab(shdr.sh_link)
1088 while offset < end:
1089 sym = self.read(self.Sym, offset)
1090 if resolve:
1091 sym = sym.resolve(strtab)
1092 yield sym
1093 offset += size
1094 if offset != end:
1095 raise ValueError('Symbol table is not a multiple of entry size')
1097 def lookup_string(self, strtab_index: int, strtab_offset: int) -> bytes:
1098 """Looks up a string in a string table identified by its link index."""
1099 try:
1100 strtab = self._stringtab[strtab_index]
1101 except KeyError:
1102 strtab = self._find_stringtab(strtab_index)
1103 return strtab.get(strtab_offset)
1105 def find_section(self, shndx: Shn) -> Shdr:
1106 """Returns the section header for the indexed section.
1108 The section name is not resolved.
1110 try:
1111 return self._section[shndx]
1112 except KeyError:
1113 pass
1114 if shndx in Shn:
1115 raise ValueError('Reserved section index {}'.format(shndx))
1116 idx = shndx.value
1117 if idx < 0 or idx > self._shdr_num:
1118 raise ValueError('Section index {} out of range [0, {})'.format(
1119 idx, self._shdr_num))
1120 shdr = self.read(
1121 self.Shdr, self.ehdr.e_shoff + idx * self.Shdr.size)
1122 self._section[shndx] = shdr
1123 return shdr
1125 def _find_stringtab(self, sh_link: int) -> StringTable:
1126 if sh_link in self._stringtab:
1127 return self._stringtab
1128 if sh_link < 0 or sh_link >= self._shdr_num:
1129 raise ValueError('Section index {} out of range [0, {})'.format(
1130 sh_link, self._shdr_num))
1131 shdr = self.read(
1132 self.Shdr, self.ehdr.e_shoff + sh_link * self.Shdr.size)
1133 if shdr.sh_type != Sht.SHT_STRTAB:
1134 raise ValueError(
1135 'Section {} is not a string table: {}'.format(
1136 sh_link, shdr.sh_type))
1137 strtab = StringTable(
1138 self.image[shdr.sh_offset:shdr.sh_offset + shdr.sh_size])
1139 # This could retrain essentially arbitrary amounts of data,
1140 # but caching string tables seems important for performance.
1141 self._stringtab[sh_link] = strtab
1142 return strtab
1145 __all__ = [name for name in dir() if name[0].isupper()]