Detailed guide to program loading, memory allocation, relocation, and execution setup
The loader is a system software component that reads an executable file from disk and loads it into memory for execution. It's the final step in the compilation/linking process that prepares a program for CPU execution.
What is a Loader?
A loader is a program (often part of the operating system) that:
- Reads executable files from disk
- Allocates memory sections
- Transfers control to the program's entry point
- Sets up runtime environment
Executable File on Disk
│
▼
┌──────────────┐
│ Loader │ (OS component)
│ (Reads .exe) │
└──────────────┘
│
▼
Program in Memory
│
▼
Execution
Loader Functions
1. Allocation
Allocate memory sections for code, data, stack, and heap:
Memory Layout After Loading:
High Address ┌─────────────────┐
│ Command-line │
│ Arguments │
├─────────────────┤
│ Environment │
├─────────────────┤
│ Stack │ ← Grows downward
│ (local vars) │
├─────────────────┤
│ Unused │
├─────────────────┤
│ Heap │ ← Grows upward
│ (dynamic mem) │
├─────────────────┤
│ .bss │ (uninitialized)
│ .data │ (initialized)
│ .text │ (code)
│ (Read-only) │
├─────────────────┤
│ Header │
Low Address └─────────────────┘
2. Relocation
Adjusting final addresses if the program wasn't linked for a specific address:
If executable linked for 0x400000 but loaded at 0x500000
All addresses adjusted: 0x400000 → 0x500000
References updated
CODE @ 0x400100 → 0x500100
DATA @ 0x400500 → 0x500500
3. Linking (Dynamic Linking at Runtime)
Resolving references to dynamically linked libraries:
Program calls: printf(...)
Loader checks:
Is printf already loaded?
If no: Load libc.so into memory
Resolve printf to its address in memory
Set up jump table entry
4. Transfer of Control
Pass control to program's entry point:
| IP/PC register | _start or main() address |
| SP register | top of stack |
| Other registers | initialized values |
Loading Process
┌─────────────────────────────┐
│ Executable File (.exe/.elf)│
└────────────┬────────────────┘
│
┌──────▼──────────┐
│ 1. Read Header │ Get section info
└──────┬──────────┘
│
┌──────▼────────────────┐
│ 2. Allocate Memory │ Create sections
└──────┬────────────────┘
│
┌──────▼──────────────────┐
│ 3. Load .text (.code) │
└──────┬──────────────────┘
│
┌──────▼──────────────────┐
│ 4. Load .data │
│ Load .bss │
└──────┬──────────────────┘
│
┌──────▼──────────────────────┐
│ 5. Perform Relocations │
│ (if necessary) │
└──────┬──────────────────────┘
│
┌──────▼──────────────────────┐
│ 6. Resolve External Refs │
│ (dynamic linking) │
└──────┬──────────────────────┘
│
┌──────▼──────────────────────┐
│ 7. Setup Stack & Registers │
│ argc, argv, envp │
└──────┬──────────────────────┘
│
┌──────▼──────────────────────┐
│ 8. Transfer to Entry Point │
│ Jump to _start/main │
└──────────────────────────────┘
│
▼
Program Execution
ELF Header
Magic number (0x7F 'E' 'L' 'F')
Architecture (x86-64, ARM, etc.)
Entry point
Program header offset
Section header offset
Program Headers
Type, offset, virtual address, size
.text segment
.data segment
.bss segment
Sections
.text (code)
.data (initialized data)
.bss (uninitialized data)
.symtab (symbol table)
.strtab (string table)
...
String tables, symbol tables, etc.
DOS Header
PE Header
Optional Header
Section Headers
Sections:
.text (code)
.data (data)
.rsrc (resources)
.reloc (relocations)
...
Runtime Environment Setup
Before execution, the loader sets up:
Stack Frame (at program start):
High Address ┌──────────────────┐
│ Environment vars│
│ (PATH, HOME,...)│
├──────────────────┤
│ Command-line │
│ Arguments │
├──────────────────┤
│ Return address │
│ (to OS) │
├──────────────────┤
│ Local variables │
│ (if any) │
├──────────────────┤
│ Program data │
│ ... │
Low Address └──────────────────┘
↑
SP register
Program Execution Flow
┌─────────────────────────────────────┐
│ Operating System │
│ (File I/O, Memory Management) │
└────────────────┬────────────────────┘
│
┌────────▼────────┐
│ Execute Program │
│ File (click it) │
└────────┬────────┘
│
┌────────▼──────────────┐
│ OS loads Loader │
│ (or linker+loader) │
└────────┬──────────────┘
│
┌────────▼──────────────┐
│ Loader reads .exe/.elf│
│ from disk │
└────────┬──────────────┘
│
┌────────▼──────────────┐
│ Allocate memory │
│ layout sections │
└────────┬──────────────┘
│
┌────────▼──────────────┐
│ Load code & data │
│ into memory │
└────────┬──────────────┘
│
┌────────▼──────────────┐
│ Resolve dynamic refs │
│ Load dynamic libs │
└────────┬──────────────┘
│
┌────────▼──────────────┐
│ Set up stack/regs │
│ argc, argv, envp │
└────────┬──────────────┘
│
┌────────▼──────────────┐
│ Jump to entry point │
│ Program starts! │
└────────┬──────────────┘
│
┌────────▼──────────────┐
│ Program Execution │
│ running... │
└──────────────────────┘
Interview Q&A
Q: What does a loader do? A: A loader reads executable files from disk, allocates memory, loads code and data sections, resolves dynamic references, and transfers control to the program's entry point.
Q: What's the difference between linker and loader? A: The linker combines object files into executable files at compile time. The loader reads executable files from disk and loads them into memory at runtime for execution.
Q: What is relocation in loading? A: Relocation in loading adjusts addresses if the program is loaded at a different memory location than it was linked for. All addresses are offset accordingly.
Q: What is dynamic linking? A: Dynamic linking resolves references to shared libraries at runtime rather than at link time. Libraries are loaded into memory when needed.
Q: What information does executable file header contain? A: The header contains magic number, architecture, entry point address, file format version, program and section header offsets, and other metadata needed to load the file.