An elf (PL: elves) is a type of humanoid supernatural being in Germanic folklore....ah I mean ELF the Executable and Linkable Format.
The structure:
+---------------------+
| ELF Header |
+---------------------+
| Prog Header Table |
+---------------------+
| LOAD SECTIONS... |
+---------------------+
| LOAD SECTIONS... |
+---------------------+
| LOAD SECTIONS... |
+---------------------+
| Section header Table|
+---------------------+
The ELF header is 64 bytes in length for 64 bits programs and 52 for 32 bits.
ELF file header
$ hexdump -C -n64 /usr/bin/ls
# hexdump of first 64 bytes
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 03 00 3e 00 01 00 00 00 a0 5f 00 00 00 00 00 00 |..>......_......|
00000020 40 00 00 00 00 00 00 00 b8 13 02 00 00 00 00 00 |@...............|
00000030 00 00 00 00 40 00 38 00 0d 00 40 00 1b 00 1a 00 |....@.8...@.....|
00000040
(64b ver.)
Bit-offset size Field Purpose
----------------------------------------------------------------- Elf Ident.
0x00 4 MAG The Magic number 0x7F E L F
0x04 1 CLASS Format: 1 - 32bit 2 - 64bit
0x05 1 DATA Endianness: 1 - LE 2 - BE
0x06 1 VERSION Current version of ELF 1
0x07 1 OSABI Target OS ABI (see appendix)
0x08 1 ABIVERSION linux ignores it *
0x09 7 PAD Padding , 0s
-----------------------------------------------------------------
0x10 2 type type of object file REL/EXEC/DYN/etc..
0x12 2 machine ISA
0x14 4 version 1
----------------------------------------------------------------- 8/4 bytes
0x18 8(4) entry Entry point
0x20 8(4) phoff offset of program header, usually 64 or 52
0x28 8(4) shoff offset of section header table
------------------------------------------------------------------
0x30 4 flags Depends on architecture
0x34 2 ehsize size of this header, normally 64 or 52
0x36 2 phentsize size of a program header entry
0x38 2 phnum numbers of program header entries
0x3A 2 shentsize size of section header entry
0x3C 2 shnum humber of section header entries
0x3E 2 shstrndx index of section header table entry
that contains the section names
0x40 -----------------END OF ELF FILE HEADER----------------
Program header table
(64b ver.)
Bit-offset size Field Purpose
-----------------------------------------------------------------
0x00 4 type See appendix
0x04 4 flags 1-X 2-W 4-R
0x08 8 offset offset of the segment in the file
0x10 8 vaddr VA of the segment in memory
0x18 8 paddr PA of segment - where applicable
0x20 8 filesz size of segment in file (bytes)
0x28 8 memsz size of segment in memory (bytes)
0x30 8 align 0 and 1 - no align. Otherwise power of 2
0x38 ------------------------END OF PROGRAM HEADER ----(56)---
Let's use this example:
$ readelf -l /usr/bin/ls
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000003638 0x0000000000003638 R 0x1000
.....
$ hexdump -C /usr/bin/ls
# Size of program header entry is 0x38 = 56
00000000 |
... | First 64 bytes ELF File header
----------------------------------------------------------
00000040 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 |........@.......|
00000050 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |@.......@.......|
00000060 d8 02 00 00 00 00 00 00 d8 02 00 00 00 00 00 00 |................|
00000070 08 00 00 00 00 00 00 00 -- -- -- -- -- -- -- -- |........
-split-- -- -- -- -- -- -- -- -- 03 00 00 00 04 00 00 00 ........|
00000080 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00 |................|
00000090 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 |................|
000000a0 1c 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
000000b0 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 38 36 00 00 00 00 00 00 38 36 00 00 00 00 00 00 |86......86......|
000000e0 00 10 00 00 00 00 00 00 01 00 00 00 05 00 00 00 |................|
000000f0 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 |.@.......@......|
Note that this thing if little endian. The first program header
[40, 4]
: Type is 6, this is PHDR[44, 4]
: Flags is 4, this is read only[48, 8]
: Offset is 0x40, this offset in file, i.e. THIS TABLE[50, 16]
: vaddr and paddr, they are the same : 0x40;[60, 8]
: filesz == 0x2d8 == 728. Here 728 == phnum * phentsize = 13 * 56. i.e.[68, 8]
: memsz == 0x2d8 == filesz, implying there is no BSS in this seg. the size of the program header table.[70, 8]
: align = 0x8 , i.e. 2^8 = 256 bytes
Appendix
EL_OSABI OS
--------------------------------------------
0x00 System V
0x01 HP-UX
0x02 NetBSD
0x03 Linux
0x04 GNU Hurd
0x06 Solaris
0x07 AIX
0x08 IRIX
0x09 FreeBSD
0x0A Tru64
0x0B Novell ModestoA
0x0C OpenBSD
0x0D OpenVMS
0x0E NonStop Kernel
0x0F AROS
0x10 FnixOS
0x11 Nuxi CloudABI
0x12 Stratus Technologies OpenVOS
Types of Program Headers:
TYPE [0:3] Name Meaning
--------------------------------------------
0x0 NULL program header table unused
0x1 LOAD loadable segment
0x2 DYNAMIC Dyn. linking info
0x3 INTERP interpreter info
0x4 NOTE Aux. info
0x5 SHLIB Reserved
0x6 PHDR Segment containing PH table itself
0x7 TLS Thread-local storage template
0x60000000 LOOS reserved inclusive range OS Specific
0x6FFFFFFF HIOS |_
0x70000000 LOPROC reserved inclusive range Processor Specific
0x7FFFFFFF HIPROC |_
ABIVERSION: ABIVERSION is ignored for statically-linked executables.