Skip to content

Instantly share code, notes, and snippets.

@zeheater
Created October 2, 2020 16:01
Show Gist options
  • Save zeheater/b70edb4f9034f5095d9a450e0d1c28f4 to your computer and use it in GitHub Desktop.
Save zeheater/b70edb4f9034f5095d9a450e0d1c28f4 to your computer and use it in GitHub Desktop.
A step-by-step breakdown of GCC compile and link process

Step-by-Step GCC

main.c

#include<stdio.h>

int main(int argc, char *argv[])
{
  printf("Hello, World !");
  return 0;
}

Step 1/4) Preprocess main.c to generate main.i:

gcc -E main.c -o main.i

Step 2/4) Compile main.i to generate main.s:

gcc -S main.i -o main.s

Step 3/4) Assemble main.s to generate main.o:

as main.s -o main.o

Combine step 1 through 3 with:

gcc -c -o main.o main.c

Step 4/4) Link main.o with other necessary object files.

Namely, crti.o & crtn.o (they define function prologs & epilogs, respectively), crt1.o (contains _start symbol for bootstrapping the initial execution of the program), libc.so path or -lc flag for libc and then finally set the name of the dynamic linker, to generate a dynamically linked ELF executable:

On x86_64:

ld -I /lib64/ld-linux-x86-64.so.2 -o main main.o /usr/lib/crti.o /usr/lib/crtn.o /usr/lib/crt1.o -lc

Or to specify path to libc.so

ld -I /lib64/ld-linux-x86-64.so.2 -o main main.o /usr/lib/crti.o /usr/lib/crtn.o /usr/lib/crt1.o /usr/lib/libc.so

Another way

main.c

#include<stdio.h>
const char x[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2";

int main(int argc, char *argv[])
{
  char hello[] = "Hello, World !";
  puts(hello);
  __asm__("mov $60, %rax; mov $0, %rdi; syscall;");
}
gcc -c -o main.o main.c
ld -e main -o main main.o -lc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment