HP OpenVMS Systems Documentation

Content starts here

HP OpenVMS Linker Utility Manual

Previous Contents Index

2.3 Ensuring Correct Symbol Resolution

For many link operations, the order in which the input files are specified in the LINK command is not important. However, in complex link operations that specify multiple library files or process input files selectively, correct symbol resolution may become problematic.

To ensure that the linker resolves all the symbolic references as you intend, you may need to know order in which the linker processes the input files. To control the order in which the linker processes input files, you must understand how the linker parses the command line. The following sections describe these processes.

2.3.1 Understanding Cluster Creation

As it parses the command line, the linker groups the input files you specify into clusters and places these clusters on a cluster list. A cluster is an internal linker construct that determines segment creation. The position of an input file in a cluster and the position of that cluster on the linker's cluster list determine the order in which the linker processes the input files you specify.

The linker always creates at least one cluster, called the default cluster. The linker may create additional clusters, called named clusters, depending on the types of input files you specify and the linker options you specify. If it creates additional clusters, the linker places them on the cluster list ahead of the default cluster, in the order in which it encounters them in the options file. The default cluster appears at the end of the cluster list. (Within the default cluster, input files appear in the same order in which they are specified on the LINK command line.)

Clusters for shareable images, specified in shareable image libraries, appear after the default cluster on the cluster list because they are created later in linker processing, when the linker knows which shareable images in the library are needed for the link operation.

The linker groups input files into clusters according to file type. Table 2-2 lists the types of input files accepted by the linker and describes how the linker processes them when creating clusters.

Table 2-2 Linker Input File Cluster Processing
Input File Cluster Processing
Object file (.OBJ) Placed in the default cluster unless explicitly placed in a named cluster using the CLUSTER= option.
Shareable image file (.EXE) Always placed in a named cluster.
Library files (.OLB) Placed in the default cluster unless explicitly placed in a named cluster using the CLUSTER= option. If the library contains shareable images and the linker includes a shareable image from the library in the link operation, the linker creates a new cluster for the shareable image.

The linker puts input files included in a link operation from a library using the /INCLUDE qualifier in the same cluster as the library.

The linker puts modules extracted from any default user library that is an object library and from STARLET.OLB in the default cluster. However, the linker puts shareable images referenced from IMAGELIB.OLB into new clusters at the end of the cluster list (after the default cluster).

Options file (.OPT) Not placed in a cluster.

The following example illustrates how the linker puts the various types of input files in clusters. To see which clusters the linker creates for this link operation, look at the Cluster Synopsis section of the image map file. Figure 2-3 illustrates the clusters created for this link operation. Note that order of cluster creation is: MY_CLUS, MY_SHARE, DEFAULT_CLUSTER, MY_SHARE_IMG.


Figure 2-3 Clusters Created for Sample Link

The linker processes input files in cluster order, processing each input file starting with the first file in the first cluster, then processing the second file, and so on, until it has processed all files in the first cluster. The linker continues processing the input files in the second, and subsequent, clusters in the same manner. Processing concludes when the linker has processed all files in all clusters.

2.3.2 Controlling Cluster Creation

You can control cluster creation and ordering by using either of the following linker options:

  • CLUSTER= option
  • COLLECT= option Using the CLUSTER= Option to Control Clustering

The CLUSTER= option causes the linker to create a named cluster and to place, in the cluster, the object modules specified in the option. (The linker puts shareable images in their own clusters.)

For example, you can use the CLUSTER= option to fix the link operation illustrated in Section 2.2.4, where the link operation yielded warnings because a shareable image was processed first and selectively. To make the linker process the object module MY_MAIN.OBJ before it processes the shareable image MY_MAIN.EXE, put the object module in a named cluster before specifying the shareble image. In the following example, the /EXECUTABLE qualifier is specified on the command line to specify the name of the resultant image, because MY_MAIN is not specified on the command line.


The Object and Image Synopsis section of the image map file verifies that the linker processed the object module MY_MAIN before it processed the shareable image MY_MATH, as in the following map file excerpt:

                       ! Object and Image Synopsis !

Module/Image     File           Ident             Attributes          Bytes
------------     ----           -----          ----------------       -----
MY_MAIN                         V1.0               Lkg     Dnrm        504
MY_MATH                         V1.0           Sel Lkg                   0
   . Using the COLLECT= Option to Control Clustering

You can also create a named cluster by specifying the COLLECT= option. The COLLECT= option directs the linker to put specific sections in a named cluster. The linker creates the cluster if it does not already exist. Note that the COLLECT= option manipulates sections, not input files.

The linker sets the global (GBL) attribute of the sections specified in a COLLECT= option to enable a global search for the definition of that section.


In this example, a cluster MYCODE_CLUS is created after MYMAIN_CLUS and the section $CODE$ is collected into the cluster MYCODE_CLUS.

2.4 Resolving Symbols Defined in the OpenVMS Executive

For I64 linking, you link against the OpenVMS executive by specifying the /SYSEXE qualifier. When this qualifier is specified, the linker selectively processes the system shareable image, SYS$BASE_IMAGE.EXE, located in the directory pointed to by the logical name IA64$LOADABLE_IMAGES. The linker does not process SYS$BASE_IMAGE.EXE by default. Note that, because the linker is processing a shareable image, references to symbols in the OpenVMS executive are fixed up at image activation.

When the /SYSEXE qualifier is specified, the linker processes the file selectively. To disable selective processing, specify the /SYSEXE=NOSELECTIVE qualifier and keyword. For more information about using the /SYSEXE qualifier, see the description of the qualifier in the command reference in Part 4.

Relation to Default Library Processing

When you specify the /SYSEXE qualifier, the linker processes the SYS$BASE_IMAGE.EXE file after processing the system shareable image library, IMAGELIB.OLB, and before processing the system object library, STARLET.OLB. (Note that the linker also processes the system service shareable image, SYS$PUBLIC_VECTORS.EXE, when it processes STARLET.OLB by default.)

The /SYSSHR and /SYSLIB qualifiers, which control processing of the default system libraries, do not affect SYS$BASE_IMAGE.EXE processing. When the /NOSYSSHR qualifier is specified with the /SYSEXE qualifier, the linker does not process IMAGELIB.OLB, but still processes SYS$BASE_IMAGE.EXE and then STARLET.OLB and SYS$PUBLIC_VECTORS.EXE. When /NOSYSLIB is specified, the linker does not process IMAGELIB.OLB, STARLET.OLB, or SYS$PUBLIC_VECTORS, but still processes SYS$BASE_IMAGE.EXE.

To process SYS$BASE_IMAGE.EXE before the shareable images in IMAGELIB.OLB, specify SYS$BASE_IMAGE.EXE in a linker options file as you would any other shareable image. If you specify SYS$BASE_IMAGE.EXE in your options file, do not use the /SYSEXE qualifier.

Figure 2-4 illustrates how the /SYSEXE qualifier, in combination with the /SYSSHR and /SYSLIB qualifiers, can affect linker processing. (The default syntax illustrated in the figure is rarely specified.)

Figure 2-4 Linker Processing of Default Libraries and SYS$BASE_IMAGE.EXE

2.5 Processing Weak and Strong Global Symbols

This section describes how the linker processes weak and strong global symbols:

  • Section 2.5.1 describes strong and weak global symbols and how the linker processes them
  • Section 2.5.2 describes how strong and weak symbol definitions are handled when processing object modules
  • Section 2.5.3 describes how the linker resolves strong and weak symbol references

2.5.1 Overview of Weak and Strong Global Symbol Processing

The linker records each symbol definition and each symbol reference in its internal global symbol table. For each symbol, the linker notes whether the symbol is strong, VMS-style weak, or UNIX-style weak.

The linker processes strong symbol definitions differently than it does UNIX-style weak symbol definitions (see Section 2.5.2. In general, a symbol can have only one strong or one VMS-style weak definition but it can have multiple UNIX-style weak definitions. When linking against libraries, note that there is also a difference between VMS-style weak and UNIX-style weak symbol definitions.

The linker processes weak references differently than it does strong references, although it handles both types of weak references in the same manner. Strong references must be resolved, whereas VMS-style and UNIX-style weak can be resolved optionally. If any weak symbol is not resolved, then the linker puts the value zero in place of the reference. In this case, the linker does not display a warning message.

By default, all global symbols generated by most I64 language processors are strong. That is, object modules usually contain strong symbol definitions and strong symbol references. You can decide to make some symbols VMS-weak definitions and references. To do so, you must use a language feature and explicitly mark the code or data as VMS-style weak. (For example, you would explicitly mark the code or data as VMS-style weak with the intention of performing a link operation on partially complete development code.) (See Section for more information about creating and using VMS-style weak symbols.)

For some language constructs, the HP C++ compiler generates UNIX-style weak symbols. That is, some object modules may contain strong and weak symbol definitions and references. The compiler produces redundent code or data in multiple object modules and the linker resolves to the first symbol encountered in the link operation. Strong Symbols

For strong global symbols, there can be only one definition. If the linker finds more than one definition in different input modules, any secondary definition is reported as a multiple definition.

By default, when adding an object module to a library, a strong symbol definition from the object module is included in the library symbol table. As a result, the symbol can be found when the linker searches a library to resolve a symbol reference. VMS-Style Weak Symbols

VMS-style weak global symbols can have only one definition. If the linker finds more than one definition in different input modules, any secondary definition is reported as multiply defined.

When adding an object module to a library, a VMS-style weak global symbol is not included in the library symbol table. As a result, if the module containing the weak symbol definition is in a library but is not selected for inclusion (by means of the /INCLUDE qualifier or to resolve a strong reference), the linker is unable to resolve the reference. UNIX-Style Weak Symbols

UNIX-style weak global symbols can have multiple definitions. When a strong definition is absent, the linker selects the first occurrence of the UNIX-style weak definition and views subsequent ones as references.

When adding an object module to a library, a UNIX weak symbol is included in the library symbol table. (The I64 Librarian is compatible with UNIX-style weak symbols.) If multiple modules define the same UNIX-style weak symbol, the librarian maintains an ordered list of symbols in its symbol table. With this information, the linker can find a UNIX-style weak symbol when searching a library for an unresolved symbol. Note that the earliest module added in the library defining the symbol is selected for inclusion.

If the object module containing any type of weak symbol definition is explicitly specified, either as an input object file or for extraction from a library (by means of the /INCLUDE qualifier or to resolve a strong reference), the VMS-style weak or UNIX-style weak symbol definitions are available for symbol resolution.

2.5.2 Strong and Weak Definitions

The OpenVMS I64 linker supports modules from various programming languages and contains rules for handling symbols from these languages under different circumstances. Table 2-3 shows how symbol definitions are handled when object modules are processed.

Table 2-3 Symbol Definition Handling
Current Symbol Definition New Symbol Definition Encountered Action
<none> <any> Assign new definition
UNIX-style weak UNIX-style weak Ignore new definition
UNIX-style weak VMS-style weak Assign VMS-style weak definition
UNIX-style weak Strong Assign Strong definition
VMS-style weak UNIX-style weak Ignore new definition
VMS-style weak VMS-style weak Report multiple defined symbols
VMS-style weak Strong Report multiple defined symbols
Strong UNIX-style weak Ignore new definition
Strong VMS-style weak Report multiple defined symbols
Strong Strong Report multiple defined symbols

An exception to the rules presented in Table 2-3 is for the special symbol, ELF$TFRADR, which defines the image entry point. Typically, each compiler defines one symbol for each module that contains code. If the module contains a main entry, then a strong symbol is defined. Conversely, if there is no main entry, a VMS-style weak symbol is defined (which behaves differently than a strong symbol).

If you have only VMS-style weak ELF$TFRADR symbols, the first-encountered definition determines the image entry and the other definitions are ignored. If there is a strong definition, it overwrites an existing VMS-style weak definition and other definitions are ignored.


This case is different than processing UNIX-style weak symbols, where ignored symbols are converted to references.

2.5.3 Resolving Strong and Weak Symbols

This section describes how the I64 linker processes strong and weak references to resolve symbols. In general, a strong reference can be resolved by a strong symbol definition or any type of weak symbol definition.

For a strong reference, the linker searches all input files (explicit and implicit) for a definition of the symbol. If the linker cannot locate the definition needed to resolve the strong reference, it reports the undefined symbol and assigns the symbol a value, which usually results in a run-time error for accessing the data or calling the routine.

When the linker resolves a weak reference with a strong symbol definition or a weak symbol definition, it resolves the weak reference in the same way it does a strong reference, with the following exceptions:

  • The linker will not search library modules that have been specified with the /LIBRARY qualifier or default libraries (user-defined or system) solely to resolve a weak reference. If, however, the linker resolves a strong reference to another symbol in such a module, it will also use that module to resolve any weak references.
  • If the linker cannot locate the definition needed to resolve a weak reference, it assigns the symbol a value, which usually results in a run-time error, but does not report an undefined symbol. If, however, the linker reports any unresolved strong references, it will also report any unresolved weak references.

By default, most global definitions in I64 languages are strongly defined.

2.5.4 Creating and Using VMS-style Weak Symbols

In the dialects of MACRO, BLISS, and Pascal supported on I64 systems, you can define a global symbol as either strong or VMS-style weak, and you can make either a strong or a VMS-style weak reference into a global symbol.

In these languages, all definitions and references are strong by default. To make a VMS-style weak definition or a VMS-style weak reference, you must use the .WEAK assembler directive (in MACRO), the WEAK attribute (in BLISS), or the WEAK_GLOBAL or WEAK_EXTERNAL attribute (in Pascal).

One purpose for making a weak reference is need to write and test incomplete programs. Resolving all symbolic references is crucial to a successful link operation. Therefore, a problem arises when the definition of a referenced global symbol does not yet exist. (This would be the case, for example, if the global symbol definition is an entry point to a module that is not yet written.) The solution to this condition is to make the reference to the symbol VMS-style weak, which informs the linker that the resolution of this particular global symbol is not crucial to the link operation.

2.6 Processing HP C++ Compiler-Generated UNIX-Style Weak and Group Symbols

UNIX-style weak symbols and groups are used by the HP C++ compiler to implement template instantiation. Templates, commonly used in the HP C++ standard library, provide a programming model that allows you to write and use data type-independent code. When this code is part of a source module, it is used with a data type, that is, the template is instantiated.

To instantiate the template, the compiler defines UNIX-style weak symbols for variables and functions used in the template and generates a group. All these symbols, along with code and data, are placed in the group and marked as group symbols. When the same template with the same data type is instantiated in several source modules, a group with the same name containing the same code and data appears in each object module.

The linker handles group symbols in a special way to generate an image which contains only one occurrence of this group of sections. The linker ensures that all references to the groups are resolved to the designated instance of the group.

Currently, UNIX-style weak symbols and group symbols are only used by the HP C++ compiler, which also limits the usage of UNIX-style weak binding to group symbols. However, UNIX-style weak symbols and group symbols can be seen as independent, and the linker handles them as such.

2.6.1 Processing Group Symbols

When linking modules, the first occurrence of a group makes its symbols known to the linker. The linker regards any additional occurrence of the group with the same name as redundant and therefore, ignors it.

Because the concept of groups (as described in the ELF specification) is limited to object modules, the use of shareable images requires a different approach: the VMS extension to ELF allows groups for shareable images. A shareable image group always takes precedence over groups found in object modules. For global symbols and identical groups, this means that all group symbols from an already processed group of an object module are replaced by the ones from the shareable image. The linker's intention is to always use the code and data from the shareable image.

Previous Next Contents Index