It is a common standard file format for executable files, relocatable code (object ie .o files), shared libraries, and core dumps. It is a spec of ABI (Application Binary interface). By design it is flexible, extensible, cross-platform, CPU architecture & ISA independent. It can be loaded at any memory address by the kernel and automatically, all symbols used, are adjusted to the offset from that memory address where it was loaded into.
File name extensions : none, .axf, .bin, .elf, .o, .prx, .puff, .ko, .mod and .so
Magic Number : 0x7F ‘E’ ‘L’ ‘F’
Image Source : Wikipedia
- Program header table : zero or more memory segments. Only appears at executable. It tells how the executable should be put into the process virtual memory (How to create a process image). This is must for process image, executable files and shared objects. For Relocatable object files, this is not needed.
- Section header table : zero or more sections. Tells how or where section should be loaded. Each section entry in table contains section name and section size. Section Header Table must for the files used in link editing.
- Data : of program header table or section header table.
- ELF header (52 or 64 byte long for 32 or 64 bit) : defines whether to use 32 or 64 bits.
- Program header : Tells how to create process image.
Sections are smallest indivisible units in ELF file that can be processed. (Linking view). Sections hold the bulk of object file information for the linking view. This data includes instructions, data, symbol table, and relocation information.
Segments are smallest individual units that can be mapped to memory by exec or linker. (Executable view)
Section vs Segment : In an object file section exists before linking, while segment exists after linking in executable file. Linker puts one or more sections into a single segment.
Sections and segments have no specified order in ELF. Only the ELF header has a fixed position in the file.
- readelf : gives info about ELF files. (from GNU binutils).
- elfutils : alternative to binutils.
- elfdump : dumps ELF information of an ELF file.
- objdump : gives info of obj files. It uses the Binary File Descriptor library as a back-end to structure the ELF data.
- file : can display some information about ELF files, including ISA for which the code in a relocatable, executable, or shared object file is intended, or on which an ELF core dump was produced.
- nm : gives symbol information of an object file.
Examples with readelf tool : git clone https://github.com/bit-Control/elf_examples.git
Kernel and ELF :
3 important Program header entry -
- PT_LOAD — areas of the new program’s running memory (code+data section of size of BSS — filled with zero)
- PT_INTERP — run-time linker needed to assemble the complete program.
- PT_GNU_STACK — indicates whether the program’s stack should be made executable or not.
Loading ELF :
- read elf header (contains info of rest of the file)
- find program header which directs to text and data section leading to executable image.
Parsing elf executable :
- Check buffer size to accommodate elf header and program header.
- Check elf magic number.
- Check max segment number in program header for validity.
- Extract segment and entry.
- Fill corresponding structure of program header from extracted data.
- Check elf header.
- Get load address.
- Allocate space form program sections.
- Copy from the image in ram to allocated space.
- Resolve kernel symbol table of external references.
- Go to entry point using entry point in header as base plus offset or do a symbol lookup or just return a success. Hence driver can be loaded later also.