A Brief Introduction To ELF
This article explores Executable & Linkable File Format (popularly known as ELF).
An executable file is a type of computer file, containing instructions that the computer's processor can directly execute.
Executable files differ greatly on Windows and Linux. The reason is that both the environments are designed differently.
Binary File Format
Executable and Linkable File Format (or ELF)
Portable Executable File Format (or PE)
File Extension
No extension required
.exe
, .dll
System Call Interface
Linux System Calls (syscall
)
Windows NT syscall layer or WinAPI
Dynamic Linker/Loader
ld-linux.so
Windows Loader
C Runtime Library
GNU C Library (or glibc
)
Microsoft C Runtime (MSVCRT
)
Linker
ld
link.exe
Calling Convention
System V AMD64 ABI
Microsoft x64 ABI
Format For Dynamic Linking
Shared objects (.so
)
Dynamic Link Library (.dll
)
This time, we are learning about Linux environment.
Brief History
It is a common standard file format for executable files, object code, shared libraries, and core dumps on Linux.
It was first released in "System V ABI, Release 4".
In 1999, it was chosen as the standard binary file format for Unix and Unix-like systems on x86 processors by the 86open project.
Modern ELF
ELF is a general-purpose file format in Linux ecosystem, which defines the structure for binaries, libraries, and core files.
It is used throughout the build and execution pipeline.
Different "types" of ELF files (relocatable, executable, shared object, core) exist to serve different roles in this pipeline.
These are typically created during specific phases.
Structure Of An ELF File
Regardless of the type of ELF, the structure of an ELF file remains mostly the same.
An ELF file can be divided into 4 parts.
ELF Header
Identifies the file as ELF and file metadata.
Program Header Table
Used by the dynamic loader at runtime.
Section Header Table
Used by the linker at build time.
Data (segments/sections)
Includes things which are referred by the above 2 tables, such as, text (code), data (globals), bss (uninitialized data), and others.
Lets take an example to understand ELF.
#include <stdio.h>
​
int main(void){
printf("Hello, World!\n");
}
The object code can be obtained by
gcc -c hello.c hello_object.o
Object files are binary representations of a program's source code, intended to be executed directly on a processor, which is why they are required to follow a consistent structure.
ELF is not reserved for executable files only. It is used by a variety of other files of the same genre, and object code (.o) & shared object (.so) libraries are two of them.
ELF files aren't readable by a text editor. Therefore, we use some command line utilities. The two most widely used and versatile utilities are objdump
and readelf
.
Understanding The Result Of `file`
We can check the type of this object file using the file
utility. It is designed to read certain bytes in a file to find the type of it.
$ file hello_object.o
hello_object.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
LSB
tells that the binary is structured inlittle-endian
format, which means that the the least significant bit (or LSB) comes first.It is different from
big-endian
where the MSB comes first.In simple words, normal arithmetic is big-endian based and cpu arithmetic is little-endian based.
relocatable
means that the file is ready to be linked with shared libraries but not for execution.A relocatable ELF is one which has unresolved references to symbols whose definition lies in shared libraries.
For example,
printf
comes fromglibc
.
not stripped
means that file still contains items which are not necessary and the code will still function the same if they are removed.version 1 (SYSV)
means it uses System V AMD64 ABI (for conventions).x86-64
tells we are on 64-bit Linux.
A binary file also follows the same structure. The above object file can be linked like this:
gcc hello_object.o -o hello_elf
Lets check this one.
$ file hello_elf
hello_elf: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped
pie executable
means position independent executable. No static locations are required.dynamically linked
means the binary resolves references during runtime via aninterpreter
calledld-linux.so
(can be different though).
Here comes the end of a brief introduction to ELF.
It was designed to serve this purpose exactly. Very soon we are going to study a binary in-detail, which is where we'll explore this in full-depth.
Last updated