Fundamentals 14 min read

From Source to Executable: Mastering the GCC Toolchain and ELF Analysis

This guide explains how C/C++ source code is transformed into a runnable binary on Linux by walking through the four stages of preprocessing, compilation, assembly, and linking, detailing GCC and Binutils utilities, command‑line examples, and ELF file inspection techniques.

Liangxu Linux
Liangxu Linux
Liangxu Linux
From Source to Executable: Mastering the GCC Toolchain and ELF Analysis

Overview

This article describes how a high‑level C/C++ source file is transformed into an executable binary on a Linux system using the GNU Compiler Collection (GCC) and the Binutils utilities.

Four stages of converting C/C++ to binary

Preprocessing – macro expansion, #include insertion, comment removal, line‑directive generation.

Compilation – lexical, syntax and semantic analysis, optimisation, generation of assembly code.

Assembly – translation of assembly instructions into an object file ( .o).

Linking – static or dynamic linking of object files and libraries into an ELF executable.

GCC toolchain components

gcc – the driver that orchestrates the whole flow.

Binutils – utilities such as as, ld, objdump, readelf, size, ldd, etc.

C runtime library (CRT) – provides the implementations of the standard C functions required by the generated code.

Example: Hello World compilation

#include <stdio.h>

int main(void) {
    printf("Hello World!
");
    return 0;
}

1. Preprocessing

All macros are expanded, #include files are inserted, comments are stripped and line directives are added. gcc -E hello.c -o hello.i The resulting hello.i is plain text and can be inspected to see the expanded source.

2. Compilation

The preprocessed file is parsed, optimised and translated into assembly.

gcc -S hello.i -o hello.s

3. Assembly

The assembly file is assembled into an ELF object file.

gcc -c hello.s -o hello.o   # using gcc
as -c hello.s -o hello.o   # using Binutils directly

4. Linking

Linking combines object files and libraries into the final executable.

Dynamic linking (default): gcc hello.c -o hello Static linking (force static libraries): gcc -static hello.c -o hello Use size to compare the footprint of the two binaries and ldd to list the shared libraries required by the dynamically linked executable.

Analyzing the resulting ELF file

Typical ELF sections include:

.text – executable code.

.rodata – read‑only data (constants).

.data – initialized global/static variables.

.bss – uninitialized global/static variables.

.debug – debugging symbols.

ELF section diagram
ELF section diagram

Viewing sections with readelf

readelf -S hello

Disassembling with objdump

Pure disassembly: objdump -D hello Mixed source and disassembly (requires compiling with -g to retain line information):

objdump -S hello

Static vs. dynamic linking details

Dynamic linking resolves symbols at run time. The search order for shared libraries during linking is:

Directories specified with -L on the gcc command line.

Paths in the LIBRARY_PATH environment variable.

Standard system directories ( /lib, /usr/lib, /usr/local/lib).

At execution time the run‑time loader searches:

Directories encoded in the executable (via -rpath or -L).

Paths in LD_LIBRARY_PATH.

Entries in /etc/ld.so.conf and its includes.

Standard system directories.

Static linking copies all required code from static libraries ( .a) into the executable, producing a larger binary that does not depend on external shared libraries (verified with ldd which reports “not a dynamic executable”).

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CompilationLinuxELFToolchaingcc
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.