Basics of ELF (Executable and Linkable Format) file

Ajmewal
4 min readJul 11, 2023

--

ELF

ELF file format

ELF is a format for Executable and Linkable Format. It’s a used for storing binaries, libraries, and core dumps on disks in Linux and Unix-based systems.

It also supports features such as dynamic linking, which allows shared libraries to be loaded and linked at runtime, and position-independent code, which enables executables and libraries to be loaded at different memory addresses.

Basic information Of ELF file

$ file /bin/bash
/bin/bash: ELF 64-bit LSB pie executable, x86–64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86–64.so.2, BuildID[sha1]=530c7f80e8a85762b8c6796632fca547c1311a42, for GNU/Linux 3.2.0, stripped

The Structure of the ELF File

The ELF file is divided in two parts. The first is ELF header and the second is ELF data.

Structure of the ELF File

Further the ELF data is made up of Program headers, Section headers, and Data. The ELF header is available in ELF file.

The ELF header

The ELF header is 32 bytes long, and identifies the format of the file. It starts with a sequence of four unique bytes that are 0x7F followed by 0x45, 0x4c, and 0x46 which translates into the three letters E, L, and F

Display ELF header using readelf using -hoption.

 $ readelf -h /bin/sh
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4760
Start of program headers: 64 (bytes into file)
Start of section headers: 123784 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 29
Section header string table index: 28

Program Headers

Program headers, also known as the program segment headers, provide information about how the segments of the executable file should be loaded into memory during the program’s execution.

Segments contains multiple sections.

Key functions of Program Headers

  • Indicate type of segment such as code, data, or dynamic linking information.
  • Specify virtual memory address where the segment should be loaded into memory.
  • Specify the offset where the segment data is located.
  • Size and Permission of the segment

Display program header using readelf command with -l option

$ readelf /bin/bash -l

Elf file type is DYN (Position-Independent Executable file)
Entry point 0x30670
There are 13 program headers, starting at offset 64

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
0x000000000002def0 0x000000000002def0 R 0x1000
LOAD 0x000000000002e000 0x000000000002e000 0x000000000002e000
0x00000000000ba2ad 0x00000000000ba2ad R E 0x1000

Section Headers

The Section header table is important during link time to create an executable.

Common sections

  • Text Section (.text): Contains the program's executable instructions.
  • Data Section (.data): Stores initialized global and static variables.
  • BSS Section (.bss): Reserves space for uninitialized global and static variables.
  • Symbol Table Section: Contains symbols (functions, variables) and their associated information.

Display program header using readelf command with -S option

$ readelf -S /bin/sh
There are 29 section headers, starting at offset 0x1e388:

Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000318 00000318
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.pr[...] NOTE 0000000000000338 00000338
0000000000000020 0000000000000000 A 0 0 8
[ 3] .note.gnu.bu[...] NOTE 0000000000000358 00000358
0000000000000024 0000000000000000 A 0 0 4
[ 4] .note.ABI-tag NOTE 000000000000037c 0000037c
0000000000000020 0000000000000000 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000000003a0 000003a0
0000000000000034 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 00000000000003d8 000003d8
00000000000009f0 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000dc8 00000dc8
00000000000003be 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 0000000000001186 00001186

Creating Executable files

gcc example.c -o example

Creating Linkable files

gcc -c example.c -o example.o

Creating Shared library

 gcc -shared example1.o example2.o -o libexample.so

To use this custom library, you need to add this file to following path /usr/lib , /usr/local/bin

Conclusion

The ELF format plays a crucial role in the compilation, linking, and execution of programs on Unix-like systems, providing a standardized and portable way to represent and organize binary code and data.

--

--