Object File Formats (VOX) The Rational Software Corporation object file formats are derived from the Berkeley UNIX 4.2 BSD a.out object file formats. The format of object files output by the embedded compiler and used as input to the cross linker is compatible with the Berkeley formats. This format is called the VOX Object eXecutable (VOX) format. However, the VOX file format, the format of an executable memory image, is slightly extended from a.out. The two file formats are referred to as relocatable and executable.
This topic consists of the following sections:
VOX Relocatable Object File FormatThis section contains the following topics:
- File Header
- Sections
- Section Tables
- PDR Record Table (MIPS and PowerPC targets only)
- Symbol Table
- Relocation and Linking
File Header
The following types are used in this section:
type addr_t is new unsigned_types.unsigned_integer; subtype ul_int is integer; type us_int is range 0 .. 65535; for us_int'size use 16; type ut_int is range 0 .. 255; for ut_int'size use 8;
A relocatable object file begins with a header described by the language structures shown below. (The offset is the byte offset, in base 16, from the beginning of the file.)
Relocatable object files have a Magic field value of 620 (base 16), Executable files have an Magic value 1620 (base 16).
type vox_magic_rec_t is -- offset description record -- ====== =========== target : ut_int; -- 0 target processor endian : ut_int; -- 1 target byte order magic : us_int; -- 2 word alignment padding end record; for vox_magic_rec_t use record at mod 4; target at 0 range 0..7; endian at 1 range 0..7; magic at 2 range 0..15; end record; for vox_magic_rec_t'size use 32; VOX_RELOC_MAGIC : constant := 16#620#; VOX_EXEC_MAGIC : constant := 16#1620#; type vox_reloc_header_t is -- offset description record -- == =========== i_magic : vox_magic_rec_t; -- 0 identifying number i_text : ul_int; -- 4 size of text (code) segment i_data : ul_int; -- 8 size of data segment i_bss : ul_int; -- c size of bss i_syms : ul_int; -- 10 size of symbol table i_entry : ul_int; -- 14 entry point (starting address) i_trsize : ul_int; -- 18 size of text relocation area i_drsize : ul_int; -- 1c size of data relocation area i_const : ul_int; -- 20 size of const segment i_crsize : ul_int; -- 24 size of const relocation area i_tsect : ul_int; -- 28 size of text section table i_csect : ul_int; -- 2c size of const section table i_dsect : ul_int; -- 30 size of data section table i_bsect : ul_int; -- 34 size of bss section table i_pdr : ul_int; -- 38 size of procedure descriptor -- record table end record; for vox_reloc_header_t'size use 15*32; VOX_RELOC_HEADER_SIZE : constant := 15*4;
The legal values of Target are
i386 m68k mips ppc rh32
The legal values for Endian are:
Big Endian 1 Little Endian 2
Figure 3 VOX Relocatable Object Format
Note that the size of the string section is given by a four-byte field immediately following the symbol table.
Sections
For readers familiar with 4.2 BSD a.out format, a brief overview of what each area in the file contains is given in the following list:
The Bss section is given a size in the header; however it does not need to be represented in the file because Bss is uninitialized data.
Section Tables
Section tables contain the information used for selective linking. The section table for each section (Text, Const, Data, Bss) can be used to eliminate unused sub-sections of code or data. Each section table is an array of records whose total size in bytes is indicated in the VOX relocatable header. Each section record indicates a slice of the corresponding section and its relocation table:
type vox_sect_info_t is -- offset description record -- ====== =========== size : ul_int; -- 0 size of subsection reloc : ul_int; -- 4 size of relocation -- information align : ul_int; -- 8 alignment requirement end record;
The align field indicates any alignment requirements on the subsection. An align field value of 0 indicates that no alignment is required.
PDR Record Table (MIPS and PowerPC targets only)
The Procedure Descriptor Record (PDR) table combines all the PDR records from the object files into one section. The format of a PDR table record is in the following example.
-- note: nameoffset must be the first field type pdr1_info_t is record p_nameoffset : ul_int; p_framereg : ul_int; p_frameoffset : ul_int; p_regoffset : ul_int; p_regmask : ul_int; p_fregoffset : ul_int; p_fregmask : ul_int; end record;
P_Framereg is the register that is used for the frame pointer (FP). See the discussion of P_Frameoffset below.
P_Frameoffset is the offset from P_Framereg of the FP. For a procedure with a fixed size local area, where the SP register doesn't change during the procedure, the code generator may decide to represent the FP as sp + size-of-fixed-locals-area In this case, P_Framereg would be set to SP and P_Frameoffset would be the offset to add to the SP to calculate the FP value. If an FP value is actually calculated and put into a register (if the FP is manifest), this register should be put into P_Framereg and P_Frameoffset should be 0. This way the debugger can always use the expression:
P_Regoffset is the offset from the FP of where the registers are saved. Since some machines have special instructions so the layout of the registers may be machine dependent.
P_Frameoffset is the offset from P_Framereg of the FP. FP is really a "concept" and not necessarily a number in a register. For a procedure with a fixed size local area, where the SP register doesn't change during the procedure, the code generator represents the FP as sp + size-of-fixed-locals-area. In this case, P_Framereg is set to SP and P_Frameoffset is the offset added to the SP to calculate the FP value. If an FP value is calculated and put into a register (that is, if the FP is manifest), this register must be the value of P_Framereg and P_Frameoffset must be 0. Then the debugger can always use the following expression as the value of the FP:
R<P_FRAMEREG> + P_FRAMEOFFSETP_Regmask is the bit vector of registers that this procedure saves during the prologue. A 1 means the register is saved. The low order bit is for R0, next for R1, etc. The highest order bit is for R31.
P_Fregoffset is the offset from the FP of the register save area. For machines where the floating point and integer registers are the same, P_Fregmask and P_Fregoffset should always be 0.
P_Fregmask is the bit mask of floating point registers that are saved to the stack during the prologue of the procedure.
Symbol Table
The symbol table contains symbols used during relocation, linking and some debugging. The format of a symbol table record is in the following example. (The offset of each field is given first.)
-- name list declarations -- type nlist_t is -- offset description record -- = ========================== n_strx : system.address; -- 0 offset into string section n_type : ut_int; -- 4 type of this symbol entry n_other : ut_int; -- 5 not used n_desc : us_int; -- 6 not used n_value : ul_int; -- 8 address of the symbol end record; for nlist_t use record at mod 4; n_strx at 0 range 0..ADDRESS_LAST;
n_type at 4 range 0..7; n_other at 5 range 0..7; n_desc at 6 range 0..15; n_value at 8 range 0..31; end record;
The N_Strx field is an offset in the string section of the object file of the name of this symbol. If N_Type is equal to N_Undf, this entry has no name. The name of each of named symbol is a null terminated string in the string section.
The following are simple values for the N_Type field that are used for relocation and linking.
-- simple n_type values N_Undf : constant := 16#0#; -- undefined N_Abs : constant := 16#2#; -- absolute N_Text : constant := 16#4#; -- text N_Data : constant := 16#6#; -- data N_Bss : constant := 16#8#; -- bss N_Const : constant := 16#a#; -- const N_Comm : constant := 16#12#; -- common N_Fn : constant := 16#1f#; -- file name symbol N_Ext : constant := 16#1#; -- external bit or'ed in N_Type : constant := 16#1f#; -- mask for all type bits
If the symbol is also externally visible, N_Ext is or'd with one of the simple values, resulting in a N_Type value with the low bit set.
In addition to these relocation and linking types of symbols, there are symbols for describing symbolic information. These symbols have an N_Type value greater than 16#1f#. Apex uses a subset of sdb-style debugging information not documented here.
Every symbol declared in the symbol table is defined in the object file unless the N_Type field is N_Undf.
The N_Value field is the address of the symbol. If the file is a relocatable file, this field is the offset of the symbol in the corresponding N_Type section.
N_TYPE = (N_UNDF + N_EXT)
and an N_Value field of zero, this is an external reference to a symbol defined in another module. It is considered an error at link time if no such symbol is found.
N_TYPE = (N_UNDF + N_EXT)
and the N_Value field is non-zero, there are two possible interpretations, depending on whether a definition for this symbol is found in another module or not. If a symbol is found, this satisfies the external reference and the address of the found symbol is used. If no symbol is found, space is allocated by the linker for the symbol in the Bss section. The amount of space allocated is equal to the value in the N_Value field.
The N_Value field is the absolute address of the symbol in a VOX file.
Relocation and Linking
Relocation occurs when each section, Text, Data, Const and Bss, of each object file is assigned an absolute address in memory. This is part of the job of the linker. After each section has an address, the linker can step through the symbol table records and for each Text (N_Text), Data (N_Data), Const (N_Const) or Bss (N_Bss) symbol, the address can be adjusted to reflect the absolute location in memory. This adjustment just means that the base address of the section is added to the N_Value field value already present in the record.
The linking operation involves two steps. The first is for the linker to find a definition for each external reference symbol. Once the linker has read in all of the object files, each external reference must be satisfied with a corresponding definition, except in the special case described above where the linker allocates the following space.
(N_TYPE = (N_UNDF | N_EXT) & N_VALUE != 0)If there is an external reference to a symbol and no definition is found, this is an unsatisfied external error.
Once all the external reference symbols have been resolved, any addresses in the text and data sections of each object file can be resolved to point to the actual address in memory. This step is performed when the linker steps through the relocation records in the text relocation and data relocation records of each object file.
A relocation record has the following definition.
-- -- relocation table declarations -- type rel_t is record r_address : ul_int; -- offset of value to be fixed up r_symbolnum : ul_int range 0 .. 16#00ffffff#; --integer(2**24 -1); -- the local symbol table record r_extern : boolean;-- does not include value of symref'd r_type : vox_reloc_t; r_offset : ul_int; -- RISC only end record; for rel_t use record r_address at 0 range 0 .. 31; r_symbolnum at 4 range 0 .. 23; r_extern at 4 range 24 .. 24; r_type at 4 range 25 .. 31; r_offset at 8 range 0 .. 31; -- RISC only end record;
The R_Address field gives an offset in either the text or data section, determined by the relocation section in which the record appears. The linker then finds the absolute address of the symbol indicated by R_Symbolnum. This address is added to the value already at the offset in the corresponding section and the result is stored back into the section.
If R_Extern is 0, R_Sybolnum is actually a value of the type N_Type for the relocation. This means that the R_Sybolnum is N_Text, N_Data, N_Bss, or N_Const. The action the linker is to perform is to relocate the item at R_Address by adding in the base address of the Text, Data, Const or Bss segment, respectively.
type vox_reloc_t is ( V_AOUT_8, V_AOUT_16, V_AOUT_32, -- [00] V_AOUT_PC_8, V_AOUT_PC_16, V_AOUT_PC_32, -- [03] V_SPARC_8, V_SPARC_16, V_SPARC_32, -- [06] V_SPARC_DISP8, V_SPARC_DISP16, V_SPARC_DISP32, -- [09] V_SPARC_WDISP30, V_SPARC_WDISP22, -- [12] V_SPARC_HI22, V_SPARC_22, V_SPARC_13, V_SPARC_LO10, -- [14] V_SPARC_SFA_BASE, V_SPARC_SFA_OFF13, -- [18] V_SPARC_BASE10, V_SPARC_BASE13, V_SPARC_BASE22, -- [20] V_SPARC_PC10, V_SPARC_PC22, -- [23] V_SPARC_JMP_TBL, V_SPARC_SEGOFF16, V_SPARC_GLOB_DAT, -- [25] V_SPARC_JMP_SLOT, V_SPARC_RELATIVE, -- [28] V_BCS_PCR16L, V_BCS_PCR26L, V_BCS_VRT16, -- [30] V_BCS_HVRT16, V_BCS_LVRT16, V_BCS_VRT32, -- [33] V_MIPS_REFHALF, V_MIPS_REFWORD, V_MIPS_JMPADDR, -- [36] V_MIPS_REFHI, V_MIPS_REFLO, V_MIPS_GPREL, V_MIPS_LITERAL, -- [39] V_RTF_POS, V_RTF_NEG, V_RTF_REL, V_RTF_TOC, V_RTF_TRL, -- [43] V_RTF_TRLA, V_RTF_GL, V_RTF_TCL, V_RTF_RL, V_RTF_RLA, -- [48] V_RTF_REF, V_RTF_BA, V_RTF_RBA, V_RTF_RBAC, V_RTF_BR, -- [53] V_RTF_RBR, V_RTF_RBRC, V_RTF_RTB, V_RTF_RRTBI, V_RTF_RRTBA,-- [58] V_AMD29K_RBYTE, V_AMD29K_RHALF, V_AMD29K_RWORD, -- [63] V_AMD29K_ABS, V_AMD29K_IREL, V_AMD29K_IABS, -- [66] V_AMD29K_ILOHALF, V_AMD29K_IHIHALF, -- [69] V_AMD29K_IGLBLRC, V_AMD29K_IGLBLRA, V_AMD29K_IGLBLRB, -- [71] V_I960_COBR, V_I960_CTRL, V_I960_MEMA, -- [74] V_860_PC26, V_860_HIGHADJ, V_860_LOW0, V_860_HIGH, -- [77] V_860_32, V_860_SPLIT, V_860_IPAIR, -- [81] V_RH32_REFHALF, V_RH32_REFWORD, V_RH32_JMPADDR, -- [84] V_RH32_REFHI, V_RH32_REFLO, V_RH32_GPREL, V_RH32_LITERAL, -- [87] V_PPC_LO, V_PPC_HI, V_PPC_HA, -- [91] V_SECTLO, V_SECTHI, V_SECTHA, V_SECTOFF, -- [94] V_PPC_EMB_SDA21, -- [98] V_M68K_GPREL, V_M68K_PCREL, V_M68K_SYMBOL_REL, -- [99] V_PPC_REL14, V_PPC_ADDR24, -- [102] V_LONG_CALL -- internal use only );
VOX Executable Object File FormatThis section contains the following:
File Header
The header for a VOX executable file is described by the following record:
type vox_exec_header_t is -- offset description record -- ====== =========== o_magic : vox_magic_rec_t; -- 0 identifying number o_entry : ul_int; -- 4 entry point of progam o_grp_recs_offset : ul_int; -- 8 offset of group record -- table o_grp_recs : ul_int; -- c size of group record table o_grps_offset : ul_int; -- 10 offset of groups o_grps : ul_int; -- 14 size of resident groups o_pdrs_offset : ul_int; -- 18 offset of PDR table o_pdrs : ul_int; -- 1c size of PRD table o_syms_offset : ul_int; -- 20 offset of symbol table o_syms : ul_int; -- 24 size of string table o_strs_offset : ul_int; -- 28 offset of string table o_strs : ul_int; -- 2c size of string table end record; VOX_EXEC_HEADER_SIZE : constant := 48;Valid values for Target and Endian, which are used by o_magic, are listed in VOX Relocatable Object File Format.
Figure 4 illustrates the layout of a VOX file.
Figure 4 Layout Of a VOX file
Group Table
Following the VOX header is the group table. There is one record in the table for each group specified by the user or by the linker.
-- -- group record -- type grp_rec_t is record g_base : addr_t; -- base address of block g_size : size_t; -- size of block g_kind : ul_int; -- kind of block end record; -- -- group block kinds -- TEXT_BLK: constant := 0; CONST_BLK: constant := 1; DATA_BLK: constant := 2; BSS_BLK: constant := 3; VOID_BLK: constant := 4; DATA_IMAGE_BLK: constant := 5;
Text, Const and Data groups are all represented in the link image; Bss is not since it represents uninitialized space. The loader zeroes out Bss groups.
Following the group table is the actual image of the groups, the bytes loaded into memory.
To load the image, the group sizes must be used (G_Size). The first group is at the beginning of the group image. The second group immediately follows the first. The base address of the block is where the group image is loaded into target memory.
The symbol table, string size and strings sections of the VOX executable file are the same as for the VOX relocatable file.
Loading
VOX files represent programs that can be loaded into target memory and executed. The file contains images for Text groups that contain instructions, Const groups that contain constants and Data groups containing initialized data that may change during program execution. Bss groups also represent uninitialized data. Only the start and length information is present for this kind of groups. The Bss groups are zeroed out when the VOX file is downloaded.
By default, with no linker directives, a program loaded into target memory is laid out as shown in Figure 5
Figure 5 Program Loaded Into Target Memory
The Text, Const, and Data groups are loaded exactly as they are described in the group record table. The cross linker defines the symbol _end whose address is the first byte following the last byte of the highest addressed Text, Const or Data group.
Using directives to the linker, it is possible to have multiple Text, Const and/or Data groups in a single VOX file. The groups can be ordered and interspersed in any way. It is also possible to supply specific starting addresses for some or all groups.
VOX Object Archive File FormatThe VOX Archive Format (VAR) provides a compact and efficient method for creating archive libraries of object files and for indexing these files to allow high-speed access by the linker. Files that have been created in this manner are designated by a .var file name extension. As an added benefit, the Rational archive format files are compatible with archive libraries created with the ar and ranlib tools supplied with UNIX 4.2 BSD.
Each VAR library consists of three sections:
The items are arranged in the order shown in Figure 6
Figure 6 Archive File Format
Archive Identification String
The archive identification string is a simple string of 8 characters consisting of the pattern "!<arch>" followed by an ASCII linefeed character. This string provides a mechanism for Apex tools to identify files that are in the VAR format.
File Header
The library and each object file within the library begins with a header that contains detailed information about the unit that follows. The header is organized in the following manner.
type ARHDR is record name : string(1..16); -- decimal date : string(1..12); -- decimal uid : string(1..6); -- decimal gid : string(1..6); -- decimal mode: string(1..8); -- octal size: string(1..10); -- decimal fmag: string(1..2); -- ARFMAG end record; for ARHDR use record at mod 1; name at 0 range 0..127; date at 16 range 0..95; uid at 28 range 0..47; gid at 34 range 0..47; mode at 40 range 0..63; size at 48 range 0..79; fmag at 58 range 0..15; end record;
All fields are blank padded. All numeric images are left justified and represent decimal values, with the exception of Mode, which represents an octal value.
Archive Library Directory
The library directory section of the file is a collection of elements that increase the efficiency with which strings contained in the archived object files can be accessed by the Apex linker. This directory is formatted as shown in Figure 7
Figure 7 Format of Library Directory Section
The header for the directory section contains the key string __.SYMDEF in the first nine characters of the file name field. In the four bytes directly following the header is a 32-bit unsigned integer representing the number of string reference records contained in the reference records section of the directory. These records are created in the form displayed in Figure 8
Figure 8 Format of VAR Library Records
Directly following the reference records is a 32-bit integer that specifies the size in bytes of the string table. The string table immediately follows the size entry and extends to the beginning of the object file library.
Object File Library
The object file library itself is composed of Apex object files in VOX format as described in VOX Relocatable Object File Format. In addition, as outlined earlier, each object file is prepended with an object file header containing relevant file data.
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2002, Rational Software Corporation. All rights reserved. |