Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

as_300(1)

as_800(1)

cc(1)

f77(1)

ld(1)

pc(1)

crt0(3)

shl_load(3X)

a.out_300(4)

a.out_800(4)

dld.sl(5)

NAME

dld.sl − dynamic loader

DESCRIPTION

The /lib/dld.sl program is the dynamic loader.  It is invoked automatically at startup time by /lib/crt0.o in programs that use shared libraries.  The dynamic loader is, itself, a shared library, although it defines no symbols for use by user programs. 

Shared Libraries

Shared libraries are executable files created with the -b option to ld (see ld(1)). They contain position-independent code (PIC) that can be mapped anywhere in the address space of a process and executed with a minimum of relocation.  PIC can use PC -relative addressing modes and/or linkage tables.  It can be generated with the +z option to the compilers.  See the Programming on HP-UX manual for details on writing PIC in assembly language. 

Incomplete Executables

When creating an executable (a.out) file from object files and libraries, the linker does not copy text from the shared library into the output file.  Instead, the dynamic loader maps the library into the address space of the process at run time.  The linker binds all program references to shared library routines to entries in a linkage table, and relies on the dynamic loader to fill in the linkage table entries once the libraries have been mapped.  This linkage table serves as a jump table.  Shared-library data items referenced by the program are copied into the program executable file so that the data references can be resolved statically.  The resultant program is called an incomplete executable. 

Loading

At run time, the dynamic loader attaches to the process all shared libraries that were linked with the program.  The text segment of a library is shared among all processes that use it.  The data and bss segments are shared on a page-by-page basis.  When a process writes to a data or bss page, a modified copy of that page is made for the process. 

Binding

The dynamic loader also resolves symbolic references between the executable and libraries.  By default, function calls are trapped via the linkage table and bound on first reference.  References to variables and other absolute address references cannot be trapped.  They are bound on the first resolution of a function call that could potentially reference the object. 

If the -B immediate option to ld is used, the loader binds all necessary references at startup time.  This dramatically increases the startup cost of a program, but ensures that no more binding operations will be required later.  Thus, better real time response may result, and the risk of a later abort due to unresolved externals is eliminated. 

Version Control

Since code from a shared library is mapped at run time from a separate shared library file, modifications to a shared library may alter the behavior of existing executables.  In some cases, this may cause programs to operate incorrectly.  A means of version control is provided to solve this problem. 

Whenever an incompatible change is made to a library interface, both versions of the affected module or modules are included in the library.  A mark indicating the date (month/year) the change was made is recorded in the new module via the pragma HP_SHLIB_VERSION in C, or the compiler directive SHLIB_VERSION in Fortran and Pascal.  This date applies to all symbols defined within the module.  A high water mark giving the date of the latest incompatible change is recorded in the shared library, and the high water mark for each library linked with the program is recorded in the incomplete executable file. 

At run time, the dynamic loader checks the high water mark of each library and loads the library only if it is at least as new as the high water mark recorded at link time.  When binding symbolic references, the loader chooses the latest version of a symbol that is not later than the high water mark recorded at link time.  These two checks help ensure that the version of each library interface used at run time is the same as was expected at link time. 

Explicit Loading And Binding

The duties of the dynamic loader as described above are all performed automatically, although they can be controlled somewhat by appropriate options to ld.  The dynamic loader can also be accessed programmatically.  The reserved variable __dld_loc, which is defined in /lib/crt0.o, points to a jump table within the dynamic loader.  The routines described under shl_load(3X) provide a portable interface that allows the programmer to explicitly attach a shared library to the process at run time, to calculate the addresses of symbols defined within shared libraries, and to detach the library when done.

DIAGNOSTICS

If the dynamic loader is not present, or cannot be invoked by the process for any reason, an error message is printed to standard error and the process terminates with a non-zero exit code. 

Normally, the operation of the dynamic loader is visible only when there is a fatal error of some kind.  In these cases, an error message is printed to standard error and a SIGABRT signal is sent to the process.  These errors fall into two basic categories: errors in attaching a shared library, and errors in binding symbols.  The former can occur only at process startup time but the latter can occur at any time during process execution unless the -B immediate option is used with ld.  Possible errors that can occur while attaching a shared library include library not present, library not executable, library corrupt, high water mark too low, or insufficient room in the address space for the library.  Possible errors that can occur while binding symbols include symbol not found (unresolved external), or library corrupt. 

When using the explicit load facilities of the dynamic loader, these types of errors are not considered fatal.  Consult shl_load(3X) for information on error handling.

WARNINGS

The startup cost of the dynamic loader is significant, even with deferred binding, and can cause severe performance degradation in processes dominated by startup costs (such as simple “hello world” programs).  In addition, position-independent code is usually slower than normal code, so performance of a program may be adversely affected by the presence of PIC in shared libraries.  However, the advantages of decreased disk space usage and decreased memory requirements for executables should outweigh these concerns in most cases. 

There are rare cases where the behavior of a program differs when using shared libraries as opposed to archive libraries.  This happens primarily when relying on undocumented and unsupported features of the compilers, assembler, and linker.  See the Programming on HP-UX manual for more details. 

The library developer is entirely responsible for version control and must be thorough in identifying incompatible changes to library interfaces.  Otherwise, programs may malfunction unexpectedly with later versions of the library.  There is little an application user can do if version control is not handled properly by the library developer.  The application developer can usually resolve problems by modifying the source code to use the new interfaces then recompiling and relinking against the new libraries. 

DEPENDENCIES

Series 300/400

The Series 300/400 Pascal compiler does not generate PIC, so true shared libraries cannot be created from Pascal source. 

Dynamic load libraries that are not completely shared can be created from modules that do not contain position-independent code, as long as the +l option to the Pascal compiler is used.  The +s option to the assembler can also be used to generate modules from non- PIC sources that can be included in dynamic load libraries." The resultant library text segment contains absolute addresses that must be relocated at run time.  This causes each text page with code that is not position independent to be modified at run time for each process, which effectively defeats sharing.  The text segments of such libraries cannot be made read only. 

Series 700/800

Copy-on-write of shared library data and bss pages is not supported; a separate copy of a page is made for each process that references (that is, either writes or reads) it. 

AUTHOR

The /lib/dld.sl program was developed by HP. 

SEE ALSO

as_300(1), as_800(1), cc(1), f77(1), ld(1), pc(1), crt0(3), shl_load(3X), a.out_300(4), a.out_800(4). 

Programming on HP-UX manual. 

Hewlett-Packard Company  —  HP-UX Release 9.0: August 1992

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026