Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Linker Utility Manual


Previous Contents Index

1.6 Linking for Different Architectures

It is possible to create OpenVMS Alpha images on an OpenVMS VAX system and to 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.

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:


Chapter 2
Understanding Symbol Resolution

As one of its primary tasks, the linker must resolve symbolic references between modules. This chapter describes how the linker performs symbol resolution and how you can control it 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 a global symbol directory (GSD) in an object module that lists all of the global symbol references and global symbol definitions it contains.

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 global symbol table (GST) of the shareable image and are available to external modules to link against.

Language processors determine whether a symbol is local or global. For example, in VAX FORTRAN, statement numbers are local symbols and module entry points are global symbols. In other languages, you can explicitly specify whether a symbol is local or global by including or excluding particular attributes in the symbol definition. Note also that some languages allow you to specify symbols as weak or strong (see Section 2.5 for more information).

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.

Note

In some Digital programming languages, certain types of global symbols, such as external variables in C and COMMON data in FORTRAN, are not listed in the GSD as global symbol references or definitions. Because these data types implement virtual memory that is shared, the languages implement them as program sections that are overlaid. These symbols appear as program section definitions in the GSD, not as a symbol definition or reference. (Compilers use program sections to define the memory requirements of an object module.) The linker does not include program section definitions in its symbol resolution processing. For information about how the linker processes program sections, see Chapter 3.

On VAX systems, the VAX C language extensions globalref and globaldef allow you to create external variables that appear as symbol references and definitions in the GSD. For more information, see the VAX C documentation.

On Alpha systems, the DEC C compiler supports the globalref and globaldef language extensions. In addition, DEC C supports command line qualifiers and source code pragma statements that allow you to control whether it implements external variables as program sections or as global symbol references and definitions. For more information, see the DEC C documentation.

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 GSD of each object module and all the universal symbols defined and referenced in the GST of each shareable image. 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.

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, X = 10). In this case, the value of the symbol is its actual value (in the example, the value of X is 10).

For symbols that represent addresses in object modules, the value is expressed initially as an offset into a program section. This is how language processors express addresses. Later in its processing, when the linker combines the program sections contributed by all the object modules into the image sections that define the virtual memory layout of the image, it determines the actual value of the address. (For information about how the linker determines the virtual memory layout of an image, see Chapter 3.)

For symbols that represent addresses in a shareable image, the value of the symbol at link time is architecture specific.

For Alpha images, at link time, the value of a symbol in a shareable image (as listed in the GST of the image) is the offset of the symbol's entry in the symbol vector of the image. A symbol vector entry is a pair of quadwords that contain information about the symbol. The contents of these quadwords depend 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. Note that, 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.

For VAX images, at link time, the value of a symbol in a shareable image (as listed in the GST of the image) is the offset into the image of the routine or data location, if the symbol was declared universal using the UNIVERSAL= option. If the symbol was declared universal using a transfer vector, the value of the symbol is the offset into the image of the transfer vector entry. If the symbol represents a constant, the GST contains the actual value of the constant.

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 relocates all the address references 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. Previously, 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 section it creates for the image. (For more information about shareable images, see Chapter 4.)

For VAX images, you can specify the address at which you want a shareable image loaded into memory by using the BASE= option. When you specify this option, the linker can calculate the absolute addresses of symbols within the shareable image because the base address of the shareable image is known. By specifying a base address, you eliminate the need for the image activator to perform fix-ups and relocations.

Note, however, that basing a shareable image can potentially destroy upward compatibility between the shareable image and other images that were linked against it.

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. The linker reports these undefined symbols as in the following example, if at least one of these 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 
%LINK-W-NUDFSYMS, 1 undefined symbols: 
(1) %LINK-I-UDFSYM,         MYSUB 
(2) %LINK-W-USEUNDEF, undefined symbol MYSUB referenced 
        in psect $CODE offset %X0000001A 
        in 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 will run successfully. If you run an image that contains undefined symbols and the image accesses the symbols at run time, the image will abort, in most cases, with an access violation because the linker assigns the value zero to undefined symbols, as in the following example:


$ run my_main
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=00000000, 
PC=00001018, PSL=03C00000 
%TRACE-F-TRACEBACK, symbolic stack dump follows 
module name     routine name                 line   rel PC    abs PC 
 
MY_MAIN          main                          15   00000018  00001018 

2.2 Input File Processing for Symbol Resolution

The linker can include object modules, shareable images, and libraries in its symbol resolution processing. For VAX images, the linker can also include a symbol table file in its symbol resolution processing. (Options files, in which linker options and input files are specified, are not included in symbol resolution.)

By default, when the linker processes an object module or shareable image, it includes all the symbol definitions from the object module or shareable image in its processing. However, if you append the /SELECTIVE_SEARCH qualifier to the object module or shareable image file specification, the linker includes in its processing only those symbols from the object module or shareable image 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. The following sections provide more detail on the linker's processing of each type of input file.

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 in its processing 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 and references listed in the GST of the image. Note, however, to avoid cluttering the map file of the resultant image, the linker lists only those symbol definitions in the map file that are referenced by other modules.

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.

+Symbol table file (.STB) By default, the linker processes all the symbol definitions and references in the GSD of the module. If you append the /SELECTIVE_SEARCH qualifier to the input file specification, the linker includes in its processing only those symbol definitions from the module that resolve symbolic references found in previously processed input files.
Library files (.OLB) The linker searches the name table of the library for symbols that are undefined in previously processed input files. (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 module in the library that contains 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 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 simply 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 will process the module selectively when it extracts it from the library.


+VAX specific

2.2.1 Processing Object Modules

The way the linker processes object modules to resolve symbolic references illustrates how the linker processes most other input files. (Symbol table files are object modules. The GST of a shareable image, which the linker processes in symbol resolution, is also created as an object module appended to the shareable image.)

For example, the program in Example 2-1 references the symbol mysub.

Example 2-1 Module Containing a Symbolic Reference: my_main.c

#include <stdio.h> 
 
int mysub(); 
 
main() 
{ 
   int num1, num2, result; 
 
   num1 = 5; 
   num2 = 6; 
   result = 0; 
 
   result = mysub( num1, num2 ); 
   printf("Result is: %d\n", result); 
} 

Mysub, which Example 2-1 references, is defined in the program in Example 2-2.

Example 2-2 Module Containing a Symbol Definition: my_math.c

myadd(value_1,value_2) 
   int value_1; 
   int value_2; 
{ 
   int result; 
 
   result = value_1 + value_2; 
   
   return( result) 
} 
 
mysub(value_1,value_2) 
   int value_1; 
   int value_2; 
{ 
   int result; 
 
   result = value_1 - value_2; 
   
   return( result) 
} 
 
mymul(value_1,value_2) 
   int value_1; 
   int value_2; 
{ 
   int result; 
 
   result = value_1 * value_2; 
   
   return( result) 
} 
 
mydiv(value_1,value_2) 
   int value_1; 
   int value_2; 
{ 
   int result; 
 
   result = value_1 / value_2; 
   
   return( result) 
} 

The GSD created by the language processor for the object module MY_MAIN.OBJ lists the reference to the symbol mysub. Because object modules cannot be examined using a text editor, the following representation of the GSD is taken from the output of the ANALYZE/OBJECT utility. The example is from the analysis of an OpenVMS Alpha object module. Differences between the format of the symbol reference between VAX object files and Alpha object files are highlighted in the list following the example.


4.  GLOBAL SYMBOL DIRECTORY (EOBJ$C_GSD) (1), 344 bytes 
               .
               .
               .
        9)  Global Symbol Specification (EGSD$C_SYM) (2)
                data type: DSC$K_DTYPE_Z (0) 
                symbol flags: 
                        (0)  EGSY$V_WEAK      0 
                        (1)  EGSY$V_DEF       0 
                        (2)  EGSY$V_UNI       0 
                        (3)  EGSY$V_REL       0 
                        (4)  EGSY$V_COMM      0 
                        (5)  EGSY$V_VECEP     0 (3)
                        (6)  EGSY$V_NORM      0 (4)
                symbol: "MYSUB" 

  1. For VAX object files, the symbol for the global symbol directory is OBJ$C_GSD.
  2. For VAX object files, the symbol for a global symbol specification is GSD$C_SYM.
  3. For VAX object files, this field is not included.
  4. For VAX object files, this field is not included. For Alpha object files, the value of this field is always zero for symbolic references.

The GSD created by the language processor for the object module MY_MATH.OBJ contains the definition of the symbol mysub, as well as the other symbols defined in the module. The definition of the symbol includes the value of the symbol.

The following excerpt from an analysis of the OpenVMS Alpha object module (performed using the ANALYZE/OBJECT utility) shows the format of a GSD symbol definition entry. Note that, in an OpenVMS Alpha object module, a symbol definition is listed as a Global Symbol Specification.


4.  GLOBAL SYMBOL DIRECTORY (EOBJ$C_GSD), 46 bytes 
        .
        .
        .
        9)  Global Symbol Specification (EGSD$C_SYM) 
                data type: DSC$K_DTYPE_Z (0) 
                symbol flags: 
                        (0)  EGSY$V_WEAK      0 
                        (1)  EGSY$V_DEF       1 
                        (2)  EGSY$V_UNI       0 
                        (3)  EGSY$V_REL       1 
                        (4)  EGSY$V_COMM      0 
                        (5)  EGSY$V_VECEP     0 
                        (6)  EGSY$V_NORM      1 (1)
           (2)   psect: 3 
           (3)   value: 64 (%X'00000040') 
           (4)   code address psect: 5 
           (5)   code address: 8 (%X'00000008') 
                symbol: "MYSUB" 
         .
         .
         .

  1. The value of the EGSY$V_NORM flag is 1 if the symbol represents a procedure. The value is set to zero if the symbol represents data.
  2. The index of the program section that contains the procedure descriptor for mysub.
  3. The location of the procedure descriptor expressed as the offset from the starting address of the program section that contains the procedure descriptor.
  4. Index of program section that contains the code entry point.
  5. The location of the code entry point, expressed as the offset from the starting address of the program section that contains the entry point.

The following excerpt from an analysis of the OpenVMS VAX object module (performed using the ANALYZE/OBJECT utility) shows the format of a GSD symbol definition entry. Note that, on VAX systems, a symbol definition is listed as an Entry Point Symbol and Mask Definition record.


4.  GLOBAL SYMBOL DIRECTORY (OBJ$C_GSD), 46 bytes 
        .
        .
        .
        2)  Entry Point Symbol and Mask Definition (GSD$C_EPM) 
                data type: DSC$K_DTYPE_Z (0) 
                symbol flags: 
                        (0)  GSY$V_WEAK       0 
                        (1)  GSY$V_DEF        1 
                        (2)  GSY$V_UNI        0 
                        (3)  GSY$V_REL        1 
                        (4)  GSY$V_COMM       0 
                psect: 0 
                value: 0 (%X'0000000C') 
                entry mask: <> 
                symbol: "MYSUB" 
        .
        .
        .

The value of the symbol is expressed as an offset into a program section.

When you link the modules shown in Example 2-1 and Example 2-2 together to create an image, you specify both object modules on the command line, as in the following example:


$ LINK MY_MAIN, MY_MATH 

When the linker processes these object modules, it reads the contents of the GSDs, obtaining the value of the symbol from the symbol definition.

Note that, for Alpha images, in the map file associated with the image, the value of the symbol mysub is the location within the image of the procedure descriptor for the routine. The procedure descriptor contains the address of the routine within the image.

For VAX images, the value of the symbol mysub is represented in the map file as the location of the entry point mask.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
4548PRO_003.HTML