Dynamic Linking with Shared Libraries
Limitations with static libraries:
- Like all software static libraries needs to be updated regularly as well, so a application programmer must be aware about the update, and do manual re linking every time a new update comes out.
- Some functions/ modules are really popular and could be in use by hundreds if not more executables at the same time, like printf, hundreds of executable having the copy of the object module defining printf is a huge waste. Would be much better if we could just have one copy of printf that every executable could read from, we save so much space that way.
Tada! Introducing Shared Libraries!
Shared libraries:
- are object module that can be linked with the executable at either load or runtime.
- can be loaded at an arbitary memory address and linked with a program in memory, this process is known as dynamic linking and performed by a program named dynamic linker
- also known as shared object and have .so extension in linux and .dll (dynamic link libraries) in windows.
- A single copy of .so file for a particular library exists in a given file system shared by all Executable Object Files referencing this shared object as opposed to static libraries where it's content are copied and embedded into the executable.
- For a shared module, only the .text segment (and maybe other read only segments) are ENTIRELY shared between the different running processes
Creating a shared library:
- Example creation of a shared library:
/*addvec.c*/
int addcnt = 0;
void addvec(int *x, int *y, int *z, int n){
int i;
addcnt++;
for(i = 0; i < n; i++)
z[i] = x[i] + y[i];
}
/*multvec.c*/
int multcnt = 0;
int multvec(int *x, int *y, int *z, int n){
int i;
multcnt++;
for(i = 0; i < n; i++)
z[i] = x[i] * y[i];
}
linux> gcc -shared -fpic -o libvector.so addvec.c mulvec.c
- the fpic flag directs compiler to generate Position Independent Code and the -shared flag is to create a shared object file. We can then link it to create some executable as such:
linux> gcc -o prog21 main2.c ./libvector.so

- This creates prog21 in the form that libc.so can be linked in run-time.
- Note that none of the code or data sections from libvector.so are actually copied into the executable when the program is loaded instead the linker copies some relocation and symbol table info that will allow references to code and data in libvector.so to be resolved at load time.
Load time dynamic linking
- When static linker finishes with a executable that needs attention from the dynamic linker for load time (NOT RUN TIME) linking, it leaves a .interp section (as well as few other sections like .rel.dyn equivalent to .rel.data in static and .rel.plt equivalent to .rel.text in static).
- when the loader loads and runs the executable prog21 it loads the partially linked executable with .interp section which has the location for the dynamic linker, which itself is a shared object (ld-linux.so on Linux).
- On finding the .interp section, the loader instead of executing the executable first executes the dynamic linker which then finishes the linking task by performing following relocations:
- Relocation text and data of libc.so in some memory segment
- Relocating text and data of libvector.so into anothermem seg
- Relocating any references in prog21 to symbols defined by libc.so and libvector.so
- Finally dynamic linker passes control to the application which executes.
- Note that the "relocation" of different section from shared object is just mapping it's already existing instance in the RAM to virtual memory
- Advantages over static linking:
- Less memory wasted specially if the said library is popular and used by a tons of application like libc.so
- If the shared library ever gets an update, we just have to install the update, and restart the pro