This chapter provides details on how compiler-system object files are formatted and processed.
The chapter addresses the following topics:
The assembler and the linker generate object files. The sections in the object files are ordered as shown in Figure 7-1. Sections that do not contain data are omitted, except for the file header, optional header, and section header, which are always present.
Object files also contain a symbol table, which is also divided into sections. Figure 7-1 shows all of the possible sections in a symbol table. The sections of the symbol table that appear in a final object file can vary:
-g1
,
-g2
,
or
-g3
compilation options).
-x
option (strip nonglobals) for the link-edit phase, the linker updates
the procedure descriptor table and strips the following tables from
the object file: line number table, local symbols table, optimization
symbols table, auxiliary symbols table, local strings table, and
relative file descriptor table.
-s
option (strip) for the link-edit phase.
Any new assembler or linker designed to work with the compiler system should lay out the object file sections in the order shown in Figure 7-1. The linker can process object files that are ordered differently, but performance may be degraded.
The standard System V COFF (common object file format) differs from the Digital UNIX compiler system format in the following ways:
filehdr.h
with the following modifications:
aouthdr.h
,
except the following fields have been added:
bldrev
,
bss_start
,
gprmask
,
fprmask
,
and
gp_value
(see
Table 7-4).
scnhdr.h
,
except the line number fields are used for global pointers (see
Table 7-6).
The definition of the section relocation information is similar to UNIX 4.3 BSD, which has local relocation types. Section 7.2.5 provides information on differences between local and external relocation entries.
The following sections describe the components of an object file. Headers are informational and provide the means for navigating the object file. Sections contain program instructions or data (or both).
The format of the file header is shown in
Table 7-1.
The file header and all of the fields described in this
section are defined in
filehdr.h
.
Declaration Type | Field | Description |
unsigned short
|
f_magic
|
Target-machine magic number (see Table 7-2) |
unsigned short
|
f_nscns
|
Number of sections |
int
|
f_timdat
|
Time and date stamp |
long
|
f_symptr
|
File pointer to symbolic header (see Chapter 8 for a description of the symbolic header) |
int
|
f_nsyms
|
Size of symbolic header |
unsigned short
|
f_opthdr
|
Size of optional header |
unsigned short
|
f_flags
|
Flags (see Table 7-3) |
The magic number in the
f_magic
field in the file header specifies the target machine on which an
object file can execute.
Table 7-2
shows the octal values and mnemonics for the magic numbers.
Symbol | Value | Description |
ALPHAMAGIC
|
0603 | Machine-code object file |
ALPHAUMAGIC
|
0617 | Ucode object file |
The
f_flags
field in the file header describes the object file characteristics.
Table 7-3
lists the flags and gives their hexadecimal values and their
meanings. The table notes
those flags that do not apply to compiler system object files.
Symbol | Value | Description |
F_RELFLG
|
0x0001 | Relocation information stripped from file |
F_EXEC
|
0x0002 | File is executable (that is, no unresolved external references) |
F_LNNO
|
0x0004 | Line numbers stripped from file |
F_LSYMS
|
0x0008 | Local symbols stripped from file |
F_NO_SHARED
|
0x0010 | Object file cannot be used to create a shared library |
F_NO_CALL_SHARED
|
0x0020 |
Object file cannot be used to create a
-call_shared
executable file
|
F_LOMAP
|
0x0040 |
Allows an executable file to be loaded at an address less than
VM_MIN_ADDRESS
|
F_AR16WR
|
0x0080 | File has the byte ordering of an AR16WR machine (for example, PDP-11/70) |
F_AR32WR
|
0x0100 | File has the byte ordering of an AR32WR machine (for example, VAX) |
F_AR32W
|
0x0200 | File has the byte ordering of an AR32W machine (for example, 3b, maxi, MC68000) |
F_PATCH
|
0x0400 | File contains "patch" list in optional header |
F_NODF
|
0x0400 | (Minimal file only.) No decision functions for replaced functions |
F_MIPS_NO_SHARED
|
0x1000 | Cannot be dynamically shared |
F_MIPS_SHARABLE
|
0x2000 | A dynamically shared object |
F_MIPS_CALL_SHARED
|
0x3000 | Dynamic executable file |
F_MIPS_NO_REORG
|
0x4000 | Do not reorder sections |
F_MIPS_NO_REMOVE
|
0x8000 | Do not remove nops |
Table Note:
The linker and the assembler fill in the optional header, and the dynamic loader, or other program that loads the object module at run time, uses the information it contains, as described in Section 7.4.
Table 7-4
shows the format of the optional header (which is defined in the
header file
aouthdr.h
).
Declaration | Field | Description |
short
|
magic
|
Object-file magic numbers (see Table 7-5) |
short
|
vstamp
|
Version stamp |
short
|
bldrev
|
Revision of build tools |
long
|
tsize
|
Text size in bytes, padded to 16-byte boundary |
long
|
dsize
|
Initialized data in bytes, padded to 16-byte boundary |
long
|
bsize
|
Uninitialized data in bytes, padded to 16-byte boundary |
long
|
entry
|
Entry point |
long
|
text_start
|
Base of text used for this file |
long
|
data_start
|
Base of data used for this file |
long
|
bss_start
|
Base of bss used for this file |
int
|
gprmask
|
General-purpose register mask |
int
|
fprmask
|
Floating-point register mask |
long
|
gp_value
|
The gp (global pointer) value used for this object |
Table 7-5
shows the octal values of the
magic
field for the optional header; the header file
aouthdr.h
contains the macro definitions.
Symbol | Value | Description |
OMAGIC
|
0407 | Impure format - The text is not write-protected or shareable; the data segment is contiguous with the text segment. |
NMAGIC
|
0410 | Shared text - The data segment starts at the next page following the text segment, and the text segment is write-protected. |
ZMAGIC
|
0413 | The object file is to be paged in on demand (demand paged) and has a special format; the text and data segments are separated. The Alpha system provides write-protection for the text segment. (Other systems using COFF may not provide write-protection.) The object can be either dynamic or static. |
See Section 7.3 for information on the format of OMAGIC, NMAGIC, and ZMAGIC files.
Table 7-6
shows the format of the section header (which is defined in the header
file
scnhdr.h
).
Declaration | Field | Description |
char
|
s_name[8]
|
Section name (see Table 7-7) |
long
|
s_paddr
|
Physical address |
long
|
s_vaddr
|
Virtual address |
long
|
s_size
|
Section size |
long
|
s_scnptr
|
File pointer to raw data for the section |
long
|
s_relptr
|
File pointer to relocations for the section |
long
|
s_lnnoptr
|
For
.pdata ,
indicates the number of entries contained in the section; otherwise,
reserved.
|
unsigned short
|
s_nreloc
|
Number of relocation entries |
unsigned short
|
s_nlnno
|
Number of global pointer tables |
int
|
s_flags
|
Flags (see Table 7-8) |
Table 7-7
shows the defined section names for the
s_name
field of the section header.
Field | ||
Declaration | Contents | Description |
_TEXT
|
.text | Text section |
_INIT
|
.init | Initialization text section for shared libraries |
_FINI
|
.fini | Cleanup 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 | ucode section |
_GOT
|
.got | Global offset table |
_DYNAMIC
|
.dynamic | Dynamic linking information |
_DYNSYM
|
.dynsym | Dynamic linking symbol table |
_REL_DYN
|
.rel.dyn | Relocation information |
_DYNSTR
|
.dynstr | Dynamic linking strings |
_HASH
|
.hash | Symbol hash table |
_MSYM
|
.msym | Additional dynamic linking symbol table |
_CONFLICT
|
.conflict | Additional dynamic linking information |
_REGINFO
|
.reginfo | Register usage information |
_XDATA
|
.xdata | Exception scope table |
_PDATA
|
.pdata | Exception procedure table |
Table Notes:
Table 7-8
shows the defined hexadecimal values for the
s_flags
field.
(Those flags that are not used by compiler system object files are
noted in the table.)
Symbol | Value | Description |
STYP_REG | 0x00 | Regular section: allocated, relocated, loaded |
STYP_DSECT |
0x01 | Dummy section: not allocated, relocated, not loaded |
STYP_NOLOAD |
0x02 | Noload section: allocated, relocated, not loaded |
STYP_GROUP |
0x04 | Grouped section: formed of input sections |
STYP_PAD |
0x08 | Padding section: not allocated, not relocated, loaded |
STYP_COPY |
0x10 | Copy section (for decision function used by field update): not allocated, not relocated, loaded |
STYP_TEXT | 0x20 | Text only |
STYP_DATA | 0x40 | Data only |
STYP_BSS | 0x80 | Bss only |
STYP_RDATA | 0x100 | Read-only data only |
STYP_SDATA | 0x200 | Small data only |
STYP_SBSS | 0x400 | Small bss only |
STYP_UCODE | 0x800 | Ucode only |
STYP_GOT |
0x1000 | Global offset table |
STYP_DYNAMIC |
0x2000 | Dynamic linking information |
STYP_DYNSYM |
0x4000 | Dynamic linking symbol table |
STYP_REL_DYN |
0x8000 | Dynamic relocation information |
STYP_DYNSTR |
0x10000 | Dynamic linking symbol table |
STYP_HASH |
0x20000 | Dynamic symbol hash table |
STYP_MSYM |
0x80000 | Additional dynamic linking symbol table |
STYP_CONFLICT |
0x100000 | Additional dynamic linking information |
STYP_REGINFO |
0x200000 | Register usage information |
STYP_FINI | 0x01000000 | .fini section text |
STYP_COMMENT | 0x02000000 | Comment section |
STYP_RCONST | 0x02200000 | Read-only constants |
STYP_XDATA | 0x02400000 | Exception scope table |
STYP_PDATA | 0x02800000 | Exception procedure table |
STYP_LITA | 0x04000000 | Address literals only |
STYP_LIT8 | 0x08000000 | 8-byte literals only |
STYP_LIT4 | 0x10000000 | 4-byte literals only |
S_NRELOC_OVFL | 0x20000000 |
s_nreloc
overflowed, the value is in
r_vaddr
of the first entry
|
STYP_INIT | 0x80000000 | Section initialization text only |
Table Notes:
The
S_NRELOC_OVFL
flag is used when the number of relocation entries in a
section overflows the
s_nreloc
field of 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 value true is in the
r_vaddr
field of the first relocation entry for that section. That
relocation entry has a type of
R_ABS
and all other fields are zero, causing it to be ignored under
normal circumstances.
Note
For performance reasons, the linker uses the
s_flags
entry instead ofs_name
to determine the type of section. The linker does correctly fill in thes_name
entry, however.
Object files contain instructions and data. The instructions and data are stored in appropriate sections according to their use. Figure 7-2 shows the layout of section data in object files.
The sections that are present in the section data and the ordering of the sections depends on the options that are in effect for a particular compilation.
The
.conflict
,
.dynamic
.dynstr
,
.dynsym
,
.got
,
.hash
,
.liblist
,
.msym
,
and
.rel.dyn
sections exist only in shared object files and are used during
dynamic linking. These sections are described in more detail in
Chapter 9.
The following table
describes the uses of the other sections:
Section Name | Use |
.ucode
|
Intermediate code (if present, all other sections are excluded) |
.bss
|
Block started by symbol |
.data
|
Large data |
.fini
|
Process termination text |
.init
|
Initialization text |
.lit4
|
4-byte literal pool |
.lit8
|
8-byte literal pool |
.lita
|
Literal address pool (only present in nonshared object files) |
.pdata
|
Exception procedure table for pdata |
.rconst
|
Read-only constants |
.rdata
|
Read-only data |
.sbss
|
Small block started by symbol |
.sdata
|
Small data |
.text
|
Machine instructions to be executed |
.xdata
|
Exception scope table for xdata |
The
.text
section contains the machine instructions that are to be executed; the
.sdata
,
.lit4
,
.lit8
,
.rdata
,
.data
,
and
.rconst
sections contain initialized data; and the
.bss
and
.sbss
sections reserve space for uninitialized data that is created by the
dynamic loader for the program before execution and filled with zeros.
The only difference between
.rdata
and
.rconst
is that only
.rdata
can have dynamic relocations.
As indicated in Figure 7-2, the sections are grouped into segments:
.rdata
(for nonshared object files),
.fini
,
.init
,
.text
,
and
.rconst
sections in all files except shared object files, which contain
additional sections.
(The
.rdata
section can go in either the text or data segment, depending on the
object file type.)
.got
(for shared object files),
.sdata
,
.lit4
,
.lit8
,
.lita
(for nonshared object files),
.rdata
(for shared object files),
and
.data
.
.bss
and
.sbss
sections.
A section is described by and referenced through the section header (see Section 7.2.3); the optional header (see Section 7.2.2) provides the same information for segments.
The linker references the data shown in Figure 7-2 as both sections and segments. It references the sections through the section header and the segments through the optional header. However, the dynamic loader, when loading the object file at run time, references the same data only by segment, through the optional header.
Program instructions and data may contain addresses that must be adjusted when the object file is linked. Relocations locate the addresses within the section and indicate how they are to be adjusted.
Table 7-9
shows the format of an entry in the relocation table (defined in
the header file
reloc.h
).
Declaration | Field | Description |
long
|
r_vaddr
|
Virtual address of an item to be relocated. |
unsigned
|
r_symndx
|
For an external relocation entry,
r_symndx
is an index into external symbols.
For a local relocation entry,
r_symndx
is the number of the section containing the symbol.
|
unsigned
|
r_type:8
|
Relocation type (see Table 7-11). |
unsigned
|
r_extern:1
|
Set to 1 for an external relocation entry. Set to 0 for a local relocation entry. |
unsigned
|
r_offset:6
|
For
R_OP_STORE ,
r_offset
is the bit offset of a field within a quadword.
|
unsigned
|
r_reserved:11
|
Must be zero. |
unsigned
|
r_size:6
|
For
R_OP_STORE ,
r_size
is the bit size of a field.
|
The setting of
r_extern
and the contents of
r_symndx
vary for external and local relocation entries:
r_extern
is set to 1 and
r_symndx
is the index into external symbols. In this
case, the value of the symbol is used as the value for relocation (see
Figure 7-3).
r_extern
is set to 0, and
r_symndx
contains a constant that refers to a section (see
Figure 7-4).
In this case, the starting address of the section to which the
constant refers is used as the value for relocation.
Table 7-10
gives the section numbers for
r_symndx
;
the
reloc.h
file contains the macro definitions.
Symbol | Value | Description |
R_SN_TEXT
|
1 |
.text
section
|
R_SN_RDATA
|
2 |
.rdata
section
|
R_SN_DATA
|
3 |
.data
section
|
R_SN_SDATA
|
4 |
.sdata
section
|
R_SN_SBSS
|
5 |
.sbss
section
|
R_SN_BSS
|
6 |
.bss
section
|
R_SN_INIT
|
7 |
.init
section
|
R_SN_LIT8
|
8 |
.lit8
section
|
R_SN_LIT4
|
9 |
.lit4
section
|
R_SN_XDATA
|
10 |
.xdata
section
|
R_SN_PDATA
|
11 |
.pdata
section
|
R_SN_FINI
|
12 |
.fini
section
|
R_SN_LITA
|
13 |
.lita
section
|
R_SN_ABS
|
14 |
for
R_OP_xxxx constants
|
R_SN_RCONST
|
15 | .rconst section |
Table 7-11
shows valid symbolic entries for the
r_type
field (which is defined in the header file
reloc.h
).
Symbol | Value | Description |
R_ABS
|
0x0 | Relocation already performed. |
R_REFLONG
|
0x1 | 32-bit reference to the symbol's virtual address. |
R_REFQUAD
|
0x2 | 64-bit reference to the symbol's virtual address. |
R_GPREL32
|
0x3 | 32-bit displacement from the global pointer to the symbol's virtual address. |
R_LITERAL
|
0x4 | Reference to a literal in the literal address pool as an offset from the global pointer. |
R_LITUSE
|
0x5 |
Identifies an instance of a literal address previously loaded into a
register. The
r_symndx
field identifies the specific usage of the register. Table 7-12
lists the valid usage types.
|
R_GPDISP
|
0x6 |
Identifies an
lda/ldah
instruction pair that is used to initialize a procedure's
global-pointer register.
The
r_vaddr
field identifies one instruction of the pair. The
r_symndx
contains a byte offset, which when added to the
r_vaddr
field, produces the address of the other instruction of the pair.
|
R_BRADDR
|
0x7 | 21-bit branch reference to the symbol's virtual address. |
R_HINT
|
0x8 |
14-bit
jsr
hint reference to the symbol's virtual address.
|
R_SREL16
|
0x9 | 16-bit self-relative reference to the symbol's virtual address. |
R_SREL32
|
0xa | 32-bit self-relative reference to the symbol's virtual address. |
R_SREL64
|
0xb | 64-bit self-relative reference to the symbol's virtual address. |
R_OP_PUSH
|
0xc | Push symbol's virtual address on relocation expression stack. |
R_OP_STORE
|
0xd |
Pop value from the relocation expression stack and store at the
symbol's virtual address. The
r_size
field determines the number of bits stored. The
r_offset
field designates the bit offset from the symbol to the target.
|
R_OP_PSUB
|
0xe | Pop value from the relocation expression stack and substract the symbol's virtual address. The result is pushed on the relocation expression stack. |
R_OP_PRSHIFT
|
0xf | Pop value from the relocation expression stack and shift right by the symbol's value. The result is pushed on the relocation expression stack. |
R_GPVALUE
|
0x10 |
Specifies a new gp value is to be used starting with the address
specified by the
r_vaddr
field. The gp value is the sum of the optional header's
gp_value
field and the
r_symndx
field.
The
r_extern
field must be zero.
|
R_GPRELHIGH
|
0x11 |
Most significant 16 bits of 32-bit displacement from
$gp
value. This is the
ldah
instruction of an
ldah/lda ,
ldah/ldq ,
or
ldah/stq
pair that is calculating an address as a displacement from the
$gp
value. Sign-extension of both offsets is
assumed. This relocation must be
followed immediately by one or more corresponding
R_GPRELLOW
relocations.
|
R_GPRELLOW
|
0x12 |
Least significant 16 bits of a 32-bit displacement from
$gp
value. This is the second instruction of an
ldah/lda ,
ldah/ldq ,
or
ldah/stq
pair that is calculating an address as a displacement from the
$gp
value. This relocation should follow the corresponding
R_GPRELHIGH
relocation.
Each
R_GPRELHIGH
relocation can have one or more
R_GPRELLOW
relocations.
|
Table 7-12
shows valid symbolic entries for the symbol index
(r_symndx
)
field for the relocation type
R_LITUSE.
Symbol | Description |
R_LU_BASE
|
The base register of a memory format instruction (except
ldah )
contains a literal address.
|
R_LU_BYTOFF
|
The byte offset register
(Rb )
of a byte-manipulation instruction contains a literal address.
|
R_LU_JSR
|
The target register of a
jsr
instruction contains a literal address.
|
Object modules with all external references defined have the same format as relocatable modules and are executable without relinking.
Local relocation entries must be used for symbols that are defined, and external relocation entries are used only for undefined symbols. Figure 7-3 gives an overview of the relocation table entry for an undefined external symbol.
The assembler creates a relocation table entry for an undefined external symbol as follows:
r_vaddr
to point to the item to be relocated.
r_vaddr
).
r_symndx
to the index of the external symbols entry that contains the symbol
value (which is used as the value for relocation).
r_type
to the constant for the type of relocation types.
Table 7-11
shows the valid constants for the relocation type.
r_extern
to 1.
Note
The assembler always sets the value of the undefined external symbols entry to 0. It may assign a constant value to be added to the relocated value at the address where the location is to be done. For relocation types other than
R_HINT
, the linker flags this as an error if the width of the constant is less than a full quadword and an overflow occurs after relocation.
When the linker determines that an external symbol is defined, it changes the relocation table entry for the symbol to a local relocation entry. Figure 7-4 gives an overview of the new entry.
To change this entry from an external relocation entry to a local relocation entry, the linker performs the following steps:
r_vaddr
).
r_symndx
to the section number that contains the external symbol.
r_extern
to 0.
The following examples show the use of external
relocation entries:
This example shows assembly statements that set the value at location
b
to the global data value
y
.
.globl y .data b: .quad y # R_REFQUAD relocation type at address b for # symbol y
In processing this statement, the assembler generates a relocation
entry of type
R_REFQUAD
for the address
b
and the symbol
y
.
After determining the address for the symbol
y
,
the linker adds the 64-bit address of
y
to the 64-bit value at location
b
and places the sum in location
b
.
The linker handles 32-bit addresses
(R_REFLONG
)
in the same manner, except it checks for overflow after determining the
relocation value.
This example shows assembly statements that call routine
x
from location
c
.
.text x: #routine x ... c: bsr x # R_BRADDR relocation type at address c for symbol x
In processing these statements, the assembler generates a relocation
entry of type
R_BRADDR
for the address and the symbol
x
.
After determining the address for the routine, the linker subtracts
the address
c+4
to form the displacement to the routine.
Then, the linker adds this result (sign-extended and multiplied by 4)
to the 21 low-order bits of the instruction at address
c
,
and after checking for overflow, places the result (divided by 4)
back into the 21 low-order bits at address
c
.
R_BRADDR
relocation entries are produced for the assembler's
br
(branch) and
bsr
(branch subroutine) instructions.
If the entry is a local relocation type, the target of the branch instruction is assembled in the instruction at the address to be relocated. Otherwise, the instruction's displacement field contains a signed offset from the external symbol.
This example shows assembly language statements that set the value
at location
a
to the offset from the global pointer to the global data value
z
.
.globl z .data a: .gprel32 z # R_GPREL32 relocation type at address a for # symbol z
In processing this statement, the assembler generates a relocation
entry of type
R_GPREL32
for the address
a
and the symbol
z
.
After determining the address for the symbol
z
,
the linker adds the 64-bit displacement of
z
from the the global pointer
to the signed 32-bit value at location
a
,
and places the sum in location
a
.
The linker checks for overflow when performing the above operation.
This example shows an assembly language statement that loads the
address of the symbol
y
into register 22.
lda $22, y
In processing this statement, the assembler generates the following code:
.lita x: .quad y # R_REFQUAD relocation type at address x for # symbol y
.text h: ldq $22, n($gp) # R_LITERAL relocation type at address h # for symbol x
The assembler uses the difference between the address for the symbol
x
and the value of the global pointer as the value of the displacement
(n
)
for the instruction. The linker gets the value of the global pointer
used by the assembler from
gp_value
in the optional header (see
Table 7-4).
This example shows an assembly language statement that loads the 32-bit
value stored at address
y
into register 22.
ldl $22, y
In processing this statement, the assembler generates the following code:
.lita x: .quad y # R_REFQUAD relocation type at address x for # symbol y
.text h: ldq $at, n($gp) # R_LITERAL relocation type at address h # for symbol x i: ldl $22, 0($at) # R_LITUSE relocation type at address i; # r_symndx == R_LU_BASE
The assembler uses the difference between the address for the symbol
x
and the value of the global pointer as the value of the displacement
(n
)
for the
ldq
instruction. The linker gets the value of the global pointer used
by the assembler from
gp_value
in the optional header (see
Table 7-4).
This example shows an assembly language statement that reloads
the value of the global pointer after a call to procedure
x
.
# call to procedure x returns here with return address in ra ldgp $gp, 0(ra)
In processing this statement, the assembler generates the following code:
j: lda $at, <gp_disp>[0:15](ra) # R_GPDISP relocation type # at address j; # r_symndx contains byte offset # from address j to address k k: ldah $gp, <gp_disp>[16:31]($at)
The assembler determines the 32-bit displacement from the address
of the
ldgp
instruction to the global pointer and stores it into the offset
fields of the
lda
and
ldah
instructions. The linker gets the value of the global pointer used
by the assembler from
gp_value
in the optional header (see
Table 7-4).
This example shows an assembly language statement that makes an
indirect jump through register 24 and specifies to the
branch-prediction logic that the target of the
jsr
instruction is the address of the symbol
x
.
# get address of procedure to call into register 24 m: jsr ra, ($24), x # R_HINT relocation type at address m # for symbol x
In processing this statement, the assembler generates a relocation
entry of type
R_HINT
for the address
m
and the symbol
x
.
The linker creates files with the following object-file formats:
To understand the descriptions of these formats, you should be familiar with the format and contents of the text, data, and bss segments as described in Section 7.2.4.
The following constraints are imposed on the address at which an object can be loaded and the boundaries of its segments:
The operating system can dictate additional constraints.
An OMAGIC file has the format shown in Figure 7-5.
The OMAGIC format has the following characteristics:
-T
and
-D
options.
An NMAGIC file has the format shown in Figure 7-6.
An NMAGIC file has the following characteristics:
.data
section is on a
pagesize
boundary.
-T
and
-D
options, can be specified for a shared text format file; the
start of the text and data segments must be a multiple of the
page size.
A ZMAGIC file is a demand paged file. Figure 7-7 shows the format of a ZMAGIC file as it appears in virtual memory and on disk.
A ZMAGIC file has the following characteristics:
pagesize
as the blocking factor. Blocking reduces the complexity of paging in
the files.
-T
and
-D
options can be specified for a demand paged format file and must be a
multiple of the page size.
A ucode object contains only a file header, the ucode section header, the ucode section, and all of the symbolic information. A ucode section never appears in a machine-code object file.
The linker produces object files with their sections in a fixed order similar to the order that was used in UNIX system object files that existed prior to the implementation of the common object file format (COFF). Figure 7-1 shows the ordering of the sections, and Section 7.2 contains information on how the sections are formatted.
The sections are grouped into segments, which are described in the optional header. To load an object file for execution, the dynamic loader needs only the magic number in the file header and the optional header to load an object file for execution.
The starting addresses and sizes of the segments for all types of object files are specified similarly, and the segments are loaded in the same manner.
After reading in the file header and the optional header, the dynamic loader must examine the file magic number to determine if the program can be loaded. Then, the dynamic loader loads the text and data segments.
The starting offset in the file for the text segment is given by the
following macro in the header file
a.out.h
:
N_TXTOFF
(f,a
)
where
f
is the file header structure and
a
is the option header structure for the object file to be loaded.
The
tsize
field in the optional header
(Table 7-4)
contains the size of the text segment and
text_start
contains the address at which it is to be loaded.
The starting offset of the data segment follows the text segment.
The
dsize
field in the section header
(Table 7-6)
contains the size of the data segment;
data_start
contains the address at which it is to be loaded.
The dynamic loader must fill the
.bss
section with zeros. The
bss_start
field in the optional header specifies the starting address;
bsize
specifies the number of bytes to be filled with zeros.
In ZMAGIC files, the linker adjusts
bsize
to account for the zero-filled area it created in the data segment
that is part of of the
.sbss
or
.bss
sections.
If the object file itself does not load the global pointer register,
it must be set to the
gp_value
field in the optional header
(Table 7-4).
The other fields in the optional header are
gprmask
and
fprmask
,
whose bits show the registers used in the
.text
,
.init
,
and
.fini
sections. They can be used by the operating system, if desired, to
avoid save register relocations when a context-switch operation
occurs.
The linker can link object files in archives created by the archiver. The archiver and the format of the archives are based on the System V portable archive format. To improve performance, the format of the archives symbol table was changed to a hash table, not a linear list.
The archive hash table is accessed through the
ranhashinit()
and
ranlookup()
library routines in
libmld.a
,
which are documented in
ranhash
(3).
The archive format definition is in the header file
ar.h
.
Certain symbols are reserved and their values are defined by the
linker. A user program can reference these symbols, but cannot define
them; an error is generated if a user program attempts to define one
of these symbols.
Table 7-13
lists the names and values of these symbols; the header file
sym.h
contains their preprocessor macro definitions.
Symbol | Value | Description |
_ETEXT
|
_etext | First location after text segment |
_EDATA
|
_edata | First location after data segment |
_END
|
_end | First location after bss segment |
_FTEXT
|
_ftext | First location of text segment |
_FDATA
|
_fdata | First location of data segment |
_FBSS
|
_fbss | First location of the bss segment |
_GP
|
_gp | gp value stored in optional header |
_PROCEDURE_TABLE
|
||
|
_procedure_table | Run-time procedure table |
_PROCEDURE_TABLE_SIZE
|
||
|
_procedure_table_size | Run-time procedure table size |
_PROCEDURE_STRING_TABLE
|
||
|
_procedure_string_table | String table for run-time procedure |
_COBOL_MAIN
|
_cobol_main | First COBOL main symbol |
_WEAK_ETEXT
|
etext | Weak symbol for first location after text segment |
_WEAK_EDATA
|
edata | Weak symbol for first location after data segment |
_WEAK_END
|
end | Weak symbol for first location after bss segment |
|
_BASE_ADDRESS |
Base address of file |
|
_DYNAMIC_LINK |
1 if creating a dynamic executable file, 0 otherwise |
|
_DYNAMIC |
Address of .dynamic section |
|
_GOT_OFFSET |
Address of .got section for dynamic executable file |
Table Notes:
-std
.
sym.h
.
The dynamic linker also reserves and defines certain symbols; see Chapter 9 for more information.
The first three symbols in
Table 7-13
(_ETEXT
,
_EDATA
, and
_END)
come from the standard UNIX system linker.
The remaining symbols are compiler-system specific.
The linker symbol
_COBOL_MAIN
is set to the symbol value of the first external symbol with the
cobol_main
bit set.
COBOL objects use this symbol to determine the main routine.
The following symbols relate to the run-time procedure table:
_PROCEDURE_TABLE
_PROCEDURE_TABLE_SIZE
_PROCEDURE_STRING_TABLE
The run-time procedure table is used by the exception systems in
languages that have exception-handling capabilities built into them.
Its description is found in the header file
sym.h
.
The table is a subset of the procedure descriptor table portion of
the symbol table with one additional field,
exception_info
.
When the procedure table entry is for an external procedure
and an external symbol table exists, the linker fills in
exception_info
with the address of the external table. Otherwise, it fills in
exception_info
with zeros.
The name of the run-time procedure table is the procedure name
concatenated with the string
_exception_info
(that is, the default value of the preprocessor macro
EXCEPTION_SUFFIX
,
as defined in the header file
excpt.h
).
The run-time procedure table provides enough information to allow a
program to unwind its stack. It is typically used by the routines
in
libexc.a
.
The comments in the header file
excpt.h
describe the routines in that library.