CPP¶
C++ Compilation Process¶
An in-depth guide to the multi-stage transformation of C++ source code into an executable binary, covering the specific responsibilities of each tool in the toolchain.
- Preprocessing: The
cpppreprocessor handles macros (#define), file inclusions (#include), and conditional compilation (#ifdef), generating expanded translation units. - Compilation: The compiler translates preprocessed source code into assembly language, performing lexical analysis, parsing (AST generation), and architecture-specific optimizations.
- Assembly: The assembler converts assembly code into machine-readable object files (
.oor.obj) containing relocatable machine code. - Linking: The linker combines object files and library code, resolving external symbols and memory addresses to produce the final executable or shared library.
- Key Concepts: Covers the role of Symbol Tables, Name Mangling, and the difference between Static and Dynamic linking.
C++ Linking: Static & Dynamic¶
A deep dive into how separate object files are unified into a final executable, covering the mechanics of symbol resolution and library management.
- Symbol Resolution: Matches undefined function/variable references with their actual definitions across object files.
- Relocation: Updates internal memory addresses once the final executable layout is determined.
- Static vs. Dynamic:
- Static: Copies library code directly into the binary; self-contained but larger.
-
Dynamic: Loads shared libraries (
.so/.dll) at runtime; saves memory and enables easy updates. -
Mechanics (GOT/PLT): Explains how the Global Offset Table and Procedure Linkage Table facilitate "lazy binding" for shared objects.
- LTO: Covers Link-Time Optimization, which allows the compiler to optimize code across different modules during the final link phase.
C++ Loading & Runtime¶
A guide to how the OS transforms an executable file into a running process, covering memory layout and the startup sequence.
- Loading Process: The kernel maps the ELF file into virtual memory and invokes the dynamic linker (
ld.so) to resolve shared libraries. - Memory Layout: Segments include the Text (code), Data/BSS (globals), Stack (local variables), and Heap (dynamic allocation).
- Startup Sequence: Control flows from
_startto runtime initialization (global constructors) before finally reachingmain(). - Security: Explains system protections like ASLR (address randomization) and NX Bit (non-executable stack/heap).
- Tooling: Use
readelfto inspect headers andLD_DEBUGto trace library loading issues.