[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP OpenVMS Linker Utility Manual


Previous Contents Index

To illustrate section creation, consider the sections created by the HP C compiler when it processes the sample programs in the following examples:

Example 3-1 Sample Program MYTEST.C

#include <stdio.h>
extern int global_data;

extern int myadd( int, int );
extern int mysub( int, int );

main()
{
  int num1, num2, res1, res2;

  num1 = 5;
  num2 = 6;

  res1 = myadd( num1, num2 );
  res2 = mysub( num1, num2 );
  printf( "res1 = %d, res2 = %d, globaldata = %d\n", res1, res2, global_data );
}

Example 3-2 Sample Program MYADD.C

#include <stdio.h>

int add_data = -1;

int myadd( int value_1, int value_2 )
{
  printf( "In MYADD.C\n" );
  add_data = value_1 + value_2;
  return add_data;
}

Example 3-3 Sample Program MYSUB.C

#include <stdio.h>

int global_data = 5;
int sub_data = -1;

int mysub( int value_1, int value_2 )
{
  printf( "In MYSUB.C\n" );
  sub_data = value_1 - value_2;
  return sub_data;
}

To see what sections the HP C compiler creates for these modules, use the ANALYZE/OBJECT utility to examine each object module. Example 3-4 presents an excerpt from the analysis of the object module MYTEST.OBJ. Only the section definitions are included in the excerpt.

Example 3-4 Sections Generated by an Analysis of Example 3-1

$ anal/object/section=all/out=mytest.anl mytest.obj
   .
   .
   .
SECTION SUMMARY

Number  Type                 Name                              Flags
    0.  NULL                                                   ------------------------------
    1.  STRTAB               .shstrtab                         ------------------------------
    2.  NOTE                 .note                             ------------------------------
    3.  PROGBITS             $CODE$                            -AE-----------------Shr-------
    4.  PROGBITS             $LITERAL$                         -A------------------Shr-------
    5.  NOBITS               $LINK$                            -A----------------------------
    6.  PROGBITS             .IA_64.unwind_info                -A----------------------------
    7.  IA_64_UNWIND         .IA_64.unwind              (1)     -A---L------------------------
    8.  STRTAB               .strtab                           ------------------------------
    9.  SYMTAB               .symtab                           ------------------------------
   10.  VMS_TRACE            .debug_line                       ------------------------------
   11.  RELA                 .rela.debug_line                  ------------------------------
   12.  VMS_TRACE            .trace_abbrev                     ------------------------------
   13.  VMS_TRACE            .trace_info                       ------------------------------
   14.  RELA                 .rela.trace_info                  ------------------------------
   15.  VMS_TRACE            .trace_aranges                    ------------------------------
   16.  RELA                 .rela.trace_aranges               ------------------------------
   17.  RELA                 .rela.IA_64.unwind_info           ------------------------------
   18.  RELA                 .rela.IA_64.unwind                ------------------------------
   19.  RELA                 .rela$CODE$                       ------------------------------

Key for Flags: W (Write), A (Alloc), E (Execute), S (Strings), I (Info link), L (Link order),
               O (OS-specific processing), G (Group), Sho (Short), Nrc (No recovery code),
               Gbl (Global), Ovr (Overlaid), Shr (Shared), Vec (Vector),
               64b (Allocate 64bit address), Pro (Protected)
   .
   .
   .

SECTION HEADER ENTRY 3. (0003)
"$CODE$"
Description                    Hex (<bitmask>)  Interpretation               Field Name
-----------                    ---------------  --------------               ----------
Name Offset in .shstrtab:             00000011  "$CODE$"     (2)              shdr$l_sh_name
Section Type:                         00000001  SHDR$K_SHT_PROGBITS          shdr$l_sh_type
Section Flags:  (3)            0000000400000006                               shdr$q_sh_flags
  Data occupies memory:      <0000000000000002> SHDR$M_SHF_ALLOC             shdr$v_shf_alloc
  Machine instructions:      <0000000000000004> SHDR$M_SHF_EXECINSTR         shdr$v_shf_execinstr
  Shareable section:         <0000000400000000> SHDR$M_SHF_VMS_SHARED        shdr$v_shf_vms_shared
Section Load Address:         0000000000000000  Not Used (Object File)       shdr$pq_sh_addr
Offset to Section Data:       0000000000000170                               shdr$q_sh_offset
Size of Section Data:         00000000000001C0     (4)                        shdr$q_sh_size
Section Link Field:                   00000000                               shdr$l_sh_link
Section Info Field:                   00000000                               shdr$l_sh_info
Alignment Constraint:         0000000000000010     (5)                        shdr$q_sh_addralign
Entry Size (if table):        0000000000000000                               shdr$q_sh_entsize
   .
   .
   .
SECTION HEADER ENTRY 7. (0007)
".IA_64.unwind"
Description                    Hex (<bitmask>)  Interpretation               Field Name
-----------                    ---------------  --------------               ----------
Name Offset in .shstrtab:             0000003C  ".IA_64.unwind"              shdr$l_sh_name
Section Type:                         70000001  SHDR$K_SHT_IA_64_UNWIND      shdr$l_sh_type
Section Flags:                0000000000000082                               shdr$q_sh_flags
  Data occupies memory:      <0000000000000002> SHDR$M_SHF_ALLOC             shdr$v_shf_alloc
  Preserve section order:    <0000000000000080> SHDR$M_SHF_LINK_ORDER        shdr$v_shf_link_order
Section Load Address:         0000000000000000  Not Used (Object File)       shdr$pq_sh_addr
Offset to Section Data:       0000000000000090                               shdr$q_sh_offset
Size of Section Data:         0000000000000030                               shdr$q_sh_size
Section Link Field: (1)                00000003                               shdr$l_sh_link
Section Info Field: (1)                00000006                               shdr$l_sh_info
Alignment Constraint:         0000000000000008                               shdr$q_sh_addralign
Entry Size (if table):        0000000000000000                               shdr$q_sh_entsize

Note

You can also determine the sections in an object module after a link operation by looking at the Program Section Synopsis section of an image map file, as illustrated in Example 3-7.

The items in the following list correspond to the numbered items in Example 3-4:

  1. The unwind table section is the only section with the Link Order attribute set. The Link Order attribute signifies that the I64 linker must preserve section ordering. See Section 3.2.1.5.
  2. The Name Offset indicates the name of the section.
  3. Section flags indicate which section attributes are set. The attributes are listed by their ELF name. Note that the keywords are only listed when the bit in shdr$q_sh_flags is set. For example SHDR$M_SHF_EXECINSTR (Machine Instructions) is an attribute of the $CODE$ section.
  4. The Size of Section Data indicates the number of bytes required for the section.
  5. Alignment Constraint specifies the address boundary at which the linker must place a module's contribution to the section. The number shown here, 10 (hexadecimal), is a byte alignment and not an OpenVMS style (power of 2) of specifying the section attributes.

Figure 3-2 illustrates some of the sections created by the HP C compiler for the modules in Example 3-1, Example 3-2, and Example 3-3. (The shaded areas represent the settings of the section attributes the linker considers when sorting the sections into image segments in an executable image. See Section 3.3.4 for more information about how the linker creates segments in an image.)

Figure 3-2 Sections Created for Examples 3-1, 3-2, and 3-3


3.2.1 Sections Created by The Linker

Unlike the VAX and Alpha linkers, the I64 linker creates new sections as well as contributions to existing sections for loadable segments.

When the linker assigns a name for a section, the name can be a reserved name containing an embedded space (e.g. $LINKER UNWIND$). The linker uses the embedded space in a reserved name to prevent you from changing the section attributes. The PSECT_ATTR option reads the embedded space and compresses it out of the name. As such, the name is not read by the linker as you intended and the attributes are preserved.

3.2.1.1 Sections for Relaxed Symbol Definitions

In HP C, relaxed symbol definitions that can act like a reference or a definition (when no other definition is found) have no section assigned to them. If there is no hard definition (i.e., a symbol with a compiler-supplied section), the linker allocates a section for the symbol. The section has the same name as the symbol, and is contributed by the I64 linker (labeled with <Linker> in the map).

3.2.1.2 Sections Embedded in Code Segments

The I64 linker contributes sections to code segments that contain calls to code outside the image, outside the code segment but to another segment within the image, or to code that can't be reached with a normal branch instruction inside the segment (called a trampoline).

The instructions can be helpful when using the debugger to step into subroutines. The instructions are grouped in 128-bit bundles, with a series of dashes marking the end of a bundle.

<Linker> is used to lable the linker contribution in the map, usually at the end of the code section (normally named $CODE$).

Calls Out of the Image

The compiler is unaware whether a call is internal or external to the image being created. The linker has this knowledge and for external calls, generates the following sequence of instructions:


addl r15=<offset>,r1;;
ld8 r16=[r15],8
nop.i
-----
ld8 r1=[r15]
mov b6=r16
br.few b6;;   (1)
-----
  1. This is an Indirect Branch (B4). For more information, see the Intel IA-64 Architecture Software Developers Manual, Volume 3, Instruction Set Reference, Revision 1.1, July 2000, pages 2-9 and 4-64.

In the first instruction, R15 contains the address of the Function Descriptor (FD), which the linker obtained by adding an offset to the Global Pointer register (GP, implemented as R1). R16 is loaded with a pointer to the code address. R1 then receives the new Global Pointer. The branch instruction completes the call sequence.

Calls Out of the Segment to Another Segment in the Same Image

The compiler is unaware whether the destination of a call is in another segment of the same. The linker has this knowledge and for calls that cross segment boundaries, generates the following sequence of instructions:


addl r15=<offset>,r1;;
ld8 r16=[r15]
nop.i
-----
nop.m
mov b6=r16
br.few b6;;   (1)
-----
  1. This is an Indirect Branch (B4). For more information, see the Intel IA-64 Architecture Software Developers Manual, Volume 3, Instruction Set Reference, Revision 1.1, July 2000, pages 2-9 and 4-64.

In the first instruction, R15 contains the address of the Function Descriptor (FD), which the linker obtained by adding an offset to the Global Pointer (GP, implemented as R1) register. R16 is loaded with a pointer to the code address. Because the instructions branch to another segment in the same image and because there is one GP per image, the linker can skip copying the GP from the FD.

Calls That Cannot be Reached with Normal Branch Instruction (Trampolines)

The linker uses a trampoline when when the branch-to-code instruction in the same segment (calculated in 128 bit or 16 byte bundles) is more than 21-bit signed offset. The trampoline must be located somewhere within the original 21-bit signed branch. The trampoline then does an indirect branch from the trampoline to the target instruction.


nop.m 0x0
movl r15=<offset between the next instruction and the target> (1)
-----
nop.m 0x0
mov r16=ip;;  (2)
add r16=r15,r16;;
-----
nop.m 0x0
mov b6=r16
br.few b6;;   (3)
-----
  1. See the Intel IA-64 Architecture Software Developers Manual, Volume 3, Instruction Set Reference, Revision 1.1, July 2000, page 2-156.
  2. The ip is the PC; it points to previous instruction that indicates the beginning of an instruction bundle.
  3. This is an Indirect Branch (B4). For more information, see the Intel IA-64 Architecture Software Developers Manual, Volume 3, Instruction Set Reference, Revision 1.1, July 2000, pages 2-9 and 4-64.

3.2.1.3 Short Data Sections

In order to make position-independent code that does not require any relocations, Itanium platforms allow code to make a reference to pointers and other short data using offsets from an address in a register. This special register is called the Global Pointer (GP) register. The language processors place such data into sections named short data sections. It is the task of the linker to collect these sections into a segment or segments and to determine the GP value. The GP value is determined so that the beginning of the first (or only) short data segment is the negative-most offset from the GP within range. For the Intel Itanium architecture, the negative-most offset is 2 MB. Therefore, the GP value is the virtual address of the beginning of the first (or only) short data segment plus 2 MB. If the address range for your short data segment or segments is less than 2Mb, the GP value may not even point to a virtual address mapped by your image. The compilers usually place data in the short data sections that are relatively short (like quadwords or smaller) and not long (like an array).

There are two kinds of short data sections --- read-only and read-write. The I64 linker is a major contributor to the read-only short data section. In this section, the linker puts addresses of data and function descriptors (termed procedure descriptors on Alpha) that can be reached by code with a short offset from the Global Pointer register. This section is named $LINKER SDATA$. In the map, <Linker> is used to label the linker contributions to this section.

Function descriptors placed in the read-only short data section have varying lengths depending on their type. The types are official and local. Official function descriptors are always three quadwords long. Local function descriptors can be two quadwords or four quadwords long, depending on whether the qualifier /NONATIVE_ONLY is present. If the image is supposed to interoperate with translated images, the /NONATIVE_ONLY qualifier must be used, and local function descriptors will be four quadwords long.

Official function descriptors represent functions that are defined by an image. One example of functions defined by an image are those functions which can be exported from a shareable image by the symbol vector and called by other images. Official function descriptors always contain the address of the first instruction of the function in the first quadword. The GP value under which the function executes is in the second quadword. The third quadword contains a zero, or if the /NONATIVE_ONLY qualifier is used it contains the function's signature or a pointer to the function's signature. A signature describes the parameters and return status of the function. If the third quadword is zero then the function descriptor has no signature, and a translated image is not allowed to call the function.

An official function descriptor has the following format at runtime:

Figure 3-3 Official Function Descriptor


A local function descriptor represents a function outside of the image. Local function descriptors made for images that do not interoperate with translated images contain at run-time the address of the first instruction of the function in the first quadword. The GP value under which the function executes is in the second quadword. The linker generates a fixup for the function descriptor because it has no knowledge of those addresses. The fixup is applied by the image activator which has already activated the image with those addresses in it.

A local function descriptor has the following format at runtime:

Figure 3-4 Local Function Descriptor - Two Quadwords


Local function descriptors made by the linker for images that can interoperate with translated images are four quadwords long. At run-time, after the image activator has determined that the target shareable image is translated, the four quadwords in the function descriptor contain the following:

  • Entry (code) address of the routine that mediates calls between native and translated code
  • Address of this function descriptor
  • Signature information for the call
  • Pointer to the official function descriptor for the entry point in the translated image (or some other unique identification that can be interpreted by the support facility the mediates calls between native and translated code)

The linker assumes the image activator will find a native image, and issues a fixup to the image activator to fill in the first two (of four) quadwords with the code address and GP. The third quadword is filled in with signature information, like an official function descriptor. The fourth quadword is filled in with a zero. If the image activator determines that the function referenced by this function descriptor in a native image, it applies the fixup and ignores the last two quadwords.

3.2.1.4 Section for the Symbol Vector

The symbol vector on Alpha is in a PSECT named $SYMVECT. The I64 Linker does not use a section with the name $SYMVECT, but places the symbol vector in a section with the name $LINKER SYMBOL_VECTOR$, and places the section in the short data segment by default. In the map, <Linker Option> is used to label this linker contribution.

You can use the qualifier /SEGMENT=(SYMBOL_VECTOR=NOSHORT) to move $LINKER SYMBOL_VECTOR$ to a data segment which is read-only. The I64 Linker creates a read-only data segment if one does not already exist.

For a look at the layout of a symbol vector see Figure 2-1.

3.2.1.5 Sections that Contain Unwind Data

When an exception is signaled by hardware or software, the condition handling facility looks for a condition handler. If a condition handler is found, the handler may choose to call SYS$UNWIND to unwind the stack. SYS$UNWIND has, at its disposal, an unwind table. The unwind table contains a pointer into a variable-sized information block that contains the unwind descriptor list and a language-specific area. The unwind table and the unwind information block are created by the compilers. The linker has to place the contributions to the unwind tables in the same order as the contributions to the code segment for unwinding to work.

The linker renames the compiler-named sections that contain unwind tables (usually named .IA_64.unwind) and unwind information blocks (usually named .IA_64_unwinfo). It can tell which sections contain unwind tables because those sections have the type SHT_IA_64_UNWIND. It also has the link order (SHF_LINK_ORDER) attribute set. The link order attribute means that the contributions to the unwind table must be in the same order as contributions pointed to by the SH_LINK field (a code section).

The new, reserved name of the section that contains the unwind tables is $LINKER UNWIND$. $LINKER UNWINFO$ is the new, reserved name of the section that contains unwind information. These names appear in the linker map; the actual names of these sections are gone by the time the map is written. The linker uses reserved names for these sections; this means that you are not allowed to change the section attributes with a PSECT_ATTR= clause or collect them with the COLLECT= option to other clusters. This is because the placement and ordering of these sections are driven by the placement and ordering of the code sections to which they refer. By altering the placement or ordering of the code sections through the use of linker options or input file ordering, the sections containing unwind tables and unwind information blocks will likewise have the placement or ordering of their contributions altered.

$LINKER UNWIND$ and $LINKER UNWINFO$ have identical significant attributes and therefore end up in the same unwind segment. This is denoted in the Image Segment Synopsis section of the map by the [UNWIND] tag. The unwind segment is connected to the corresponding code segment by entries in the dynamic segment (which the image activator uses for activating an image).

If you have a complex link with an options file that contains a number of CLUSTER= or COLLECT= options, you may have more unwind segments than you really need. The I64 linker constructs one unwind segment per cluster with one or more code segments. To reduce the number of unwind segments, you should reduce the number of clusters containing code. This is done by collecting code sections onto a smaller number of clusters or onto a single cluster.

3.3 Creating Segments

On I64 systems, the linker creates segments, which are analogous to image sections on Alpha and VAX systems. Segments define the memory requirements and page protection characteristics of an image.

To create segments, the linker processes the sections in the object modules specified in the link operation. The number and type of segments the linker creates depend on the input files and what is specified in the link operation. Section 3.3.1 describes how the clustering of input files affects segment creation. Section 3.3.2 describes the effects of section attributes on segment creation.


Previous Next Contents Index