LOGBOOK

HELP

1 / 31
Other keys: showSpace: good1-4: rate0: skip5: flag

Question

What are the stages a C program goes through from source code to executable?

Answer

Compile each .c to assembly, assemble that to a .o object file, then link all the objects plus the C runtime into one executable.

Compilation pipeline: main.c and swap.c each compiled to assembly, assembled to object files, then linked with the CRT into one executable

* Each source file travels its own compile → assemble path to a .o; the linker fuses all objects plus the C runtime into the final executable. *

The compilation pipeline:

Stage Tool Input Output
1. Compilation cc1/cpp .c file .s (assembly)
2. Assembly as .s file .o (relocatable object)
3. Linking ld/collect2 .o files + libraries executable

Key insight: Each .c file is compiled independently to its own .o file. The linker combines all .o files plus the C runtime library (CRT) into the final executable.

# View the full compilation process
$ gcc -v -O2 -Wall -g -o prog main.c swap.c

Tip: GCC is actually a "compiler driver" - it orchestrates calls to the preprocessor, compiler, assembler, and linker.

Go deeper:

Illustration
Free Software Foundation, Inc. · CC BY-SA 3.0 · Wikimedia Commons
or press any other key

Question

What is the role of the dynamic linker (ld-linux.so) in program execution?

Answer

It loads the executable and its shared libraries into memory, then resolves every symbol and relocation before main runs.

Process address space: kernel space, user stack, memory-mapped shared libraries, heap, read/write .data/.bss segment, and read-only .text/.rodata segment

* What the dynamic linker builds: code and read-only data map low, writable data and heap above, shared libraries in the middle, and the stack at the top. *

The kernel actually launches the dynamic linker first (its path is recorded in the ELF header); the linker then maps in the program and its .so dependencies and patches everything up so the code can find the functions and data it calls.

The dynamic linker handles:

  1. Load the executable into memory
  2. Find required shared libraries (.so files)
  3. Load shared libraries into the process address space
  4. Resolve symbols - connect function calls to their implementations
  5. Perform relocations for position-independent code

Process memory layout after dynamic linking:

Region Contents
Kernel virtual memory OS kernel space
User stack Function call frames
Memory-mapped region Shared libraries (.so)
Run-time heap malloc allocations
Read/write segment .data, .bss
Read-only segment .init, .text, .rodata

Tip: The dynamic linker itself is specified in the ELF header and loaded by the kernel before the program starts.

Go deeper:

or press any other key