C Compilation in Action

C.1 Working with Docker Containers

Docker helps you set up very quickly a minimal virtual image of different operating systems (and applications/services). This will allow you to quickly experiment with different Linux environments without modifying your personal environment.

In the in-class lecture, we examined in detail the compilation process that occurs on a Linux/Unix machine on an x86 architecture. We saw the ELF (executable and linking file) format of binary executable or relocatable objects.

This is a bit difficult to do on a machine with a different operating system as it may not compile source files into ELF formats.

C.2 Compiling, Assembling and Linking a file

Here are the steps for you to replicate the in-class demo from the Bootloading class:

  • Download docker desktop:
  • Make sure your installation worked. Open your terminal and run the following
docker run hello-world
  • Get an actual Linux distribution running.
docker run -it ubuntu bash
  • This image has no developer tools installed so make sure you get the following by executing the following commands in the shell:
apt-get update
apt-get install gcc
apt-get install vim
  • Create different C source code files. Experiment with ones that include standard libraries, or require functions defined in other files, and ones that don’t. You can write your code in vim. You can copy this code to get started:
    int main () {
       int i;
       int c = 0;
       for (i=0; i<5; i++) {
            c = c+i;
       }
       return 1;
    }
  • Now examine the different files generated with the following instructions.
# Get the C preprocessor output:
gcc -E file.c > file.i

# get the assembly file - stored in file.s
gcc -S file.c
    
# get the binary relocatable object file (i.e. sidestep the linker):
gcc -c file.c -o file.o

# get the executable file
gcc file.c

#Read the executable link format (ELF):
readelf -h -S -s a.out

#Read the ELF of a relocatable object:
readelf -h -S -s file.o