Skip to content

01. Hello World Lifecycle and ELF Execution Pipeline (Program Lifecycle)

Tracing the complete execution lifecycle of the classic "Hello World" program from source text to terminal output and termination through compiler toolchains and the Linux operating system kernel.


1. Learning Objectives & Overview

  • Trace the transformation of C source code (hello.c) through the preprocessor, compiler, assembler, and linker into a 64-bit ELF executable.
  • Investigate how typing ./hello triggers the execve() system call, transferring execution into Ring 0 kernel space.
  • Examine how the Linux kernel's load_elf_binary() routine constructs the virtual memory area (VMA) layout and maps PT_LOAD segments.
  • Understand the role of the dynamic linker (ld-linux.so) and the C runtime startup sequence (_start ➔ __libc_start_main) leading to main() invocation.

2. Interactive Execution Lifecycle Diagram

Explore the 5 stages from source compilation to kernel entry and exit through the interactive diagram below:


3. Four-Stage Build Pipeline Deep-Dive

Converting C source code into an executable binary traverses four sequential tools:

[hello.c] ➔ [Preprocessor cpp] ➔ [hello.i] ➔ [Compiler cc1] ➔ [hello.s]
          ➔ [Assembler as]     ➔ [hello.o] ➔ [Linker ld]    ➔ [hello (ELF64)]
  1. Preprocessing (cpp):
  2. Expands #include <stdio.h> header files inline, replaces macros, and strips code comments.
  3. Compilation (cc1):
  4. Parses high-level syntax into an Abstract Syntax Tree (AST), outputting target-specific assembly instructions (hello.s).
  5. Assembly (as):
  6. Translates human-readable assembly instructions into raw machine bytecode, generating a relocatable object file (hello.o, ELF Relocatable).
  7. Linking (ld):
  8. Resolves symbol addresses with C runtime startup objects (crt1.o, crti.o) and shared libraries (libc.so) to produce the final executable ELF binary.

4. Kernel-Space Process Loading: load_elf_binary()

When an executable binary is launched from a terminal, the shell and kernel collaborate across the privilege boundary:

sequenceDiagram
    autonumber
    actor User as User / Terminal
    participant Shell as Shell (Bash/Zsh)
    participant Kernel as Linux Kernel (Ring 0)
    participant Linker as Dynamic Linker (ld-linux.so)
    participant Main as C Program (main)

    User->>Shell: Enter ./hello
    Shell->>Shell: fork() spawns child process
    Shell->>Kernel: execve("./hello", argv, envp) syscall
    Kernel->>Kernel: do_execve() ➔ bprm_execve()
    Kernel->>Kernel: load_elf_binary() invoked
    Kernel->>Kernel: Flush old memory & map PT_LOAD segments to VMA
    Kernel->>Kernel: Discover PT_INTERP (/lib64/ld-linux-x86-64.so.2)
    Kernel->>Linker: Return to Ring 3 at dynamic linker entry
    Linker->>Linker: Map shared libraries (libc.so) & resolve PLT/GOT relocations
    Linker->>Main: Jump to _start ➔ __libc_start_main ➔ main()
    Main->>Kernel: write(1, "Hello World\n", 12)
    Main->>Kernel: exit_group(0) clean process teardown

5. Lab Source Code & ELF Inspection

5.1 Running the Demo

cd labs/principles/01-hello-lifecycle
make run
=== [1] Running Hello World Binary ===
./hello
[+] Hello, System Security Principles!
[+] Process PID: 12458, PPID: 11020
[+] main() address: 0x55dc98a21149
[+] g_greeting (.rodata): 0x55dc98a22008
[+] g_run_counter (.data): 0x55dc98a24018 (value=1)
[+] argc: 1, argv[0]: ./hello

5.2 Deep ELF Inspection

make inspect
  • readelf -h hello: View the ELF magic bytes (\x7fELF), target architecture, and entry point (0x1060).
  • readelf -l hello: Review kernel PT_LOAD segments and enforced memory permissions (R E, RW).
  • readelf -S hello: Verify boundaries and offsets of .text, .rodata, .data, and .bss sections.

6. Summary & Next Chapter

  • A simple "Hello World" application relies on an intricate symphony of toolchains, ELF segment parsing, kernel execve handling, dynamic linking, and runtime initialization.
  • In the next chapter, we examine how the kernel organizes memory segments within the 64-bit address space: 02. Process Anatomy and Virtual Address Space.