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 |
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:
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
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$).
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) ----- |
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) ----- |
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) ----- |
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:
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 |