ELF is a binary file format, analogous to the PE EXE file format used in recent versions of Windows. The ELF file format was originally developed by the Unix System Laboratories (USL) to replace the less-flexible COFF and a.out formats. It has been adopted as the executable file format of choice on a wide array of Unix and Unix-like operating systems including Linux, Solaris, and Unix SVR4.

ELF stands for Executable and Linking Format, and it is used not only for executables, but also for unlinked object files and shared libraries. ELF files start with an ELF header, followed by an optional program header table, an optional section header table, and any number of sections. The ELF header simply identifies the file as an ELF, and provides pointers to the program header and the section header. The program header tells the loader how the executable should be loaded into memory and is only required for executables. The section header is just an index into the sections. And finally, the sections themselves hold the actual code and data of the executable, library, or object file.

Each section of an ELF file has a name that identifies its purpose. Some of the most important sections are:

  • .bss - bss stands for Block Started by Symbol for historic reasons, but its purpose is to represent all the uninitialized data in the executable. Since the data is uninitialized, it doesn't need to be stored, so only the size is stored in the file.
  • .comment - Human-readable comments.
  • .data - All the program data that can't be stored in the .bss or .rodata sections goes here.
  • .debug - Debugging information such as variable and function names. This section is removed when a program is stripped.
  • .fini - Special cleanup code in this section gets executed after an executable has finished (exited from main()).
  • .init - Special initialization code in this section gets executed before an executable begins (before main() is invoked)
  • .dynamic, .dynsym, .dynstr - The information necessary for dynamic linking is stored here.
  • .line - The source code line numbers of code, used along with the .debug section by debuggers. This section is also removed when a program is stripped.
  • .rel - The relocation data required to load executables into different memory addresses.
  • .rodata - Read-only data that will not be modified by the program get put in the .rodata section. Most operating systems allow one copy of the .rodata section to be shared between multiple running instances of a program.
  • .symtab - A symbol table for object files and shared libraries.
  • .text - The program's executable code.

Sources:
Solaris Linker and Libraries Guide (http://docs.sun.com)
Extending Sim286 to the Intel386 Architecture with 32-bit processing and Elf Binary input, Michael L. Haungs (http://www.cs.ucdavis.edu/~haungs/paper/paper.html)