HP OpenVMS Systems Documentation

Content starts here

OpenVMS Programming Concepts Manual

Previous Contents Index

25.6 Example

The VAX Linker uses the cross-reference routines to generate cross-reference listings. This section uses the linker's code as an example of using the cross-reference routines in a MACRO program.

25.6.1 Defining Control Tables

Cross-reference routines use two control tables:

  • The symbol-by-name table
  • The symbol-by-value table

First, the linker uses the $CRFCTLTABLE macro to set up the characteristics and fields of the symbol-by-name table. This table will list symbols by name and provide a cross-reference synopsis. The table is set up as follows:

LNK$NAMTAB Names the address of the control table
KEYTYPE=ASCIC Specifies that the keys are counted ASCII strings (that is, symbol names)
ERROR=LNK$ERR_RTN Indicates that LNK$ERR_RTN is the address of the routine to be executed in case of error
OUTPUT=LNK$MAPOUT Names LNK$MAPOUT as the address of the user-supplied routine that prints the formatted table

The remaining arguments provide the addresses of the field descriptor tables.

After setting up the control tables, the linker defines each field of the cross-reference output line, using the $CRFFIELD macro. After each set of definitions for a field, it calls $CRFFIELDEND to mark the end of the field.

Note particularly the following two features of this set of definitions:

  • The definition of LNK$VAL2 describes a flag to be associated with VAL1. The definition contains alternative bit patterns, depending on the bit mask. When an entry is made to the table, the entry contains flag information. Then, when LIB$CRF_OUTPUT is called to format the data, the routine checks each entry, matching the flags argument against the bit masks specified in the control table. When LIB$CRF_OUTPUT finds a match, it uses that definition to determine the format of the entry in the output table. For example, BIT_MASK=SYM$M_DEF marks an entry as the defining reference. The corresponding VAL1 entry is placed in the output table with an asterisk in its flags field.
  • The FAO control strings are defined to produce an output of the maximum character size for each field. This ensures that the columns will line up correctly in the output. For example, !15AC produces the variable symbol name left-aligned and right-filled with spaces. Another example is the three sets of characters to be printed for field VAL2. Each FAO control string produces two characters, which is the maximum size of the field.

            $CRFFIELD      BIT_MASK=0, FAO_STRING=\!15AC\,-
            $CRFFIELD      BIT_MASK=0,FAO_STRING=\ \,-
                           SET_CLEAR=SET, FIELD_WIDTH=1

            $CRFFIELD      BIT_MASK=0,FAO_STRING=\!XL\,-
            $CRFFIELD      BIT_MASK=0, FAO_STRING=\!2*  \,-
            $CRFFIELD      BIT_MASK=SYM$M_DEF, FAO_STRING=\-*\,-
            $CRFFIELD      BIT_MASK=0,FAO_STRING=\!6* \,-
            $CRFFIELD      BIT_MASK=SYM$M_WEAK,FAO_STRING=\!3* WK-\,-

            $CRFFIELD      BIT_MASK=0,FAO_STRING=\!16AC\,-

After initializing the symbol-by-name table, the linker sets up a second control table. This table defines the output for a symbol-by-value synopsis. For this output, the value fields are eliminated. The symbols having this value are entered as reference indicators. None is specified as the defining reference. The control table uses the field descriptors set up previously. The following macro instructions are used:


25.6.2 Inserting Table Information

After initializing the format data for the symbol tables, the linker enters data into the cross-reference tables by calling LIB$CRF_INS_KEY.

As the linker processes the first object module, MAPINITIAL, it encounters a symbol definition for $MAPFLG. The following is an example of a call to enter the symbol MAPINITIAL as a key in the cross-reference symbol table:

        CALLS     #4,G^LIB$CRF_INS_KEY
LNK$NAMTAB Is the address of the control table
SYMBOL_ADDR Is the address of the counted ASCII string $MAPFLG
VALUE_ADDR Is the address of the symbol value
VALUE_FLAGS Is the address of a word whose bits are used to select special characters to print beside the value

The linker then calls LIB$CRF_INS_REF to process the defining reference indicator:

        PUSHAB    DEF
        PUSHAB    REF_ADDR
        CALLS     #5,G^LIB$CRF_INS_REF
LNK$NAMTAB Is the address of the control table
SYMBOL_ADDR Is the address of the counted string $MAPFLG
REF_ADDR Is the address of the referrer's counted ASCII string
REF_FLAGS Is the address of a word whose bits are used to select special characters to print beside the reference

Further on in the input module, the linker encounters a global symbol reference to CS$GBL. The call to store data for this reference is as follows:

REF:      .LONG     CRF$K_REF
          PUSHAB    REF
          PUSHAB    REF_FLAGS
          PUSHAB    REF_ADDR
          PUSHAB    LNK$NAMTAB
          CALLS     #5,G^LIB$CRF_INS_REF

The arguments are similar to the previous example, except for CRF$K_REF, which indicates that this is not the defining reference.

After it has performed symbol relocation for the module being linked, the linker calls LIB$CRF_INS_REF to build a table ordered by value.

        PUSHAB    REF
        PUSHAB    REF_ADDR
        PUSHAB    VAL_ADDR
        CALLS     #5,G^LIB$CRF_INS_REF
LNK$VALTAB Is the address of the control table for the symbol synopsis by value
VAL_ADDR Is the address of the value (binary longword key)
REF_ADDR Is the address of the symbol name having the value contained in VAL_ADDR
REF_FLAGS Is the address of a word whose bits are used to select special characters to print beside the value
CRF$K_REF Is the indicator that this is not a defining reference

25.6.3 Formatting Information for Output

After all input modules are processed, the linker requests the information for the map. It calls LIB$CRF_OUTPUT once for each type of output. The following MACRO example illustrates a call to list the symbols and their values. Three calls are illustrated here.

LNWID:  .LONG   132
        PUSHAB  VAL
        PUSHAB  SAVE
        PUSHAB  LNSP1

In this example, CRF$K_VALUES means that no reference indicators are to be printed, while CRF$K_SAVE means that the cross-reference table is to be saved. It is also possible to list all cross-reference data. The type of output produced by this call is shown in Section 25.5, Figure 25-2.

The following call produces such a summary and releases the storage at the same time:

LNWID:  .LONG   132
        PUSHAB  LNSP1

The type of output produced by this call is shown in Section 25.5, Figure 25-4.

CRF$K_DEFS_REFS indicates that the first two reference fields are used for the defining references, and CRF$K_DELETE indicates that the table is deleted.

Another call is made to list the symbol by value synopsis, as follows:

LNWID:      .LONG     132
            PUSHAB    DELETE
            PUSHAB    VALREF
            PUSHAB    LNSOP
            PUSHAB    LNSP1
            PUSHAB    LNWID
            PUSHAB    LNK$VALTAB
            CALLS     #6,G^LIB$CRF_OUTPUT

This is similar to the previous call in that it produces a complete cross-reference output by value, but it does not have the defining reference fields.

25.7 How to Link to the Cross-Reference Shareable Image

The cross-reference routines are located in a shareable image CRFSHR.EXE. This shareable image is part of the default system shareable image library, SYS$LIBRARY:IMAGELIB.OLB. For this reason, the cross-reference routines are automatically included in your image, unless you specify /NOSYSHR in the LINK command. If you have specified /NOSYSHR and you want to include CRFSHR.EXE, your LINK command must include the following:


Chapter 26
Shareable Resources

This chapter describes the techniques available for sharing data and program code among programs. It contains the following sections:

Section 26.1 describes how to share code among programs.

Section 26.2 describes shareable images.

Section 26.3 defines and describes how to use local and global symbols to share images.

The operating system provides the following techniques for sharing data and program code among programs:

  • DCL symbols and logical names
  • Libraries
  • Shareable images
  • Global sections
  • Common blocks installed in a shareable image
  • OpenVMS Record Management Services (RMS) shared files

Symbols and logical names are also used for intraprocess and interprocess communication; therefore, they are discussed in Chapter 32.

Libraries and shareable images are used for sharing program code.

Global sections, common blocks stored in shareable images, and RMS shared files are used for sharing data. You can also use common blocks for interprocess communication. For more information, refer to Chapter 3.

26.1 Sharing Program Code

To share code among programs, you can use the following operating system resources:

  • Text, macro, or object libraries that store sections of code. Text and macro libraries store source code; object libraries store object code. You can create and manage libraries using the Librarian utility (LIBRARIAN). Refer to the OpenVMS Command Definition, Librarian, and Message Utilities Manual for complete information about using the Librarian utility.
  • Shareable images, which are images that have been compiled and linked but cannot be run independently. These images can also be stored in libraries.

26.1.1 Object Libraries

You can use object libraries to store frequently used routines, thereby avoiding repeated recompiling, which allows you to minimize the number of files you must maintain, and simplify the linking process. The source code for the object modules can be in any VAX supported language, and the object modules can be linked with any other modules written in any VAX supported language.

Use the .OLB file extension for any object library. All modules stored in an object library must have the file extension .OBJ. System- and User-Defined Default Object Libraries

The operating system provides a default system object library, STARLET.OLB. You can also define one or more default object libraries to be automatically searched before the system object library. The logical names for the default object libraries are LNK$LIBRARY and LNK$LIBRARY_1 through LNK$LIBRARY_999. To use one of these default libraries, first define the logical name. The libraries are searched sequentially starting at LNK$LIBRARY. Do not skip any numbers. If you store object modules in the default libraries, you do not have to specify them at link time. However, you do have to maintain and manage them as you would any library.

The following example defines the library in the file PROCEDURES.OLB (the file type defaults to .OLB, meaning object library) in $DISK1:[DEV] as a default user library:

$ DEFINE LNK$LIBRARY $DISK1:[DEV]PROCEDURES How the Linker Searches Libraries

When the linker is resolving global symbol references, it searches user default libraries at the process level first, then libraries at the group and system level. Within levels, the library defined as LNK$LIBRARY is searched first, then LNK$LIBRARY_1, LNK$LIBRARY_2, and so on. Creating an Object Library

To create an object library, invoke the Librarian utility by entering the LIBRARY command with the /CREATE qualifier and the name you are assigning the library. The following example creates a library in a file named INCOME.OLB (.OLB is the default file type):

$ LIBRARY/CREATE INCOME Managing an Object Library

To add or replace modules in a library, enter the LIBRARY command with the /REPLACE qualifier followed by the name of the library (first parameter) and the names of the files containing the (second parameter). After you put object modules in a library, you can delete the object file. The following example adds or replaces the modules from the object file named GETSTATS.OBJ to the object library named INCOME.OLB and then deletes the object file:


You can examine the contents of an object library with the /LIST qualifier. Use the /ONLY qualifier to limit the display. The following command displays all the modules in INCOME.OLB that start with GET:


Use the /DELETE qualifier to delete a library module and the /EXTRACT qualifier to recreate an object file. If you delete many modules, you should also compress (/COMPRESS qualifier) and purge (PURGE command) the library. Note that the /ONLY, /DELETE, and /EXTRACT qualifiers require the names of modules---not file names---and that the names are specified as qualifier values, not parameter values.

26.1.2 Text and Macro Libraries

Any frequently used routine can be stored in libraries as source code. Then, when you need the routine, it can be called in from your source program.

Source code modules are stored in text libraries. The file extension for a text library is .TLB.

When using VAX MACRO assembly language, any source code module can be stored in a macro library. The file extension for a macro library is .MLB. Any source code module stored in a macro library must have the file extension .MAR.

You also use LIBRARIAN to create and manage text and macro libraries. Refer to Section and Section for a summary of LIBRARIAN commands.

26.2 Shareable Images

A shareable image is a nonexecutable image that can be linked with executable images. If you have a program unit that is invoked by more than one program, linking it as a shareable image provides the following benefits:

  • Saves disk space---The executable images to which the shareable image is linked do not physically include the shareable image. Only one copy of the shareable image exists.
  • Simplifies maintenance---If you use transfer vectors and the GSMATCH (on VAX systems) or symbol vectors (on Alpha systems) option, you can modify, recompile, and relink a shareable image without having to relink any executable image that is linked with it.

Shareable images can also save memory, provided that they are installed as shared images. See the OpenVMS Linker Utility Manual for more information about creating shareable images and shareable image libraries.

26.3 Symbols

Symbols are names that represent locations (addresses) in virtual memory. More precisely, a symbol's value is the address of the first, or low-order, byte of a defined area of virtual memory, while the characteristics of the defined area provide the number of bytes referred to. For example, if you define TOTAL_HOUSES as an integer, the symbol TOTAL_HOUSES is assigned the address of the low-order byte of a 4-byte area in virtual memory. Some system components (for example, the debugger) permit you to refer to areas of virtual memory by their actual addresses, but symbolic references are always recommended.

26.3.1 Defining Symbols

A symbolic name can consist of up to 31 letters, digits, underscores (_), and dollar signs ($). Uppercase and lowercase letters are equivalent. By convention, dollar signs are restricted to symbols used in system components. (If you do not use the dollar sign in your symbolic names, you will never accidentally duplicate a system-defined symbol.)

26.3.2 Local and Global Symbols

Symbols are either local or global in scope. A local symbol can only be referenced within the program unit in which it is defined. Local symbol names must be unique among all other local symbols within the program unit but not within other program units in the program. References to local symbols are resolved at compile time.

A global symbol can be referenced outside the program unit in which it is defined. Global symbol names must be unique among all other global symbols within the program. References to global symbols are not resolved until link time.

References to global symbols in the executable portion of a program unit are usually invocations of subprograms. If you reference a global symbol in any other capacity (as an argument or data value---see the following paragraph), you must define the symbol as external or intrinsic in the definition portion of the program unit.

System facilities, such as the Message utility and the VAX MACRO assembler, use global symbols to define data values.

The following program segment shows how to define and reference a global symbol, RMS$_EOF (a condition code that may be returned by LIB$GET_INPUT):

2                       'New text: ',
2                       NT_SIZ)

26.3.3 Resolving Global Symbols

References to global symbols are resolved by including the module that defines the symbol in the link operation. When the linker encounters a global symbol, it uses the following search method to find the defining module:

  1. Explicitly named modules and libraries---Generally used to resolve user-defined global symbols, such as subprogram names and condition codes. These modules and libraries are searched in the order in which they are specified.
  2. System default libraries---Generally used to resolve system-defined global symbols, such as procedure names and condition codes.
  3. User default libraries---Generally used to avoid explicitly naming libraries, thereby simplifying linking.

If the linker cannot find the symbol, the symbol is said to be unresolved and a warning results. You can run an image containing unresolved symbols. The image runs successfully as long as it does not access any unresolved symbol. For example, if your code calls a subroutine but the subroutine call is not executed, the image runs successfully.

If an image accesses an unresolved global symbol, results are unpredictable. Usually the image fails with an access violation (attempting to access a physical memory location outside those assigned to the program's virtual memory addresses).

Previous Next Contents Index