<aside>
💡 .text → all code
.bss → uninit variable (global / static)
.data → initialized variable
</aside>
Linking allows to link two output files and then convert them to binary into an executable containing all of the code and data for all of the functions defined.
Benefits of Linking
- Modularity, program can be written as a collection of smaller source files and libraries rather than monolithic applications
- time & space efficiency, allows for separate compilation so that we can only recompile the things that changed rather than the entire program
What do Linkers Do?
Symbol Resolution
- each of the programs define and reference symbols (global variables and functions)
- symbol definitions are stored in the object file and the symbol table
- symbol table is an array of structs which contain, name, location, size
- each entry includes name, size, and the location of the symbol
- during the symbol resolution step, the linker associates each symbol reference with exactly one symbol definition
void swap() {…} /* define symbol swap */
swap(); /* reference symbol swap */
int *xp = &x; /* define symbol xp, reference x */
Symbol Relocation
- merges separate code and data sections into a single section
- relocates symbols from their relative locations to their final absolute memory locations within the executable
- updates all of the references of these symbols to reflect their new positions
Different Types of Object Files
- relocatable object file (.o file)
- contains code and data in a form that can be combined with other relocatable files
- executable object files (a.out)
- contains code and data in a form that can bee copied directly into memory and then executed
- shared object file (.so)
- special types of relocatable object files that can be loaded into memory and linked dynamically at either load time or run-time