Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running gcc's steps manually, compiling, assembling, linking

Tags:

c

gcc

If you have a simple C program, like

int main(void) {return 0;} 

It can be compiled with gcc -o test test.c.

As I understand, gcc performs compiling, assembling then linking. The latter two steps are achieved by it running as and ld.

I can generate the assembly code by using gcc -S test.c.

What would you type into a terminal, to convert the assembly code into an executable?

(the reason for doing so is to learn assembly)

like image 763
checkers Avatar asked Dec 15 '11 22:12

checkers


People also ask

How do I compile without linking GCC?

The -c option in the command means compile (but don't link). The result of this will be .o (object) files. Try the command without the -c , it should link and create your snmpy executable.

Is GCC only a compiler?

gcc is a collection of compilers, as indicated in gcc.gnu.org: "The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, Ada, Go, and D..."


2 Answers

These are the different stages using gcc

gcc -E  --> Preprocessor, but don't compile gcc -S  --> Compile but don't assemble gcc -c  --> Preprocess, compile, and assemble, but don't link gcc with no switch will link your object files and generate the executable 
like image 50
quicoju Avatar answered Sep 28 '22 04:09

quicoju


// main.c #include <stdio.h>  int main(void) {         printf("Hello World !\n");         return 0; } 

For preprocessing, compiling, assembling and then finally linking the simple aforementioned hello world program, follow the steps below:

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

$: gcc -E main.c -o main.i 

NOTE: You could call the C preprocessor directly as well:

$: cpp 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 

NOTE: You can combine the aforementioned steps 1, 2 and 3 by using the -c (small C) flag of gcc:

$: gcc -c main.s -o main.o // OR $: gcc -c main.c -o main.o 

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 /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o -lc main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable 

OR (if you'd like to specify path to libc.so)

$: ld /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/libc.so main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable 

On 32-bit ARM:

$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o -lc main.o -dynamic-linker /lib/ld-linux.so.3 -o main_ELF_executable 

OR (if you'd like to specify path to libc.so)

$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o /usr/lib/arm-linux-gnueabihf/libc.so main.o -dynamic-linker /lib/ld-linux-armhf.so.3 -o main_ELF_executable 

You can then run the ELF executable 'main_ELF_executable':

$: ./main_ELF_executable 

Hello World !

Sources:

https://linux.die.net/man/1/gcc

https://linux.die.net/man/1/ld

https://dev.gentoo.org/~vapier/crt.txt

like image 40
ZeZNiQ Avatar answered Sep 28 '22 04:09

ZeZNiQ