Chapter 1:
The compilation process :
Preprocessing , Compilation , Assembly , Linking
Preprocessing : Expands any #define and #include directives in source file To stop at preprocessing phase : gcc -E -P file.c
Compilation : Preprocessed code is translated into assembly
To stop at compilation phase : gcc -S file.c
Assembly Phase : Input are assembly files and output is a set of object files.
Stop at Assembly : gcc -c file.c
Detect object files : Relocatable
Object files are compiled independently from each other , so the assembler has no way of knowing the memory address of other object files , hence they're relocatable. So we can link them to form a complete binary executable.
Linking phase : Links all object files into single binary executable.
Symbolic References : References that rely on a relocation symbols
Relocation Symbols : Specify how function and variable symbols should be resolved.
Static Libraries : All references resolved at time of loading [.a extension]
Dynamic Shared Libraries : Shared among all programs in system
Interpreter : ex -> /lib64/ld-linux-x86-64.so.2 : tells which dynamic linker is used to resolve the final dependencies on dynamic libraries when the executable is loaded into memory for execution.
View Symbolic Information : readelf --syms binary
Disassembling an object file : objdump -M intel -d file.o
Viewing the .rodata of object file : objdump -sj .rodata file.o
Disassembling an executable : objdump -M intel -d binary
On linux , interpreter is a shared library - ld-linux.so
On windows , interpreter is a part of ntdll.dll
Lazy Binding : Instead of resolving all references during start , the program resolves references only when the function is invoked once.