Expert C Programming

(Jeff_L) #1

One Purpose of Dynamic Linking Is the ABI


A major purpose of dynamic linking is to decouple programs from the particular library
versions they use. Instead, we have the convention that the system provides an interface to
programs, and that this interface is stable over time and successive OS releases.


Programs can call services promised by the interface, and not worry about how they are
provided or how the underlying implementation may change. Because this is an interface
between application programs and the services provided by library binary executables, we
call it an Application Binary Interface or ABI.


A single ABI is the purpose of unifying the UNIX world around AT&T's SVr4. The ABI
guarantees that the libraries exist on all compliant machines, and ensures the integrity of the
interface. There are four specific libraries for which dynamic linking is mandatory: libc (C
runtimes), libsys (other system runtimes), libX (X windowing), and libnsl (networking
services). Other libraries can be statically linked, but dynamic linking is strongly preferred.


In the past, application vendors had to relink their software with each new release of the OS
or a library. It caused a huge amount of extra work for all concerned. The ABI does away
with this, and guarantees that well-behaved applications will not be affected by well-
behaved upgrades in underlying system software.


Although an individual executable has a slightly greater start-up cost, dynamic linking helps overall
performance in two ways:



  1. A dynamically linked executable is smaller than its statically linked counterpart. It saves disk
    and virtual memory, as libraries are only mapped in to the process when needed. Formerly,
    the only way to avoid binding a library copy into each executable was to put the service in the
    kernel instead of a library, contributing to the dreaded "kernel bloat."

  2. All executables dynamically linked to a particular library share a single copy of the library at
    runtime. The kernel ensures that libraries mapped into memory are shared by all processes
    using them. This provides better I/O and swap space utilization and is sparing of physical
    memory, improving overall system throughput. If the executables were statically linked, each
    would wastefully contain its own complete duplicate copy of the library.


For example, if you have eight XView™ applications running, only one copy of the XView library
text segment has to be mapped into memory. The first process's mmap [1] call will result in the kernel
mapping the shared object into memory. The next seven process mmaps will cause the kernel to share
the existing mapping in each process. Each of the eight processes will share one copy of the XView
library in memory. If the library were statically linked, there would be eight individual copies
consuming more physical memory and causing more paging.


[1] The system call mmap() maps a file into a process address space. The contents of the file can then be


obtained by reading successive memory locations. This is particularly appropriate when the file contains
executable instructions. The file system is regarded as part of the virtual memory system in SVr4, and mmap
is the mechanism for bringing a file into memory.


Dynamic linking permits easy versioning of libraries. New libraries can be shipped; once installed on
the system, old programs automatically get the benefit of the new versions without needing to be
relinked.

Free download pdf