Implicit Dynamic Linking or loading
Implicit linking or Implicit dynamic loading in the system process, where the loader of operating system loads the DLL executable at the same time as the executable that uses it.
Dynamic linking happens in two stages.
- Stage #1 happens during compilation/build time and
- stage #2 happens during loading time.
Any symbol which is a part of external libraries goes through a different process than any symbol which are present in the other object files. A symbol or function or variable links to the other object file or links to a static library file is linked directly as a payload to the binary. Functions are placed in the .text section and variables are in .data/.bss/.rodata sections. Then they are resolved by the offset address. The effective address is the load address of this section sum with the offset address.
A symbol or function or variable which is not present in object files are the external symbols and they are linked via import libraries. We have to specify the library name with the argument -l
Let us consider linking printf and getchar function.
Libc binary holds a list of functions which can be used by application. Linker adds few sections to the binary to hold information about these functions. String name the function, offset address, index etc are added in the dynamic sections and library is generated. Now we are linking our application along with this libc. Linker checks which functions are not available and if they are present in the library. Here printf and getchar are not present in the object modules and they are present in the dynamic sections of libc. So linker takes these two as resolved symbols. Linker add some sections to tell that libc is the library binary needed when this application is going to execute and these two function has to be resolved by dynamic loader/linker at that time.
Linker adds some sections that are used in dynamic loading purpose. These contain the name of the library, the names of imported functions, offset address entry and table to map virtual address. It also adds a stub table to resolve the symbols. Linker links the function to the procedure linkage table. This table contains a lookup table. Control jumps to the table and from here it jumps to the actual address. Initially the function addresses are zero. These entries will be resolved by dynamic linker.
Dynamic loader loads the executable in virtual memory then it checks the sections for dynamic loading. It checks the library file path and also loads the library in virtual memory. Now it checks the table of imported functions needed by the application. Here dynamic linking process happens. Loader checks the function printf and looks up in the export sections of libc. Libc has the function entry and it has a load address and offset. So virtual address is calculated and it is places in the procedure linkage table. Here actual linking process is completed for printf. Same way getchar also gets the proper address. This way all the entries in procedure linkage table are filled and linking process comes to an end. There after the application is ready to run. So the loader jumps to the entry point of the application.
Dynamic sections in C App (Linux)
Dynamic section at offset 0xf14 contains 24 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libc.so.6] ... 0x6ffffef5 (GNU_HASH) 0x80481ac 0x00000005 (STRTAB) 0x804822c 0x00000006 (SYMTAB) 0x80481cc 0x0000000a (STRSZ) 84 (bytes) 0x0000000b (SYMENT) 16 (bytes) 0x00000015 (DEBUG) 0x0 0x00000003 (PLTGOT) 0x804a000 0x00000002 (PLTRELSZ) 32 (bytes) 0x00000014 (PLTREL) REL 0x00000017 (JMPREL) 0x80482b4 0x00000011 (REL) 0x80482ac ... 0x00000000 (NULL) 0x0 Relocation section '.rel.dyn' at offset 0x2ac contains 1 entries: Offset Info Type Sym.Value Sym. Name 08049ffc 00000306 R_386_GLOB_DAT 00000000 __gmon_start__ Relocation section '.rel.plt' at offset 0x2b4 contains 4 entries: Offset Info Type Sym.Value Sym. Name 0804a00c 00000107 R_386_JUMP_SLOT 00000000 printf 0804a010 00000207 R_386_JUMP_SLOT 00000000 getchar 0804a014 00000307 R_386_JUMP_SLOT 00000000 __gmon_start__ 0804a018 00000407 R_386_JUMP_SLOT 00000000 __libc_start_main The decoding of unwind sections for machine type Intel 80386 is not currently supported. Symbol table '.dynsym' contains 6 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.0 (2) 2: 00000000 0 FUNC GLOBAL DEFAULT UND getchar@GLIBC_2.0 (2) 3: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 4: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2) 5: 0804850c 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
Dynamic sections in Libc(Linux)
Symbol table '.dynsym' contains 2394 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 OBJECT GLOBAL DEFAULT UND __libc_stack_end@GLIBC_2.1 (34) 2: 00000000 0 OBJECT GLOBAL DEFAULT UND _rtld_global@GLIBC_PRIVATE (35) ..... 640: 0004d410 52 FUNC GLOBAL DEFAULT 12 printf@@GLIBC_2.0 ..... 919: 00067630 233 FUNC GLOBAL DEFAULT 12 getchar@@GLIBC_2.0
Dynamic sections in C App (Windows)
Windows world uses PE/COFF format for the executable binary. The section names and data formats are different but the mechanism is same. Linker adds sections various sections to hold the dependent library name, names of these external functions, effective address of these functions, offset table, procedure linkage table etc to the ELF binary.
Windows Libc import library
List of import symbols by implicit app
Dynamic sections in Libc(Windows)
List of export symbols by libc/msvcrt.dll
Explicit Dynamic Linking or loading
Operating system loads the DLL on demand at runtime. An executable that uses a DLL by explicit linking must explicitly load and unload the DLL. It must also set up a function pointer to access each function it uses from the DLL. Unlike calls to functions in a statically linked library or an implicitly linked DLL, the client executable must call the exported functions in an explicitly linked DLL through function pointers. Explicit linking is sometimes referred to as dynamic load or run-time dynamic linking.
Windows Explicit Linking
When application does not links the external symbol by import library rather it loads the DLL at runtime. It does the same mechanism as operating system does during loading of the implicit linked DLL calls.
This is done by using Win32 APIs like :
- LoadLibrary() - loads and links a input library form the DLL path, or current path,
- GetProcAddress() - finds the symbol/function address by its name for a loaded DLL
- FreeLibrary() - unloads the loaded DLL instance
Windows DLL project
Windows App project
Linux Explicit Linking
Let us consider once again math.c file for explicit linking. The steps for creating a shared library are same as that of implicit linking.
First we compile it with position independent flag on(-fPIC). This is needed for dynamic/static linking.
$cc -fPIC -c mathlib.c -o mathlib.o
Now make a shared library with the object file.
$cc -shared -o libmath.so mathlib.o
To use this shared library in a application we need to load the library then find the function pointer address, invoke the function, and at last unload the library.
Linux provides some dynamic link library APIs to achieve this. Her are some useful frequently use APIs:
- dlopen() - loads a dynamic link binary
- dlsym() - returns the function pointer if found the function entry
- dlclose() - unloads the dynamic link binary
Linux SO project
Linux App project
SO and App build and run
About our authors: Team EQA
You have viewed 1 page out of 27. Your DLL learning is 0.00% complete. Login to check your learning progress.
Learn on Youtube