In this lesson, you will learn how the Executable and Linkable Format (ELF) serves as the structural blueprint that organizes your compiled code and data into a format that the hardware can actually load and execute.
While a relocatable object file (the output of the assembler) holds raw machine code, it is essentially a collection of "fragments" waiting for addresses. The linker takes these fragments and organizes them into an ELF binary, which acts as a bridge between your source code and the processor’s memory map.
The Anatomy of an ELF File
An ELF binary is defined by three primary components that guide the loader:
- The ELF Header: This is the "ID card" of the file. It specifies the machine architecture (e.g., ARM Cortex-M), the entry point (the memory address where execution starts, usually
Reset_Handler), and the offsets to the other tables. - Program Header Table: This is crucial for embedded execution. It defines segments—the actual chunks of memory the loader needs to map into RAM or Flash. For example, a
PT_LOADsegment tells the system: "Copy these bytes from the file into this specific memory address." - Section Header Table: This provides the developer’s view of the file. It labels groups of data, such as
.text(executable code),.data(initialized global variables), and.bss(zero-initialized memory).
Visualizing the Load Process
Consider a simple embedded mapping:
// When compiled, this data is organized by the linker:
int data_val = 10; // Moves into the .data section
void main() { ... } // Moves into the .text section
The linker places these into sections, but the ELF file uses the Program Header to group these sections into segments. When you flash your device, the loader ignores section names like .text and instead looks at the program segments to determine exactly which bytes go to which physical address in your microcontroller's memory map. Without this structure, the processor would have no way of knowing where your code ends and your constants begin.
Key Takeaway: The ELF format provides a dual-view structure where the Section Header Table helps the linker resolve symbols, while the Program Header Table provides the physical instructions needed to load the image into the target’s memory space.