← New search

Other meanings of Executable and Linkable Format

Systems software

Executable and Linkable Format

Executable and Linkable Format (ELF) is a standard binary file format for executables, object code, and shared libraries on Unix-like systems. It defines how compiled code, data, symbols, relocation information, and program-loading instructions are represented in a file.

1990s
Adopted broadly
Became the principal binary format for Unix-like systems
3
Core file classes
Relocatable files, executable files, and shared objects
2
Address widths
Common 32-bit and 64-bit variants
1

Structure and purpose

ELF separates the information needed for linking from the information needed for loading. Its file header identifies the class, byte order, target machine, entry point, and locations of other tables; additional headers describe sections and loadable segments.1 A relocatable object file normally contains sections such as machine-code text, initialized data, uninitialized data, symbol tables, and relocation records. A linker combines these objects into an executable or shared object.

The format serves several related stages rather than one single tool. The compiler commonly emits relocatable ELF files, the linker resolves symbols and lays out sections, and the operating system's program loader maps selected segments into memory. Shared libraries use the same general representation, allowing code and data to be loaded at run time and symbols to be resolved across binary boundaries.

ELF is extensible through processor-specific flags, sections, dynamic tags, and notes. The generic specification therefore supplies a common framework while individual architectures and operating systems define details such as instruction-set identifiers, calling conventions, and dynamic-linking behavior.

2

Linking and loading

ELF uses sections for link-time organization and segments for run-time mapping. A section header table describes fine-grained regions such as .text, .rodata, .data, and .bss, whereas a program header table groups file ranges into segments with permissions such as readable, writable, or executable.1 The loader generally consults the program headers, not the section names, when creating a process image.

Relocation records tell the linker or dynamic linker how addresses and other machine-word values must be adjusted. The dynamic section identifies dependencies, symbol tables, relocation tables, search information, and initialization or finalization routines used by a shared object. An ELF executable may name a dynamic linker, which loads required shared libraries and performs remaining relocations before transferring control to the program's entry point.2

Position-independent code and position-independent executables reduce dependence on a fixed virtual address. Together with address-space layout randomization, they support defenses against some memory-corruption attacks, although ELF itself is a container and does not guarantee a particular security policy.

3

Tools and operating-system use

ELF is handled by a toolchain rather than by a single program. Assemblers produce object files; linkers such as ld combine them; and utilities such as readelf, objdump, and nm inspect headers, disassembly, symbols, and sections. The GNU Binary Utilities documentation describes these inspection and transformation operations, while the ABI specifies the structures they interpret.3

On Linux, the kernel recognizes ELF executables through its binary-format loader and creates memory mappings from their program headers. The initial process state includes an entry address and a stack containing arguments, environment strings, and auxiliary values supplied to the program; language runtimes and the C library use this information during startup.4

ELF is strongly associated with Linux, the BSD systems, Solaris, and other Unix-like environments, but compatibility is not automatic. An ELF file still depends on a compatible instruction set, ABI, operating-system conventions, interpreter, libraries, and sometimes kernel features. A file can therefore be valid ELF yet fail to execute on a different platform.

4

Lesser-known aspects

ELF contains several less visible mechanisms that support debugging, identification, and tooling. NOTE segments can carry build identifiers, ABI information, core-dump metadata, and operating-system-specific records; a build ID can let debuggers or package systems locate matching unstripped debug data. The .gnu_debuglink convention provides another association between an executable and a separate debug file.5

Section names are conventional rather than fundamental. A loader can execute a file whose section-header table has been removed, because loadable segments contain the information needed for mapping; stripping commonly removes symbols and other link-time material while preserving execution. Conversely, malformed or deliberately unusual ELF files are useful in security research, forensic analysis, and compatibility testing.

ELF also supports thread-local storage, symbol versioning, lazy or immediate symbol binding, and GNU extensions such as GNU hash tables and indirect-function resolvers. These features explain why two files that both identify as ELF may differ substantially in startup behavior, relocation cost, diagnostics, and portability. The format's longevity comes from this combination of stable generic headers and extensible platform-specific conventions.

Glossary

Relocatable file
An object file containing code and data that have not yet been assigned final addresses and may require linker relocation.
Shared object
An ELF file intended for dynamic linking, commonly using the .so filename convention on Unix-like systems.
Program header
A table entry describing a run-time segment, including its file range, memory size, alignment, and access permissions.
Section
A link-time region of an ELF file holding a particular kind of code, data, metadata, or relocation information.
Relocation
A recorded adjustment that resolves an address or symbol reference when an object is linked or loaded.

ELF is a file-format specification and ABI framework; exact behavior depends on the target architecture, operating system, compiler, linker, and loader.