.de pp .fi .sp1 .ne2 .. .th x.out 5 "Object Module Format" .na .sh NAME x.out - Z8000 C Compiler, assembler, and link editor output .sh SYNOPSIS #include .sh DESCRIPTION .ul x.out is the output file of the Z8000 C Compiler .ul c8k, assembler .ul a8k, and the link editor .ul l8k. The same format is used as input to the link editor. It is capable of describing object modules both for the Z8001 and the Z8002. The layout of the file is the folllowing: .in+15 .nf +----------------------+ | header | +----------------------+ | segment | | description | +----------------------+ | code and | | data | | segments | +----------------------+ | relocation | | data | | (if present) | +----------------------+ | symbol | | table | | (if present) | +----------------------+ .fi .in-15 There can be a multiplicity of code and data segments which will appear in the file in the order that they are described in the header. The normal output of the linker will have all the code segments preceding the data segments, but this may not necessarily be the case for output of the compiler and the assembler. .sp3 Each of these sections will now be described. .bp .ul Header .nf struct x_hdr { short x_magic; /* magic number */ short x_nseg; /* number of segments in file */ long x_init; /* length of initialized part of file */ long x_reloc; /* length of relocation part of file */ long x_symb; /* length of symbol table part of file */ }; .ul Segment Descriptions struct x_sg { char x_sg_no; /* assigned number of segment */ char x_sg_typ; /* type of segment */ unsigned x_sg_len; /* length of segment */ } x_sg[]; /* array of size x_nseg */ Valid magic numbers: #define X_SU_MAGIC 0xEE00 /* segmented, non executable */ #define X_SX_MAGIC 0xEE01 /* segmented, executable */ #define X_NU_MAGIC 0xEE02 /* non-seg, non executable */ #define X_NXN_MAGIC 0xEE03 /* non-seg, executable, non-shared */ #define X_NXS_MAGIC 0xEE07 /* non-seg, executable, shared */ #define X_NXI_MAGIC 0xEE0B /* non-seg, executable, split ID */ .pp The number of segments in the file is a count of the number of entries in the array of segment information that immediately following the base portion of the header. The length of the initialized portion of the file is the byte count (which is always even) of the code, constant pool, and initialized data in the file. .pp The length of the relocation portion of the file is the byte count (always even) of the size of the relocation data. If the file has been finally linked, this will normally be zero. The length of the symbol table portion of the file is the byte count (always even) of the size of the symbol table. If the file has been stripped, this will be zero. .pp The segment number in the segment information array is either a pre-assigned segment number in the range of 0-127, or the number 255. A segment number of 255 indicates that it may be assigned any segment desired by the linker or the loader. .bp .pp The segment type indicates the content of the associated segments in the file in accordance with the following keys: .nf #define X_SG_BSS 1 /* non-initialized data segment, the corresponding portion of the file is not present */ #define X_SG_STK 2 /* stack segment, no data in file */ #define X_SG_COD 3 /* code segment */ #define X_SG_CON 4 /* constant pool */ #define X_SG_DAT 5 /* initialized data */ #define X_SG_MXU 6 /* mixed code-data, not protectable */ #define X_SG_MXP 7 /* mixed code-data, protectable */ .pp The bss and stack types have no associated data in the file. The execution length is given by s_sg_len. .pp The mixed types are for convenience in "romming" code and data. Clearly no mixed segment is allowed if the Z8000 is being operated as a split I and D space machine. A mixed type that is not protectable indicates that the code may need to store into the data items. A mixed type that is protectable may be safely put into ROM. .ul Relocation Section .pp The relocation section of the file consists of a series of structures each describing some item to be relocated. The relocation items are in the following form: .nf struct x_rel { /* relocation item */ char x_rl_sgn; /* segment with item to be relocated */ char x_rl_flg; /* relocation type (see below) */ unsigned x_rl_loc; /* location of item to be relocated */ unsigned x_rl_bas; /* number of (external) element in symbol table or (internal) segment by which to relocate */ }; .pp The segment number referred to in the preceding is the ordinal (starting with 0) of the segment, in this file, containing the item to be relocated. This number must be less than x_segn in the header. .pp The relocation flags are interpreted as follows: .nf #define X_RL_OFF 1 /* adjust a 16 bit offset value only */ #define X_RL_SSG 2 /* adjust a short form seg plus offset */ #define X_RL_LSG 3 /* adjust a long form (32 bit) seg plus off */ #define X_RL_XOF 5 /* adjust a 16 bit offset by an external */ #define X_RL_XSSG 6 /* adjust a short seg ref by an external */ #define X_RL_XLSG 7 /* adjust a long seg ref by an external */ .pp The first three cases above are references between segments in the current file, hence the relocation value is that of the relevant segment number where the segment number is that by which the segment is known in this file. The last three cases reference some item not defined in this file and must be made by reference to the symbol table. Note particularly that while provision is made for constructing a short external segment reference, there is no way that the C compiler can generate such. .ul Symbol Table .nf #define XNAMELN 8 /* length of a symbol */ struct x_sym { char x_sy_sg; /* the segment number */ char x_sy_fl; /* the type of entry */ unsigned x_sy_val; /* the value of this entry */ char x_sy_name[XNAMELN]; /* the symbol name, null padded */ }; .pp The segment number is the segment number (in this file) containing the symbol if it is defined in this file. Tt is 255 if either the value is absolute, or the value is an external reference. .pp The type of entry is defined by the following flags: .nf #define X_SY_LOC 1 /* local symbol (for debug only) */ #define X_SY_UNX 2 /* undefined external entry */ #define X_SY_GLB 3 /* global definition */ #define X_SY_SEG 4 /* segment name */ .fi Interpretation of the flags: .in+20 .ti-16 local symbol -- this merely makes a symbol table entry for the use of the debugging system, and does not influence linking. .ti-16 und external -- this represents a reference to an external symbol that should be present in some other module. If the associated value field is not zero, however, the linker is requested to allocate space for it. .ti-16 global -- this represents a symbol (either absolute or relocatable) that is defined in the current module. .in-20 The value field is either the amount of space to be allocated (for undefined external) or the offset in the segment where the symbol is located. .ul Segment Names .pp The default names for the standard sections are .in+10 .nf __text first (or only) text segment __text[1..] subsequent text segments __data first data segment __data[1..] subsequent data segments __bss first uninitialized data (bss) segment __bss[1...] subsequent bss segments .in-10 .fi .pp Of course, the assembler makes provision for naming segments. This is for the purpose of prescribing to the loader which segments are to be jointly loaded. However, the segment numbers that are assigned to the segments during assembly are not necessarily the final segment numbers that are produced by the loader. There will be a loader provision for forcing the correspondence between segment names and numbers. .ul File Size .pp The size of the object file (in bytes) is given by .nf sizeof( struct x_hdr ) + x_nseg * sizeof( struct x_sg ) + x_init + x_reloc + x_symb