File: elf.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (787 lines) | stat: -rw-r--r-- 29,412 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
//===--- elf.h - Definitions of ELF structures for import into Swift ------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Definitions of ELF structures for import into Swift code
//
// The types here are taken from the System V ABI update, here:
// <http://www.sco.com/developers/gabi/2012-12-31/contents.html>
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_ELF_H
#define SWIFT_ELF_H

#include <inttypes.h>

/* .. Useful macros ......................................................... */

#define ELF_ENUM(t,n)   \
  enum __attribute__((enum_extensibility(open))) n: t
#define ELF_OPTIONS(t,n) \
  t n; \
  enum __attribute__((flag_enum,enum_extensibility(open))): t

/* .. Data Representation ................................................... */

// Common sizes (these don't change between 32-bit and 64-bit)
typedef uint8_t  Elf_Byte;
typedef uint16_t Elf_Half;
typedef uint32_t Elf_Word;
typedef uint64_t Elf_Xword;
typedef int32_t  Elf_Sword;
typedef int64_t  Elf_Sxword;

// 32-bit sizes (includes some aliases of the above, for compatibility)
typedef Elf_Byte  Elf32_Byte;
typedef uint32_t  Elf32_Addr;
typedef Elf_Half  Elf32_Half;
typedef uint32_t  Elf32_Off;
typedef Elf_Sword Elf32_Sword;
typedef Elf_Word  Elf32_Word;

// 64-bit sizes (includes some aliases of the above, for compatibility)
typedef Elf_Byte   Elf64_Byte;
typedef uint64_t   Elf64_Addr;
typedef uint64_t   Elf64_Off;
typedef Elf_Half   Elf64_Half;
typedef Elf_Word   Elf64_Word;
typedef Elf_Sword  Elf64_Sword;
typedef Elf_Xword  Elf64_Xword;
typedef Elf_Sxword Elf64_Sxword;

/* .. Constants ............................................................. */

// e_type values
typedef ELF_ENUM(Elf_Half, Elf_Ehdr_Type) {
  ET_NONE   = 0,      // No file type
  ET_REL    = 1,      // Relocatable file
  ET_EXEC   = 2,      // Executable file
  ET_DYN    = 3,      // Shared object file
  ET_CORE   = 4,      // Core file
  ET_LOOS   = 0xfe00, // Operating system specific
  ET_HIOS   = 0xfeff, // Operating system specific
  ET_LOPROC = 0xff00, // Processor specific
  ET_HIPROC = 0xffff, // Processor specific
} Elf_Ehdr_Type;

// e_machine values
typedef ELF_ENUM(Elf_Half, Elf_Ehdr_Machine) {
  EM_NONE          = 0,   // No machine
  EM_M32           = 1,   // AT&T WE 32100
  EM_SPARC         = 2,   // SPARC
  EM_386           = 3,   // Intel 80386
  EM_68K           = 4,   // Motorola 68000
  EM_88K           = 5,   // Motorola 88000

  EM_860           = 7,   // Intel 80860
  EM_MIPS          = 8,   // MIPS I Architecture
  EM_S370          = 9,   // IBM System/370 Processor
  EM_MIPS_RS3_LE   = 10,  // MIPS RS3000 Little-endian

  EM_PARISC        = 15,  // Hewlett-Packard PA-RISC

  EM_VPP500        = 17,  // Fujitsu VPP500
  EM_SPARC32PLUS   = 18,  // Enhanced instruction set SPARC
  EM_960           = 19,  // Intel 80960
  EM_PPC           = 20,  // PowerPC
  EM_PPC64         = 21,  // 64-bit PowerPC
  EM_S390          = 22,  // IBM System/390 Processor
  EM_SPU           = 23,  // IBM SPU/SPC

  EM_V800          = 36,  // NEC V800
  EM_FR20          = 37,  // Fujitsu FR20
  EM_RH32          = 38,  // TRW RH-32
  EM_RCE           = 39,  // Motorola RCE
  EM_ARM           = 40,  // ARM 32-bit architecture (AARCH32)
  EM_ALPHA         = 41,  // Digital Alpha
  EM_SH            = 42,  // Hitachi SH
  EM_SPARCV9       = 43,  // SPARC Version 9
  EM_TRICORE       = 44,  // Siemens TriCore embedded processor
  EM_ARC           = 45,  // Argonaut RISC Core, Argonaut Technologies Inc.
  EM_H8_300        = 46,  // Hitachi H8/300
  EM_H8_300H       = 47,  // Hitachi H8/300H
  EM_H8S           = 48,  // Hitachi H8S
  EM_H8_500        = 49,  // Hitachi H8/500
  EM_IA_64         = 50,  // Intel IA-64 processor architecture
  EM_MIPS_X        = 51,  // Stanford MIPS-X
  EM_COLDFIRE      = 52,  // Motorola ColdFire
  EM_68HC12        = 53,  // Motorola M68HC12
  EM_MMA           = 54,  // Fujitsu MMA Multimedia Accelerator
  EM_PCP           = 55,  // Siemens PCP
  EM_NCPU          = 56,  // Sony nCPU embedded RISC processor
  EM_NDR1          = 57,  // Denso NDR1 microprocessor
  EM_STARCORE      = 58,  // Motorola Star*Core processor
  EM_ME16          = 59,  // Toyota ME16 processor
  EM_ST100         = 60,  // STMicroelectronics ST100 processor
  EM_TINYJ         = 61,  // Advanced Logic Corp. TinyJ embedded processor family
  EM_X86_64        = 62,  // AMD x86-64 architecture
  EM_PDSP          = 63,  // Sony DSP Processor
  EM_PDP10         = 64,  // Digital Equipment Corp. PDP-10
  EM_PDP11         = 65,  // Digital Equipment Corp. PDP-11
  EM_FX66          = 66,  // Siemens FX66 microcontroller
  EM_ST9PLUS       = 67,  // STMicroelectronics ST9+ 8/16 bit microcontroller
  EM_ST7           = 68,  // STMicroelectronics ST7 8-bit microcontroller
  EM_68HC16        = 69,  // Motorola MC68HC16 Microcontroller
  EM_68HC11        = 70,  // Motorola MC68HC11 Microcontroller
  EM_68HC08        = 71,  // Motorola MC68HC08 Microcontroller
  EM_68HC05        = 72,  // Motorola MC68HC05 Microcontroller
  EM_SVX           = 73,  // Silicon Graphics SVx
  EM_ST19          = 74,  // STMicroelectronics ST19 8-bit microcontroller
  EM_VAX           = 75,  // Digital VAX
  EM_CRIS          = 76,  // Axis Communications 32-bit embedded processor
  EM_JAVELIN       = 77,  // Infineon Technologies 32-bit embedded processor
  EM_FIREPATH      = 78,  // Element 14 64-bit DSP Processor
  EM_ZSP           = 79,  // LSI Logic 16-bit DSP Processor
  EM_MMIX          = 80,  // Donald Knuth's educational 64-bit processor
  EM_HUANY         = 81,  // Harvard University machine-independent object files
  EM_PRISM         = 82,  // SiTera Prism
  EM_AVR           = 83,  // Atmel AVR 8-bit microcontroller
  EM_FR30          = 84,  // Fujitsu FR30
  EM_D10V          = 85,  // Mitsubishi D10V
  EM_D30V          = 86,  // Mitsubishi D30V
  EM_V850          = 87,  // NEC v850
  EM_M32R          = 88,  // Mitsubishi M32R
  EM_MN10300       = 89,  // Matsushita MN10300
  EM_MN10200       = 90,  // Matsushita MN10200
  EM_PJ            = 91,  // picoJava
  EM_OPENRISC      = 92,  // OpenRISC 32-bit embedded processor
  EM_ARC_COMPACT   = 93,  // ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)
  EM_XTENSA        = 94,  // Tensilica Xtensa Architecture
  EM_VIDEOCORE     = 95,  // Alphamosaic VideoCore processor
  EM_TMM_GPP       = 96,  // Thompson Multimedia General Purpose Processor
  EM_NS32K         = 97,  // National Semiconductor 32000 series
  EM_TPC           = 98,  // Tenor Network TPC processor
  EM_SNP1K         = 99,  // Trebia SNP 1000 processor
  EM_ST200         = 100, // STMicroelectronics (www.st.com) ST200 microcontroller
  EM_IP2K          = 101, // Ubicom IP2xxx microcontroller family
  EM_MAX           = 102, // MAX Processor
  EM_CR            = 103, // National Semiconductor CompactRISC microprocessor
  EM_F2MC16        = 104, // Fujitsu F2MC16
  EM_MSP430        = 105, // Texas Instruments embedded microcontroller msp430
  EM_BLACKFIN      = 106, // Analog Devices Blackfin (DSP) processor
  EM_SE_C33        = 107, // S1C33 Family of Seiko Epson processors
  EM_SEP           = 108, // Sharp embedded microprocessor
  EM_ARCA          = 109, // Arca RISC Microprocessor
  EM_UNICORE       = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University
  EM_EXCESS        = 111, // eXcess: 16/32/64-bit configurable embedded CPU
  EM_DXP           = 112, // Icera Semiconductor Inc. Deep Execution Processor
  EM_ALTERA_NIOS2  = 113, // Altera Nios II soft-core processor
  EM_CRX           = 114, // National Semiconductor CompactRISC CRX microprocessor
  EM_XGATE         = 115, // Motorola XGATE embedded processor
  EM_C166          = 116, // Infineon C16x/XC16x processor
  EM_M16C          = 117, // Renesas M16C series microprocessors
  EM_DSPIC30F      = 118, // Microchip Technology dsPIC30F Digital Signal Controller
  EM_CE            = 119, // Freescale Communication Engine RISC core
  EM_M32C          = 120, // Renesas M32C series microprocessors

  EM_TSK3000       = 131, // Altium TSK3000 core
  EM_RS08          = 132, // Freescale RS08 embedded processor
  EM_SHARC         = 133, // Analog Devices SHARC family of 32-bit DSP processors
  EM_ECOG2         = 134, // Cyan Technology eCOG2 microprocessor
  EM_SCORE7        = 135, // Sunplus S+core7 RISC processor
  EM_DSP24         = 136, // New Japan Radio (NJR) 24-bit DSP Processor
  EM_VIDEOCORE3    = 137, // Broadcom VideoCore III processor
  EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture
  EM_SE_C17        = 139, // Seiko Epson C17 family
  EM_TI_C6000      = 140, // The Texas Instruments TMS320C6000 DSP family
  EM_TI_C2000      = 141, // The Texas Instruments TMS320C2000 DSP family
  EM_TI_C5500      = 142, // The Texas Instruments TMS320C55x DSP family

  EM_MMDSP_PLUS    = 160, // STMicroelectronics 64bit VLIW Data Signal Processor
  EM_CYPRESS_M8C   = 161, // Cypress M8C microprocessor
  EM_R32C          = 162, // Renesas R32C series microprocessors
  EM_TRIMEDIA      = 163, // NXP Semiconductors TriMedia architecture family
  EM_QDSP6         = 164, // QUALCOMM DSP6 Processor
  EM_8051          = 165, // Intel 8051 and variants
  EM_STXP7X        = 166, // STMicroelectronics STxP7x family of configurable and extensible RISC processors
  EM_NDS32         = 167, // Andes Technology compact code size embedded RISC processor family
  EM_ECOG1         = 168, // Cyan Technology eCOG1X family
  EM_ECOG1X        = 168, // Cyan Technology eCOG1X family
  EM_MAXQ30        = 169, // Dallas Semiconductor MAXQ30 Core Micro-controllers
  EM_XIMO16        = 170, // New Japan Radio (NJR) 16-bit DSP Processor
  EM_MANIK         = 171, // M2000 Reconfigurable RISC Microprocessor
  EM_CRAYNV2       = 172, // Cray Inc. NV2 vector architecture
  EM_RX            = 173, // Renesas RX family
  EM_METAG         = 174, // Imagination Technologies META processor architecture
  EM_MCST_ELBRUS   = 175, // MCST Elbrus general purpose hardware architecture
  EM_ECOG16        = 176, // Cyan Technology eCOG16 family
  EM_CR16          = 177, // National Semiconductor CompactRISC CR16 16-bit microprocessor
  EM_ETPU          = 178, // Freescale Extended Time Processing Unit
  EM_SLE9X         = 179, // Infineon Technologies SLE9X core
  EM_L10M          = 180, // Intel L10M
  EM_K10M          = 181, // Intel K10M

  EM_AARCH64       = 183, // ARM 64-bit architecture (AARCH64)

  EM_AVR32         = 185, // Atmel Corporation 32-bit microprocessor family
  EM_STM8          = 186, // STMicroeletronics STM8 8-bit microcontroller
  EM_TILE64        = 187, // Tilera TILE64 multicore architecture family
  EM_TILEPRO       = 188, // Tilera TILEPro multicore architecture family
  EM_MICROBLAZE    = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core
  EM_CUDA          = 190, // NVIDIA CUDA architecture
  EM_TILEGX        = 191, // Tilera TILE-Gx multicore architecture family
  EM_CLOUDSHIELD   = 192, // CloudShield architecture family
  EM_COREA_1ST     = 193, // KIPO-KAIST Core-A 1st generation processor family
  EM_COREA_2ND     = 194, // KIPO-KAIST Core-A 2nd generation processor family
  EM_ARC_COMPACT2  = 195, // Synopsys ARCompact V2
  EM_OPEN8         = 196, // Open8 8-bit RISC soft processor core
  EM_RL78          = 197, // Renesas RL78 family
  EM_VIDEOCORE5    = 198, // Broadcom VideoCore V processor
  EM_78KOR         = 199, // Renesas 78KOR family
  EM_56800EX       = 200, // Freescale 56800EX Digital Signal Controller (DSC)
  EM_BA1           = 201, // Beyond BA1 CPU architecture
  EM_BA2           = 202, // Beyond BA2 CPU architecture
  EM_XCORE         = 203, // XMOS xCORE processor family
  EM_MCHP_PIC      = 204, // Microchip 8-bit PIC(r) family
} Elf_Ehdr_Machine;

// e_version values
typedef ELF_ENUM(Elf_Word, Elf_Ehdr_Version) {
  EV_NONE    = 0, // Invalid version
  EV_CURRENT = 1, // Current version
} Elf_Ehdr_Version;

// e_ident[] identification indices
enum {
  EI_MAG0       = 0, // File identification =     0x7f
  EI_MAG1       = 1, // File identification = 'E' 0x45
  EI_MAG2       = 2, // File identification = 'L' 0x4c
  EI_MAG3       = 3, // File identification = 'F' 0x46
  EI_CLASS      = 4, // File class
  EI_DATA       = 5, // Data encoding
  EI_VERSION    = 6, // File version
  EI_OSABI      = 7, // Operating system/ABI identification
  EI_ABIVERSION = 8, // ABI version
  EI_PAD        = 9, // Start of padding bytes
};

// Magic number
enum : uint8_t {
  ELFMAG0 = 0x7f,
  ELFMAG1 = 'E',
  ELFMAG2 = 'L',
  ELFMAG3 = 'F',
};

// File class
typedef ELF_ENUM(Elf_Byte, Elf_Ehdr_Class) {
  ELFCLASSNONE = 0, // Invalid class
  ELFCLASS32   = 1, // 32-bit objects
  ELFCLASS64   = 2, // 64-bit objects
} Elf_Ehdr_Class;

// Data encoding
typedef ELF_ENUM(Elf_Byte, Elf_Ehdr_Data) {
  ELFDATANONE = 0, // Invalid data encoding
  ELFDATA2LSB = 1, // 2's complement Little Endian
  ELFDATA2MSB = 2, // 2's complement Big Endian
} Elk_Ehdr_Data;

// OS/ABI identification
typedef ELF_ENUM(Elf_Byte, Elf_Ehdr_OsAbi) {
  ELFOSABI_NONE    = 0,  // No extensions or unspecified
  ELFOSABI_HPUX    = 1,  // Hewlett-Packard HP-UX
  ELFOSABI_NETBSD  = 2,  // NetBSD
  ELFOSABI_GNU     = 3,  // GNU
  ELFOSABI_LINUX   = 3,  // Linux (historical - alias for ELFOSABI_GNU)
  ELFOSABI_SOLARIS = 6,  // Sun Solaris
  ELFOSABI_AIX     = 7,  // AIX
  ELFOSABI_IRIX    = 8,  // IRIX
  ELFOSABI_FREEBSD = 9,  // FreeBSD
  ELFOSABI_TRU64   = 10, // Compaq TRU64 UNIX
  ELFOSABI_MODESTO = 11, // Novell Modesto
  ELFOSABI_OPENBSD = 12, // Open BSD
  ELFOSABI_OPENVMS = 13, // Open VMS
  ELFOSABI_NSK     = 14, // Hewlett-Packard Non-Stop Kernel
  ELFOSABI_AROS    = 15, // Amiga Research OS
  ELFOSABI_FENIXOS = 16, // The FenixOS highly scalable multi-core OS
} Elf_Ehdr_OsAbi;

// Special Section Indices
enum {
  SHN_UNDEF     = 0,      // Undefined, missing, irrelevant or meaningless

  SHN_LORESERVE = 0xff00, // Lower bound of reserved indices

  SHN_LOPROC    = 0xff00, // Processor specific
  SHN_HIPROC    = 0xff1f,

  SHN_LOOS      = 0xff20, // OS specific
  SHN_HIOS      = 0xff3f,

  SHN_ABS       = 0xfff1, // Absolute (symbols are not relocated)
  SHN_COMMON    = 0xfff2, // Common
  SHN_XINDEX    = 0xffff, // Indicates section header index is elsewhere

  SHN_HIRESERVE = 0xffff,
};

// Section types
typedef ELF_ENUM(Elf_Word, Elf_Shdr_Type) {
  SHT_NULL          = 0,          // Inactive
  SHT_PROGBITS      = 1,          // Program-defined information
  SHT_SYMTAB        = 2,          // Symbol table
  SHT_STRTAB        = 3,          // String table
  SHT_RELA          = 4,          // Relocation entries with explicit addends
  SHT_HASH          = 5,          // Symbol hash table
  SHT_DYNAMIC       = 6,          // Information for dynamic linking
  SHT_NOTE          = 7,          // Notes
  SHT_NOBITS        = 8,          // Program-defined empty space (bss)
  SHT_REL           = 9,          // Relocation entries without explicit addents
  SHT_SHLIB         = 10,         // Reserved
  SHT_DYNSYM        = 11,
  SHT_INIT_ARRAY    = 14,         // Pointers to initialization functions
  SHT_FINI_ARRAY    = 15,         // Pointers to termination functions
  SHT_PREINIT_ARRAY = 16,         // Pointers to pre-initialization functions
  SHT_GROUP         = 17,         // Defines a section group
  SHT_SYMTAB_SHNDX  = 18,         // Section header indices for symtab

  SHT_LOOS          = 0x60000000, // OS specific
    SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes
    SHT_GNU_HASH       = 0x6ffffff6, // GNU-style hash table
    SHT_GNU_LIBLIST    = 0x6ffffff7, // Prelink library list
    SHT_CHECKSUM       = 0x6ffffff8, // Checksum for DSK content

    SHT_LOSUNW         = 0x6ffffffa, // Sun-specific
    SHT_SUNW_move      = 0x6ffffffa,
    SHT_SUNW_COMDAT    = 0x6ffffffb,
    SHT_SUNW_syminfo   = 0x6ffffffc,

    SHT_GNU_verdef     = 0x6ffffffd,
    SHT_GNU_verneed    = 0x6ffffffe,
    SHT_GNU_versym     = 0x6fffffff,

    SHT_HISUNW         = 0x6fffffff,
  SHT_HIOS          = 0x6fffffff,

  SHT_LOPROC        = 0x70000000, // Processor specific
  SHT_HIPROC        = 0x7fffffff,

  SHT_LOUSER        = 0x80000000, // Application specific
  SHT_HIUSER        = 0xffffffff,
} Elf_Shdr_Type;

// Section attribute flags (we can't have a type for these because the
// 64-bit section header defines them as 64-bit)
enum {
  SHF_WRITE            = 0x1,        // Writable
  SHF_ALLOC            = 0x2,        // Mapped
  SHF_EXECINSTR        = 0x4,        // Executable instructions
  SHF_MERGE            = 0x10,       // Mergeable elements
  SHF_STRINGS          = 0x20,       // NUL-terminated strings
  SHF_INFO_LINK        = 0x40,       // Section header table index
  SHF_LINK_ORDER       = 0x80,       // Special ordering requirement
  SHF_OS_NONCONFORMING = 0x100,      // OS-specific processing
  SHF_GROUP            = 0x200,      // Section group member
  SHF_TLS              = 0x400,      // Thread Local Storage
  SHF_COMPRESSED       = 0x800,      // Compressed
  SHF_MASKOS           = 0x0ff00000, // Operating system specific flags
  SHF_MASKPROC         = 0xf0000000, // Processor specific flags
};

// Section group flags
enum : Elf_Word {
  GRP_COMDAT   = 0x1,        // COMDAT group
  GRP_MASKOS   = 0x0ff00000, // Operating system specific flags
  GRP_MASKPROC = 0xf0000000, // Processof specific flags
};

// Compression type
typedef ELF_ENUM(Elf_Word, Elf_Chdr_Type) {
  ELFCOMPRESS_ZLIB   = 1,          // DEFLATE algorithm
  ELFCOMPRESS_ZSTD   = 2,          // zstd algorithm

  ELFCOMPRESS_LOOS   = 0x60000000, // Operating system specific
  ELFCOMPRESS_HIOS   = 0x6fffffff,

  ELFCOMPRESS_LOPROC = 0x70000000, // Processor specific
  ELFCOMPRESS_HIPROC = 0x7fffffff
} Elf_Chdr_Type;

// Symbol table entry
enum : Elf_Word {
  STN_UNDEF = 0
};

typedef ELF_ENUM(Elf_Byte, Elf_Sym_Binding) {
  STB_LOCAL  = 0,
  STB_GLOBAL = 1,
  STB_WEAK   = 2,

  STB_LOOS   = 10, // Operating system specific
  STB_HIOS   = 12,

  STB_LOPROC = 13, // Processor specific
  STB_HIPROC = 15
} Elf_Sym_Binding;

typedef ELF_ENUM(Elf_Byte, Elf_Sym_Type) {
  STT_NOTYPE  = 0,  // Unspecified
  STT_OBJECT  = 1,  // Data object (variable, array, &c)
  STT_FUNC    = 2,  // Function or other executable code
  STT_SECTION = 3,  // A section
  STT_FILE    = 4,  // Source file name
  STT_COMMON  = 5,  // Uninitialized common block
  STT_TLS     = 6,  // Thread Local Storage

  STT_LOOS    = 10, // Operating system specific
  STT_HIOS    = 12,

  STT_LOPROC  = 13, // Processor specific
  STT_HIPROC  = 15,
} Elf_Sym_Type;

typedef ELF_ENUM(Elf_Byte, Elf_Sym_Visibility) {
  STV_DEFAULT   = 0,
  STV_INTERNAL  = 1, // Processor specific but like hidden
  STV_HIDDEN    = 2, // Not visible from other components
  STV_PROTECTED = 3, // Visible but cannot be preempted
} Elf_Sym_Visibility;

// Program header types
typedef ELF_ENUM(Elf_Word, Elf_Phdr_Type) {
  PT_NULL    = 0,          // Element unused
  PT_LOAD    = 1,          // Loadable segment
  PT_DYNAMIC = 2,          // Dynamic linking information
  PT_INTERP  = 3,          // Interpreter
  PT_NOTE    = 4,          // Auxiliary information
  PT_SHLIB   = 5,          // Reserved
  PT_PHDR    = 6,          // Program header table
  PT_TLS     = 7,          // Thread Local Storage

  PT_LOOS    = 0x60000000, // Operating system specific
    PT_GNU_EH_FRAME = 0x6474e550, // GNU .eh_frame_hdr segment
    PT_GNU_STACK    = 0x6474e551, // Indicates stack executability
    PT_GNU_RELRO    = 0x6474e552, // Read-only after relocation

    PT_LOSUNW       = 0x6ffffffa,
    PT_SUNWBSS      = 0x6ffffffa,
    PT_SUNWSTACK    = 0x6ffffffb,
    PT_HISUNW       = 0x6fffffff,
  PT_HIOS    = 0x6fffffff,

  PT_LOPROC  = 0x70000000, // Processor specific
  PT_HIPROC  = 0x7fffffff,
} Elf_Phdr_Type;

// Program header flags
typedef ELF_OPTIONS(Elf_Word, Elf_Phdr_Flags) {
  PF_X        = 0x1,        // Execute
  PF_W        = 0x2,        // Write
  PF_R        = 0x4,        // Read,

  PF_MASKOS   = 0x0ff00000, // Operating system specific
  PF_MASKPROC = 0xf0000000, // Processor specific
};

// Dynamic linking tags
enum {
  DT_NULL            = 0,  // Marks the end of the _DYNAMIC array
  DT_NEEDED          = 1,  // String table offset of name of needed library
  DT_PLTRELSZ        = 2,  // Total size of relocation entries for PLT
  DT_PLTGOT          = 3,  // Address of PLT/GOT
  DT_HASH            = 4,  // Address of symbol hash table
  DT_STRTAB          = 5,  // Address of string table
  DT_SYMTAB          = 6,  // Address of symbol table
  DT_RELA            = 7,  // Address of DT_RELA relocation table
  DT_RELASZ          = 8,  // Size of DT_RELA table
  DT_RELAENT         = 9,  // Size of DT_RELA entry
  DT_STRSZ           = 10, // Size of string table
  DT_SYMENT          = 11, // Size of symbol table entry
  DT_INIT            = 12, // Address of initialization function
  DT_FINI            = 13, // Address of termination function
  DT_SONAME          = 14, // String table offset of name of shared object
  DT_RPATH           = 15, // String table offset of search path
  DT_SYMBOLIC        = 16, // Means to search from shared object first
  DT_REL             = 17, // Address of DT_REL relocation table
  DT_RELSZ           = 18, // Size of DT_REL table
  DT_RELENT          = 19, // Size of DT_REL entry
  DT_PLTREL          = 20, // Type of PLT relocation entry (DT_REL/DT_RELA)
  DT_DEBUG           = 21, // Used for debugging
  DT_TEXTREL         = 22, // Means relocations might write to read-only segment
  DT_JMPREL          = 23, // Address of relocation entries for PLT
  DT_BIND_NOW        = 24, // Means linker should not lazily bind
  DT_INIT_ARRAY      = 25, // Address of pointers to initialization functions
  DT_FINI_ARRAY      = 26, // Address of pointers to termination functions
  DT_INIT_ARRAYSZ    = 27, // Size in bytes of initialization function array
  DT_FINI_ARRAYSZ    = 28, // Size in bytes of termination function array
  DT_RUNPATH         = 29, // String table offset of search path
  DT_FLAGS           = 30, // Flags

  DT_ENCODING        = 32, // Tags equal to or above this follow encoding rules

  DT_PREINIT_ARRAY   = 32, // Address of pre-initialization function array
  DT_PREINIT_ARRAYSZ = 33, // Size in bytes of pre-initialization fn array

  DT_LOOS            = 0x6000000D, // Operating system specific
  DT_HIOS            = 0x6ffff000,

  DT_LOPROC          = 0x70000000, // Processor specific
  DT_HIPROC          = 0x7fffffff,
};

// Dynamic linking flags
enum {
  DF_ORIGIN     = 0x1,  // Uses $ORIGIN substitution string
  DF_SYMBOLIC   = 0x2,  // Search shared object first before usual search
  DF_TEXTREL    = 0x4,  // Relocations may modify read-only segments
  DF_BIND_NOW   = 0x8,  // Linker should not lazily bind
  DF_STATIC_TLS = 0x10, // Uses static TLS - must not be dynamically loaded
};

// GNU note types
enum {
  NT_GNU_ABI_TAG         = 1, // ABI information
  NT_GNU_HWCAP           = 2, // Synthetic hwcap information
  NT_GNU_BUILD_ID        = 3, // Build ID
  NT_GNU_GOLD_VERSION    = 4, // Generated by GNU gold
  NT_GNU_PROPERTY_TYPE_0 = 5, // Program property
};

/* .. ELF Header ............................................................ */

#define EI_NIDENT 16

typedef struct {
  Elf32_Byte       e_ident[EI_NIDENT];
  Elf_Ehdr_Type    e_type;
  Elf_Ehdr_Machine e_machine;
  Elf_Ehdr_Version e_version;
  Elf32_Addr       e_entry;
  Elf32_Off        e_phoff;
  Elf32_Off        e_shoff;
  Elf32_Word       e_flags;
  Elf32_Half       e_ehsize;
  Elf32_Half       e_phentsize;
  Elf32_Half       e_phnum;
  Elf32_Half       e_shentsize;
  Elf32_Half       e_shnum;
  Elf32_Half       e_shstrndx;
} Elf32_Ehdr;

typedef struct {
  Elf64_Byte       e_ident[EI_NIDENT];
  Elf_Ehdr_Type    e_type;
  Elf_Ehdr_Machine e_machine;
  Elf_Ehdr_Version e_version;
  Elf64_Addr       e_entry;
  Elf64_Off        e_phoff;
  Elf64_Off        e_shoff;
  Elf64_Word       e_flags;
  Elf64_Half       e_ehsize;
  Elf64_Half       e_phentsize;
  Elf64_Half       e_phnum;
  Elf64_Half       e_shentsize;
  Elf64_Half       e_shnum;
  Elf64_Half       e_shstrndx;
} Elf64_Ehdr;

/* .. Section Header ........................................................ */

typedef struct {
  Elf32_Word    sh_name;
  Elf_Shdr_Type sh_type;
  Elf32_Word    sh_flags;
  Elf32_Addr    sh_addr;
  Elf32_Off     sh_offset;
  Elf32_Word    sh_size;
  Elf32_Word    sh_link;
  Elf32_Word    sh_info;
  Elf32_Word    sh_addralign;
  Elf32_Word    sh_entsize;
} Elf32_Shdr;

typedef struct {
  Elf64_Word    sh_name;
  Elf_Shdr_Type sh_type;
  Elf64_Xword   sh_flags;
  Elf64_Addr    sh_addr;
  Elf64_Off     sh_offset;
  Elf64_Xword   sh_size;
  Elf64_Word    sh_link;
  Elf64_Word    sh_info;
  Elf64_Xword   sh_addralign;
  Elf64_Xword   sh_entsize;
} Elf64_Shdr;

/* .. Compression Header .................................................... */

typedef struct {
  Elf_Chdr_Type ch_type;
  Elf32_Word    ch_size;
  Elf32_Word    ch_addralign;
} Elf32_Chdr;

typedef struct {
  Elf_Chdr_Type ch_type;
  Elf64_Word    ch_reserved;
  Elf64_Xword   ch_size;
  Elf64_Xword   ch_addralign;
} Elf64_Chdr;

/* .. Symbol Table .......................................................... */

typedef struct {
  Elf32_Word st_name;
  Elf32_Addr st_value;
  Elf32_Word st_size;
  Elf32_Byte st_info;
  Elf32_Byte st_other;
  Elf32_Half st_shndx;
} Elf32_Sym;

typedef struct {
  Elf64_Word  st_name;
  Elf64_Byte  st_info;
  Elf64_Byte  st_other;
  Elf64_Half  st_shndx;
  Elf64_Addr  st_value;
  Elf64_Xword st_size;
} Elf64_Sym;

static inline Elf_Sym_Binding ELF32_ST_BIND(Elf_Byte i) { return i >> 4; }
static inline Elf_Sym_Type ELF32_ST_TYPE(Elf_Byte i) { return i & 0xf; }
static inline Elf_Byte ELF32_ST_INFO(Elf_Sym_Binding b, Elf_Sym_Type t) {
  return (b << 4) | (t & 0xf);
}

static inline Elf_Sym_Binding ELF64_ST_BIND(Elf_Byte i) { return i >> 4; }
static inline Elf_Sym_Type ELF64_ST_TYPE(Elf_Byte i) { return i & 0xf; }
static inline Elf_Byte ELF64_ST_INFO(Elf_Sym_Binding b, Elf_Sym_Type t) {
  return (b << 4) | (t & 0xf);
}

static inline Elf_Sym_Visibility ELF32_ST_VISIBILITY(Elf_Byte o) {
  return o & 3;
}
static inline Elf_Sym_Visibility ELF64_ST_VISIBILITY(Elf_Byte o) {
  return o & 3;
}

/* .. Relocation ............................................................ */

typedef struct {
  Elf32_Addr    r_offset;
  Elf32_Word    r_info;
} Elf32_Rel;

typedef struct {
  Elf32_Addr    r_offset;
  Elf32_Word    r_info;
  Elf32_Sword   r_addend;
} Elf32_Rela;

typedef struct {
  Elf64_Addr    r_offset;
  Elf64_Xword   r_info;
} Elf64_Rel;

typedef struct {
  Elf64_Addr    r_offset;
  Elf64_Xword   r_info;
  Elf64_Sxword  r_addend;
} Elf64_Rela;

static inline Elf32_Byte ELF32_R_SYM(Elf32_Word i) { return i >> 8; }
static inline Elf32_Byte ELF32_R_TYPE(Elf32_Word i) { return i & 0xff; }
static inline Elf32_Word ELF32_R_INFO(Elf32_Byte s, Elf32_Byte t) {
  return (s << 8) | t;
}

static inline Elf64_Word ELF64_R_SYM(Elf64_Xword i) { return i >> 32; }
static inline Elf64_Word ELF64_R_TYPE(Elf64_Xword i) { return i & 0xffffffff; }
static inline Elf64_Xword ELF64_R_INFO(Elf64_Word s, Elf64_Word t) {
  return (((Elf64_Xword)s) << 32) | t;
}

/* .. Program Header ........................................................ */

typedef struct {
  Elf_Phdr_Type   p_type;
  Elf32_Off       p_offset;
  Elf32_Addr      p_vaddr;
  Elf32_Addr      p_paddr;
  Elf32_Word      p_filesz;
  Elf32_Word      p_memsz;
  Elf_Phdr_Flags  p_flags;
  Elf32_Word      p_align;
} Elf32_Phdr;

typedef struct {
  Elf_Phdr_Type   p_type;
  Elf_Phdr_Flags  p_flags;
  Elf64_Off       p_offset;
  Elf64_Addr      p_vaddr;
  Elf64_Addr      p_paddr;
  Elf64_Xword     p_filesz;
  Elf64_Xword     p_memsz;
  Elf64_Xword     p_align;
} Elf64_Phdr;

/* .. Note Header ........................................................... */

typedef struct {
  Elf32_Word n_namesz;
  Elf32_Word n_descsz;
  Elf32_Word n_type;
} Elf32_Nhdr;

typedef struct {
  Elf64_Word n_namesz;
  Elf64_Word n_descsz;
  Elf64_Word n_type;
} Elf64_Nhdr;

/* .. Dynamic Linking ....................................................... */

typedef struct {
  Elf32_Sword   d_tag;
  union {
    Elf32_Word  d_val;
    Elf32_Addr  d_ptr;
  } d_un;
} Elf32_Dyn;

typedef struct {
  Elf64_Sxword  d_tag;
  union {
    Elf64_Xword d_val;
    Elf64_Addr  d_ptr;
  } d_un;
} Elf64_Dyn;

/* .. Hash Table ............................................................ */

typedef struct {
  Elf32_Word h_nbucket;
  Elf32_Word h_nchain;
} Elf32_Hash;

typedef struct {
  Elf64_Word h_nbucket;
  Elf64_Word h_nchain;
} Elf64_Hash;

static inline unsigned long
elf_hash(const unsigned char *name)
{
  unsigned long h = 0, g;
  while (*name) {
    h = (h << 4) + *name++;
    if ((g = h & 0xf0000000))
      h ^= g >> 24;
    h &= ~g;
  }
  return h;
}

#endif // ELF_H