A typical process for operating a digital computer involves the steps of writing a plurality of programs in one or more source languages, compiling (or assembling) the source programs into object modules, linking one or more object modules together into a load module, and loading and running the load module. In the typical case where the object modules and load modules are relocatable, the addresses in these modules are relative addresses, i.e., they are addresses relative to the beginning of the respective modules. The modules include relocation information which is used by the operating system to convert the relative addresses to absolute addresses when the modules are loaded for execution.
In a computer system including multiple programs, access between programs is generally accomplished by means of a CALL statement or its equivalent. The CALL statement includes the word CALL and also specifies the name of the program that is to be called. When such a statement is included in a source program, the compiler translates it into a statement for transferring control to the address where the callable program is located. Because the compiler has no way to determine the address of the callable program, the compiler lists the callable program as an unresolved external reference.
The process of combining a number of object modules into a load module is accomplished by a program commonly called a linkage editor. The linkage editor produces a relocatable load module in which addresses are relative to the beginning of the load module. In the case where one object module in a load module CALLs a second object module in that load module, the linkage editor resolves the reference such that the transfer representing the CALL statement transfers control to the relative address of the second object module in the load module. When the relocatable load module is to be executed, the operating system determines the beginning load location, converts all relative addresses to absolute addresses based upon that location, and then loads and runs the load module.
In systems such as those described above, the programmer who wishes to make a particular program available to several load modules must either include the program in each load module, or create a separate load module consisting of that program alone, and store such load module in a library. Both of these approaches have drawbacks. Storing the program in several load modules is redundant and wasteful of storage space. Storing the program as a separate load module leads to a complex library system in which the logical relationships between programs are obscured.