Expert C Programming

(Jeff_L) #1

to anywhere, simply by fixing up the offset tables. So when the code is mapped in at runtime, the
runtime linker can directly put it wherever there is room, and the code itself doesn't have to be
changed.


By default, the compilers don't generate PICode as the additional pointer dereference is a fraction
slower at runtime. However, if you don't use PICode, the generated code is tied to a fixed address—
fine for an executable, but slower for a shared library, since every global reference now has to be fixed
up at runtime by page modification, in turn making the page unshareable.


The runtime linker will fix up the page references anyway, but the task is greatly simplified with
position-independent code. It is a trade-off whether PICode is slower or faster than letting the runtime
linker fix up the code. A rule of thumb is to always use PICode for libraries. Position-independent
code is especially useful for shared libraries because each process that uses a shared library will
generally map it at a different virtual address (though sharing one physical copy).


A related term is "pure code." A pure executable is one that contains only code (no static or initialized
data). It is "pure" in the sense that it doesn't have to be modified to be executed by any specific
process. It references its data off the stack or from another (impure) segment. A pure code segment
can be shared. If you are generating PIcode (indicating sharing) you usually want it to be pure, too.


Five Special Secrets of Linking with Libraries


There are five essential, non-obvious conventions to master when using libraries. These aren't
explained very clearly in most C books or manuals, probably because the language documenters
consider linking part of the surrounding operating system, while the operating system people view
linking as part of the language. As a result, no one makes much more than a passing reference to it
unless someone from the linker team gets involved! Here are the essential UNIX linking facts of life:


1. Dynamic libraries are called lib something .so , and static libraries are


called lib something .a


By convention, all dynamic libraries have a filename of the form libname .so


(version numbers may be appended to the name). Thus, the library of thread routines

is called libthread .so. A static archive has a filename of the form libname.a.


Shared archives, with names of the form libname .sa, were a transient


phenomenon, helping in the transition from static to dynamic libraries. Shared
archives are also obsolete now.

2. You tell the compiler to link with, for example, libthread.so by giving the


option -lthread


The command line argument to the C compiler doesn't mention the entire pathname to
the library file. It doesn't even mention the full name of the file in the library
directory! Instead, the compiler is told to link against a library with the command line

option -lname where the library is called libname .so—in other words, the


"lib" part and the file extension are dropped, and -l is jammed on the beginning


instead.


  1. The compiler expects to find the libraries in certain directories

Free download pdf