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:
The file header identifies the object file and indicates its type.
The
a.out
header provides the size, location,
and addresses of the object's segments.
Section headers store the name, size, and mapped address of their sections and contain the locations of the section's raw data and relocation entries. Each object file section that is not part of the symbol table has a section header.
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:
A new section header definition that uses reserved bits for specifying section alignment (see Section 2.2.3).
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
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
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. |
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 |
_GOT 1 |
.got |
Global offset table |
_DYNAMIC 1 |
.dynamic |
Dynamic linking information |
_DYNSYM 1 |
.dynsym |
Dynamic linking symbol table |
_REL_DYN 1 |
.rel.dyn |
Relocation information |
_DYNSTR 1 |
.dynstr |
Dynamic linking strings |
_HASH 1 |
.hash |
Dynamic symbol hash table |
_MSYM 1 |
.msym |
Additional dynamic linking symbol table |
_LIBLIST 1 |
.liblist |
Shared library dependency list |
_CONFLICT 1 |
.conflict |
Additional dynamic linking information.
(This name
is truncated to
.conflic
when stored in the
s_name
field of the section header.) |
_XDATA 2 |
.xdata |
Runtime procedure descriptors and GP range information |
_PDATA 2 |
.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:
These sections exist only in dynamic executables and shared libraries and are used during dynamic linking. See Chapter 6 for details.
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_GOT 1 |
0x00001000 |
Global offset table |
STYP_DYNAMIC 1 |
0x00002000 |
Dynamic linking information |
STYP_DYNSYM 1 |
0x00004000 |
Dynamic linking symbol table |
STYP_REL_DYN 1 |
0x00008000 |
Dynamic relocation information |
STYP_DYNSTR 1 |
0x00010000 |
Dynamic linking symbol table |
STYP_HASH 1 |
0x00020000 |
Dynamic symbol hash table |
STYP_DSOLIST 1 |
0x00040000 |
Shared library dependency list |
STYP_MSYM 1 |
0x00080000 |
Additional dynamic linking symbol table |
STYP_CONFLICT 1 |
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_OVFL 2 |
0x20000000 |
Indicates that section header field
s_nreloc
overflowed |
STYP_INIT |
0x80000000 |
Initialization text only |
Table Notes:
These sections exist only in dynamic executables and shared libraries and are used during dynamic linking. See Chapter 6 for details.
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:
OMAGIC
)
OMAGIC
files are
typically relocatable object files.
They are referred to as "impure"
because
the text segment
is writable.
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.
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:
Segments must not overlap.
The
bss
segment must follow the data segment.
All text
addresses in the object file must be within two gigabytes (0x7fff8000
) of all data addresses in the file.
The
OMAGIC
format typically has the following layout
and characteristics:
Segments must not overlap.
All text
addresses in the object file must be within two gigabytes (0x7fff8000
) of all data addresses in the file.
Starting section addresses are aligned on a 16-byte boundary.
Pre-link
OMAGIC
objects are zero-based, with the
data segment contiguous to the text segment.
The default text segment address
for partially linked objects is
0x10000000
, and the data
segment follows the text segment.
Usually contain relocation information.
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:
Segments must not overlap.
All text
addresses in the object file must be within two gigabytes (0x7fff8000
) of all data addresses in the file.
Text and data segment addresses fall on page-size boundaries. The bss segment is aligned on a 16-byte boundary.
By default,
the starting address of the text segment is
0x20000000
and the starting address of the data segment is
0x40000000
.
Cannot be a relocatable object, partially linked object, or a shared object.
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.
Segments must not overlap.
The bss segment must follow the data segment.
All text
addresses in the object file must be within two gigabytes (0x7fff8000
) of all data addresses in the file.
Text and data segments are blocked; the blocking factor is the page size.
By default the starting address of the text segment is
0x120000000
and the starting address of the data segment is
0x140000000
.
The bss segment follows the data segment.
Can be either a shared or static object, but not a relocatable object.
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:
Alpha instructions support only 16-bit relative addressing, but the generated code must be able to quickly and efficiently access arbitrary 64-bit addresses.
The generated code must be position independent.
The addressing method must support symbol preemption (see Section 6.3.4).
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:
For objects with a
.lita
section, the section
header field
s_nlnnoptr
indicates the number of GP ranges, as explained in
Section 2.2.3.
In
a relocatable object (
OMAGIC
file), a new GP range is signaled
by a
R_GPVALUE
relocation entry.
See
Section 4.3.4.18
for details.
In shared objects, multiple GP ranges are indicated by entries
in the dynamic header section
(.dynamic
), which are described in
Section 6.2.1.
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.
Atomic data items are aligned using natural alignment.
Structures are aligned based on the size of their largest member.
Arrays are aligned according to the alignment requirements of the array element.
Procedures are aligned on a 16-byte (quadruple instruction word) boundary. This preserves the integrity of multiple-instruction issue established by the instruction scheduling phase of code generation.
Common
storage class symbols must be aligned when they are allocated.
The
value
field for a common storage class symbol indicates its
size and determines which section it will be allocated in (.bss
or
.sbss
).
The
alignment
field
for the common storage class symbol indicates the required power-of-two alignment
biased by 2^3.
If
alignment
is zero, the default
alignment is based on the symbol's size.
Common storage class symbols with
a size of 16-bytes or greater are aligned to octaword (16-byte) boundaries,
otherwise they are aligned to quadword (8-byte) boundaries.
The maximum alignment
supported for allocating common storage class symbols is 64K bytes.
This
is represented in the
alignment
field as the value
"13".
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_ADDRESS 3
|
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. |
edata 1 |
Weak symbol for end of data segment. |
_end |
End of bss segment. |
end 1 |
Weak symbol for end of bss segment. |
_etext |
End of text segment. |
etext 1
|
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_OFFSET 3
|
Starting address of
.got
section
if present; otherwise, zero. |
_gp 3 |
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_table 2 |
String table for run-time procedures |
_procedure_table 2 |
Run-time procedure table. |
_procedure_table_size 2 |
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_context 1 |
Weak symbol pointing to loader's data structures. |
_rld_new_interface |
The generic loader entry point servicing all loader function calls. |
Table Notes:
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.
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.
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.