HP OpenVMS Linker Utility Manual


Previous Contents Index

1.5 Linking for Different Architectures (Alpha and VAX)

You can create OpenVMS Alpha images on an OpenVMS VAX system and create OpenVMS VAX images on an OpenVMS Alpha system. To do this, you must mount a system disk of the target architecture and make it accessible on the system where the link is to occur. Also, you must assign logical names to point to portions of the target architecture disk.

Note

You cannot create OpenVMS I64 images on Alpha and VAX platforms, nor create images for Alpha and VAX on I64 systems.

Table 1-5 lists the logical names and the conditions of their use.

Table 1-5 Logical Names for Cross-Architecture Linking
Logical Name Description
ALPHA$LIBRARY The linker uses this logical name when creating an OpenVMS Alpha image to locate the target system's shareable images and system libraries.
VAX$LIBRARY The linker uses this logical name when creating an OpenVMS VAX image on an OpenVMS Alpha computer to locate the target system's shareable images and system libraries.
SYS$LIBRARY The linker uses this logical name when creating an OpenVMS VAX image on an OpenVMS VAX computer to locate the target system's shareable images and system libraries.
ALPHA$LOADABLE_IMAGES The linker uses this logical when creating an OpenVMS Alpha image to locate the target system's base image SYS$BASE_IMAGE.EXE when the /SYSEXE qualifier is in the link command line.

The /ALPHA and /VAX qualifiers control which architecture an image is built for:


Part 2
Linking on OpenVMS I64 Systems


Chapter 2
Understanding Symbol Resolution (I64)

This chapter describes how the linker performs symbol resolution on OpenVMS I64 systems. For information on performing symbol resolution on Alpha and VAX systems, see Chapter 6.

As one of its primary tasks, the linker must resolve symbolic references between modules. This chapter describes how you can control the process to ensure that the linker resolves symbolic references as you intend.

2.1 Overview

Programs are typically made up of many interdependent modules. For example, one module may define a symbol to represent a program location or data element that is referenced by many other modules. The linker is responsible for finding the correct definition of each symbol referenced in all the modules included in the link operation. This process of matching symbolic references with their definitions is called symbol resolution.

2.1.1 Types of Symbols

Symbols can be categorized by their scope, that is, the range of modules over which they are intended to be visible. Some symbols, called local symbols, are meant to be visible only within a single module. Because the definition and the references to these symbols must be confined to a single module, language processors such as compilers can resolve these references.

Other symbols, called global symbols, are meant to be visible to external modules. A module can reference a global symbol that is defined in another module. Because the value of the symbol is not available to the compiler processing the source file, it cannot resolve the symbolic reference. Instead,a compiler creates an ELF symbol table (SYMTAB) in an object module that includes all of the global symbol references and global symbol definitions itcontains. These symbols are part of the global symbol directory (GSD).

On I64, the GSD has a conceptual meaning. It no longer indicates an area within an object module, in which all named entities are listed. For ELF objects, the named entities for data and code are listed in the ELF symbol table; the name identities for sections are listed in the section header table. To use the traditional name GSD for I64, the GSD can be seen as a subset of the ELF symbol table, plus a subset of the section header table.

In most programming languages, you can explicitly specify whether a symbol is global or local by setting or omitting particular attributes in the symbol definition or reference. For example, in C all functions are global symbols by default but the functions with the static attribute are local symbols.

In shareable images, symbols that are intended to be visible to external modules are called universal symbols. A universal symbol in a shareable image is the equivalent of a global symbol in an object module. Note, however, that only those global symbols that have been declared as universal are listed in the ELF symbol table (SYMTAB) of the shareable image and are available to external modules to link against. These symbols are part of the global symbol table (GST).

Similar to the GSD, the GST has a conceptual meaning on I64 systems; that is, it no longer indicates an area within an image file, in which all named entities are listed. For ELF images, the named entities for data and code are listed in the ELF symbol table and the named entities for sections are listed in the section header table. To use the traditional name GST for I64, the GST can be seen as a subset of the ELF symbol table, plus a subset of the section header table.

You must explicitly declare universal symbols as part of the link operation in which the shareable image is created. For more information about declaring universal symbols, see Chapter 4.

2.1.1.1 Understanding Strong and Weak Symbols

As on Alpha and VAX systems, the linker on I64 systems supports global symbols that can be strong or weak. Weak symbols can be one of two types: VMS-style weak and UNIX-style weak.

The VMS-style weak symbol is identical to the weak symbol on Alpha and VAX. Using VMS-style weak symbols reflects a programming concept where the developer marks a a symbol as weak depending on available language support. For information about how the linker processes VMS-style weak symbols, see Section 2.5.

UNIX-style weak symbols are unique to I64 and primarily used by the C++ compiler. Using UNIX-style weak symbols reflects an implementation concept, where the compiler marks symbols as weak, depending on language constructs. For information about how the linker processes UNIX-style weak symbols, see Section 2.6.

2.1.1.2 Group Symbols

Global symbols can be gathered in a group which is seen by the linker as a single entity. All symbols in a group are included or excluded in the link process. The group is identified by its group name, which is also called a group signature. A group also defines a set of sections, which contain definitions or references of the group symbols. As with UNIX-style weak symbols, groups are an implementation concept, primarily used by the HP C++ compiler. For more information about working with group symbols, see Section 2.6.

2.1.1.3 The C Extern Common Model

In some HP programming languages, certain types of global symbols, such as external variables in the C common extern model and COMMON data in FORTRAN, are not listed in the symbol table as global symbol references or definitions. Because these data types implement virtual memory that is shared, the languages implement them as sections that are overlaid. Rather than appearing as global symbol definitions or references, these variable names emerge as section names. (Compilers use sections to define the memory requirements of an object module.) Although this may look like symbol resolution to the user, the linker does not process symbols. For information about how the linker processes sections, see Chapter 3.

For example, this C definition and the Fortran data that follows are matched and address the same data:


#pragma extern_model common_block 
struct { int first; int second; } numbers; 


INTEGER*4 first, second 
COMMON /numbers/ first, second 

2.1.1.4 Tentative Definitions in C

In the HP C programming language, external variables can be defined in a strict or a relaxed reference/definition model. The strict model allows only one strong definition. The relaxed model, allows several tentative definitions. Any initialized variable is a strong symbol definition in the strict model. All uninitialized variables can be relaxed or tentative definitions. For both types of external variables, strong global symbols are generated by the compiler. For a strong definition in any model, the compiler reserves memory in the defining module. For tentative definitions, the compiler does not reserve memory. Tentative definitions result in global symbols in the symbol table, marked as ELF common.

Note

Do not confuse the term "ELF common" with "Fortran common"; these are different concepts.

If there is one strong definition, the linker uses it as the primary definition and treats all the tentative definitions as references. Otherwise, the linker does the following:

The section created by the linker contains the overlay attribute. Any other section with the same name and the same attributes can overlay onto this section.

For example, the following C definitions are tentative:


/* module A */ 
#pragma extern_model relaxed_refdef 
int my_data; 
 
/* module B */ 
#pragma extern_model relaxed_refdef 
int my_data; 

The linker creates a section with memory for the variable and marks module A as the defining module for the section.

Note

The linker does not include section names in its symbol resolution processing. The name spaces for symbols and sections are separate. The overlaying of sections with a created section for a tentative definition with the same name does not produce an exception.

2.1.1.5 Considerations for C Language Extensions

On I64 systems, the HP C language extensions globalref and globaldef allow you to create external variables that appear as symbol references and definitions in the symbol table. For more information, see the HP C User's Guide for OpenVMS Systems.

In addition, HP C supports command line qualifiers and source code pragma statements (as shown in the previous examples) that allow you to control the extern model. For more information, see the HP C User's Guide for OpenVMS Systems.

2.1.2 Linker Symbol Resolution Processing

During its first pass through the input files specified in the link operation, the linker attempts to find the definition for every symbol referenced in the input files. By default, the linker processes all the global symbols defined and referenced in the symbol table of each object module (GSD) and all the universal symbols defined in the global symbol table (GST) of each shareable image and any symbol defined by linker options. The definition of the symbol provides the value of the symbol. The linker substitutes this value for each instance where the symbol is referenced in the image being created. This value might not be the actual value of the virtual address at run time, because the values might be relocated by the image activator.

The value of a symbol depends on what the symbol represents. A symbol can represent a routine entry point or a data location within an image. For these symbols, the value of the symbol is an address. A symbol can also represent a data constant (for example, the linker option SYMBOL=X,10). In this case, the value of the symbol is its actual value.

For symbols that represent addresses in object modules, the value is expressed initially as an offset into a section. (This is the manner in which language processors express addresses.) Later in its processing, the linker determines the symbol's preliminary value after combining all module contributions into segments, which yields the proposed memory layout. For information about how the linker determines the virtual memory layout of an image, see Chapter 3.

For I64 images, at link time, the value of a symbol in a shareable image (as listed in the GST of the image) is the index of the symbol's entry in the symbol vector of the image.

A symbol vector entry is a quadword that contains the value of the symbol. The contents of the quadword depends on whether the symbol represents a procedure entry point, data location, or a constant. Figure 2-1 illustrates the contents of a symbol vector entry for each of these three types of symbols. At link time, a symbol vector entry for a procedure entry point or a data location is expressed as an offset into the image. At image activation time, when the image is loaded into memory and the base address of the image is known, the image activator converts the image offset into a virtual address. Figure 2-1 shows the contents of the symbol vector at link time and at image activation time.

Figure 2-1 Symbol Vector Contents


Note that the linker does not allow programs to make procedure calls to symbols that represent data locations.

The actual value of an address symbol in a shareable image is determined at run time by the image activator when it loads the shareable image into memory. The image activator converts or relocates all the addresses within a shareable image when it loads the image into memory. Once it has determined the absolute values of these addresses, the image activator fixes up references to these addresses in the image that linked against the shareable image. When the image was linked, the linker created fix-ups that flag to the image activator where it must insert the actual addresses to complete the linkage of a symbolic reference to its definition in an image. The linker listed these fix-ups in the fix-up table, which is part of the dynamic segment created for the image. For more information about shareable images, see Chapter 4.

Note

For I64 images, you can not specify an address at which you want an image mapped into virtual memory. The image activator decides where to place the image.

Figure 2-2 illustrates the interdependencies created by symbolic references among the modules that make up an application. In the figure, arrows point from a symbol reference to a symbol definition. (The statements do not reflect a specific programming language.)

Figure 2-2 Symbol Resolution


The linker creates an image, even if it cannot find a definition for every symbol referenced in the input files it processes. As shown in the following example, the linker reports these undefined symbols if at least one of the unresolved references is a strong reference. (For information about strong and weak symbolic references, see Section 2.5.) The linker includes the message in the map file, if a map file was requested.


$ LINK MY_MAIN  ! The module MY_MATH is omitted  
%ILINK-W-NUDFSYMS, 1 undefined symbol: 
(1) %ILINK-I-UDFSYM,        MYSUB 
(2) %ILINK-W-USEUNDEF, undefined symbol MYSUB referenced 
        section: $CODE$ 
        offset: %X0000000000000110  slot: 2 
        module: MY_MAIN 
        file: WORK:[PROGRAMS]MY_MAIN.OBJ;1 
 

  1. The linker issues an informational message for each symbol for which it cannot find a definition.
  2. The linker issues a warning message for each instance where an undefined symbol is referenced in the image.

If you run an image that contains undefined symbols and the symbols are never accessed, the program runs successfully. However, if you run an image that contains undefined symbols and the image accesses the symbols at run time, then the image will abort. In most cases, it aborts with an access violation because the linker assigns the value zero to undefined symbols or because the linker indicates that an undefined function symbol was called, as shown in the following example:


$ RUN MY_MAIN 
%SYSTEM-F-CALLUNDEFSYM, Call using undefined function symbol 
%TRACE-F-TRACEBACK, symbolic stack dump follows 
image     module    routine               line      rel PC           abs PC 
 
MY_MAIN                                      0 00000000000101B2 00000000000101B2 
MY_MAIN  MY_MAIN  main                    1594 0000000000000120 0000000000010120 
MY_MAIN  MY_MAIN  __main                  1586 00000000000000C0 00000000000100C0 
                                             0 FFFFFFFF80B7FB30 FFFFFFFF80B7FB30 
DCL                                          0 000000000006BD60 000000007AE25D60 
%TRACE-I-END, end of TRACE stack dump 
 

2.2 Input File Processing for Symbol Resolution

The linker can include object modules, shareable images, and libraries in its symbol resolution processing. Options files do not play an important role in symbol resolution (the SYMBOL= option can define a symbol and its value).

By default, the linker includes all the symbol definitions from the object module or shareable image. However, if you append the /SELECTIVE_SEARCH qualifier to the object module or shareable image file specification, then the linker includes in its processing only those symbols that define symbols referenced in a previously processed input file. For more information about selectively processing input files, see Section 2.2.4.

Table 2-1 summarizes how the linker processes these different types of input files when performing symbol resolution.

Table 2-1 Linker Input File Processing
Input File How Processed
Object file (.OBJ) By default, the linker processes all the symbol definitions and references listed in the GSD of the module. If you append the /SELECTIVE_SEARCH qualifier to the input file specification, the linker includes only those symbol definitions from the GSD that resolve symbolic references found in previously processed input files.
Shareable image file (.EXE) By default, the linker processes all symbol definitions listed in the GST of the image. However, the linker lists only those symbol definitions in the map file that are referenced by other modules in order to reduce map file clutter.

If you append the /SELECTIVE_SEARCH qualifier to the input file specification, the linker includes in its processing only those symbol definitions from the GST that resolve symbolic references found in previously processed input files.

Library files (.OLB) Specifying /LIBRRY, the linker searches the name table of the library for symbols that are undefined in previously-processed input files. (Usually, a library file's name table lists all the symbols available in all of the modules it contains.) If the linker finds the definition of a symbol referenced by a previously-processed input file, it includes in the link operation, the library module containing the definition of the symbol. Once the object module or shareable image is included in the link operation, the linker processes it as any other object module or shareable image.

If you append only the /INCLUDE qualifier to a library file specification, the linker does not search the library's name table to find undefined symbolic references. Instead, the linker includes the specified object module or shareable image specified as a parameter to the /INCLUDE qualifier.

You cannot process a library file selectively. However, if the Librarian utility's /SELECTIVE_SEARCH qualifier was specified when the object module or shareable image was inserted into the library, the linker processes the module selectively when it extracts it from the library.


Previous Next Contents Index