2    Headers

Headers serve as a cover page and table of contents for the object file. They contain size descriptions, magic numbers, and pointers to other sections.

The object file components covered in this chapter are the file header, a.out header, and section headers:

An object file may contain other header sections that are used to navigate the symbol table and dynamic loading information. The symbolic header and dynamic header are discussed in Chapter 5 and Chapter 6 respectively.

2.1    New or Changed Header Features

Tru64 UNIX V5.1 includes the following new or modified features:

2.2    Structures, Fields, and Values for Headers

2.2.1    File Header (filehdr.h)

struct filehdr {
        coff_ushort     f_magic;   
        coff_ushort     f_nscns;  
        coff_int        f_timdat;
        coff_off        f_symptr;
        coff_int        f_nsyms;
        coff_ushort     f_opthdr;       
        coff_ushort     f_flags;        
};

SIZE - 24 bytes, ALIGNMENT - 8 bytes

File Header Fields

f_magic

File magic number (see Table 2-1). Used for identification.

f_nscns

Number of section headers in the object file.

f_timdat

Time and date stamp. This field is implemented as a signed 32-bit quantity that acts as a forward or backward offset in seconds from midnight on January 1, 1970. The resulting date range is approximately 1902-2038.

f_symptr

File offset to symbolic header. This field is set to zero in a stripped object.

f_nsyms

Size of symbolic header (in bytes). This field is set to zero in a stripped object.

f_opthdr

Size of a.out header (in bytes).

f_flags

Flags (see Table 2-2 ) that describe the object file. Note that the file header flags cannot be treated as a bit vector because some values are overloaded.

Table 2-1:  File Header Magic Numbers

Symbol Value Description
ALPHAMAGIC 0603 Object file.
ALPHAMAGICZ 0610 Compressed object file.
ALPHAUMAGIC 0617 ( - V4.0x) Ucode object file.

Table 2-2:  File Header Flags

Symbol Value Description
F_RELFLG 0x0001 File does not contain relocation information. This flag applies to actual relocations only, not compact relocations.
F_EXEC 0x0002 File is executable (has no unresolved external references).
F_LNNO 0x0004 Line numbers are stripped from file.
F_LSYMS 0x0008 Local symbols are stripped from file.
F_NO_SHARED 0x0010 Currently unused.
F_NO_CALL_SHARED 0x0020 Object file cannot be used to create a -call_shared (dynamic) executable file.
F_LOMAP 0x0040 Allows a static executable file to be loaded at an address less than VM_MIN_ADDRESS (0x10000). This flag cannot be used by dynamic executables.
F_SHARABLE 0x2000 Shared library.
F_CALL_SHARED 0x3000 Dynamic executable file.
F_NO_REORG 0x4000 Tells object consumer not to reorder sections.
F_NO_REMOVE 0x8000 Tells object consumer not to remove NOP instructions.

2.2.2    a.out Header (aouthdr.h)

The a.out header is also referred to as the "optional header". Note that "optional" is a misnomer because the header is actually mandatory.

typedef struct aouthdr {
        coff_ushort     magic;         
        coff_ushort     vstamp;       
        coff_ushort     bldrev;
        coff_ushort     padcell;
        coff_long       tsize;       
        coff_long       dsize;      
        coff_long       size;     
        coff_addr       entry;  
        coff_addr       text_start;     
        coff_addr       data_start;     
        coff_addr       bss_start;      
        coff_uint       gprmask;        
        coff_word       fprmask;       
        coff_long       gp_value;     
} AOUTHDR;

SIZE - 80 bytes, ALIGNMENT - 8 bytes

a.out Header Fields

magic

Object-file magic numbers (see Table 2-4).

vstamp

Object file version stamp. This value consists of a major version number and a minor version number, as defined in the stamp.h header file:

Symbol Value Description
MAJ_OBJ_STAMP 3 Current major object format version
MIN_OBJ_STAMP 13 Current minor object format version

This version stamp covers all parts of the object file exclusive of the symbol table, which is covered by an independent version stamp stored in the symbolic header

See Section 1.4.5 for a description of object file versioning.

bldrev

Revision of system build tools. This value is defined in stamp.h and is updated for each major release of the operating system. The values for Tru64 UNIX releases to date are shown below. This field is not meaningful to users.

Table 2-3:  Build Revision Constants

Release bldrev
V1.2 --
V1.3 2
V2.0 4
V3.0 6
V3.2 8
V4.0 10
V5.0 12

tsize

Text segment size (in bytes) padded to 16-byte boundary; set to zero if there is no text segment.

For ZMAGIC object files, this value includes the size of the header sections (file header, a.out header, and all section headers). See Section 2.3.2 for more information.

dsize

Data segment size (in bytes) padded to 16-byte boundary; set to zero if there is no data segment..

bsize

Bss segment size (in bytes) padded to 16-byte boundary; set to zero if there is no bss segment.

entry

Virtual address of program entry point. This field is meaningful primarily for executable objects. For shared libraries, it contains the starting address of the first procedure. For pre-link objects, it is typically set to zero.

text_start, data_start, bss_start

Base address of text, data, and bss segments, respectively, for this file. Alignment requirements are discussed in Section 2.3.2.

gprmask

Unused.

fprmask

Unused.

gp_value

The initial GP (Global Pointer) value used for this object. The kernel loads this value into the GP register ($gp) when a program is executed. The program entry point identified by the entry field will load its GP value into the GP register, which may or may not be different than the value in this field for objects with multiple GP ranges. See Section 2.3.4. This value is also used by the linker as a basis for relocation adjustments in objects. See Section 4.3.3.2.

Table 2-4:  a.out Header Magic Numbers

Symbol Value Description
OMAGIC 0x107 Impure format. The text segment is not write-protected or shareable; the data segment is contiguous with the text segment. An OMAGIC file can be a relocatable object or an executable.
NMAGIC 0x108 Shared text format. NMAGIC files are static executables. This layout is rarely used but supported for historical reasons.
ZMAGIC 0x10b Demand-paged format. The text and data segments are separated and the text segment is write-protected and shareable. The object can be a dynamic or static executable, or a shared library. All shared objects use a ZMAGIC layout.

2.2.3    Section Headers (scnhdr.h)


Version Note

The following structure definition is for Tru64 UNIX V5.1 and greater. It is compatible with object format V3.13 and greater. New fields are identified in the field descriptions following the structure.


struct scnhdr {
        char            s_name[8];  
        coff_addr       s_paddr;   
        coff_addr       s_vaddr;   
        coff_long       s_size;     
        coff_off        s_scnptr;  
        coff_off        s_relptr;  
        coff_ulong      s_lnnoptr;  
        union {
            struct {
                coff_ushort  _s_nreloc;
                coff_ushort  _s_nlnno;
            } _s;
            struct {
                coff_uint    _s_nreloc:16;
                coff_uint    _s_alignment:4;
                coff_uint    _s_reserved:12;
            } _b;
        }               s_u;
        coff_uint       s_flags;    
};
#define s_nreloc     s_u._s._s_nreloc
#define s_nlnno      s_u._s._s_nlnno
#define s_alignment  s_u._b._s_alignment
#define s_reserved   s_u._b._s_reserved

SIZE - 64 bytes, ALIGNMENT - 8 bytes

Section Header Fields

s_name

Section name (see Table 2-5); null-terminated unless exactly 8 bytes. Long section names are truncated to 8 bytes and are not null-terminated. Unused bytes are zero filled.

s_paddr

Base virtual address of section in the image. Although this field contains the same value as s_vaddr, normally s_vaddr is used and s_paddr is ignored.

s_vaddr

Base virtual address of a loadable section in the image.

This field is set to zero for nonloadable sections such as .comment.

For the sections .tlsdata and .tlsbss, this field contains an offset from the beginning of the object's dynamically allocated TLS region.

s_size

Section size rounded to 16-byte multiple.

s_scnptr

File offset to beginning of raw data for the section. The raw data pointed to by this field, and described by the s_size field, is mapped at s_vaddr (if non-zero) in the process image.

For sections with no raw data, such as .bss, this field is set to zero.

s_relptr

File offset to relocations for the section; set to zero if the section has no relocations.

s_lnnoptr

In .lita section header, indicates number of GP ranges used for the object:

Value Meaning
0 Object has one GP range.
1 Invalid value.
2 or higher Object has this number of GP ranges.

For sections with GP relative relocations, this field contains the number of R_GPVALUE relocation entries for that section. In .pdata this field contains the number of run-time procedure descriptors.

For other sections, the field is reserved and must be zero.


Version Note

For object formats less than V3.13 the value of this field may not be zero and should be ignored.


s_nreloc

Number of relocation entries; 0xffff if number of entries overflows size of this field (see Table 2-6).

s_nlnno

Not used. This field overlays the s_alignment and s_reserved fields.

s_alignment

(V5.1 - ) Contains a power-of-two biased alignment factor. The alignment is calculated by adding 3 to this value and interpreting the sum as a power of two. The value 0 is interpreted as 16 byte alignment because this is the minimum section rounding allowed. The maximum value that can be represented is 15 which is 256k byte alignment.


Version Note

For object formats less than V3.13 the value of this field may not be zero and should be ignored.


s_reserved

(V5.1 - ) Reserved. Must be zero.


Version Note

For object formats less than V3.13 the value of this field may not be zero and should be ignored.


s_flags

Flags identifying the section (see Table 2-6). Not all of these flag values are single bit masks. See Section 2.3.6 for information on testing section flags.

Table 2-5:  Section Header Constants for Section Names

Symbol Field Contents Description
_TEXT .text Text section
_INIT .init Initialization text section
_FINI .fini Termination (clean-up) text section
_RCONST .rconst Read-only constant section
_RDATA .rdata Read-only data section
_DATA .data Large data section
_LITA .lita Literal address pool section
_LIT8 .lit8 8-byte literal pool section
_LIT4 .lit4 4-byte literal pool section
_SDATA .sdata Small data section
_BSS .bss Large bss section
_SBSS .sbss Small bss section
_UCODE .ucode (obsolete) Ucode section
_GOT1 .got Global offset table
_DYNAMIC1 .dynamic Dynamic linking information
_DYNSYM1 .dynsym Dynamic linking symbol table
_REL_DYN1 .rel.dyn Relocation information
_DYNSTR1 .dynstr Dynamic linking strings
_HASH1 .hash Dynamic symbol hash table
_MSYM1 .msym Additional dynamic linking symbol table
_LIBLIST1 .liblist Shared library dependency list
_CONFLICT1 .conflict Additional dynamic linking information. (This name is truncated to .conflic when stored in the s_name field of the section header.)
_XDATA2 .xdata Runtime procedure descriptors and GP range information
_PDATA2 .pdata Code range descriptors
_TLS_DATA .tlsdata Initialized TLS data
_TLS_BSS .tlsbss Uninitialized TLS data
_TLS_INIT .tlsinit Initialization for TLS data
_COMMENT .comment Comment section

Table Notes:

  1. These sections exist only in dynamic executables and shared libraries and are used during dynamic linking. See Chapter 6 for details.

  2. The .xdata and .pdata sections contain exception-handling data. See the Calling Standard for Alpha Systems for details. Other sections are described in Chapter 3.

Table 2-6:  Section Flags (s_flags field)

Symbol Value Description
STYP_REG 0x00000000 Regular section: allocated, relocated, loaded. User section flags have this setting.
STYP_TEXT 0x00000020 Text only
STYP_DATA 0x00000040 Data only
STYP_BSS 0x00000080 Bss only
STYP_RDATA 0x00000100 Read-only data only
STYP_SDATA 0x00000200 Small data only
STYP_SBSS 0x00000400 Small bss only
STYP_UCODE 0x00000800 (obsolete) Ucode
STYP_GOT1 0x00001000 Global offset table
STYP_DYNAMIC1 0x00002000 Dynamic linking information
STYP_DYNSYM1 0x00004000 Dynamic linking symbol table
STYP_REL_DYN1 0x00008000 Dynamic relocation information
STYP_DYNSTR1 0x00010000 Dynamic linking symbol table
STYP_HASH1 0x00020000 Dynamic symbol hash table
STYP_DSOLIST1 0x00040000 Shared library dependency list
STYP_MSYM1 0x00080000 Additional dynamic linking symbol table
STYP_CONFLICT1 0x00100000 Additional dynamic linking information
STYP_FINI 0x01000000 Termination text only
STYP_COMMENT 0x02000000 Comment section
STYP_RCONST 0x02200000 Read-only constants
STYP_XDATA 0x02400000 Runtime procedure descriptors and GP range information
STYP_TLSDATA 0x02500000 Initialized TLS data
STYP_TLSBSS 0x02600000 Uninitialized TLS data
STYP_TLSINIT 0x02700000 Initialization for TLS data
STYP_PDATA 0x02800000 Code range descriptors
STYP_RESTEXT 0x02900000 (not supported) Resident text
STYP_LITA 0x04000000 Address literals only
STYP_LIT8 0x08000000 8-byte literals only
STYP_EXTMASK 0x0ff00000 Identifies bits used for multiple bit flag values.
STYP_LIT4 0x10000000 4-byte literals only
S_NRELOC_OVFL2 0x20000000 Indicates that section header field s_nreloc overflowed
STYP_INIT 0x80000000 Initialization text only

Table Notes:

  1. These sections exist only in dynamic executables and shared libraries and are used during dynamic linking. See Chapter 6 for details.

  2. The S_NRELOC_OVFL flag is used when the number of relocation entries in a section overflows the s_nreloc field in the section header. In this case, s_nreloc contains the value 0xffff and the s_flags field has the S_NRELOC_OVFL flag set. The actual relocation count is in the first relocation entry for the section.


Version Note

The value STYP_RESTEXT is reserved for use on Tandem big-endian systems. It is not supported on Tru64 UNIX.


General Notes:

The system linker uses the s_flags field instead of s_name to determine the section type. User-defined sections (see Section 3.3.10) constitute an exception; they are identified exclusively by section name.

Each section header must be unique within the object file. For system-defined sections, both the section name and flags must be unique. For user-defined sections, the name must be unique.

2.3    Header Usage

2.3.1    Object Recognition

Object file consumers use the file header to recognize an input file as an object file. Other tools that do not support objects may use the file header to determine that they cannot process the file. The file command can also identify an object by means of the file and a.out headers.

A file is identified as an object in its first 16 bits. These bits correspond to the magic number field in the file header. Objects built for the Alpha architecture are identified by the magic number ALPHAMAGIC; equivalent compressed objects are identified by ALPHAMAGICZ. Foreign objects, which are objects built for other architectures, may also be positively identified. However, once a foreign object is recognized, it is not considered to be a linkable or executable object file on the Alpha system.

In addition to providing basic identification, the file header also provides a high-level description of the object file through its flags field. File header flags store the following information: whether the object is executable, whether symbol table sections have been stripped, whether the file is suitable for creation of a shared library, and more. See Table 2-2 for a list of all flags.

The a.out header magic numbers also contribute important information about the file format. The magic numbers signify different organizations of object file sections and indicate where the image will be mapped into memory (see Section 2.3.2).

2.3.2    Image Layout

The a.out header stores run-time information about the object. Its magic number field indicates how the file is to be organized in virtual memory. Note that the contents and ordering of the sections of the image can be affected by compilation options and program contents in addition to the MAGIC classification.

The possible image formats are:

Impure Format ( OMAGIC)

OMAGIC files are typically relocatable object files. They are referred to as "impure" because the text segment is writable.

Shared Text Format ( NMAGIC)

NMAGIC files are static executables that use a different organization from the default ZMAGIC layout. The NMAGIC format is historical and offers no special advantages. This format can be selected by using the linker option -n or -nN in conjunction with -non_shared. In an NMAGIC file, the text segment is shared.

Demand Paged Format ( ZMAGIC)

ZMAGIC files are executable files or shared libraries. This format is referred to as demand-paged because its segments are blocked on page boundaries, allowing the operating system to page in text and data as needed by the running process. By default, the linker aligns ZMAGIC segments on 64K boundaries, the maximum possible page size on Alpha systems.

The ordering of sections within segments is flexible. Diagrams in this section depict the default ordering as laid out by the linker.

The default segment ordering, which places the text segment before the data segment, is flexible. However, the bss segment is required to contiguously follow the data segment, wherever the data segment is located.

All three formats are constrained by the following restrictions:

2.3.2.1     OMAGIC

The OMAGIC format typically has the following layout and characteristics:

Figure 2-1:   OMAGIC Layout

Starting addresses can be specified for the text and data segments using -T and -D options. These addresses can be anywhere in the virtual address space but must be aligned on a 16-byte boundary.

OMAGIC layout is most commonly used for pre-link object files produced by compilers. Post-link OMAGIC files tend to be used for special purposes such as loadable device drivers and om input objects.

Loadable device drivers must be built as OMAGIC files because the kernel loader kloadsrv relies upon relocation information in order to link objects into the kernel image.

OMAGIC files can also be executable. An important example of an OMAGIC executable file is the kernel, /vmunix. A programmer might also choose to use an OMAGIC format for self-modifying programs or for any other application that has a reason to write to the text segment.

2.3.2.2     NMAGIC

The NMAGIC file format is of historical interest only.

The NMAGIC format typically has the following layout and characteristics:

Figure 2-2:   NMAGIC Layout

Addresses can be specified for the start of the text and data segments using -T and -D options. These addresses may be anywhere in the virtual address space but must be a multiple of the page size.

2.3.2.3     ZMAGIC

The ZMAGIC format typically has the following layout and characteristics:

Figure 2-3:   ZMAGIC Layout for Shared Object

Figure 2-4:   ZMAGIC Layout for Static Executable Objects

The .rdata and .tlsinit sections are shown as part of the text segment. However, it is possible that one or both of those sections might be in the data segment. They are placed in the data segment only if they contain dynamic relocations.

Addresses can be specified for the start of the text and data segments using -T and -D options. Those addresses can be anywhere in the virtual address space but must be a multiple of the page size.

2.3.3    Address Space

At load time, an executable object is mapped into the system's virtual memory using one of the formats detailed in Section 2.3.2. The user can choose where the object, transformed into the program image, will be loaded, but system-specific constraints exist. This section discusses the general layout of the address space and the various considerations involved in choosing memory locations for object file segments.

Figure 2-5 shows the default memory scheme for a dynamic image.

Figure 2-5:  Address Space Layout

The stack is used for storing local variables. It grows toward zero. The stack pointer (stored in register $sp) points to the top of the stack at all times. In generated code, items on the stack are often referenced relative to the stack pointer.

The program heap is reserved for system memory-allocation calls (brk() and sbrk() ). TLS sections are allocated from the heap. The heap begins where the bss segment of the program ends, and the special symbol _end indicates the start of the heap. The heap's placement can also be calculated using the starting addresses and sizes of segments in the a.out header. The mapping of shared libraries may impose an upper bound on the heap's size. Some programs do not have a heap.

The dynamic loader and shared libraries reside in memory during program execution. See Section 6.3.2 for details.

User programs can request additional memory space that is dynamically allocated. One way to request space is through an anonymous mmap() call. This system call creates a new memory region belonging to the process. The user can attempt to specify the address where the region will be placed. However, if it is not possible to accommodate that placement, the system will rely on environment variables to dictate placement. See the mmap(2) man page for details.

The usable address range for user mode addresses is 0x0 - 0x40000000000. Attempts to map object file segments outside this range will fail, and the defaults will be invoked or execution aborted.

2.3.3.1    Address Selection

Several mechanisms permit the user to select addresses for loadable objects or assist the user in choosing viable addresses. Unless there is a good reason to do otherwise, it is preferable to rely on system defaults, which are designed to enhance performance and reduce conflicts.

The linker's -T and -D options may be used to specify the starting addresses for the text and data segments of an executable, respectively. Use of these options may be appropriate for large applications with dependencies on many shared libraries that need to explicitly manage their address space. Programs relying in any way on fixed addresses may also need to control the segment placement.

Another use of the address selection options is to place an application in the lowest 31 bits of the address space. To restrict an application to this part of the address space, the -T and -D switches may be used in conjunction with the -taso option (see Section 2.3.3.2) or separately.

The default placement of the text and data segments at 0x120000000 and 0x140000000 for executables means the default maximum size of the text segment is 0x20000000 bytes, or approximately 500MB. If this space is insufficient, the -D option can be used to enlarge it by specifying a higher starting address for the data segment.

The -T and -D options can also be used to change the segment ordering. Some applications, such as those ported from other platforms onto the Alpha platform, may rely upon the data segment being mapped in lower addresses than the text segment.

If only -T or only -D is specified on the link line, system defaults are used for the nonspecified address. If a given address is not properly aligned, the linker rounds the value to the applicable boundary. If inappropriate addresses are chosen, such as addresses for the text and data segments that are too far apart, linking may fail. Alternatively, linking may succeed, but execution can abnormally terminate if addresses are incompatible with the system memory configuration.

The linker option -B, which specifies a placement for the bss segment, is available for partial links only. For executable objects, the bss segment should be contiguous with the data segment, which is the system default. As a general rule, the -B option should not be used.

Another mechanism permits address selection for shared libraries. A registry file, by default named so_locations, stores shared library segment addresses and sizes. The so_locations directives, described in the Programmer's Guide, can be used to control the linker's address selection for shared libraries.

2.3.3.2    TASO Address Space

The TASO (Truncated Address Space Option) address space is a 32-bit address-space emulation that is useful for porting 32-bit applications to 64-bit Alpha systems. Selection of the -taso linker option causes object file segments to be loaded into the lower 31 bits of the memory space. This can also be accomplished, in part, by using -T and -D. If the -taso option is used in conjunction with the -T or -D options, the addresses specified with -T and -D take precedence.

Use of the -taso option also causes shared libraries linked outside the 31-bit address space to be appropriately relocated by the loader. All executable objects and shared libraries will be mapped to the address range 0x0 - 0x7fffffff.

The default segment addresses for a TASO executable are 0x12000000 for the text segment and 0x14000000 for the data segment, with the bss segment directly following the data segment. The -T and -D options can be used to alter the segment placement if necessary.

Figure 2-6 is a diagram of the TASO address space layout.

Figure 2-6:  TASO Address Space Layout

A TASO shared object is marked as such with the RHF_USE_31BIT_ADDRESSES flag in the DT_FLAGS entry in the dynamic header. The loader recognizes dynamic executable objects marked with the TASO flag and maps their shared library dependencies to the TASO address space. A TASO static executable is not explicitly identified.

2.3.4    GP (Global Pointer) Ranges

Programs running on Tru64 UNIX obtain the addresses of procedures and global data by means of a GP (Global Pointer) and an address table. Address ranges and address-table sections (.lita and .got) are described further in Section 3.3.2 and Section 6.3.3. However, several important pieces of information concerning GP-relative addressing are contained in the headers.

During program execution, the global pointer register ($gp ) contains the active GP value. This value is used to access run-time addresses stored in the image's address-table section. Addresses are specified in generated code as an offset to the GP.

There are several reasons for using this GP-relative addressing technique:

A GP range is the set of addresses reachable from a given GP. The size of this range is approximately 64KB, or 8K 64-bit addresses.

Although only one GP value is active at any time, a program can use several GP values. A program's text can be divided into ranges of addresses with a different GP value for each range. The linker will start a new GP range at a boundary between two input object file's section contributions. As a result, a GP range will rarely be filled before a new GP range is started. Regardless of how much of a GP range is actually used, the linker always sets the GP value associated with that range as follows:

  GP value = GP range start address + 32752  
 

Figure 2-7 is a depiction of the use of GP values and ranges.

Figure 2-7:  GP (Global Pointer) Ranges

Objects can share a GP range, as shown in Figure 2-7, or use more than one GP range, depending on the amount of program data. However, the Calling Standard for Alpha Systems specifies that a single procedure can use only one GP value. The a.out header's gp_value field contains either the GP value of the object (if there is only one) or the first one the program should use (if there are multiple GP ranges).

How the number of GP ranges is represented in an object depends on the object's type:

2.3.5    Alignment

Alignment is an architectural issue that must be dealt with in the object file at several levels: object file segments, object file sections, and program variables all have alignment requirements.

Data alignment refers to the rounding that must be applied to a data item's address. For natural alignment, a data item's address must be a multiple of its size. For example, the natural alignment of a character variable is one byte, and the natural alignment of a double-precision floating-point variable is 8 bytes.

On Alpha systems, all data should be aligned on proper boundaries. Unaligned references can result in substantially slower access times or cause fatal errors. The compiler and the user have some control over the alignments through the use of assembler directives and compilation flags (see the Programmer's Guide and Assembly Language Programmer's Guide). When designing alignment attributes, however, the architectural cost of loading unaligned values should be considered.

Object file segments are, by default, aligned as indicated in Section 2.3.2. Segment alignment can be impacted by section alignment. The segment alignment must be evenly divisible by the highest alignment factor for sections contained in that segment.

For shared libraries that are not mapped at their quickstart addresses the loader will map segments with a minimum alignment of 8K bytes. If any section in the shared library requires an alignment greater than 8K bytes, the loader will map the text segment with 64K byte alignment. The linker is responsible for assigning segment addresses with a distance that is a 64K byte multiple. This will allow the loader to align the data segment address which is mapped at a fixed distance from the text segment.

Object file sections may have a power-of-two alignment factor specified in their section headers (see Section 2.2.3). The default section alignment is 16 bytes.


Version Note

Power-of-two section alignment is supported in object format V3.13 and greater for Tru64 UNIX V5.1 and greater.


The default alignment boundary for raw data is 16 bytes. Smaller alignments can be applied to individual data items allocated in raw section data. If a data item must be aligned with greater than 16 byte alignment, the section in which it is allocated must be aligned with a power-of-two alignment factor that is greater than or equal to the data item's required alignment.

Individual data items should meet the following minimum requirements. Structure members and array elements are aligned according to the minimum requirements in order to minimize pad bytes between members. Other data items are typically aligned with 8 or 16 byte rounding due to alignment requirements imposed by the generated code used to access data addresses.


Version Note

The definition of a power-of-two alignment field in external symbol table entries is supported in Tru64 UNIX V5.1 and greater. Objects built by compilers that do no support the alignment field will appear to have the alignment set to 0 which will yield the desired default behavior.


Sections are padded wherever necessary to maintain proper alignment. Padding is done with zero bytes in the data and bss sections. In the text segment, each routine is padded with NOP instructions to a 16-byte boundary. The section sizes reported in the section headers and the segment sizes reported in the a.out header reflect this padding.

2.3.6    Section Types

The primary unit of an object file is a section, and the sections in an object are identified, located, and broadly characterized by means of the section headers. Object files are organized into sections primarily to enable the linker to combine multiple input objects into an executable image. At link time, sections of the same type are concatenated or merged. The sectional breakdown also provides the linker flexibility in segment mapping; the linker has a choice in assigning sections to segments for memory-mapping and loading.

Section headers include flags that describe the section type. These flags identify the section type and attributes. See Table 2-6 for a complete listing of section flags. Note that the s_flags field cannot be treated as a simple bit vector when testing or accessing section types because some of the flag values are overloaded. The algorithm below illustrates how to test for a particular section type using the s_flags field.

if (type & STYP_EXTMASK)
    FOUND = ((SHDR.s_flags & STYP_EXTMASK) == type)
else
    FOUND = (SHDR.s_flags & type)

Sections can be mapped or unmapped. A mapped section is one that is part of the process image as well as the object file. An unmapped section is present only in the on-disk object file.

Raw data, organized by section and segment, is part of the process image. For a ZMAGIC file, all header sections in the object are also mapped into memory as part of the text segment.

2.3.7    Special Symbols

Some special symbol names are reserved for use by the linker or loader. The majority of these special symbols correspond to locations in the image layout.

Table 2-7 describes the special symbols and indicates whether they are reserved for the linker or the loader. Additional special symbols for debug information are described in Section 5.3.9.

Table 2-7:  Special Symbols

Linker Reserved Symbols
Symbol Description
_BASE_ADDRESS3 Base address of text segment.
_cobol_main First COBOL main symbol; undefined if not a COBOL program.
_DYNAMIC Starting address of .dynamic section if present; otherwise, zero.
_DYNAMIC_LINK Enumeration value identifying module type: 0 = static executable, 1 = dynamic executable, 2 = shared library.
_ebss End of bss segment.
_edata End of data segment.
edata1 Weak symbol for end of data segment.
_end End of bss segment.
end1 Weak symbol for end of bss segment.
_etext End of text segment.
etext1 Weak symbol for end of text segment.
_fbss First location of bss data. Usually the virtual address of either the .sbss or .bss section.
_fdata First location of initialized data. Usually the virtual address of the .data section and data segment.
_fpdata Start of .pdata section.
_fpdata_size Number of entries in .pdata. The exception-handling object file sections (.pdata and .xdata) are included in the output object if this symbol is referenced.
__fstart Start of .fini section.
_ftext First location of executable text. Usually the virtual address of the .text section.
_ftlsinit The address of the .tlsinit section.
_GOT_OFFSET3 Starting address of .got section if present; otherwise, zero.
_gp3 GP value stored in a.out header.
_gpinfo Table of GP ranges used exclusively by exception handling code.
__istart Start of .init section.
_procedure_string_table2 String table for run-time procedures
_procedure_table2 Run-time procedure table.
_procedure_table_size2 Number of entries in run-time procedure table.
__tlsbsize Size of the .tlsbss section.
__tlsdsize Size of the .tlsdata section.
__tlskey The value of this symbol is the address of the GOT or .lita entry of the tlsoffset symbol.
__tlsoffset Offset in the TSD array of the TLS pointer for a particular object. For static executables, this value is set at link time. For shared objects, the value is set to 0 at link time and filled in at run time.
__tlsregions The number of TLS regions (TSD entries) that are used by an executable or library.
Loader Reserved Symbols
_ldr_process_context Points to loader's data structures.
ldr_process_context1 Weak symbol pointing to loader's data structures.
_rld_new_interface The generic loader entry point servicing all loader function calls.

Table Notes:

  1. These symbols are not defined under strict ANSI standards. They are weak symbols that are retained for backward compatibility. See Section 6.3.4.2 for further discussion of weak aliasing to strong symbols.

  2. These symbols relate to the run-time procedure table, which is a table of RPDR structures (their declaration is in the header file sym.h). The table is a subset of the procedure descriptor table portion of the symbol table with one unused field, exception_info, that is set to zero. The run-time procedure table is maintained for historical reasons. It is not used by the system's exception handling software, nor any other Tru64 UNIX runtime support.

  3. These symbols are recorded as scAbs symbols in the external symbol table, but their values are relocatable addresses that are not absolute values in a shared library. This misclassification is maintained partly for historical reasons, and partly because the values of these symbols cannot be described as an offset within a specific section. The equivalent dynamic symbol table entries identify these symbols as text ( SHN_TEXT) or data symbols ( SHN_DATA) rather than absolute symbols ( SHN_ABS).


    Version Note

    Prior to Tru64 UNIX V5.1 the system linker records these symbols as absolute symbols ( SHN_ABS) in the dynamic symbol table, and they are not relocated correctly by the dynamic loader.


The linker defines special symbols only if they are referenced.

The majority of these symbols have local binding in a shared object's dynamic symbol table. Consequently, a shared object can only reference its own definition of these symbols. However, several special symbols have global scope. The linker-defined symbols end, _end, __istart, and _cobol_main are global, which implies that each has a unique value process-wide. The symbol _end and its weak counterpart end are used by libc.so to identify the start of the heap in memory. The symbol _cobol_main gives a COBOL program's main entry point.

Special symbols in addition to those listed in Table 2-1 are defined by the linker to represent object file section addresses:

.bss
.comment
.data
.fini
.init
.lit4
.lit8
.lita
.pdata
.rconst
.rdata
.sbss
.sdata
.text
.xdata

The value of the symbol is the starting address of the corresponding section. These symbols generally are not referenced by user code. For shared objects, they may appear in the dynamic symbol table.

2.3.7.1    Accessing

A user program can reference, but not define, reserved symbols. An error message is generated if a user program attempts to define a symbol reserved for system use.

A special symbol is a label, and thus its value is its address. Interpreting a label's contents as its value may lead to an access violation, particularly for those linker-defined symbols that are not address locations within the image (for example, _DYNAMIC_LINK or _procedure_table_size).

The following example shows how linker-defined labels are referenced in code:

$ cat gprange.c
#include <stdio.h>
#include <excpt.h>
 
extern unsigned long _gpinfo[];
extern unsigned long _ftext;
extern unsigned long _fdata;
 
main(){
    int i;
    unsigned long tstart, tend;
    unsigned long gpval;
 
    if (!_gpinfo || _gpinfo[0] != GPINFO_MAGIC) {
        printf("No GP range info\n");
 
    } else {
        for (i=1; _gpinfo[i] != GPINFO_LAST; i+=3){
 
            tstart = (unsigned long)&_ftext + _gpinfo[i];
            tend = tstart + _gpinfo[i+1];
 
            gpval = (unsigned long)&_fdata + _gpinfo[i+2];
 
            printf("GP=0x%lx for Text Range [0x%lx - 0x%lx]\n",
                   gpval, tstart, tend);
        }
    }
}

$ cc gprange.c
$ a.out
GP=0x1400080c0 for Text Range [0x120000fe0 - 0x120001440]

This example prints out the GP ranges recorded in the .xdata section. See Section 3.3.8 for a description of the GP range info.

2.4    Language-Specific Header Features

The linker-defined symbol _cobol_main is set to the symbol value of the first external symbol encountered by the linker with its cobol_main flag set. COBOL programs use this symbol to determine the program entry point.