Kenwood HP 9000 Personal Computer User Manual


 
Chapter 5 159
Creating and Using Libraries
Switching from Archive to Shared Libraries
More commonly, programmers may take advantage of undocumented
linker behavior to minimize the size of routines copied into the a.out
files from archive libraries. This is no longer necessary if all libraries are
shared.
Although it is impossible to characterize the new resolution rules exactly,
the following rules always apply:
If a symbol is defined in two shared libraries, the definition used at
run time is the one that appeared first, regardless of where the
reference was.
The linker treats shared libraries more like object files.
As a consequence of the second rule, programs that call wrapper libraries
may become larger. (A wrapper library is a library that contains
alternate versions of C library functions, each of which performs some
bookkeeping and then calls the actual C function. For example, each
function in the wrapper library might update a counter of how many
times the actual C routine is called.) With archive libraries, if the
program references only one routine in the wrapper library, then only the
wrapper routine and the corresponding routine from the C library are
copied into the a.out file. If, on the other hand, a shared wrapper library
and archive C library are specified, in that order, then all routines that
can be referenced by any routine in the wrapper library are copied from
the C library. To avoid this, link with archive or shared versions for both
the wrapper library and C library, or use an archive version of the
wrapper library and a shared version of the C library.
Absolute Virtual Addresses
Writing code that relies on the linker to locate a symbol in a particular
location or in a particular order in relation to other symbols is known as
making an implicit address dependency. Because of the nature of
shared libraries, the linker cannot always preserve the exact ordering of
symbols declared in shared libraries. In particular, variables declared in
a shared library may be located far from the main program's virtual
address space, and they may not reside in the same relative order within
the library as they were linked. Therefore, code that has implicit address
dependencies may not work as expected with shared libraries.
An example of an implicit address dependency is a function that assumes
that two global variables that were defined adjacently in the source code
will actually be adjacent in virtual memory. Since the linker may