Appendix C - Relocatable Object File Format
The object code generated by the C assembler must be processed by the
linker before the code is executable. The C assembler writes the
object code in a special relocatable object file format (ROF) to
allow the linker to link together separately assembled modules into
a single executable module. The ROF contains information such as
global data definitions, code entry point, external references, object
code, initialized and un-initialized data.
It is unlikely that a programmer would have to deal with the internal
of an ROF. The information given here is for informational purposes.
The rdump program can be used to display ROF data from an existing
relocatable files.
$0000 |
4 |
Sync Bytes |
Rlink uses the sync bytes to reconize the ROF. |
$0004 |
2 |
Type/Language. |
The type/language bytes from the psect. The bytes are used by the
linker to determine the desired OS-9 module format. Only a mainline
segment can have these bytes non-zero.
|
$0006 |
1 |
Assembly Valid |
The assembly valid byte will be non-zero if errors occured during assembly.
Prevents the linker from linking to an erroreous module
|
$0007 |
5 |
Date/Time |
Indicates date and time of assembly. |
$000C |
1 |
Edition Number |
The OS-9 edition number placed in the output module for mainline segments.
For non-mainline segments the edition number provides module information only.
|
$000D |
1 |
Version |
Indicates to the linker the assembler version number. Used to pevent problems
that could occur when mixing different versions of the assembler and linker.
For this byte rma generates $01 while c.asm generates $00.
|
$000E |
2 |
BSS Data Size |
The linker reserves static data storage for the module.
The linker determines the static storage requirements from
the total size of the vsect rmb statements in the psects.
|
$0010 |
2 |
Direct Page BSS Size |
RLink determines the uninitialized Direct Page requirements from
the modules vsect dp declaration using the rmb statement.
|
$0012 |
2 |
Initialized Data Size |
Tells the linker the size of initialized data the module contains.
The size is determined by the total size of the fcb, fdb, and fcc
statements in the vsects declaration.
|
$0014 |
2 |
Initialized Direct Page Data Size |
RLink determines the Direct Page requirements from the
modules vsect DP statement.
|
$0016 |
2 |
Module Code Size |
Executable code size after linkage. |
$0018 |
2 |
Module Stack Size |
The stack size word tells the linker the stack space required by the module.
The linler takes the value directly from the psect.
|
$001A |
2 |
Module Entry Point |
The offset to the entry point in the assembled object code.
The offset is relative to the beginning of the module.
The linker obtains the value directly from the psect.
|
$001C |
? |
Module Name |
The NULL terminated module name string taken directly
from the psect directive. The linker uses the name to
identify the psect in case of an unresolved reference
or other error.
|
psect name_a,0,0,0,0,0
* The ROF Header:
$0000 fdb $62cd,$2387 Sync bytes
$0004 fdb $0000 Type/Language
$0006 fcb $00 Valid Assembly
$0007 fcb $56 Creation date (5 bytes)
$0008 fcb $09
$0009 fcb $09
$000A fcb $0d
$000B fcb $23
$000C fcb $00 Edition byte
$000D fcb $01 Assembler Version
$000E fdb $0000 Uninitialized Data Size
$0010 fdb $0000 Uninitialized DP Data Size
$0012 fdb $0000 Initialized Data Size
$0014 fdb $0000 Initialized DP Data Size
$0016 fdb $0013 Module Code Size
$0018 fdb $0000 Module Stack size
$001A fdb $0000 Module Entry Point
$001C fcc "name_a" Module Name (1 to 9 bytes)
fcb $00 NULL String Terminator
|
Global Definitions
The global definitions section contains a 2-byte count of global definitions,
Global Name, null terminator, Flag Type byte, and offset into the code. The
following format describes one global entry:
Global Variable Table:
fdb $0001 Number of Global entries
fcc "_name" Global Name (1 to 9 bytes)
fcb $00 NULL string terminator
fcb $04 Type Flag (04 = code)
fdb $0000 Offset into code
|
The Code Section:
_name: lda 3,s Get first param off stack
ldb #$FF B is $FF
ldx 4,s Get second param off stack
pshs y Store y for future
ldy 8,s Get third param off stack
os9 I$SetStt Set status
puls y Restore y
lbra sysret Go have system check Carry bit
|
External references are stored as a 2-byte count, followed by that number of
references. Each reference has a 1-byte flag value indicating the type of
reference, followed by the 2-byte offset where that reference is found.
External Reference Table:
fdb $0002 Number of externals
fcc "_sysret" External Name (1 to 9 bytes)
fcb $00 NULL string terminator
fdb $0001 Count of this external entry
fcb $A0 Type Flag (A0 = code/word/pc)
fdb $0011 Offset into code
fcc "I$SetStt" Name of external
fcb $00 NULL string terminator
fdb $0001 Count of this external entry
fcb $28 Type (28 = code/byte)
fdb $000D Offset into code |
Local Variable Table:
fdb $0000 Number of Local entries
|
Common Block Variable Table:
fdb $0000 Count of Number
endsect
|
Each reference in the global definitions, external references, or local references
section is marked by a 1-byte flag value. This value indicates the section the
reference is located (whether it is a code value, or a pointer from an initialized
data section), what it refers to (code, initialized DP data, uninitialized DP
data, initialized data, uninitialized data, or constant), and any other special
properties of the reference. All such flags are bit-mapped as follows:
Bit | Description |
7 |
0 | Reference is stored as an absolute value. |
1 | Reference is stored relative to the location of the reference |
6 |
0 | Reference value is unmodified |
1 | Reference is negated |
Bit | Description |
5 |
0 | Reference is in a data section (bit 4 is used) |
1 | Reference is in the code section (bit 4 is ignored) |
4 |
0 | |
1 | Reference is in the direct page |
3 |
0 | The size of the reference is 16 bits |
1 | The size of the reference is 8 byte |
Bit | Description |
2 |
0 | The reference refers to data |
1 | The reference refers to code |
1 |
0 | The reference refers to non direct-page data |
1 | The reference refers to direct-page data |
0 |
0 | The reference refers to uninitialized data |
1 | The reference refers to initialized data |
As a special case, if both bits 1 and 2 are set, the reference is a constant value.
Hex Value | Bit Value | Description |
04 | 00000100 | reference to code |
02 | 00000010 | reference to dp bss |
01 | 00000001 | reference to non-dp data |
00 | 00000000 | reference to non-dp bss |
Hex Value | Bit Value | Description |
a0 | 10100000 | reference is in code (word pcr) |
20 | 00100000 | reference is in code (word) |
Hex Value | Bit Value | Description |
2a | 00101010 | in code/byte - to non-dp bss |
22 | 00100010 | in code/word - to dp bss |
21 | 00100001 | in code/word - to non-dp data |
20 | 00100000 | in code/word - to non-dp bss |
04 | 00000100 | in non-dp data/word - to code |
02 | 00000001 | in non-dp data/word - to non-dp data |
00 | 00000000 | in non-dp data/word - to non-dp bss |
|