HP OpenVMS Systems Documentation

Content starts here

OpenVMS Linker Utility Manual


Previous Contents Index

3.3.6.3 Isolating a Program Section into an Image Section

You can specify that the linker place a particular program section into its own image section. This can be useful for programs that map data into predefined locations within an image.

To isolate a program section into an image section, specify the SOLITARY attribute of the program section using the PSECT_ATTR= option. For example, to isolate the GLOBAL_DATA program section in the sample link into its own image section, specify the following:


$ LINK/MAP/FULL MYTEST,MYADD,SYS$INPUT/OPT
CLUSTER=MYSUB_CLUS,,,MYSUB
PSECT_ATTR=GLOBAL_DATA,SOLITARY
[Ctrl/Z]

For Alpha linking, when mapping data into an existing location in the virtual memory of your program using the Create and Map Global Section ($CRMPSC) system service or the Map Global Section ($MGBLSC) system service, you must specify an address range (in the inadr argument) that is aligned on a CPU-specific page boundary. Because the linker aligns image sections on CPU-specific page boundaries and the program section in which the section is to be mapped is the only program section in the image section, you ensure that the start address of the location is page aligned. In addition, because Alpha systems must map at least an entire page of memory at a time, using the SOLITARY attribute allows you to ensure that no other data in the image section is inadvertently overwritten by the mapping. By default, the linker creates the next image section on the next page boundary so that no data can be overwritten.

3.4 Initializing an Image

After allocating memory for the image, the linker initializes the image by writing the binary contents of the image sections by processing text information and relocation (TIR) records in the object modules. These records direct the linker in the initialization of the image section by telling it what to store in the image section buffers. In addition, the linker inserts the addresses of symbols within the image wherever they are referenced.

3.4.1 Writing the Binary Contents of Image Sections

A TIR record contains object language commands, such as stack and store commands. Stack commands direct the linker to put information on its stack, and store commands direct the linker to write the information from its stack to the buffer for that image section.

During this image section initialization, the linker keeps track of the program section being initialized and the image section to which it has been allocated. The first attempt to initialize part of an image section by storing nonzero data causes the linker to allocate a buffer in its own program region to contain the binary contents of the generated image section. This allocation is achieved by the Expand Region ($EXPREG) system service, and it requires that the linker have available a virtually contiguous region of its own memory at least as large as the image section being initialized.

A buffer is not allocated for an image section until the linker executes a store command (with nonzero data) within that image section.

Debugger information (DBG) records and traceback information (TBT) records are processed only if the debugger was requested and traceback information was not excluded by the /NOTRACE qualifier in the LINK command. Otherwise, these records are ignored. The records contain stack and store object language commands (TIR records), but they are stored in the debugger symbol table (DST) instead of in an image section. (The linker expands its memory region to accommodate the DST, unless the /NOTRACEBACK qualifier was specified in the LINK command.)

When the linker processes end-of-module (EOM) records, it checks that its internal stack has been collapsed to its initial state. When this processing is complete, the linker has written the binary contents of all image sections to image section buffers in its own address space.

The linker writes the contents of its buffers in the following order:

  1. All image sections to the image file.
  2. The debugger symbol table to the image file, unless /NOTRACEBACK was specified in the LINK command.
  3. The remaining sections of the map to the map file, if requested in the LINK command. (These sections include all requested sections except the Object Module Synopsis, which it already wrote, and the Link Run Statistics, which it cannot write until the linking operation finishes.)
  4. The global symbol table to the image file, and also to another separate file, if requested in the LINK command.
  5. The image header to the image file.
  6. The link statistics to the map file, if requested in the LINK command.

3.4.2 Fixing Up Addresses

Executable images and based images are loaded into memory at a known location in P0 space. The linker cannot know where in memory a shareable image will be located when it is loaded into memory at run time by the image activator. Thus, the linker cannot initialize references to symbols within the shareable image from external modules or to internal symbolic references within the shareable image itself. For shareable images, the linker creates fix-ups that the image activator must resolve when it activates the images at run time.

The linker uses the fix-up image section in the following ways:

  • The fix-up image section adjusts the values stored by any .ADDRESS directives that are encountered during the creation of the nonbased shareable image. This action, together with subsequent adjustment of these values by the image activator, preserves the position independence of the shareable image.
    On Alpha systems, an error message informs you at link time that the linker is placing global symbols from shareable images in byte- or word-sized fields. The OpenVMS Alpha image header format does not allow byte or word fixups.
    Following is an example of the kind of error message the system displays:


    %LINK-E-NOFIXSYM, unable to perform WORD fixup for symbol TPU$_OPTIONS
            in psect $PLIT$ in module TEST_MODULE file USER:[ACCOUNT]TEST.OLB;1
    

    To work around the Alpha image header format restriction, move the symbolic value into a selected location at run time rather than at link time. For example, in MACRO, rather than performing .WORD TPU$_OPTIONS, use the following instruction:


    MOVW #TPU$_OPTIONS, dest
    
  • For VAX linking, the fix-up image section processes all general-address-mode code references to targets in position-independent shareable images. In this way, it creates the linkage between these code references and their targets, whose locations are not known until run time.

3.4.3 Keeping the Size of Image Files Manageable

Because neither language processors nor the linker initialize data areas in a program with zeros, leaving this task to the operating system instead, some image sections might contain uninitialized pages. To keep the size of the image file as small as possible, the linker does not write pages of zeros to disk for these uninitialized pages unless you explicitly disable this function. The linker can search image sections that contain initialized data for groups of contiguous, uninitialized pages and creates demand-zero image sections out of these pages (called demand-zero compression). Demand-zero image sections reduce the size of the image file and enhance the performance of the program. At run time, when a reference is made that initializes the section, the operating system initializes the allocated page of physical memory with zeros (hence the name "demand-zero").

The Alpha compilers identify to the linker program sections that have not been initialized by setting the NOMOD attribute of the program section. The linker groups these uninitialized program sections into a demand-zero image section.

If two modules contribute to the same program section and one contribution has the NOMOD attribute set and the other does not, the linker performs a logical AND of the NOMOD bits so that the two contributions end up in the same (non-demand-zero) image section.

Note that the linker creates demand-zero image sections only for OpenVMS VAX executable images. On OpenVMS Alpha systems, the linker can create demand-zero image sections for both executable and shareable images. Program sections with the SHR and the NOMOD attributes set are not sorted into demand-zero image sections in shareable images.

3.4.3.1 Controlling Demand-Zero Image Section Creation

When performing demand-zero compression, by default the linker searches the pages of existing image sections looking for the default minimum of contiguous, uninitialized pages. You can specify a different minimum by using the DZRO_MIN= option. For more information about the effect of this option on image size and performance, see the description of the DZRO_MIN= option in Part 2.

You can control demand-zero compression by specifying the maximum number of image sections that the linker can create using the ISD_MAX= option.


Chapter 4
Creating Shareable Images

This chapter describes how to create shareable images and how to declare universal symbols in shareable images.

4.1 Overview

To create a shareable image, specify the /SHAREABLE qualifier on the LINK command line. You can specify as input files in the link operation any of the types of input files accepted by the linker, as described in Chapter 1.

Note, however, to enable other modules to reference symbols in the shareable image, you must declare them as universal symbols. High- and mid-level languages do not provide semantics to declare universal symbols. You must declare universal symbols at link time using linker options. The linker lists all universal symbols in the global symbol table (GST) of the shareable image. The linker processes the GST of a shareable image specified as an input file in a link operation during symbol resolution. (For more information about symbol resolution, see Chapter 2.)

For VAX linking, you declare universal symbols by listing the symbols in a UNIVERSAL= option statement in a linker options file. You can create shareable images that can be modified, recompiled, and relinked without causing the images that were linked against previous versions of the shareable image to be relinked. To provide this upward compatibility, you must create a transfer vector that contains an entry for each universal symbol in the image. For more information about these topics, see Section 4.2.

For Alpha linking, you declare universal symbols by listing the symbols in a SYMBOL_VECTOR= option statement in a linker options file. You do not need to create a transfer vector to create an upwardly compatible shareable image. The symbol vector can provide upward compatibility. For more information about this topic, see Section 4.3.

The linker supports qualifiers and options that control various aspects of shareable image creation. Table 4-1 lists these qualifiers and options. (For more information about linker qualifiers and options, see Part 2.)

Table 4-1 Linker Qualifiers and Options Used to Create Shareable Images
Qualifier Description
++/GST For Alpha images, directs the linker to include universal symbols in the global symbol table (GST) of the shareable image, which is the default. When you specify the /NOGST qualifier, the linker creates an empty GST for the image. See Section 4.3.4 for more information about using this qualifier to create run-time kits. Not supported for VAX images.
/PROTECT Directs the linker to protect the shareable image from write access by user or supervisor mode.
/SHAREABLE Directs the linker to create a shareable image, when specified in the link command line. When appended to a file specification in a linker options file, this qualifier identifies the input file as a shareable image.
Option Description
GSMATCH= Sets the major and minor identification numbers in the header of the shareable image and specifies the algorithm the linker uses when comparing identification numbers.
PROTECT= When specified with the YES keyword in a linker options file, this option directs the linker to protect the clusters created by subsequent options specified in the options file. You turn off protection by specifying the PROTECT=NO option in the options file.
++SYMBOL_TABLE= For Alpha linking, when specified with the GLOBALS keyword, this option directs the linker to include in a symbol table file all the global symbols defined in the shareable image, in addition to the universal symbols. By default, the linker includes only universal symbols in a symbol table file associated with a shareable image (SYMBOL_TABLE=UNIVERSALS). Not supported for VAX linking.
++SYMBOL_VECTOR= For Alpha linking, specifies symbols in the shareable image that you want declared as universal. Not supported for VAX linking.
+UNIVERSAL= For VAX linking, specifies symbols in the shareable image that you want declared as universal. Not supported for Alpha linking.

++Alpha specific
+VAX specific

4.2 Declaring Universal Symbols in VAX Shareable Images

For VAX linking, you declare universal symbols by specifying the UNIVERSAL= option in an options file. List the symbol or symbols you want to be universal as an argument to the option. The symbols listed in a UNIVERSAL= option can represent procedures, relocatable data, or constants. For each symbol declared as universal, the linker creates an entry in the global symbol table (GST) of the image. At link time, when the linker performs symbol resolution, it processes the symbols listed in the GSTs of the shareable images included in the link operation.

To illustrate how to declare universal symbols, consider the programs in the following examples.

Example 4-1 Shareable Image Test Module: my_main.c

#include <stdio.h>

extern int my_data;

globalref int my_symbol;

int mysub();

main()
{
   int num1, num2, result;

   num1 = 5;
   num2 = 6;

   result = mysub( num1, num2 );
   printf("Result= %d\n", result);
   printf("Data implemented as overlaid psect= %d\n", my_data);
   printf("Global reference data is= %d\n", my_symbol);
}

Example 4-2 Shareable Image: my_math.c

int my_data = 5;

globaldef int my_symbol = 10;

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 );
}
mydiv( 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 );
}

To implement Example 4-2 as a shareable image, you must declare the universal symbols in the image by using the following LINK command:


$ LINK/SHAREABLE MY_MATH, SYS$INPUT/OPT
PSECT_ATTR=my_data,NOSHR
UNIVERSAL=myadd
UNIVERSAL=mysub
UNIVERSAL=mymul
UNIVERSAL=mydiv
UNIVERSAL=my_symbol
[Ctrl/Z]

Note that the symbol my_data in Example 4-2 does not have to be declared universal because of the way in which VAX C implements it. Several Compaq programming languages, including VAX C and Compaq Fortran for OpenVMS VAX, implement certain external variables as program sections with the overlaid (OVR), global (GBL), and relocatable (REL) attributes. When the linker processes these object modules, it overlays the program sections so that the various object modules that reference the variable access the same virtual memory. Symbols implemented in this way are declared universal (appear in the GST of the image) by default.

In the sample link operation, the SHR attribute of the program section that implements the data symbol my_data is reset to NOSHR. If you do not reset the shareable attribute for program sections that are writable, you must install the shareable image to run the program. (The shareable attribute [SHR] determines whether multiple processes have shared access to the memory.)

The following example illustrates how to link the object module MY_MAIN.OBJ with the shareable image MY_MATH.EXE. Note that the LINK command sets the shareability attribute of the program section my_data to NOSHR, as in the link operation in which the shareable was created.


$ LINK  MY_MAIN, SYS$INPUT/OPT
MY_MATH/SHAREABLE
PSECT_ATTR=my_data,NOSHR
[Ctrl/Z]

4.2.1 Creating Upwardly Compatible Shareable Images (VAX Linking Only)

For VAX linking, you can create a shareable image that can be modified, recompiled, and relinked without causing the images that were linked against previous versions of the image to be relinked. To provide this upward compatibility, you must ensure that the values of relocatable universal symbols within the image remain constant with each relinking.

Universal Symbols that Represent Procedures

To fix the locations of universal symbols that represent procedures in a shareable image, create a transfer vector for the shareable image. In a transfer vector, you create small routines in VAX MACRO that define an entry point in the image and then transfer control to another location in memory. You declare the entry points defined in the transfer vector as the universal symbols and have each routine transfer control to the actual location of the procedures within the shareable image. As long as you ensure that the location of the transfer vector remains the same with each relinking, images that linked with previous versions of the shareable image will access the procedures at the locations they expect.

Figure 4-1 illustrates the flow of control at run time between a main image and a shareable image in which the actual routines are declared as universal symbols (as shown in Section 4.2) and between a main image and a shareable image in which the transfer vector entry points are declared as universal symbols (as shown in Section 4.2.1.1).

Figure 4-1 Comparison of UNIVERSAL = Option and Transfer Vectors


Universal Symbols that Represent Data

To provide upwardly compatible symbols that represent data locations, you must also fix these locations within memory. You can accomplish this by allocating the data symbols at the end of the transfer vector file. In this way, when you fix the location of the transfer vector within an image, the data locations also remain the same. (This is described in the next section.)

4.2.1.1 Creating a Transfer Vector (VAX Linking Only)

You create a transfer vector using VAX MACRO. Specify the .TRANSFER directive because it declares the symbol that you specify as its argument as a universal symbol by default. Compaq recommends the following coding conventions for creating a transfer vector:


(1) .transfer    FOO       ;Begin transfer vector to FOO
(2) .mask        FOO       ;Store register save mask
(3) jmp          L^FOO+2   ;Jump to routine
  1. The .TRANSFER directive causes the symbol, named FOO in the example, to be added to the shareable image's global symbol table. (You do not need to also specify the symbol in a UNIVERSAL= statement in a linker options file.)
  2. The .MASK directive causes the assembler to allocate 2 bytes of memory, find the register save mask accompanying the entry point ( FOO in the example), and store the register save mask of the procedure. (According to the OpenVMS calling standard, procedure calls using the CALLS or CALLG instructions include a word, called the register save mask, whose bits represent which registers must be preserved by the routine.)
  3. The JMP instruction transfers control to the address specified as its argument. In the example, this address is two bytes past the routine entry point FOO (the first two bytes of the routine are the register save mask).
    Compaq recommends that you use a jump instruction (for example, JMP L^) in the transfer vector. Transfering control with a BSBW or JSB instruction results in saving the address of the next instruction from the transfer vector on the stack. In addition, the displacement used by the BSBW instruction must be expressible in 16 bits, which may not be sufficient to reach the target routine. Also, to avoid making the image position dependent, do not use an absolute mode instruction.

Note that the preceding convention assumes that the routine is called using the procedure call format, the default for most high-level language compilers. If a routine is called as a subroutine, using the JSB instruction, you do not need to include the .MASK directive. When creating a transfer vector for a subroutine call, Compaq recommends adding bytes of padding to the transfer vectors. This padding makes a subroutine transfer vector the same size as a transfer vector for a procedure call. If you need to replace a subroutine transfer vector with a procedure call transfer vector, you can make the replacement without disturbing the addresses of all the succeeding transfer vectors.

The following example illustrates a subroutine transfer vector that uses the .BLKB directive to allocate the padding:


.TRANSFER    FOO      ;Begin transfer vector to FOO
JMP          L^FOO    ;Jump to routine
.BLKB        2        ;Pad vector to 8 bytes

To ensure upward compatibility, follow these guidelines when creating a transfer vector:

  • Preserve the order and placement of entries in a transfer vector. Once you establish the order in which entries appear in a transfer vector, do not change it. Images that were linked against the shareable image depend on the location of the symbol in the transfer vector.
    You can reserve space within a transfer vector for future growth by specifying dummy transfer vector entries at various positions in a transfer vector.
  • Add new entries to the end of a transfer vector. When including universal data in a transfer vector file, use padding to leave adequate room for future growth between the end of the transfer vector and the beginning of the list of universal data declarations.

A transfer vector for the program in Example 4-2 is illustrated in Example 4-3.

Example 4-3 Transfer Vector for the Shareable Image MY_MATH.EXE

.transfer myadd
.mask  myadd
jmp  l^myadd+2
.transfer mysub
.mask  mysub
jmp  l^mysub+2
.transfer mymul
.mask  mymul
jmp  l^mymul+2
.transfer mydiv
.mask  mydiv
jmp  l^mydiv+2
.end

Assemble the transfer vector file to create an object module that can be included in a link operation:


$ MACRO MY_MATH_TRANS_VEC.MAR


Previous Next Contents Index