aboutsummaryrefslogtreecommitdiff
path: root/core/elf.h
blob: 66fedee29fe2abfe310f51c31d711667dc6e2f79 (plain)
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
/**
 * ELF format.
 */

#ifndef ELF_H
#define ELF_H

enum {
	EI_MAG0       = 0,          // File identification index.
	EI_MAG1       = 1,          // File identification index.
	EI_MAG2       = 2,          // File identification index.
	EI_MAG3       = 3,          // File identification index.
	EI_CLASS      = 4,          // File class.
	EI_DATA       = 5,          // Data encoding.
	EI_VERSION    = 6,          // File version.
	EI_OSABI      = 7,          // OS/ABI identification.
	EI_ABIVERSION = 8,          // ABI version.
	EI_PAD        = 9,          // Start of padding bytes.
	EI_NIDENT     = 16          // Number of bytes in e_ident.
};

struct Elf32_Ehdr {
	uint8_t     e_ident[EI_NIDENT]; // ELF Identification bytes
	uint16_t    e_type;      // Type of file (see ET_* below)
	uint16_t    e_machine;   // Required architecture for this file (see EM_*)
	uint32_t    e_version;   // Must be equal to 1
	uint32_t    e_entry;     // Address to jump to in order to start program
	uint32_t    e_phoff;     // Program header table's file offset, in bytes
	uint32_t    e_shoff;     // Section header table's file offset, in bytes
	uint32_t    e_flags;     // Processor-specific flags
	uint16_t    e_ehsize;    // Size of ELF header, in bytes
	uint16_t    e_phentsize; // Size of an entry in the program header table
	uint16_t    e_phnum;     // Number of entries in the program header table
	uint16_t    e_shentsize; // Size of an entry in the section header table
	uint16_t    e_shnum;     // Number of entries in the section header table
	uint16_t    e_shstrndx;  // Sect hdr table index of sect name string table
};

struct Elf64_Ehdr {
	uint8_t     e_ident[EI_NIDENT];
	uint16_t    e_type;
	uint16_t    e_machine;
	uint32_t    e_version;
	uint64_t    e_entry;
	uint64_t    e_phoff;
	uint64_t    e_shoff;
	uint32_t    e_flags;
	uint16_t    e_ehsize;
	uint16_t    e_phentsize;
	uint16_t    e_phnum;
	uint16_t    e_shentsize;
	uint16_t    e_shnum;
	uint16_t    e_shstrndx;
};

enum {
	ELFCLASSNONE = 0,
	ELFCLASS32 = 1, // 32-bit object file
	ELFCLASS64 = 2  // 64-bit object file
};

enum {
	EV_NONE = 0,
	EV_CURRENT = 1
};

enum {
	ELFOSABI_NONE = 0,			// UNIX System V ABI
	ELFOSABI_SYSV = 0,			// Alias
	ELFOSABI_HPUX = 1,			// HP-UX
	ELFOSABI_NETBSD = 2,		// NetBSD
	ELFOSABI_GNU = 3,			// Object uses GNU ELF extensions
	ELFOSABI_LINUX = 3,			// Compatibility alias
	ELFOSABI_SOLARIS = 6,		// Sun Solaris
	ELFOSABI_AIX = 7,			// IBM AIX
	ELFOSABI_IRIX = 8,			// SGI Irix
	ELFOSABI_FREEBSD = 9,		// FreeBSD
	ELFOSABI_TRU64 = 10,		// Compaq TRU64 UNIX
	ELFOSABI_MODESTO = 11,		// Novell Modesto
	ELFOSABI_OPENBSD = 12,		// OpenBSD
	ELFOSABI_ARM_AEABI = 64,	// ARM EABI
	ELFOSABI_ARM = 97,			// ARM
	ELFOSABI_STANDALONE = 255	// Standalone (embedded) application
};

enum {
	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_LOPROC = 0xff00, // Beginning of processor-specific codes
	ET_HIPROC = 0xffff  // Processor-specific
};

enum {
	EM_NONE          = 0, // No machine
	EM_M32           = 1, // AT&T WE 32100
	EM_SPARC         = 2, // SPARC
	EM_386           = 3, // Intel 386
	EM_68K           = 4, // Motorola 68000
	EM_88K           = 5, // Motorola 88000
	EM_486           = 6, // Intel 486 (deprecated)
	EM_860           = 7, // Intel 80860
	EM_MIPS          = 8, // MIPS R3000
	EM_S370          = 9, // IBM System/370
	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, // PowerPC64
	EM_S390          = 22, // IBM System/390
	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
	EM_ALPHA         = 41, // DEC Alpha
	EM_SH            = 42, // Hitachi SH
	EM_SPARCV9       = 43, // SPARC V9
	EM_TRICORE       = 44, // Siemens TriCore
	EM_ARC           = 45, // Argonaut RISC Core
	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
	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
	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_HEXAGON       = 164, // Qualcomm Hexagon 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 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_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
	EM_KM32          = 210, // KM211 KM32 32-bit processor
	EM_KMX32         = 211, // KM211 KMX32 32-bit processor
	EM_KMX16         = 212, // KM211 KMX16 16-bit processor
	EM_KMX8          = 213, // KM211 KMX8 8-bit processor
	EM_KVARC         = 214, // KM211 KVARC processor
	EM_CDP           = 215, // Paneve CDP architecture family
	EM_COGE          = 216, // Cognitive Smart Memory Processor
	EM_COOL          = 217, // iCelero CoolEngine
	EM_NORC          = 218, // Nanoradio Optimized RISC
	EM_CSR_KALIMBA   = 219  // CSR Kalimba architecture family
};

/*
typedef uint64_t Elf64_Addr;
typedef uint64_t Elf64_Off;
typedef uint16_t Elf64_Half;
typedef uint32_t Elf64_Word;
typedef  int32_t Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef  int64_t Elf64_Sxword;
typedef  int16_t Elf64_Section;
*/

struct Elf32_Phdr {
	uint32_t  p_type;   // Type of segment
	uint32_t  p_offset; // File offset where segment is located, in bytes
	uint32_t  p_vaddr;  // Virtual address of beginning of segment
	uint32_t  p_paddr;  // Physical address of beginning of segment (OS-specific)
	uint32_t  p_filesz; // Num. of bytes in file image of segment (may be zero)
	uint32_t  p_memsz;  // Num. of bytes in mem image of segment (may be zero)
	uint32_t  p_flags;  // Segment flags
	uint32_t  p_align;  // Segment alignment constraint
};

struct Elf64_Phdr {
	uint32_t  p_type;   // Type of segment
	uint32_t  p_flags;  // Segment flags
	uint64_t  p_offset; // File offset where segment is located, in bytes
	uint64_t  p_vaddr;  // Virtual address of beginning of segment
	uint64_t  p_paddr;  // Physical addr of beginning of segment (OS-specific)
	uint64_t  p_filesz; // Num. of bytes in file image of segment (may be zero)
	uint64_t  p_memsz;  // Num. of bytes in mem image of segment (may be zero)
	uint64_t  p_align;  // Segment alignment constraint
};

enum {
	PT_NULL    = 0, // Unused segment.
	PT_LOAD    = 1, // Loadable segment.
	PT_DYNAMIC = 2, // Dynamic linking information.
	PT_INTERP  = 3, // Interpreter pathname.
	PT_NOTE    = 4, // Auxiliary information.
	PT_SHLIB   = 5, // Reserved.
	PT_PHDR    = 6, // The program header table itself.
	PT_TLS     = 7, // The thread-local storage template.
	PT_LOOS    = 0x60000000, // Lowest operating system-specific pt entry type.
	PT_HIOS    = 0x6fffffff, // Highest operating system-specific pt entry type.
	PT_LOPROC  = 0x70000000, // Lowest processor-specific program hdr entry type.
	PT_HIPROC  = 0x7fffffff, // Highest processor-specific program hdr entry type.

	// x86-64 program header types.
	// These all contain stack unwind tables.
	PT_GNU_EH_FRAME  = 0x6474e550,
	PT_SUNW_EH_FRAME = 0x6474e550,
	PT_SUNW_UNWIND   = 0x6464e550,

	PT_GNU_STACK  = 0x6474e551, // Indicates stack executability.
	PT_GNU_RELRO  = 0x6474e552, // Read-only after relocation.
};

enum : unsigned {
	PF_X        = 1,         // Execute
	PF_W        = 2,         // Write
	PF_R        = 4,         // Read
};

#define SHN_UNDEF 0

struct Elf32_Shdr {
	uint32_t  sh_name;      // Section name (index into string table)
	uint32_t  sh_type;      // Section type (SHT_*)
	uint32_t  sh_flags;     // Section flags (SHF_*)
	uint32_t  sh_addr;      // Address where section is to be loaded
	uint32_t  sh_offset;    // File offset of section data, in bytes
	uint32_t  sh_size;      // Size of section, in bytes
	uint32_t  sh_link;      // Section type-specific header table index link
	uint32_t  sh_info;      // Section type-specific extra information
	uint32_t  sh_addralign; // Section address alignment
	uint32_t  sh_entsize;   // Size of records contained within the section
};

struct Elf64_Shdr {
	uint32_t  sh_name;
	uint32_t  sh_type;
	uint64_t  sh_flags;
	uint64_t  sh_addr;
	uint64_t  sh_offset;
	uint64_t  sh_size;
	uint32_t  sh_link;
	uint32_t  sh_info;
	uint64_t  sh_addralign;
	uint64_t  sh_entsize;
};

enum : unsigned {
	SHT_NULL          = 0,  // No associated section (inactive entry).
	SHT_PROGBITS      = 1,  // Program-defined contents.
	SHT_SYMTAB        = 2,  // Symbol table.
	SHT_STRTAB        = 3,  // String table.
	SHT_RELA          = 4,  // Relocation entries; explicit addends.
	SHT_HASH          = 5,  // Symbol hash table.
	SHT_DYNAMIC       = 6,  // Information for dynamic linking.
	SHT_NOTE          = 7,  // Information about the file.
	SHT_NOBITS        = 8,  // Data occupies no space in the file.
	SHT_REL           = 9,  // Relocation entries; no explicit addends.
	SHT_SHLIB         = 10, // Reserved.
	SHT_DYNSYM        = 11, // Symbol table.
	SHT_INIT_ARRAY    = 14, // Pointers to initialization functions.
	SHT_FINI_ARRAY    = 15, // Pointers to termination functions.
	SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
	SHT_GROUP         = 17, // Section group.
	SHT_SYMTAB_SHNDX  = 18, // Indices for SHN_XINDEX entries.
	SHT_LOOS          = 0x60000000, // Lowest operating system-specific type.
	SHT_GNU_ATTRIBUTES= 0x6ffffff5, // Object attributes.
	SHT_GNU_HASH      = 0x6ffffff6, // GNU-style hash table.
	SHT_GNU_verdef    = 0x6ffffffd, // GNU version definitions.
	SHT_GNU_verneed   = 0x6ffffffe, // GNU version references.
	SHT_GNU_versym    = 0x6fffffff, // GNU symbol versions table.
	SHT_HIOS          = 0x6fffffff, // Highest operating system-specific type.
	SHT_LOPROC        = 0x70000000, // Lowest processor arch-specific type.
	SHT_ARM_EXIDX           = 0x70000001U, // Exception Index table
	SHT_ARM_PREEMPTMAP      = 0x70000002U, // BPABI DLL dynamic linking pre-emption map
	SHT_ARM_ATTRIBUTES      = 0x70000003U, // Object file compatibility attributes
	SHT_ARM_DEBUGOVERLAY    = 0x70000004U,
	SHT_ARM_OVERLAYSECTION  = 0x70000005U,
	SHT_HEX_ORDERED         = 0x70000000, // Link editor is to sort the entries in this section based on their sizes
	SHT_X86_64_UNWIND       = 0x70000001, // Unwind information
	SHT_MIPS_REGINFO        = 0x70000006, // Register usage information
	SHT_MIPS_OPTIONS        = 0x7000000d, // General options
	SHT_MIPS_ABIFLAGS       = 0x7000002a, // ABI information.
	SHT_HIPROC        = 0x7fffffff, // Highest processor arch-specific type.
	SHT_LOUSER        = 0x80000000, // Lowest type reserved for applications.
	SHT_HIUSER        = 0xffffffff  // Highest type reserved for applications.
};

enum : unsigned {
	SHF_WRITE = 0x1, // Section data should be writable during execution.
	SHF_ALLOC = 0x2, // Section occupies memory during program execution.
	SHF_EXECINSTR = 0x4, // Section contains executable machine instructions.
	SHF_MERGE = 0x10, // The data in this section may be merged.
	SHF_STRINGS = 0x20, // The data in this section is null-terminated strings.
	SHF_INFO_LINK = 0x40U, // A field in this section holds a section header table index.
	SHF_LINK_ORDER = 0x80U, // Adds special ordering requirements for link editors.
	SHF_OS_NONCONFORMING = 0x100U, // This section requires special OS-specific processing to avoid incorrect behavior.
	SHF_GROUP = 0x200U, // This section is a member of a section group.
	SHF_TLS = 0x400U, // This section holds Thread-Local Storage.
	SHF_EXCLUDE = 0x80000000U, // This section is excluded from the final executable or shared library.
	SHF_MASKOS   = 0x0ff00000,
	SHF_MASKPROC = 0xf0000000,
	SHF_X86_64_LARGE = 0x10000000,
	SHF_HEX_GPREL = 0x10000000,
	SHF_MIPS_NODUPES = 0x01000000,
	SHF_MIPS_NAMES   = 0x02000000,
	SHF_MIPS_LOCAL   = 0x04000000, // Section data local to process.
	SHF_MIPS_NOSTRIP = 0x08000000, // Do not strip this section.
	SHF_MIPS_GPREL   = 0x10000000, // Section must be part of global data area.
	SHF_MIPS_MERGE   = 0x20000000, // This section should be merged.
	SHF_MIPS_ADDR    = 0x40000000, // Address size to be inferred from section entry size.
	SHF_MIPS_STRING  = 0x80000000 // Section data is string data by default.
};

struct Elf32_Sym {
	uint32_t  st_name;  // Symbol name (index into string table)
	uint32_t  st_value; // Value or address associated with the symbol
	uint32_t  st_size;  // Size of the symbol
	uint8_t   st_info;  // Symbol's type and binding attributes
	uint8_t   st_other; // Must be zero; reserved
	uint16_t  st_shndx; // Which section (header table index) it's defined in
};

struct Elf64_Sym {
	uint32_t  st_name;  // Symbol name (index into string table)
	uint8_t   st_info;  // Symbol's type and binding attributes
	uint8_t   st_other; // Must be zero; reserved
	uint16_t  st_shndx; // Which section (header tbl index) it's defined in
	uint64_t  st_value; // Value or address associated with the symbol
	uint64_t  st_size;  // Size of the symbol
};

enum {
	STT_NOTYPE  = 0,   // Symbol's type is not specified
	STT_OBJECT  = 1,   // Symbol is a data object (variable, array, etc.)
	STT_FUNC    = 2,   // Symbol is executable code (function, etc.)
	STT_SECTION = 3,   // Symbol refers to a section
	STT_FILE    = 4,   // Local, absolute symbol that refers to a file
	STT_COMMON  = 5,   // An uninitialized common block
	STT_TLS     = 6,   // Thread local data object
	STT_LOOS    = 7,   // Lowest operating system-specific symbol type
	STT_HIOS    = 8,   // Highest operating system-specific symbol type
	STT_GNU_IFUNC = 10, // GNU indirect function
	STT_LOPROC  = 13,  // Lowest processor-specific symbol type
	STT_HIPROC  = 15   // Highest processor-specific symbol type
};

enum {
	STB_LOCAL = 0,   // Local symbol, not visible outside obj file containing def
	STB_GLOBAL = 1,  // Global symbol, visible to all object files being combined
	STB_WEAK = 2,    // Weak symbol, like global but lower-precedence
	STB_GNU_UNIQUE = 10,
	STB_LOOS   = 10, // Lowest operating system-specific binding type
	STB_HIOS   = 12, // Highest operating system-specific binding type
	STB_LOPROC = 13, // Lowest processor-specific binding type
	STB_HIPROC = 15  // Highest processor-specific binding type
};

struct Elf32_Rel {
	uint32_t r_offset; // Location (file byte offset, or program virtual addr)
	uint32_t r_info;   // Symbol table index and type of relocation to apply
};

struct Elf64_Rel {
	uint64_t r_offset; // Location (file byte offset, or program virtual addr)
	uint32_t r_type;   // Type of relocation to apply
	uint32_t r_ssym;   // Symbol table index
};

struct Elf32_Rela {
	uint32_t r_offset; // Location (file byte offset, or program virtual addr)
	uint32_t r_info;   // Symbol table index and type of relocation to apply
	uint32_t r_addend;
};

struct Elf64_Rela {
	uint64_t r_offset; // Location (file byte offset, or program virtual addr)
	uint32_t r_type;   // Type of relocation to apply
	uint32_t r_ssym;   // Symbol table index
	uint64_t r_addend;
};

struct Elf32_Dyn {
	uint32_t d_tag;            // Type of dynamic table entry.
	union
	{
		uint32_t d_val;         // Integer value of entry.
		uint32_t d_ptr;         // Pointer value of entry.
	} d_un;
};

struct Elf64_Dyn {
	uint64_t d_tag;           // Type of dynamic table entry.
	union
	{
		uint64_t d_val;        // Integer value of entry.
		uint64_t d_ptr;        // Pointer value of entry.
	} d_un;
};

enum {
	DT_NULL         = 0,        // Marks end of dynamic array.
	DT_NEEDED       = 1,        // String table offset of needed library.
	DT_PLTRELSZ     = 2,        // Size of relocation entries in PLT.
	DT_PLTGOT       = 3,        // Address associated with linkage table.
	DT_HASH         = 4,        // Address of symbolic hash table.
	DT_STRTAB       = 5,        // Address of dynamic string table.
	DT_SYMTAB       = 6,        // Address of dynamic symbol table.
	DT_RELA         = 7,        // Address of relocation table (Rela entries).
	DT_RELASZ       = 8,        // Size of Rela relocation table.
	DT_RELAENT      = 9,        // Size of a Rela relocation entry.
	DT_STRSZ        = 10,       // Total size of the string table.
	DT_SYMENT       = 11,       // Size of a symbol table entry.
	DT_INIT         = 12,       // Address of initialization function.
	DT_FINI         = 13,       // Address of termination function.
	DT_SONAME       = 14,       // String table offset of a shared objects name.
	DT_RPATH        = 15,       // String table offset of library search path.
	DT_SYMBOLIC     = 16,       // Changes symbol resolution algorithm.
	DT_REL          = 17,       // Address of relocation table (Rel entries).
	DT_RELSZ        = 18,       // Size of Rel relocation table.
	DT_RELENT       = 19,       // Size of a Rel relocation entry.
	DT_PLTREL       = 20,       // Type of relocation entry used for linking.
	DT_DEBUG        = 21,       // Reserved for debugger.
	DT_TEXTREL      = 22,       // Relocations exist for non-writable segments.
	DT_JMPREL       = 23,       // Address of relocations associated with PLT.
	DT_BIND_NOW     = 24,       // Process all relocations before execution.
	DT_INIT_ARRAY   = 25,       // Pointer to array of initialization functions.
	DT_FINI_ARRAY   = 26,       // Pointer to array of termination functions.
	DT_INIT_ARRAYSZ = 27,       // Size of DT_INIT_ARRAY.
	DT_FINI_ARRAYSZ = 28,       // Size of DT_FINI_ARRAY.
	DT_RUNPATH      = 29,       // String table offset of lib search path.
	DT_FLAGS        = 30,       // Flags.
	DT_ENCODING     = 32,       // Values from here to DT_LOOS follow the rules for the interpretation of the d_un union.
	DT_PREINIT_ARRAY = 32,      // Pointer to array of preinit functions.
	DT_PREINIT_ARRAYSZ = 33,    // Size of the DT_PREINIT_ARRAY array.

	DT_LOOS         = 0x60000000, // Start of environment specific tags.
	DT_HIOS         = 0x6FFFFFFF, // End of environment specific tags.
	DT_LOPROC       = 0x70000000, // Start of processor specific tags.
	DT_HIPROC       = 0x7FFFFFFF, // End of processor specific tags.
	DT_GNU_HASH     = 0x6FFFFEF5, // Reference to the GNU hash table.
	DT_RELACOUNT    = 0x6FFFFFF9, // ELF32_Rela count.
	DT_RELCOUNT     = 0x6FFFFFFA, // ELF32_Rel count.
	DT_FLAGS_1      = 0X6FFFFFFB, // Flags_1.
	DT_VERSYM       = 0x6FFFFFF0, // The address of .gnu.version section.
	DT_VERDEF       = 0X6FFFFFFC, // The address of the version definition table.
	DT_VERDEFNUM    = 0X6FFFFFFD, // The number of entries in DT_VERDEF.
	DT_VERNEED      = 0X6FFFFFFE, // The address of the version Dependency table.
	DT_VERNEEDNUM   = 0X6FFFFFFF, // The number of entries in DT_VERNEED.
};

/* Version definition sections.  */

struct Elf32_Verdef
{
	uint16_t	vd_version;		/* Version revision */
	uint16_t	vd_flags;		/* Version information */
	uint16_t	vd_ndx;			/* Version Index */
	uint16_t	vd_cnt;			/* Number of associated aux entries */
	uint32_t	vd_hash;		/* Version name hash value */
	uint32_t	vd_aux;			/* Offset in bytes to verdaux array */
	uint32_t	vd_next;		/* Offset in bytes to next verdef entry */
};

struct Elf64_Verdef
{
	uint16_t	vd_version;		/* Version revision */
	uint16_t	vd_flags;		/* Version information */
	uint16_t	vd_ndx;			/* Version Index */
	uint16_t	vd_cnt;			/* Number of associated aux entries */
	uint32_t	vd_hash;		/* Version name hash value */
	uint32_t	vd_aux;			/* Offset in bytes to verdaux array */
	uint32_t	vd_next;		/* Offset in bytes to next verdef entry */
};

/* Legal values for vd_version (version revision).  */
#define VER_DEF_NONE	0		/* No version */
#define VER_DEF_CURRENT	1		/* Current version */
#define VER_DEF_NUM	2		/* Given version number */

/* Legal values for vd_flags (version information flags).  */
#define VER_FLG_BASE	0x1		/* Version definition of file itself */
#define VER_FLG_WEAK	0x2		/* Weak version identifier */

/* Versym symbol index values.  */
#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */

/* Auxialiary version information.  */

struct Elf32_Verdaux
{
	uint32_t	vda_name;		/* Version or dependency names */
	uint32_t	vda_next;		/* Offset in bytes to next verdaux entry */
};

struct Elf64_Verdaux
{
	uint32_t	vda_name;		/* Version or dependency names */
	uint32_t	vda_next;		/* Offset in bytes to next verdaux entry */
};

/* Version dependency section.  */

struct Elf32_Verneed
{
	uint16_t	vn_version;		/* Version of structure */
	uint16_t	vn_cnt;			/* Number of associated aux entries */
	uint32_t	vn_file;		/* Offset of filename for this dependency */
	uint32_t	vn_aux;			/* Offset in bytes to vernaux array */
	uint32_t	vn_next;		/* Offset in bytes to next verneed entry */
};

struct Elf64_Verneed
{
	uint16_t	vn_version;		/* Version of structure */
	uint16_t	vn_cnt;			/* Number of associated aux entries */
	uint32_t	vn_file;		/* Offset of filename for this dependency */
	uint32_t	vn_aux;			/* Offset in bytes to vernaux array */
	uint32_t	vn_next;		/* Offset in bytes to next verneed entry */
};

/* Legal values for vn_version (version revision).  */
#define VER_NEED_NONE	 0		/* No version */
#define VER_NEED_CURRENT 1		/* Current version */
#define VER_NEED_NUM	2	/* Given version number */

/* Auxiliary needed version information.  */

struct Elf32_Vernaux 
{
	uint32_t	vna_hash;		/* Hash value of dependency name */
	uint16_t	vna_flags;		/* Dependency specific information */
	uint16_t	vna_other;		/* Unused */
	uint32_t	vna_name;		/* Dependency name string offset */
	uint32_t	vna_next;		/* Offset in bytes to next vernaux entry */
};

struct Elf64_Vernaux
{
	uint32_t	vna_hash;		/* Hash value of dependency name */
	uint16_t	vna_flags;		/* Dependency specific information */
	uint16_t	vna_other;		/* Unused */
	uint32_t	vna_name;		/* Dependency name string offset */
	uint32_t	vna_next;		/* Offset in bytes to next vernaux entry */
};

#define	R_386_NONE		0	/* relocation type */
#define	R_386_32		1
#define	R_386_PC32		2
#define	R_386_GOT32		3
#define	R_386_PLT32		4
#define	R_386_COPY		5
#define	R_386_GLOB_DAT		6
#define	R_386_JMP_SLOT		7
#define	R_386_RELATIVE		8
#define	R_386_GOTOFF		9
#define	R_386_GOTPC		10
#define R_386_IRELATIVE	42

#define R_X86_64_IRELATIVE	37

#define ELF_PAGE_SIZE 0x1000

#ifndef PROT_NONE
#define PROT_NONE	0x0     /* Page can not be accessed.  */
#define PROT_READ	0x1     /* Page can be read.  */
#define PROT_WRITE	0x2     /* Page can be written.  */
#define PROT_EXEC	0x4     /* Page can be executed.  */
#endif

#endif