TopSpeed Binary File Formats ============================ This file describes the format of TopSpeed binary files. BNF and Pascal/Modula-2-like languages are used in the descriptions. THE INFORMATION IS NOT GUARANTEED TO BE COMPLETE, UP TO DATE OR ACCURATE, it is intended to give you a flying start if you want to write utility programs which operate on the binary files. The debug format may change slightly in future versions. .OBJ/.LIB ( object file ) ------------------------- This is the standard Intel object file format, with extra coment records used by the 'make'. Only the subset generated by TopSpeed compilers is described here. (The linker does however support other record types such as iterated data etc.) BNF ::= { } ::=
{ }
::= 80H Length Crc (* string is source name *) ::= | 8AH Length 0 Crc (* not program entry point *) | 8AH Length 0C1H 0 0 0 Crc (* program entry point *) ::= | | | | | [ ] | [ ] | (* used by make *) | (* used by make *) | (* used by make *) | | (* applies to last segdef *) ::= 96H Length { } Crc ::= 98H Length Attr SegLen Crc ::= 9AH Length { 0FFH } Crc ::= 8CH Length { Type } Crc ::= 90H Length [ Frame ] { Offset Type } Crc ::= 0A0H Length Offset { Byte } Crc ::= 9CH Length { Locat FixDat Index [ Index ] [ Offset ] } Crc ::= COMENT Length 0C700H Hash Crc (* used by make *) ::= COMENT Length 0C500H Date { Char } Crc ::= COMENT Length 0C900H { Char } Crc ::= COMENT Length 0CF00H { Char } Crc ::= COMENT Length 0CB00H { Char } Crc ::= COMENT Length 0CD00H HeapSize StackSize Crc ::= COMENT Length 0CA00H Crc ::= COMENT Length 0C800H Crc ::= Len { Char } ::= Index ::= Index ::= Index Terminal symbols: Length is a 2-byte value present in every record which is the length in bytes of the record - 3. Len is a 1-byte string length. Char is a 1-byte character, which should be a printing character. Crc is a 1-byte checksum. It is either zero or -(sum of bytes in record). Index is a 2 byte value represented as 1 or 2 bytes. If getb() returns the next byte from the file, a routine to fetch an Index is as follows: tmp := CARDINAL( getb() ); IF tmp < 128 THEN RETURN tmp; ELSE RETURN ( tmp - 128 ) * 256 + CARDINAL( getb() ); END; , , , and records implicitly define indices which are then used to refer to the objects defined. The indices start from 1. Offset is a 2-byte offset in a segment. Frame is present only when the segment index for the public is zero (an absolute public), and is normally 0. Type is a 1-byte hash value in the range 0..127 used by the JPI linker to perform type-consistency checks (note that this is a deviation from standard Intel format where this is interpreted as a type-index, but existing linkers mostly ignore this field. If there is a problem the field could be set to zero by a utility program or by disabling smart linking. Byte is a 1-byte data value. Attr is the 1-byte segment attribute. SegLen is the 2-byte length of the segment. Locat (2 bytes) defines the offset in the preceding ledata record which is to be fixed up (bits 0..9), the kind of location (bits 10..12) and whether the fixup is non-relative (bit 14). Bit 15 is always 1, Bit 13 is always 0. The location kinds are 1=>offset, 2=>segment, 3=>pointer FixDat (1 byte) defines what kind of index is used for the target of the fixup (bits 0..1), whether the offset is missing (bit 2), and what kind of index is used for the frame of the fixup (bits 4..6). The bits 3 and 7 are zero. The encoding of the index kind is 0=>, 1=>, 2=>, 5=>no frame index, use target Hash is a 4-byte hash value used by the make system. Date is a 4-byte file date in MSDOS/OS2 format. HeapSize and StackSize are 2-byte values for the heap and stack of the program (specified by the data pragma in the main module). .EXE/.DLL ( executable file format ) ------------------------------------ The .exe/.dll file format is as follows: ::= ::=
{ } ::= { } ::= longcard size of ::= byte 0 ::= byte size of following ::= word count of following ::= word offset followed by word segment
::= 'jpi0' where is the standard Microsoft .exe/.dll format. .DBD file ( debug information ) ------------------------------- The BNF for a modules debug data is as follows : ::= Mod { } EndMod ::= | | ::= Proc { } EndProc ::= Signed | Unsigned | Float | Char | Boolean | Procedure | Indirect | Array | OpenArray Aux | Pointer | SubRange | Set | ShortPtr Aux | | Rec { } EndRec | (Enum|SparseEnum) { EnumVal } EndEnum . ::= Var ::= Field | BitField The terminal symbols in the grammar correspond to records of the following type: TYPE DbRec = RECORD (* variable size *) recsize : SHORTCARD; (* record size in bytes, including this byte *) CASE tag: DbRecKind OF | Source: sourcename : string; | Module: lang : SHORTCARD; ofs : CARDINAL; seg : CARDINAL; (* -1 => external *) name : string; | EndModule: modulesize : t_offset; | LineNum: line : ARRAY [0..62] OF RECORD (* variable size *) ofs : CARDINAL; num : CARDINAL; END; | Rte: rteofs : CARDINAL; rtenum : CARDINAL; rtecol : CARDINAL; | Var, Aux: varflags : DbVarFlags; ofs : CARDINAL; (* 1 => no address if local or param *) seg : CARDINAL; name : string; | Field: fieldofs : CARDINAL; fieldname : string; | BitField: fieldofs : CARDINAL; bitfieldbitofs : SHORTCARD; bitfieldsize : SHORTCARD; bitfieldname : string; | Proc: procflags : DbProcFlags; (* the complete set is only in EndProc !! *) ofs : CARDINAL; seg : CARDINAL; name : string; | EndProc: procflags : DbProcFlags; procsize : t_offset; | Indirect: handle : Handle; | Rec: typesize : CARDINAL; id : Handle; | EndRec: | Enum: typesize : CARDINAL; id : Handle; | EnumVal: enumval : INTEGER; enumname : string; | EndEnum: | Subrange: typesize : CARDINAL; rangehigh, rangelow:LONGCARD; | Signed, Unsigned, Float, Char, Boolean, Pointer, Procedure, Array, OpenArray, Set, ShortPtr: typesize:CARDINAL; ELSE b:ARRAY [0..252] OF SHORTCARD; END; END; where TYPE Handle = LONGCARD; CONST Nil = MAX(Handle); (* 0FFFFFFFFH *) TYPE string = ARRAY [0..127] OF CHAR; (* variable length *) TYPE DbRecKind = ( Module, EndModule, LineNum, Rte, Var, Proc, EndProc, Indirect, Rec, EndRec, Enum, EnumVal, Field, BitField, EndEnum, Subrange, Void, Signed, Unsigned, Float, Char, Boolean, Pointer, Procedure, Array, OpenArray, Set, ShortPtr, Source, Aux ); TYPE DbVarTypeEnum = ( varparam, valparam,local,nonvolatile); TYPE DbVarFlags = SET OF DbVarTypeEnum; TYPE DbProcTypeEnum = (near,NoFrame,VarArg,OptVarArg); TYPE DbProcFlags = SET OF DbProcTypeEnum; An Indirect record is a pointer to an Enumeration or Record type so that these types can be re-used. Note that the following records expect sub types to follow (i.e. be defined immediately afterwards) Array expects + to follow OpenArray expects + Aux to follow Pointer expects to follow Subrange expects to follow Set expects to follow ShortPtr expects + Aux to follow The segment values correspond to segment indices in the .OBJ file, and are translated into run-time segment values using the VID information at the end of the .EXE/.DLL file. .SES, .CFG, .HLP files ---------------------- not yet done