[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP OpenVMS Linker Utility Manual


Previous Contents Index

  1. Linker created segments which can not be controlled by the user, see Section 3.4.3.
  2. UNWIND is not a segment attribute and is therefore printed in brackets. Marking the unwind segment here, helps to differentiate this segment from segments into which other sections are collected.

For more information about the image segment synopsis section of a map file, see Chapter 5.

To find out which sections the linker placed in each segment, look at the Program Section Synopsis section of the map file. This section lists all the sections in each cluster and lists the contributions (the number of bytes) to each section from each object module. By comparing the base address of the sections with the base address of the segments in the Image Segment Synopsis section, you can tell in which segment the sections appear. Example 3-7 is an excerpt from the Program Section Synopsis section of the map file produced by the sample link operation (Example 3-5).

Example 3-7 Section Information in a Map File



                               +--------------------------+
                               ! Program Section Synopsis !
                               +--------------------------+

Psect Name Module/Image   Base     End       Length            Attributes (1)
---------- ------------   ----     ---       ------            ----------

GLOBAL_DATA             00010000 00010003 00000004 (   4.) NOEXE,  WRT
           MYSUB        00010000 00010003 00000004 (   4.) Initializing Contribution

SUB_DATA                00010010 00010013 00000004 (   4.) NOEXE,  WRT
           MYSUB        00010010 00010013 00000004 (   4.) Initializing Contribution

$CODE$                  00020000 0002008F 00000090 ( 144.)   EXE,NOWRT
           MYSUB        00020000 0002006F 00000070 ( 112.)
           <Linker>     00020070 0002008F 00000020 (  32.)

$LITERAL$               00030000 0003000C 0000000D (  13.) NOEXE,NOWRT
           MYSUB        00030000 0003000C 0000000D (  13.)

$LINKER UNWIND$         00040000 00040017 00000018 (  24.) NOEXE,NOWRT
           MYSUB        00040000 00040017 00000018 (  24.)

$LINKER UNWINFO$        00040018 0004002F 00000018 (  24.) NOEXE,NOWRT
           MYSUB        00040018 0004002F 00000018 (  24.)

ADD_DATA                00050000 00050003 00000004 (   4.) NOEXE,  WRT
           MYADD        00050000 00050003 00000004 (   4.) Initializing Contribution

$CODE$                  00060000 000602CF 000002D0 ( 720.)   EXE,NOWRT
           MYTEST       00060000 000601BF 000001C0 ( 448.)
           MYADD        000601C0 0006022F 00000070 ( 112.)
           <Linker>     00060230 000602CF 000000A0 ( 160.)

$LITERAL$               00070000 0007003C 0000003D (  61.) NOEXE,NOWRT
           MYTEST       00070000 00070027 00000028 (  40.)
           MYADD        00070030 0007003C 0000000D (  13.)

$LINKER UNWIND$         00080000 00080047 00000048 (  72.) NOEXE,NOWRT
           MYTEST       00080000 0008002F 00000030 (  48.)
           MYADD        00080030 00080047 00000018 (  24.)

$LINKER UNWINFO$        00080048 000800A7 00000060 (  96.) NOEXE,NOWRT
           MYADD        000601C0 0006022F 00000070 ( 112.)
           <Linker>     00060230 000602CF 000000A0 ( 160.)

$LITERAL$               00070000 0007003C 0000003D (  61.) NOEXE,NOWRT
           MYTEST       00070000 00070027 00000028 (  40.)
           MYADD        00070030 0007003C 0000000D (  13.)

$LINKER UNWIND$         00080000 00080047 00000048 (  72.) NOEXE,NOWRT
           MYTEST       00080000 0008002F 00000030 (  48.)
           MYADD        00080030 00080047 00000018 (  24.)

$LINKER UNWINFO$        00080048 000800A7 00000060 (  96.) NOEXE,NOWRT
           MYTEST       00080048 0008008F 00000048 (  72.)
           MYADD        00080090 000800A7 00000018 (  24.)

$LINKER SDATA$          00090000 000900B7 000000B8 ( 184.) NOEXE,NOWRT,SHORT
           <Linker>     00090000 000900B7 000000B8 ( 184.)

  1. To fit on a page, the attribute column of the Program Section Synopsis is reduced to show only the attributes listed in Table 3-6.

For more information about the Program Synopsis Section of a map file, see Section 5.2.4.

3.3.5 Allocating Memory for Segments

When it creates a segment, the linker allocates enough memory for the image segment to accommodate all the sections it contains. Each section definition includes its size.

The linker aligns segments on CPU-specific page boundaries. Within a segment, the linker assigns to each section a virtual address relative to the base address of the segment.

Concatenated Sections

If the sections have the concatenated (CON) attribute set, the linker positions the sections one after the other within a segment, inserting padding bytes between the sections if necessary to achieve the alignment requirement of a particular contribution to a section. The linker retains the alignment specified for each section contribution but uses the largest alignment of a contributing module as the alignment of the whole section.

With a PSECT_ATTR= option you can align the section within the segment. However, aligning the section does not influence the alignment of the individual contributions to the section. The linker follows the compiler's alignment specification when it aligns each individual contribution. If you specify a smaller alignment for a section than any compiler-assigned alignment from all contributions, the linker issues a warning.

Overlaid Program Sections

If the sections have the overlaid (OVR) attribute set, the linker uses the same start address for the sections so that they occupy the same virtual memory (that is, the sections overlay each other). For overlaid sections, the linker allocates enough space to accommodate the largest of all the section contributions. Note that the linker does not generate a warning message if the contributions specify different size allocations.

Any module can initialize the contents of an overlaid program section. However, the I64 linker only allows compatible initializations for the same section data. See Section 3.4.1 for an explanation of a compatible initialization.

Assigning Virtual Addresses

The linker allocates virtual memory to all the segments beginning at a page size boundary. The linker usually places segments in the P0 region. It currently uses a default page size of 10000 hexadecimal, which is an architecture specific value. However, you can specify the page size using the /BPAGE qualifier. (For information about the /BPAGE qualifier, see Part 4.)

By default, the first P0 segment is placed at 10000 hexadecimal, leaving the first page unused as a guard page. The first P2 segment (for example containing sections with the ALLOC_64BIT attribute) is placed at 80000000 hexadecimal. However, all segment base addresses are only suggestions for the OpenVMS image activator. The image activator can determine a different base address for each segment (within the address region) to map the segment. This is always the case for shareable images. This is also the case for all images being installed as resident images, where the INSTALL utility determines the addresses. Unlike the Alpha and VAX platforms, executable images can also have their segment base addresses determined by the image activator or the INSTALL utility.

An image not activated by the OpenVMS image activator might need a specific base address for the first segment. For such an image, you can specify this address with the /BASE_ADDRESS qualifier. (For information about the /BASE_ADDRESS qualifier, see Part 4.)

Because the linker processes clusters in the order in which they appear in the cluster list, the virtual address space of the final image will generally contain contiguous segments of consecutive clusters on the basis of their order in the cluster list.

After allocating memory for all segments in a cluster, the linker relocates their contents by performing the following processing:

  1. Relocating each section in the segment. The linker adds the starting virtual address of the segment to the relative offset of the section from the base of the segment.
  2. Relocating each global symbol in the section. The linker adds the newly calculated section virtual address to the relative offset of the global symbols from the base of the section.

3.3.6 Segment Attributes

When it creates segments, the linker assigns attributes to the segment based on the attributes of the sections it contains. The segment attributes describe certain characteristics of the portion of memory they represent, for example, the protection characteristics. For example, a segment that contains sections with the writability attribute also has the writability attribute set. Table 3-4 and Table 3-5 include the segment attributes associated with a segment that contains sections with a particular set of attributes. Table 3-7 lists all the segment attributes. Segment attributes, like section attributes, are Boolean values that are either on or off.

Table 3-7 Segment Attributes
Attribute Symbol1 Function
Executability PF_X The mapping of the EXE attribute from the section.
Write PF_W The mapping of the WRT attribute from the section.
Readability PF_R All segments have this attribute set.
Modified if Relocated PF_VMS_NOWRIT_RELOC The attribute is set by the linker if the the segment contents is changed when relocated. The image activator sets the protection to NOWRT after the relocation.
Initial Code PF_VMS_INITALCODE This attribute is reserved by HP.
Resident PF_VMS_RESIDENT This attribute is reserved by HP.
Vectored PF_VMS_VECTOR The mapping of the VEC attribute from the section.
Protected PF_VMS_PROTECT Protect indicates that a section is protected. The linker sets the PF_VMS_PROTECT attribute whenever PF_VMS_VECTOR is set. PROTECT is also set if the /PROTECT qualifier is used, or if the cluster that the segment is spawned from came after a PROTECT=YES option (and before a PROTECT=NO option).
Modified by Fix-Ups PF_VMS_NOWRIT_FIXUP The attribute is set by the linker if the segment contents is changed for fix-ups. The image activator sets the protection to NOWRT after the fix-ups are applied.
Short Data PF_VMS_SHORT The mapping of the SHORT attribute from the section.
Shared PF_VMS_SHARED The SHR mapping of the SHR attribute from the sections.

1These symbols are prefixed with PHDR$V_.

The Image Segment Synopsis section of a map file lists the attributes of each segment created in the Protection and Attributes columns. See Example 3-6 for an illustration and see Table 3-3 for the display names in these columns. You can also get a listing of all the segments created by the linker by using the ANALYZE/IMAGE utility. The output generated by this utility includes a list of all the segments that make up the image, with their attributes. An excerpt from the analysis of the image file MYTEST.EXE is shown in Example 3-8.

Example 3-8 Image Segment Descriptions in an ANALYZE/IMAGE Display


SEGMENT HEADER ENTRY 0.
Offset    Description                    Hex (<bitmask>)  Interpretation
------    -----------                    ---------------  --------------
00000000  Segment Type:                         00000001  PHDR$K_PT_LOAD
00000004  Segment Flags:                        00000006 (1)
            Segment is writeable:              <00000002> PHDR$M_PF_W
            Segment is readable:               <00000004> PHDR$M_PF_R
00000008  Offset to Segment Data:       0000000000000400 (2)
00000010  Memory Virtual Address:       0000000000010000 (3)
00000018  Page Fault Cluster Size:      0000000000000000 (4)
00000020  Segment Size in File:         0000000000000014 (5)
00000028  Segment Size in Memory:       0000000000000014 (6)
00000030  Alignment Constraint:         0000000000000010

SEGMENT HEADER ENTRY 1. (0001)               56. (0038) bytes
Offset    Description                    Hex (<bitmask>)  Interpretation
------    -----------                    ---------------  --------------
00000000  Segment Type:                         00000001  PHDR$K_PT_LOAD
00000004  Segment Flags:                        00000005 (1)
            Segment is executable:             <00000001> PHDR$M_PF_X
            Segment is readable:               <00000004> PHDR$M_PF_R
00000008  Offset to Segment Data:       0000000000000600 (2)
00000010  Memory Virtual Address:       0000000000020000 (3)
00000018  Page Fault Cluster Size:      0000000000000000 (4)
00000020  Segment Size in File:         0000000000000090 (5)
00000028  Segment Size in Memory:       0000000000000090 (6)
00000030  Alignment Constraint:         0000000000000010
   .
   .
   .

The items in the following list correspond to the numbers in Example 3-8:

  1. The settings of segment attributes. Table 3-7 lists these attributes.
  2. The offset in the image file in bytes, at which the segment begins.
  3. The virtual base address assigned to the segment by the linker. Note that at run time the image activator may decide to map this segment at a different address.
  4. The number of pagelets that should be mapped in when the initial page fault occurs. You can set this value by using the CLUSTER= option.
  5. The size of the segment in the image file, expressed in bytes. Note that demand zero segments have a file size of zero but a nonzero memory size.
  6. The size of the segment in the memory, expressed in bytes. For the shown segments, both sizes are identical so they are not demand zero segments.

3.3.7 Controlling Segment Creation

You can control how the linker combines sections into segments in the following ways:

  • By modifying the attributes of sections
  • By using the SOLITARY attribute
  • By using the /SEGMENT_ATTRIBUTES qualifier
  • By putting object modules into named clusters
  • By collecting sections

3.3.7.1 Modifying Section Attributes

The linker combines sections in the same cluster into the same segment if they have the same settings for the significant section attributes. To force the linker to put the sections into different segments, change the attributes of one of the sections by using the PSECT_ATTR= option.

For example, in the sample link operation, the GLOBAL_DATA section has the WRT attribute. But its contents, the variable global_data, serves as a constant (initialized but never changed). If you want the GLOBAL_DATA section to appear in a read-only segment, change the writability attribute. For example, in the following link of the sample programs, the writability attribute is set to NOWRT.


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

Example 3-9 shows the image and program section synopsis for the second link.

Example 3-9 Image and Program Section Synopsis of Second Link


                               +--------------------------+
                               ! Program Section Synopsis !
                               +--------------------------+

Psect Name Module/Image   Base     End       Length            Attributes
---------- ------------   ----     ---       ------            ----------

SUB_DATA                00010000 00010003 00000004 (   4.) NOEXE,  WRT,NOVEC,  MOD
           MYSUB        00010000 00010003 00000004 (   4.) Initializing Contribution

$CODE$                  00020000 0002008F 00000090 ( 144.)   EXE,NOWRT,NOVEC,  MOD
           MYSUB        00020000 0002006F 00000070 ( 112.)
           <Linker>     00020070 0002008F 00000020 (  32.)

$LITERAL$               00030000 0003000C 0000000D (  13.) NOEXE,NOWRT,NOVEC,  MOD
           MYSUB        00030000 0003000C 0000000D (  13.)

GLOBAL_DATA             00030010 00030013 00000004 (   4.) NOEXE,NOWRT,NOVEC,  MOD
           MYSUB        00030010 00030013 00000004 (   4.) Initializing Contribution

$LINKER UNWIND$         00040000 00040017 00000018 (  24.) NOEXE,NOWRT,NOVEC,  MOD
           MYSUB        00040000 00040017 00000018 (  24.)
   .
   .
   .

Note that there is no change in the number and attributes of the segments. However, the GLOBAL_DATA section moved into an existing read-only segment. (It also moved in the address space.) The GLOBAL_DATA section is now in the same segment as the read-only $LITERAL$ section, which it follows, based on alphabetical order (for a comparison, see Example 3-7).

3.3.7.2 Alternate Way to Modify Section Attributes

With the /SEGMENT_ATTRIBUTE qualifier, you can change some attributes for a class of sections. The keywords SHORT_DATA, CODE, and SYMBOL_VECTOR define obvious classes of sections: all sections with the SHORT, all sections with the EXE attribute, and the symbol vector section. The attribute to change depends on the class.

For short data sections, you can set WRT. For executable sections, you can set or clear the ALLOC_64BIT attribute. For the symbol vector, you can set or clear the SHORT attribute. To be compatible with other DCL command qualifiers, for the first two classes, more descriptive names are used: WRITE for WRT, P0 for NOALLOC_64BIT, P2 for ALLOC_64BIT. (For information about the /SEGMENT_ATTRIBUTE qualifier, see the Command Reference in Part 4.)

With /SEGMENT_ATTRIBUTE, the section attributes are changed before the sections are collected into segments. As a result, the effect is the same as using the PSECT_ATTR= for each member of the class. However, /SEGMENT_ATTRIBUTE can do more because even the linker-generated sections are members of the classes (for example, $LINKER SDATA$ and $LINKER SYMBOL_VECTOR$).

To move all code into P2 space, you can use the /SEGMENT_ATTRIBUTE=CODE=P2 command qualifier. Please note, that if you use clusters in the same link command (with linker options) and if EXE sections are put on specific clusters, setting ALLOC_64BIT does not change the per cluster segment creation. You then will see more than one executable segment with base addresses in P2 space.

The /SEGMENT_ATTRIBUTE=SHORT_DATA=WRITE command qualifier allows you to combine the read-only and the read-write short data segments into a single segment, reclaiming up to 65,535 bytes of unused, read-only space (default value for /BPAGE). When setting SHORT_DATA to WRITE, your program may accidentally write to formerly read-only data. Therefore, this qualifier is recommended only if your short data segment has reached the limit of 4 MB.

By default, the linker stores the shareable image's symbol vector into the read-only short data segment. That is, the linker created section $LINKER SYMBOL_VECTOR$ has the SHORT attribute. By specifying /SEGMENT_ATTRIBUTE=SYMBOL_VECTOR=NOSHORT, the linker clears the SHORT attribute of the section and, therefore, collects the symbol vector into a read-only data segment of the default cluster. If the shareable image has no read-only data se is created. This frees up the symbol vector entries from the short data. This qualifier is recommended only if your short data segment has reached the limit of 4 MB.

3.3.7.3 Manipulating Cluster Creation

In general, the linker creates segments on a per-cluster basis; that is, only sections within a particular cluster can contribute to segment creation. (The linker can collect sections with the global attribute from all clusters into a single segment. However, there is one expection: sections with the SHORT attribute can not be collected.) To ensure that a section appears in a particular segment, put the section in a specific cluster.

For example, in the sample link operation illustrated in Example 3-5, the linker puts all the sections in the object module MYSUB.OBJ in the cluster named MYSUB_CLUS because the CLUSTER= option is specified. If you wanted to group all of the sections that contain code from all the other clusters into the MYSUB_CLUS cluster, you could specify the COLLECT= option, as in the following example.

Note

Section naming conventions are language processor specific. By convention, most OpenVMS language processors put the code they generate into sections named $CODE$. An exception is the HP C++ compiler which puts code into a section named .text .


$ LINK/MAP/FULL MYTEST, MYADD, SYS$INPUT/OPT
CLUSTER=MYSUB_CLUS,,,MYSUB
COLLECT=MYSUB_CLUS,$CODE$
[Ctrl/Z]


Previous Next Contents Index