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.