This manual describes the operations of the Solaris OS link-editor and runtime linker, together with the objects on which the link-editors operate. The basic operation of the Solaris OS link editors involves the combination of objects. This combination results in the symbolic references from one object being connected to the symbolic definitions within another object.
This manual expands the following areas.
The link-editor, ld(1), concatenates and interprets data from one or more input files. These files can be relocatable objects, shared objects, or archive libraries. From these input files, one output file is created. This file is either a relocatable object, an executable application, or a shared object. The link-editor is most commonly invoked as part of the compilation environment.
The runtime linker, ld.so.1(1), processes dynamic executables and shared objects at runtime, binding the executable and shared objects together to create a runnable process.
Shared objects are one form of output from the link-edit phase. Shared objects are sometimes referred to as Shared Libraries. Shared objects are importance in creating a powerful, flexible runtime environment.
These areas, although separable into individual topics, have a great deal of overlap. While explaining each area, this document brings together the connecting principles.
Link-editing takes a variety of input files, typically generated from compilers, assemblers, or ld(1). The link-editor concatenates and interprets the data within these input files to form a single output file. Although the link-editor provides numerous options, the output file that is produced is one of four basic types.
Static executable – A concatenation of input relocatable objects that have all symbolic references resolved. This executable represents a ready-to-run process. See Static Executables.
Dynamic executable – A concatenation of input relocatable objects that requires intervention by the runtime linker to produce a runnable process. A dynamic executable might still need symbolic references bound at runtime. Dynamic executables typically have one or more dependencies in the form of shared objects.
Shared object – A concatenation of input relocatable objects that provide services that might be bound to a dynamic executable at runtime. The shared object can have dependencies on other shared objects.
These output files, and the key link-editor options used in their creation, are shown in Figure 1–1.
Dynamic executables and shared objects are often referred to jointly as dynamic objects. Dynamic objects are the main focus of this document.
The creation of static executables has been discouraged for many releases. In fact, 64–bit system archive libraries have never been provided. Because a static executable is built against system archive libraries, the executable contains system implementation details. This self-containment has a number of drawbacks.
The executable is immune to the benefits of system patches delivered as shared objects. The executable therefore, must be rebuilt to take advantage of many system improvements.
The ability of the executable to run on future releases can be compromised.
The duplication of system implementation details negatively affects system performance.
With the Solaris 10 release, 32–bit system archive libraries are no longer provided. Without these libraries, specifically libc.a, the creation of a static executable is no longer achievable without specialized system knowledge. Note, that the link-editors capability to process static linking options, and the processing of archive libraries, remains unchanged.
Runtime linking involves the binding of objects, usually generated from one or more previous link-edits, to generate a runnable process. During the generation of these objects by the link-editor, appropriate bookkeeping information is produced to represent the verified binding requirements. This information enables the runtime linker to load, relocate, and complete the binding process.
During process execution, the facilities of the runtime linker are made available. These facilities can be used to extend the process' address space by adding additional shared objects on demand. The two most common components involved in runtime linking are dynamic executables and shared objects.
Dynamic executables are applications that are executed under the control of a runtime linker. These applications usually have dependencies in the form of shared objects, which are located, and bound by the runtime linker to create a runnable process. Dynamic executables are the default output file generated by the link-editor.
Shared objects provide the key building-block to a dynamically linked system. A shared object is similar to a dynamic executable, however, shared objects have not yet been assigned a virtual address.
Dynamic executables usually have dependencies on one or more shared objects. Typically, one or more shared objects must be bound to the dynamic executable to produce a runnable process. Because shared objects can be used by many applications, aspects of their construction directly affect shareability, versioning, and performance.
Shared object processing by the link-editor or the runtime linker can be distinguished by the environment in which the shared object is used.
Dynamic linking is a term often used to embrace a number of linking concepts. Dynamic linking refers to those portions of the link-editing process that generate dynamic executables and shared objects. Dynamic linking also refers to the runtime linking of these objects to generate a runnable process. Dynamic linking enables multiple applications to use the code provided by a shared object by binding the application to the shared object at runtime.
By separating an application from the services of standard libraries, dynamic linking also increases the portability and extensibility of an application. This separation between the interface of a service and its implementation enables the system to evolve while maintaining application stability. Dynamic linking is a crucial factor in providing an application binary interface (ABI), and is the preferred compilation method for Solaris OS applications.
Binary interfaces between system and application components are defined to enable the asynchronous evolution of these facilities. The Solaris OS link editors operate upon these interfaces to assemble applications for execution. Although all components handled by the Solaris OS link editors have binary interfaces, the whole set of interfaces provided by the system is referred to as the Solaris ABI.
The Solaris ABI is a technological descendent for work on ABI's that started with the System V Application Binary Interface. This work evolved with additions performed by SPARC International, Inc.® for SPARC processors, called the SPARC Compliance Definition (SCD).
The link-editor is provided as a 32–bit application and a 64–bit application. Each link-editor can operate on 32–bit objects and 64–bit objects. On systems that are running a 64–bit environment, both versions of the link-editor can be executed. On systems that are running a 32–bit environment, only the 32–bit version of the link-editor can be executed. For more details see The 32–bit link-editor and 64–bit link-editor.
The runtime linker is provided as a 32–bit object and a 64–bit object. The 32–bit object is used to execute 32–bit processes, and the 64–bit object is used to execute 64–bit processes.
The operations of the link-editors on 32–bit objects and 64–bit objects are identical. This document typically uses 32–bit examples. Cases where 64–bit processing differs from the 32–bit processing are highlighted.
For more information on 64–bit applications, refer to the Solaris 64-bit Developer’s Guide.
The link-editors support a number of environment variables that begin with the characters LD_, for example LD_LIBRARY_PATH. Each environment variable can exist in its generic form, or can be specified with a _32 or _64 suffix, for example LD_LIBRARY_PATH_64. This suffix makes the environment variable specific, respectively, to 32–bit or 64–bit processes. This suffix also overrides any generic, non-suffixed, version of the environment variable that might be in effect.
Prior to the Solaris 10 release, the link-editors ignored environment variables that were specified without a value. Therefore, in the following example, the generic environment variable setting, /opt/lib, would have been used to search for the dependencies of the 32–bit application prog.
$ LD_LIBRARY_PATH=/opt/lib LD_LIBRARY_PATH_32= prog
With the Solaris 10 release, environment variables specified without a value, that have a _32 or _64 suffix, are processed. These environment variables effectively cancel any associated generic environment variable setting. Thus in the previous example, /opt/lib will not be used to search for the dependencies of the 32–bit application prog.
The Solaris OS also provides several support tools and libraries. These tools provide for the analysis and inspection of these objects and the linking processes. These tools include elfdump(1), lari(1), nm(1), dump(1), ldd(1), pvs(1), elf(3ELF), and a linker debugging support library. Throughout this document, many discussions are augmented with examples of these tools.