Copyright (c) 1993 Borland International, Inc. All Rights Reserved Symbolic Debugging Information This version of the Symbol and Type OMF information is a complete redesign. The effect of the design is to move from treating the debug information as a byte stream to treating it as a stream of structures. Field sizes and arrangement have been changed to maintain "natural alignment" to improve performance. Natural alignment indicates that a field begins on an address that is divisible by the size of the field. For example, a four byte (long) value begins on an address that is evenly divisible by four. Some architectures, such as the MIPS R4000, impose an severe penalty for loading data that is not in natural alignment. Even for the Intel 80 386 and 486 processors, there is a significant improvement processing data that is in natural alignment. Compilers that emit Symbol and Type OMF according to this specification indicate so by placing a signature of 0x00000002 at the beginning of the $$BSYMS, $$BTYPES tables, and a 0x00000001 at the beginning of the $$BNAMES table. The format of the symbol records has been changed. The length field at the beginning of the symbol records are now two bytes rather than one, the symbol index is now two bytes rather than one, and the symbol indices have been renumbered. The format of type records has also been changed. The linkage field at the beginning of each type record, which has never been used, has been eliminated. Leaf indices have been changed from one byte to two bytes and renumbered. Field sizes and arrangement have been changed to maintain "natural alignment". The definition of unused records has been removed from the specification. In all structure descriptions and value enumerations, all values not specified in this document are reserved for future use. Logical segments When the linker emits address information about a symbol, it is done in a segment: offset format. The segment is a logical segment index assigned by the linker and the offset is the offset from the beginning of the logical segment. The physical address is assigned by the operating system when the program is loaded. Lexical scope linkage The model of a program envisioned by this document is that programs have nested scopes. The outermost scope is module scope which encompasses all of the symbols not defined within any inner (lexical) scope. Symbols and types defined at one scoping level are visible to all scopes nested within it. Symbols and types defined at module scope are visible to all inner scopes. The next level of scoping is "function" scope, which in turn contains lexical blocks (including other functions scopes) that can be further nested. Nested lexical scopes are opened by a procedure, method, thunk, with, or block start symbol. They are closed by the matching block-end symbol. To improve performance, the lexical scopes are linked so that the symbols for inner lexical scopes do not have to be searched. Symbols that can begin an outermost lexical scope have three fields defined for linkage: Field Linkage pParent Local procedures, global procedures, thunk start, with start, and block start. If the scope has no enclosing lexical scopes, then pParent is zero. Otherwise, the parent of this scope is the offset from the start of the symbol table for this module to the symbol for the scope that encloses this scope but encloses no other scope that encloses this scope. pNext Start search and for local procedures, global procedures, and thunk start if they are the outermost lexical scope. The pNext field, along with the start search symbol, defines a group of lexically scoped symbols that share a code segment (or object) within a symbol table. For each segment (object) represented in the symbol table, there is a search symbol that contains the offset from the start of the symbols for this module to the first procedure or thunk contained in the segment. Each outermost lexical scope symbol has a next field containing the next outermost scope symbol contained in the segment. The last outermost scope in the symbol table for each segment has a next field of zero. pEnd This field is defined for local procedures, global procedures, thunk, block, and with symbols. The end field contains the offset from the start of the symbols for this module to the matching block end symbol that terminates the lexical scope. Numeric leaves When the symbol or type processor knows that a numeric leaf is present, it examines the next two bytes of the symbol or type string. If the value of these two bytes is less than LF_NUMERIC (0x8000), then the two bytes contain the actual numeric value. If the value is greater than or equal to LF_NUMERIC (0x8000), then the numeric data follows the two-byte leaf index and is contained in the number of bytes specified by the leaf index. It is the responsibility of routines reading numeric fields to handle the potential non alignment of the data fields. See the section on numeric leafs for details. Types Definition Segment All Symbol and Type OMF records for which a type index field is part of the specification must have a valid type index. The one exception is for public symbols from modules compiled without Borland 32 bit symbol information. In this case, a type index of 0x0000 is permitted. Since many types (relating to hardware primitives) are common, type index values less than 0x0000 are reserved for a set of predefined primitive types. A list of predefined types and their indices are defined in this document. Type indices of 0x1000 and higher are used to index into the set of type definitions in the module's $$BTYPES segment. Thus 0x1000 is the first type, 0x1001 the second, and so on. Type indices must be sequential and contain no gaps in the numbering. $$BSYMS and $$BTYPES Segment Definitions $$BTYPES Segment Definition Type information appears in OMF-286 TYPDEF format as LEDATA records that contribute to the special $$BTYPES debug segment. A SEGDEF record for this segment must be produced in each module that contains Symbol and Type OMF type information and have these attributes: Name: $$BTYPES Class: DEBTYP The first four bytes of the $$BTYPES table is used as a signature to specify the version of the Symbol and Type OMF contained in the $$BTYPES segment. $$BSYMS Segment Definition Symbol information appears in OMF-286 TYPDEF format as LEDATA records that contribute to the special $$BSYMS debug segment. A SEGDEF record for this segment must be produced in each module that contains Symbol and Type OMF symbol information and have these attributes: Name: $$BSYMS Class: DEBSYM The first four bytes of the $$BSYMS segment is used as a signature to specify the version of the Symbol and Type OMF contained in the $$BSYMS segment. Symbols Format of Symbol Records Data in the $$BSYMS segment is a series of symbol records with the format DW Length // Length of record, excluding the length field. DW Index // Type of symbol * data... // Data specific to each symbol format The symbol records are described below. Numbers above fields indicate length in bytes, and * means variable length in the following section. Symbol indices are broken in to three ranges. The first range is for symbols whose format does not change with the compilation model of the program or the target machine. These include register symbols, user-defined type symbols, and so on. The second range of symbols are those that contain 16:16 segmented addresses. The third symbol range is for symbols that contain 16:32 addresses. Note that even for flat model programs, there is an implied segment for every symbol. For architectures that do not have segment registers, the segment portion of a 16:32 address is zero. The symbol indices are listed below, and each record is then described in the following sections. The symbol records are formatted such that most fields fall into natural alignment if the symbol length field is placed on a long word boundary. For all symbols, the variable length data has been moved to the end of the symbol structure. Note specifically that fields that contain data in potentially nonaligned numeric fields must either pay the load penalty or first do a byte wise copy of the data to a memory that is in natural alignment. Please refer to the description of the type records for details about numeric leaves. Compilers do not have to emit padding bytes between symbols to maintain natural alignment. The linker places the symbols into the executable files in natural alignment and pads the symbol lengths to force alignment. Symbol Indices 0x0001 S_COMPILE Compile flags symbol 0x0002 S_REGISTER Register variable 0x0003 S_CONST Constant symbol 0x0004 S_UDT User-defined Type 0x0005 S_SSEARCH Start search 0x0006 S_END End block, procedure, with, or thunk 0x0007 S_SKIP Skip - Reserve symbol space 0x0008 S_CVRESERVE Reserved for Code View internal use 0x0009 S_OBJNAME Specify name of object file 0x0100 S_BPREL16 BP relative 16:16 0x0101 S_LDATA16 Local data 16:16 0x0102 S_GDATA16 Global data 16:16 0x0103 S_PUB16 Public symbol 16:16 0x0104 S_LPROC16 Local procedure start 16:16 0x0105 S_GPROC16 Global procedure start 16:16 0x0106 S_THUNK16 Thunk start 16:16 0x0107 S_BLOCK16 Block start 16:16 0x0108 S_WITH16 With start 16:16 0x0109 S_LABEL16 Code label 16:16 0x010a S_CEXMODEL16 Change execution model 16:16 0x010b S_VFTPATH16 Virtual function table path descriptor 16:16 0x0200 S_BPREL32 BP relative 16:32 0x0201 S_LDATA32 Local data 16:32 0x0202 S_GDATA32 Global data 16:32 0x0203 S_PUB32 Public symbol 16:32 0x0204 S_LPROC32 Local procedure start 16:32 0x0205 S_GPROC32 Global procedure start 16:32 0x0206 S_THUNK32 Thunk start 16:32 0x0207 S_BLOCK32 Block start 16:32 0x0208 S_WITH32 With start 16:32 0x0209 S_LABEL32 Label 16:32 0x020a S_CEXMODEL32 Change execution model 16:32 0x020b S_VFTPATH32 Virtual function table path descriptor 16:32 Compile Flag S_COMPILE 0x0001 This symbol communicates to Code View compile time information on a per module basis, such as the language and version number of the compiler, the ambient model for code and data, and the target processor. DW Length DW S_COMPILE DB machine DB,DW flags * version machine enumeration specifying target processor. Values not specified below are reserved: 0x00 Intel 8080 0x01 Intel 8086 0x02 Intel 80286 0x03 Intel 80386 0x04 Intel 80486 0x10 MIPS R4000 flags flags showing compile time options: Language :8 PCodePresent :1 FloatPrecision :2 FloatPackage :2 AmbientData :3 AmbientCode :3 Mode32 :1 Compiled for 32 bit addresses chsign :1 True is 'char' is a signed type Reserved :3 Language enumeration: 0 C 1 C++ 2 FORTRAN 3 Masm 4 Pascal 5 Basic 6 COBOL 7-255 Reserved Ambient code and data memory model enumeration 0 Near 1 Far 2 Huge 3-7 Reserved Floating package enumeration 0 Hardware processor (80x87 for Intel 80x86 processors) 1 Emulator 2 Altmath 3 Reserved The FloatPrecision flag is set to 1 if the -OP option was enabled during the compilation. version Length-prefixed string specifying compiler version. Compilers can place additional data in version string if desired. Register S_REGISTER 0x0002 This symbol record describes a symbol that has been registered: DW Length DW S_REGISTER DD @type DW register DD @name DD reserved type The type of the symbol register Enumerate of the registers in which the symbol value is stored. This field is treated as two bytes. The high order byte specifies the register that the high order part of the value is stored. The low byte specifies the register for the low order part of the value. If the value is not stored in two registers then high order register field contains the enumerate value for no register. For register enumeration values, see below. The register index enumeration is specific to the processor model for the module. name Length-prefixed name of the symbol stored in the register @name Name index of the symbol reserved 0 Constant S_CONSTANT 0x0003 This record is used to output FORTRAN and C constants and C enums. If used to output an enum, then the type index refers to the containing enum. DW length DW S_CONSTANT DD @type DD @name DD reserved * value @type Type of symbol @name name index of the constant value Numeric leaf containing the value of symbol reserved 0 User-defined type S_UDT 0x0004 This specifies a C type or user-defined type, such as classes, structures, unions, or enums. This symbol allows for scoped searches of a type name and casting to a user-defined type. S_UDT symbols are moved to either the sstGlobalSym section or an sstAlignSym section, depending on the scope in which they are defined. If the S_UDT is emitted at top level scope, it is moved to the sstGlobalSym section. Otherwise it goes to the sstAlignSym section of the module in which it was defined. DW length DW S_UDT DD @type DW property DD @name DD reserved @type Type index of the type property istag :1 True if this is a tag (not a typedef) isnest :1 True if the type is a nested type (its name will be 'class_name::type_name' in that case) @name Name index of the type reserved 0 Start Search S_SSEARCH 0x0005 These records are always the first symbol records in a module's $$BSYMS section. There is one Start Search symbol for each segment to which the module contributes code. Each symbol contains the segment number and $$BSYMS offset of the record of the first procedure or thunk in this module that physically appears in the specified segment of the load image. This is the symbol used to initiate CS:IP searches within this module. These symbols are used to perform lexical scope searching of symbols. The linker or packer creates this symbol. Translators do not create this symbol. DW length DW S_SSEARCH DD sym off DW segment DW LPROC/GPROC/THUNK count DW LDATA count DD firstLDATA start sym $$BSYMS offset of the procedure or thunk record for this module that has the lowest offset for the specified segment. See the section on lexical scope linking. segment Segment that this Start Search refers to codeCount Total number of all LPROCxx, GPROCxx and THUNKxx symbols in this sstAlignSym section for the segment specified by the SSEARCH symbol. dataCount Total number of all LDATAxx symbols in this sstAlignSym section for the segment specified by the SSEARCH symbol. firstLDATA Offset to the first LDATA symbol in this sstAlignSym section which belongs to the segment specified in the SSEARCH symbol. End of Block S_END 0x0006 Closes the scope of the nearest preceding Block Start, Global Procedure Start, Local rocedure Start, With Start, or Thunk Start definition. DW length DW S_END Skip Record S_SKIP 0x0007 This record reserves symbol space for incremental compilers. The compiler can reserve a dead space in the OMF for future expansions due to an incremental build. This symbol and the associated reserved space is removed by the linker. This record is not used by Borland tools. DW length DW S_SKIP * skip data skip data Unused data. Use the length field that precedes every symbol record to skip this record. Object File Name S_OBJNAME 0x0009 This symbol specifies the name of the object file for this module. DW length DW S_OBJNAME DD signature DD @name signature Signature for the CodeView information contained in this module. @name Name index of OBJ file. Global Procedure Forwarding Pointer S_GPROCREF 0x0020 DW length DW S_GPROCREF DD offset DD @type DD @name DD reserved DD coffset DD segment offset Here, offset is an offset from the start of the NB0x header which points to the S_GPROCxx record. For each S_GPROCxx symbol that is encountered, a corresponding S_GPROCREF symbol will be generated and emitted to the sstGlobalSym section. Translators do not emit the S_GPROCREF symbol. @type Type of this symbol @name Name index of this symbol reserved 0 coffset Code offset. Same as offset field in corresponding xPROCyy symbol. segment Code segment. Same as segment field in corresponding xPROCyy symbol. Note that the ordering of fields is different from the S_xPROCyy records for convenience of alignment. When an EPROC is encountered by the linker, it will create a GPROCREF with a 0 offset field (if no GPROC exists that matches the EPROC). One and only one GPROCREF will be created for the name that an EPROC refers to. Global Data Forwarding Pointer S_GDATAREF 0x0020 DW length DW S_GDATAREF DD offset DD @type DD @name DD reserved DD doffset DD segment offset This field should be 0 @type Type of this symbol @name Name index of this symbol reserved 0 doffset Data offset. Same as offset field in corresponding xDATAyy symbol. segment Data segment. Same as segment field in corresponding xDATAyy symbol. External Data S_EDATA 0x022 This symbol is used by the translator to describe an external symbol used in a particular compilation unit. If the linker finds no GDATAxx record for the public symbol described here, it will create a GDATAREF, and use the information in the S_EDATA. If there is a GDATAREF for the public symbol described here, then the linker will merge information from this S_EDATA. S_EDATA symbols never appear in EXE images. They only appear in OBJ files. DW length DW S_EDATA DD @type DD @name DW externalIndex DD reserved @type Type of this symbol @name Name index of this symbol externalIndex An index into the EXTDEFs for the OBJ file. If this field is 0, the name of the public symbol is specified in a length preceeded name which follows the reserved field in this symbol. reserved 0 External Procedure S_EPROC 0x023 DW length DW S_EPROC DD @type DD @name DW externalIndex DD reserved @type Type of this symbol @name Name index of this symbol externalIndex An index into the EXTDEFs for the OBJ file. If this field is 0, the name of the public symbol is specified in a length preceeded name which follows the reserved field in this symbol. reserved 0 The external index field is an index into the EXTDEFs for the OBJ file. The linker will use this to obtain the mangled name for the symbol. If the external index is 0, then there follows a length preceeded name which is identical to the EXTDEF version of the name. This is to avoid the need for an additional TASM pass through. In both symbols, the '@name' field refers to the same name as would appear in the GDATA or GPROC records that correspond to the external symbol. These are NOT necessarily the same as the linker namespace names for the symbols, since GPROC names are commonly divorced from their base classes. These two symbols are used to permit people to call functions like printf in the debugger. The linker will take EPROCs and EDATAs and construct GPROCREFs and GDATAREFs for them. The EPROCs and EDATAs will not appear in the EXE debug information. [-----------------------------------------------------------------------] [ Symbols for 16:16 Segmented Architectures ] [-----------------------------------------------------------------------] BP Relative 16:16 S_BPREL16 0x0100 This symbol specifies symbols that are allocated on the stack for a procedure. For C/C++, these include the actual parameters to a function and the local nonstatic variables of functions. DW length DW S_BPREL16 DW offset DD @type DD @name DD reserved offset Signed offset relative to BP. If offset is 0, then the symbol was assigned to a register by the optimizer and cannot be evaluated. @type Type of this symbol @name Name index of this symbol reserved 0 Local Data 16:16 S_LDATA16 0x0101 These symbols are used for data that is not exported from a module, In C/C++, symbols that are declared static are emitted as Local Data symbols. Symbols that are emitted as Local Data cannot be moved into the global symbol table for the executable file. DW length DW S_LDATA16 DW offset DW segment DW flags DD @type DD @name DD reserved offset Offset portion of the symbol address segment Segment portion of the symbol address flags The flags field has only one flag defined: 0x0001 The SYMBOL was qualified with _thread. This means that the compiler generated a reference through the per thread data segment, using the index in fs:[2c] as the index into the per thread area. Debuggers will have to understand this code in order to properly display symbols so qualified. This flag only applies to global data. @type Type index of the symbol @name Name index of symbol reserved 0 Global Data Symbol 16:16 S_GDATA16 0x0102 This symbol record has the same format as the Local Data 16:16 except that the record type is S_GDATA16. For C/C++, symbols that are not specifically declared static are emitted as Global Data Symbols and can be compacted by into the global symbol table. Local and Global Procedure Start 16:16 S_LPROC16 0x0104 S_GPROC16 0x0105 The symbol records define local (file static) and global procedure definitions. For C/C++, functions that are declared static to a module are emitted as Local Procedure symbols. Functions not specifically declared static are emitted as Global Procedures. For each S_GPROC16 emitted, an S_GPROCREF symbol must be fabricated and emitted to the sstGlobalSym section. DW length DW symbol DD pParent DD pEnd DD pNext DW proc length DW debug start DW debug end DW offset DW segment DW flags DD @proctype DD @name DD reserved symbol S_LPROC16 or S_GPROC16 pParent See the section on lexical scope linking pEnd See the section on lexical scope linking pNext See the section on lexical scope linking proc length Length in bytes of this procedure debug_start Offset in bytes from the start of the procedure to the point where the stack f rame has been set up. Frame and register variables can be viewed at this point. debug_end Offset in bytes from the start of the procedure to the point where the procedure is ready to return and has calculated its return value, if any. Frame and register variables can still be viewed. offset Offset portion of the segmented procedure address segment Segment portion of the segmented procedure address flags Type of return the procedure makes: 0 near 4 far @proctype Type index of the procedure type record @name Name index of procedure. reserved 0 Thunk Start 16:16 S_THUNK16 0x0106 This symbol is used to specify any piece of code that exists outside a procedure. It is followed by an END record. DW length DW S_THUNK16 DD pParent DD pEnd DD pNext DW offset DW segment DW thunk length DB ordinal DD @name * variant pParent See the section on lexical scope linking pEnd See the section on lexical scope linking pNext See the section on lexical scope linking offset Offset portion of the segmented procedure address segment Segment portion of the segmented procedure address thunk length Length in bytes of this thunk ordinal Ordinal specifying the type of thunk: 0 notype 1 adjustor 2 vcall 3 native alias @name Name index of thunk. variant Variant field, depending on the value of the thunk type. If ordinal is notype, there will be no variant field. If ordianal is adjustor, the variant field will be a two-byte signed value specifying the delta to be added to this pointer, followed by the name of the target function. If the ordinal is vcall, then the variant field will be a two-byte signed displacement into the virtual table. Note specifically that because of the variable length name, the data in the variant field will not be in natural alignment. If ordinal is native alias, then the variant is the seg:off of the pcode enry point. Block Start 16:16 S_BLOCK16 0x0107 This symbol specifies the sart of a block of lexically scoped symbols. The lexical scope is terminated by a matching End symbol. DW length DW S_BLOCK16 DD pParent DD pEnd DW length DW offset DW segment DD @name pParent See the section on lexical scope linking pEnd See the section on lexical scope linking block length Length in bytes of the scope of this block offset Offset portion of the segmented procedure address segment Segment portion of the segmented procedure address @name Name index of the block With Start 16:16 S_WITH16 0x0108 This symbol describes the lexical scope of the Pascal with statement DW length DW S_WITH16 DD pParent DD pEnd DW length DW offset DW segment DW value pParent See the section on lexical scope linking pEnd See the section on lexical scope linking length Length in bytes of the scope of the with block offset Offset portion of the block start address segment Segment portion of the block start address value Name index of the value used in the Pascal with statement. Code Label 16:16 S_LABEL16 0x0109 DW length DW S_LABEL16 DW offset DW segment DB NEAR/FAR DD @name offset Offset portion of the code label address segment Segment portion of the code label address NEAR/FAR Address mode of label: 0 near 4 far @name Name index of code label Change Execution Model 16:16 S_CEXMODEL16 0x010a This record is used to notify the debugger that, following the given code offset and until next such record, the execution model is of a particular type. For backwards compatibility, the native execution model will be assumed in the absence of Change Execution Model records. DW length DW S_CEXMODEL16 DW offset DW segment DW model * variant offset Offset portion of start of the block segment Segment portion of start of block model The execution model: 0 Not an executable code (e.g., a table) 0x01-0x1f Reserved for specific noncode types 0x20 Native model (no processor specified) 0x21-0x3F Reserved for processor-specific native models. 0x40 Pcode variant Variable data dependent upon the execution model field. If the variant record contains segment or offset information, then the linker and debugger must be modified to process the segment information. DW Fcn Header DW SPI Fcn Header Offset of the Pcode procedure's Function Header SPI Offset of the Pcode segment's SPI record (Segment Pcode Information). Both addresses are in the specified code segment. Virtual Function Table Pat 16:16 S_VFTPATH16 0x010b This record is used to describe the base class path for the virtual function table descriptor. DW length DW S_VFTPATH16 DW offset DW segment DD @root DD @path offset Offset portion of start of the virtual function table segment Segment portion of the virtual function table @root The type index of the class at the root of the path @path Type index of the record describing the base class path from the root to the leaf class for the virtual function table. Application Entry Point S_ENTRY16 0x110 DW 6 ; symbol length DW 0x0110 ; S_ENTRY16 DD &entry ; 16:16 address of entry point This symbol is emitted by hand in Borland's startup code. The &entry field is fixed up to be the far pointer to the application's entry point (e.g. _main, WinMain). This symbol is moved to the sstGlobalSym section, and must be the first symbol to appear in that section. It is OK for no S_ENTRYxx symbol to be present. Variable Live Range Support S_OPTVAR16 0x0111 S_REGISTER and S_BPRELxx records my be followed by an S_OPTVARxx record. DW 4 + 6*n ; symbol-length DW 0x0111 ; S_OPTVAR16 DW n ; number-of-ranges-that-follow [start repeat 'n' times] DW start ; start offset DW length ; length DW reg# ; register number (same as in S_REGISTER) [end repeat 'n' times] Procedure Return/Epilogue Indicator S_PROCRET16 0x0112 This symbol may occur in multiple places within a single procedure scope. They must always fall within some procedure scope, and therefore are always left in sstAlignSym by the linker/packer. DW 6 ; symbol length DW 0x0112 ; S_PROCRET16 DW addr ; offset of epilogue start within fn DW length ; length of epilogue [-----------------------------------------------------------------------] [ Symbols for 16:32 Segmented Architectures ] [-----------------------------------------------------------------------] BP Relative 16:32 S_BPREL32 0x0200 This symbol is used to specify symbols that are allocated on the stack for a procedure. For C/C++, these include the actual parameters to a function and the local nonstatic variables of functions. DW length DW S_BPREL32 DD offset DD @type DD @name offset Signed offset relative to BP @type Type of this symbol @name Name index of the symbol Local Data 16:32 S_LDATA32 0x0201 These symbols are used for data that is not exported from a module. In C/C++, symbols that are declared static are emitted as Local Data symbols. Symbols that are emitted as Local Data cannot be moved into the global symbol table for the executable file. DW length DW S_LDATA32 DD offset DW segment DD @type DD @name offset Offset portion of the symbol address. Iff offset is 0, then the symbol was assigned to a register by the optimizer and cannot be evaluated. segment Segment portion of the symbol address @type Type index of the symbol @name Name index of symbol Global Data Symbol 16:32 S_GDATA32 0x0202 This symbol record has the same format as the Local Data 16:32 except that the symbol type is S_GDATA32. For C/C++, symbols that are not specifically declared static are emitted as Global Data Symbols and can be compacted by the global symbol table. Public 16:32 S_PUB32 0x0203 This symbol has the same format as the Local Data 16:32 symbol. Its use is reserved to symbols in the Publics table in the Symbol and Type OMF portion of the executable file. Global and Local Procedure Start 16:32 S_LPROC32 0x0204 S_GPROC32 0x0205 The symbol records define local (file static) and global procedure definition. For C/C++, functions that are declared static to a module are emitted as Local Procedure symbols. Functions not specifically declared static are emitted as Global Procedures. For each S_GPROC32 emitted, an S_GPROCREF symbol must be fabricated and emitted to the sstGlobalSym section. DW length DW symbol DD pParent DD pEnd DD pNext DD proc length DD debug start DD debug end DD offset DW segment DD @proctype DB NEAR/FAR DD @name symbol S_LPROC32 or S_GPROC32 pParent See the section on lexical scope linking pEnd See the section on lexical scope linking pNext See the section on lexical scope linking offset Offset portion of the segmented address of the start of the procedure in the code segment segment Segment portion of the segmented address of the start of the procedure in the code segment @proctype Type of the procedure type record proc length Length in bytes of this procedure debug_start Offset in bytes from the start of the procedure to the point where the stack frame has been set up. debug_end Offset in bytes from the start of the procedure to the point where the procedure is ready to return and has calculated its return value, if any. Frame and register variables an still be viewed. NEAR/END Type of return the procedure makes: 0 near 4 far @name Name index of procedure Thunk Start 16:32 S_THUNK32 0x0206 This record specifies any piece of code that exists outside a procedure. It is followed by an End record. DW length DW S_THUNK32 DD pParent DD pEnd DD pNext DD offset DW segment DW thunk length DB ordinal DD @name * variant pParent See the section on lexical scope linking pEnd See the section on lexical scope linking pNext See the section on lexical scope linking offset Offset portion of the segmented address of the start of the thunk in the code segment segment Segment portion of the segmented address of the start of the thunk in the code segment thunk length Length in bytes of this thunk ordinal Ordinal specifying the type of thunk 0 notype 1 adjustor 2 vcall 3 native alias @name Name index of thunk variant Variant field, depending on value of thunk ordinal. If ordinal is notype, there will be no variant field. If ordinal is adjustor, the variant field will be a two- byte signed value specifying the delta to be added to the this pointer, followed by the name of the target function. If the ordinal is vcall, then the variant field will be a two-byte signed displacement into the virtual table. If ordinal is native alias, then the variant is the seg:offset of the pcode entry point. Block Start 16:32 S_BLOCK32 0x0207 This symbol specifies the start of a block of lexically scoped symbols. The lexical scope is terminated by a matching End symbol. DW length DW S_BLOCK32 DD pParent DD pEnd DD length DD offset DW segment DD @name pParent See the section on lexical scope linking pEnd See the section on lexical scope linking block length Length in bytes of the scope of this block offset Offset portion of the segmented address of the start of the block segment Segment portion of the segmented address of the start of the block @name Name index of the block With Start 16:32 S_WITH32 0x0208 DW length DW S_WITH32 DD pParent DD pEnd DW with length DD offset DW segment DW value pParent See the section on lexical scope linking pEnd See the section on lexical scope linking length Length in bytes of the scope of the with block offset Offset portion of the segmented address of the start of the block segment Segment portion of the segmented address of the start of the block value Name index of the value used in the with statement. Code Label 16:32 S_LABEL32 0x0209 DW length DW S_LABEL32 DD offset DW segment DB NEAR/FAR DD @name offset Offset portion of the segmented address of the start of the block segment Segment portion of the segmented address of the start of the block NEAR/FAR Address mode of label: 0 near 4 far @name Name index of label Change Execution Model 16:32 S_CEXMODEL32 0x020a The format of this symbol has not been defined for 16:32 addressing. The symbol is defined as a placeholder. Virtual Function Table Path 16:32 S_VFTPATH32 0x020b This record is used to describe the base class path for the virtual function table descriptor. DW length DW S_VFTPATH32 DD offset DW segment DD @root DD @path offset Offset portion of start of the virtual function table segment Segment portion of the virtual function table @root The type of index of the class at the root of the path @path Type index of the record describing the base class path from the root to the leaf class for the virtual function table. Application Entry Point S_ENTRY32 0x210 DW 8 ; symbol length DW 0x0210 ; S_ENTRY32 DP &entry ; 16:32 address of entry point This symbol is emitted by hand in Borland's startup code. The &entry field is fixed up to be the far pointer to the application's entry point (e.g. _main, WinMain). This symbol is moved to the sstGlobalSym section, and must be the first symbol to appear in that section. It is OK for no S_ENTRYxx symbol to be present. Variable Live Range Support S_OPTVAR32 0x0211 S_REGISTER and S_BPRELxx records my be followed by an S_OPTVARxx record. DW 4 + 10*n; symbol-length DW 0x0211 ; S_OPTVAR32 DW n ; number-of-ranges-that-follow [start repeat 'n' times] DD start ; start offset DD length ; length DW reg# ; register number (same as in S_REGISTER) [end repeat 'n' times] Procedure Return/Epilogue Indicator S_PROCRET32 0x0212 This symbol may occur in multiple places within a single procedure scope. They must always fall within some procedure scope, and therefore are always left in sstAlignSym by the linker/packer. DW 8 ; symbol length DW 0x0212 ; S_PROCRET32 DD addr ; offset of epilogue start within fn DD length ; length of epilogue [-----------------------------------------------------------------------] [ Types Definition Segment ($$BTYPES) ] [-----------------------------------------------------------------------] A $$BTYPES segment may appear in linkable modules. It provides descriptions of the types of the symbols found in the $$PUBLICS and $$SYBMOLS debug section for the module. Type Record A type record has the format: DW length * type string length The length in bytes of the following type string. This count does not include the length field. Type String A type string is a series of consecutive leaf structures. DW leaf * data DW leaf * data ... leaf LF_...index, as described below data Data specified to each leaf type No leaf index can have a value of 0x0000. The leaf indices are separated into four ranges according to the use of the type record. The first range is for the type records that are directly referenced in symbols. The second range is for type records that are not referenced by symbols but instead are referenced by other type records. All type records must have a starting leaf index in these first two ranges. The third range of leaf indices is used to build up complex lists such as the field list of class type record. No type record can begin with one of the leaf indices in this range. The fourth ranges of type indices are used to represent numeric data in a symbol or type records. These leaf indices are greater than 0x8000. At the point that the type or symbol processor is expecting a numeric field, the next two bytes in the type record are examined. If the value is less than 0x8000, then the two bytes contain the numeric value. If the value is greater than 0x8000, then the data follows the leaf index in a format specified by the leaf index. See the detailed description of the numeric leaf indices. Because of the method used to maintain natural alignment in complex lists, no leaf index can have a value greater than or equal to 0xf000. Also, no leaf index can have a value such that the least significant 8 bits of the value is greater than or equal to 0xf0. Leaf indices for type records that can be referenced from symbols: 0x0001 LF_MODIFIER 0x0002 LF_POINTER 0x0003 LF_ARRAY 0x0004 LF_CLASS 0x0005 LF_STRUCTURE 0x0006 LF_UNION 0x0007 LF_ENUM 0x0008 LF_PROCEDURE 0x0009 LF_MFUNCTION 0x000a LF_VTSHAPE 0x000b LF_COBOL0 0x000c LF_COBOL1 0x000d LF_BARRAY 0x000e LF_LABEL 0x000f LF_NULL 0x0010 LF_NOTTRAN 0x0011 LF_DIMARRAY 0x0012 LF_VFTPATH Leaf indices for type records that can be referenced from other type records. 0x0200 LF_SKIP 0x0201 LF_ARGLIST 0x0202 LF_DEFARG 0x0203 LF_LIST 0x0204 LF_FIELDLIST 0x0205 LF_DERIVED 0x0206 LF_BITFIELD 0x0207 LF_METHODLIST 0x0208 LF_DIMCONU 0x0209 LF_DIMCONLU 0x020a LF_DIMVARU 0x020b LF_DIMVARLU 0x020c LF_REFSYM Leaf indices for fields of complex lists: 0x0400 LF_BCLASS 0x0401 LF_VBCLASS 0x0402 LF_IVBCLASS 0x0403 LF_ENUMERATE 0x0404 LF_FRIENDFCN 0x0405 LF_INDEX 0x0406 LF_MEMBER 0x0407 LF_STMEMBER 0x0408 LF_METHOD 0x0409 LF_NESTTYPE 0x040a LF_VFUNCTAB 0x040b LF_FRIENDCLS Leaf indices for numeric fields of symbols and type records: 0x8000 LF_NUMERIC 0x8000 LF_CHAR 0x8001 LF_SHORT 0x8002 LF_USHORT 0x8003 LF_LONG 0x8004 LF_ULONG 0x8005 LF_REAL32 0x8006 LF_REAL64 0x8007 LF_REAL80 0x8008 LF_REAL128 0x8009 LF_QUADWORD 0x800a LF_UQUADWORD 0x800b LF_REAL48 0xf0 LF_PAD0 0xf1 LF_PAD1 0xf2 LF_PAD2 0xf3 LF_PAD3 0xf4 LF_PAD4 0xf5 LF_PAD5 0xf6 LF_PAD6 0xf7 LF_PAD7 0xf8 LF_PAD8 0xf9 LF_PAD9 0xfa LF_PAD10 0xfb LF_PAD11 0xfc LF_PAD12 0xfd LF_PAD13 0xfe LF_PAD14 0xff LF_PAD15 Member attribute field Several of the type records below reference a field attribute bit field. This has the following format: access: :2 Specifies the access protection of the item 0 No access protection 1 Private 2 Protected 3 Public mprop :3 Specifies the properties for methods 0 Vanilla method 1 Virtual method 2 Static method 3 Friend method 4 Introducing virtual method 5 Pure virtual method 6 Pure introducing virtual method 7 Reserved pseudo :1 True if the method is never instantiated by the compiler noninherit :1 True if the class cannot be inherited noconstruct :1 True if the class cannot be constructed ovlop :1 True if this is an overloaded operator cnvop :1 True if this is a type conversion operator isctor :1 True if this is a constructor isdtor :1 True if this is a destructor bltin :1 True if this is a compiler-created method isbitfield :1 True is this is a bitfield member reserved :2 Leaf Indices that can be Referenced from Symbols Type Modifier LF_MODIFIER 0x0001 This record is used to indicate the const and/or volatile properties for any particular type. DW LF_MODIFIER DW attribute DD @index attribute const :1 const attribute. volatile :1 volatile attribute. reserved :14 @index type index of the modified type Pointer LF_POINTER 0x0002 This record is the generic pointer type record. It supports the C++ referenct type, pointer to data member, and pointer to method. It also conveys the const and volatile pointer types. DW LF_POINTER DW attribute DW @type * variant attribute Consists of five bit fields: ptrtype :5 Ordinal specifying size of pointer 0 Near 1 Far 2 Huge 3 Based on segment 4 Based on value 5 Based on segment of value 6 Based on address of symbol 7 Based on segment of symbol address 8 Based on type 9 Based on self 10 Near 32 bit pointer 11 Far 32 bit pointer 12-31 Reserved ptrmode :3 Ordinal specifying pointer mode 0 Pointer 1 Reference 2 Pointer to data member 3 Pointer to method 4-7 Reserved isflat32 :1 True if 16:32 pointer volatile :1 Volatile pointer attribute const :1 Const pointer attribute unused :5 Unused and reserved @type Type index of object pointed to variant variant position of the record, depending upon the pointer type based on segment Segment value based on type Index of type followed by length-prefixed name based on self Nothing based on symbol Copy of symbol record including length field pointer to data member Union specifying pointer to data member pointer to method Union specifying pointer to method The union specifying the pointer to data member has the format: DW format DW @class format 0 16:16 data for classs with no virtual functions or virtual bases. 1 16:16 data for classs with virtual functions. 2 16:16 data for class with virtual bases. 3 16:32 data for classes with or without virtual functions and no virtual bases. 4 16:32 data for class with virtual bases. 5 16:16 near method nonvirtual bases with single address point. 6 16:16 near method nonvirtual bases with multiple address points. 7 16:16 near method with virtual bases. 8 16:16 far method nonvirtual bases with single address point. 9 16:16 far method nonvirtual bases with multiple address points. 10 16:16 far method with virtual bases. 11 16:32 method nonvirtual bases with single address point. 12 16:32 method nonvirtual bases with multiple address points. 13 16:16 method with virtual bases. 32 single inheritance only 33 multiple inheritance, no virtual bases 34 multiple inheritance with virtual bases The pointer to data member and pointer to method have the following formats in memory. In the following descriptions of the format and value of the NULL pointer, * means any value. * 16:16 pointer to data member for a class with no virtual functions or bases. DW mdisp mdisp Displacement to data. NULL is 0xffff * 16:16 pointer to data member for a class with virtual functions. DW mdisp mdisp Displacement to data. NULL is 0 * 16:16 pointer to data member for a class with virtual functions. DW mdisp DW pdisp DW vdisp mdisp displacement to data. pdisp this pointer displacement to virtual base table pointer. vdisp displacement within virtual base table. NULL value is (,,0xffff) * 16:32 near pointer to data member for a class with and without virtual functions and no virtual bases. DD mdisp mdisp Displacement to data. NULL is 0x80000000 * 16:32 near pointer to data member for a class with virtual bases. DD mdisp DD pdisp DD vdisp mdisp displacement to data pdisp this pointer displacement to virtual base table pointer vdisp displacement within virtual base table. NULL value is (,,0xffffffff) * 16:16 pointer to near member function for a class with no virtual functions or bases and a single address point. DW off off near address of method. NULL is 0 * 16:32 pointer to near member function for a class with no virtual bases with multiple address points. DW off DW disp off offset of function disp displacement of address point. NULL is (0,*) * 16:16 pointer to near membr function for a class with virtual bases DW off DW mdisp DW pdisp DW vdisp off offset of function mdisp displacement to data pdisp this pointer displacement to virtual base table pointer vdisp displacement within virtual base table. NULL value is (0,*,*,*) * 16:16 pointer to far member function for a class with no virtual bases and a single address point DW off DW disp off offset function disp displacement of address point. NULL is (0:0) * 16:16 pointer to far member function for a class with no virtual bases and multiple address points DW off DW seg DW disp off offset of function seg segment of function disp displacement of address point. NULL is (0:0,*) * 16:16 pointer to far member function for a class with virtual bases DW off DW seg DW mdisp DW pdisp DW vdisp off offset of function seg segment of function mdisp displacement to data pdisp this pointer displacement to virtual base table pointer vdisp displacement within virtual base table. NULL value is (0,*,*,*) * 16:32 pointer to member function for a class with no virtual bases and a single address point DD off off offset of function. NULL is 0L * 16:32 pointer to member function for a class with no virtual bases and multiple address points DD off DD seg off offset of function seg displacement of address point. NULL is (0L:0L) * 16:32 pointer to member function for a class with virtual bases DD off DD mdisp DD pdisp DD vdisp off offset of function mdisp displacement to data pdisp this pointer displacement to virtual base table pointer vdisp displacement within virtual base table. NULL value is (0L,*,*,*) Simple Array LF_ARRAY 0x0003 DW LF_ARRAY DD @elemtype DD @idxtype DD @name * length * nElts @elemtype Type index of each array element @idxtype Type index of indexing variable @name Name index of array length Numeric field giving length of array in bytes nElts Numeric leaf giving number of elts in array Classes and Structures LF_CLASS 0x0004 LF_STRUCTURE 0x0005 The format for structures and classes is as follows: DW leaf DW count DD @field DW property DD @cclass DD @dList DD @vshape DD @name * length leaf LF_CLASS or LF_STRUCTURE count Number of elements in the class or structure. This count includes direct, virtual, and indirect virtual bases, and methods including overloads, data members, static data members, friends, and so on. @field Type index of the field list for this class property Property bit field ctor :1 Class has a constructor :1 Class has overloaded operators isnested :1 Class is a nested class cnested :1 Class contains nested classes opassign :1 Class has overloaded assignment opcast :1 Class has casting methods fwdref :1 Class/structure is a forward (incomplete) reference dtor :1 Class has a destructor reserved :7 @cclass If cclass is non-zero, then the enum is a nested enum, and the value is the type index of the class that contains the enum Note that in the 'GlobalSym' table, nested types show up as S_UDT records with names like 'outer::inner'. @dList Type index of the derivation list. This is output by the compiler as 0x0000 and is filled in by the linker to a LF_DERIVED record containing the type indices of those classes which immediately inherit the current class. A zero index indicates that no derivation information is available. A null list indicates that the class is not inherited by other classes. @vshape Type index of the virtual function table shape descriptor @name Name index of this type length Numeric leaf specifying size in bytes of the structure Unions LF_UNION 0x0006 The format for a Union is as follows: DW LF_UNION DW count DD @field DW property DD @cclass DD @name * length count Number of fields in the union @field Type index of field list. See LF_CLASSS/LF_STRUCTURE property Property bit field. See LF_CLASSS/LF_STRUCTURE @cclass If cclass is non-zero, then the enum is a nested enum, and the value is the type index of the class that contains the enum Note that in the 'GlobalSym' table, nested types show up as S_UDT records with names like 'outer::inner'. @name Name index of union length Numeric leaf specifying size in bytes of the union Enumeration LF_ENUM 0x0007 The format for an Enum is as follows: DW LF_ENUM DW count DD @type DD @fList DD @cclass DD @name count Number of enumerates @type Underlying type of enum @field Type index of field list. See LF_CLASS/LF_STRUCTURE @cclass If cclass is non-zero, then the enum is a nested enum, and the value is the type index of the class that contains the enum @name Name index of enum Procedure LF_PROCEDURE 0x0008 DW LF_PROCEDURE DD @rvtype DB call DB reserved DW #parms DD @arglist @rvtype Type index of the value returned by the procedure call Calling convention of the procedure 0 Near C (arguments pushed right to left, caller pops arguments), short 1 Far C 2 Near pascal (arguments pushed left to right, callee pops arguments) 3 Far pascal 4 Near fastcall 5 Far fastcall 6 Reserved 7 Near stdcall 8 Far stdcall 9 Near syscall 10 Far syscall 11 This call 12-255 Reserved The value 0x80 can be combined with any of the other calling convention values to specify 'fastthis' (methods only) #parms Number of parameters @arglist Type index of argument list type record Member Function LF_MFUNCTION 0x0009 DW LF_MFUNCTION DD @rvtype DD @class DD @this DB call DB res DW parms DD @arglist DD thisadjust @rvtype Type index of the value returned by the procedure @class Type index of the containing class of the function @this Type index of the this parameter of the member function. A type of void indicates that the member function is static and has no this parameter. call Calling convention of the procedure. See Procedure description. #parms Number of parameters. This count does not include the this parameter. @arglist List of parameter specifiers. This list does not include the this parameter. thisadjust Logical this adjustor for the method. Whenever a class element is referenced via the this pointer, thisadjust will be added to the resultant offset before referencing the element. Virtual Function Table Shape LF_VTSHAPE 0x000a This record describes the format of a virtual function table. This record is accessed via vfunctabptr in the member list of a class which introduces the virtual function. The member of the class at the address point of the introducing class has a type of LF_POINTER and points to the virtual function table. The underlying type of the pointer is a VTShape type record. This record describes how to interpret the memory at the location pointed to by the virtual function table pointer. DW LF_VTSHAPE DW count (DD ((4 bits) * count)) descriptor count Number of descriptors descriptor A four-bit ordinal describing the entry in the virtual table 0 Near 1 Far 2 Thin 3 Address point displacement to outermost class. This is at entry [-1] from tables address. 4 Far pointer to metaclass descriptor. This is at entry [-2] from table address. 5 Near32 6 Far32 7-15 Reserved Label LF_LABEL 0x000e This is used for assembler labels where there is no typing information about the label. DW LF_LABEL DW mode mode Addressing mode of the lable 0 Near label 4 Far label Null LF_NULL 0x000f This is used where the symbol requires a type record but the data content is null. DW LF_NULL Not Translated LF_NOTTRANS 0x0010 This is used when the linker encounters a type record that has no equivalent in the Borland 32 bit symbol format. DW LF_NOTTRANS Multiply Dimensioned Array LF_DIMARRAY 0x0011 This record is used to describe a multiply dimensioned array. DW LF_DIMARRAY DW @utype DW @diminfo DW name @utype Underlying type of the array @diminfo Index of the type record containing the dimension information name Name index of the array Path to Virtual Function Table LF_VFTPATH 0x0012 This record is used to describe the path to the virtual function table. DW LF_VFTPATH DW count DW * count bases count Count of number of bases in the path to the virtual function table bases Type indices of the base classes in the path Type Records Referenced from Type Records Skip LF_SKIP 0x0200 This is used by incremental compilers to reserve space for future indexes. DW LF_SKIP DW index * pad index In processing $$BTYPES, the index counter is advanced to index count, skipping all intermediate indices. This is the next valid index. pad Space reserved for incremental compilations. Note that this record is removed by the link/pack utility so there is no requirement for maintaining natural alignment for this record. Argument List LF_ARGLIST 0x0201 DW LF_ARGLIST DW argcount * indices argcount Count of number of indices in list indices List of type indices for describing the formal parameters to a function or method. Default Argument LF_DEFARG 0x0202 DW LF_DEFARG DD @index DD @name @type Type index of resulting expression @name Name index of expression Arbitrary List LF_LIST 0x0203 DW LF_LIST * data data A list of leaves with a format defined by the leaf which indexes the list. This leaf type has been superseded by more specific list types. Derived Classes LF_DERIVED 0x0205 This type record specifies all of the classes that are directly derived from the class that references this type record. DW LF_DERIVED DW count count Number of types in the list @type Type indices of the classes that directly inherit from the class that references this class Field List LF_FIELDLIST 0x0204 A field list contains the descriptors of the fields of a structure, class, union, or enumeration. The field list is composed of zero or more subfields. Because of the requirement for natural alignment, there may be padding between elements of the field list. As a program walks down the field list, the address of the next subfield is calculated by adding the length of the previous field to the address of the previous field. The byte at the new address is examined and if it is greater than 0xf0, the low four bits are extracted and added to the address to find the address of the next subfield. These padding fields are not included in the count field of the class, structure, union, or enumeratin type records. If the field list is broken into two or more pieces by the compiler, then the last field of each piece is a LF_INDEX with the type being the index of the continuation. The LF_INDEX and LF_PADx fields of the field list are not included in field list count specified in the class, structure, union, or enumeration record. DW leaf * data * pad [repeats] Bitfields LF_BITFIELD 0x0206 Bitfields are represented by an entry in the field list that indexes a bitfield type definition. DW LF_BITFIELD DB length DB position DD @type length The length in bits of the object position Starting position (from bit 0) of the object in the word. @type Type index of the field Method List LF_MLIST 0x0207 DW LF_MLIST DW attribute DD @type DD reserved [repeat] attribute Attribute of the member function @type Type index of the procedure record for this occurrence of the function. reserved 0 vtab offset Present only when property attribute is introducing virtual (optional). Offset in vtable of the class which contains the pointer to the function. Once a method has been found in this list, its symbol is found by qualifying the method name with its class (T::name) and then searching the symbol table for a symbol by that name with the correct type index. Note that the number of repeats is determined by the subleaf of the field list that references this LF_MLIST record. Dimensioned Array with Constant Upper Bound LF_DIMCONU 0x0208 This record is used to describe a dimensioned array with default lower bound and constant upper bound. The default lower bound is language specific. DW LF_DIMCONU DW rank DW @index s*rank bound rank Number of dimensions @index Type of the index bound Constants for the upper bound of each dimension of the array. Each constant is of the size s specific by @index. Dimensioned Array with Constant Lower and Upper Bounds LF_DIMCONLU 0x0209 This record is used to describe a dimensioned array with constant lower and upper bound. DW LF_DIMCONLU DW rank DW @index DW*s*rank bound rank Number of dimensions @index Type of the index bound Pairs of constants for the lower and upper bound of each dimension of the array. Each constant is of the size s specified by @index. The ordering is lower bound followed by upper bound for each dimension. Dimensioned Array with Variable Upper Bound LF_DIMVARU 0x020a This record is used to describe a dimensioned array with default lower bound and variable upper bound. The default lower bound is language specific. DW LF_DIMVARU DW rank DW @index DW*rank @var rank Number of dimensions @index Type of the index @var Array of type index of LF_REFSYM record describing the variable upper bound. If one dimension of the array is variable, then all dimensions must be described using LF_REFSYM records. Dimensioned Array with Variable Lower and Upper Bounds LF_DIMVARLU 0x020b This record is used to describe a dimensioned array with variable lower and upper bound. DW LF_DIMVARLU DW rank DW @index DW*rank bound rank Number of dimensions @index Type of index @var Array of type indices of LF_REFSYM records describing the variable lower and upper bounds. If one dimensin of the array is variable, then all dimensions must be described using LF_REFSYM records. The order is lower bound followed by upper bound for each dimension. Referenced Symbol LF_REFSYM 0x020c Don't you dare emit this record. This record is used to describe a symbol that is referenced by a type record. The record is defined because type records cannot reference symbols or locations in the $$BSYMSS table because global symbol compaction will move symbols. DW LF_REFSYM * sym sym Copy of the referenced symbol including the length field. Subfields of complex lists Currently, the only complex list that uses the following leaf indices is the field list of a structure, class, union, or enumeration. Index To Another Type Record LF_INDEX 0x0405 DW LF_INDEX DD @index index Type index. This field is emitted by the compiler when a complex list needs to be split during writing. Real Base Class LF_BCLASS 0x0400 This leaf specifies a real base class. If a class inherits base classes, the corresponding BaseClass records will precede all other member records in the field list of that class. Base class records are emitted in left to right declaration order for real bases. DW LF_BCLASS DD @type DW attribute * offset @type Index to type record of the class. The class name can be obtained from this record. attribute Member attribute bit field offset Offset of subobject that represents the base class within the structure. Direct and Indirect Virtual BaseClass LF_VBCLASS 0x0401 LF_IVBCLASS 0x0402 This leaf specifies a directly inherited virtual base class. If a class inherits virtual base classes, the corresponding Direct Virtual BaseClass records will follow all Base Class member records and precede all other member records in the fList of that class. Direct Virtual Base class records are emitted in bottommost left-to-right order for virtual bases. DW type DD @btype DD @vbptype (void *) DW attribute * vbpoff * vboff (-1) type LF_VBCLASS or LF_IVBCLASS @btype Index to type record of the direct virtual base class. The class name can be obtained from this record. @vbptype Type index of the virtual base pointer for this base attribute Member attribute bit field vbpoff Numeric leaf specifying the offset of the virtual base pointer from the address point of the class for this virtual base. vboff Numeric leaf specifying the index into the virtual base displacement table of the entry that contains the displacement of the virtual base. The displacement is relative to the address point of the class plus vbpoff. Friend Class LF_FRIENDCLS 0x040b This leaf specifies a friend class. DW LF_FRIENDCLS DD @type @type Index to type record of the friend class. The name of the class can be obtained from the referenced record. Friend Function LF_FRIENDFCN 0x0404 This leaf specifies a friend function. DW LF_FRIENDFCN DD @type DD @name @type Index to type record of the friend function @name Name index of friend function Data Member LF_MEMBER 0x0406 This leaf specifies nonstatic data members of a class. DW LF_MEMBER DD @type DW attribute DD @name DD reserved * offset @type Index to type record for field attribute Data member bit field access :2 @name Name index of the member field reserved 0 offset Numeric leaf specifying the offset of field in the structure Static Data Member LF_STMEMBER 0x0407 This leaf specifies static data member of a class. DW LF_STMEMBER DD @type DW attribute DD @name DD reserved @type Index to type record for field attribute Member attribute bit field @name Name index of the member field reserved 0 Once a static data member has been found in this list, its symbol is found by qualifying the name with its class (T::name) and then searching the symbol table for a symbol by that name with the correct type index. Virtual Function Table Pointer LF_VFUNCTAB 0x040a This leaf specifies virtual table pointers within the class. It is a requirement that this record be emitted in the field list before any virtual functions are emitted to the field list. DW LF_VFUNCTAB DD @type * offset @type Index to the pointer record describing the pointer. The pointer will in turn have a LF_VTSHAPE type record as the underlying type. Note that the offset of the virtual function table pointer from the address point of the class is always zero. offset Numeric field giving the offset of the vtable pointer within the class. Member Function LF_METHOD 0x0408 This leaf specifies the member functions of a class. DW LF_METHOD DW count DD @mList DD @name count Number of occurrences of function within the class. If the functin is overloaded then there will be multiple entries in the method list. @mList Type index of method list @name Name index of method Enumeration Name and Value LF_ENUMERATE 0x403 This leaf specifies the name and value of an enumerate within an enumeration. DW LF_ENUMERATE DW attribute DD @name DD reserved * value attribute Member attribute bit field value Numeric leaf specifying the value of enumerate @name Name index of the member field reserved 0 Nested Type Definition LF_NESTTYPE 0x0409 This leaf specifies nested type definition with classes, structures, unions, or enums. DW LF_NESTTYPE DD @index DD @name DD reserved @index Type index of nested type @name Name index of type reserved 0 Numeric Leaf LF_NUMERIC 0x8000 The following leaves are used in symbols and types where actual numeric values need to be specified. When the symbol or type processor knows that a numeric leaf is present, the next two bytes of the record are examined. If the value of these two bytes is less than LF_NUMERIC(0x8000), then the two bytes contain the actual value. If the value is greater than or equal to LF_NUMERIC (0x8000), then the numeric data follows the two-byte leaf index and is contained in the number of bytes specified by the leaf index. Note that there is not a need for a LF_UCHAR numeric field since the value of the eight-bit unsigned character is less than 0x8000. It is the responsibility of routines reading numeric fields to handle the potential nonalignment of the data fields. Signed Char LF_CHAR 0x8000 DW LF_CHAR DB char char 8-bit value Signed Short LF_SHORT 0x8001 DW LF_SHORT DW short short 16-bit signed value Unsigned Short LF_USHORT 0x8002 DW LF_USHORT DW ushort ushort 16-bit unsigned value Signed Long LF_LONG 0x8003 DW LF_LONG DD long long 32-bit signed value Unsigned Long LF_ULONG 0x8004 DW LF_ULONG DD ulong ulong 32-bit unsigned value 32 Bit Float LF_REAL32 0x8005 DW LF_REAL32 DD real32 real32 32-bit floating-point value 48 Bit Float LF_REAL48 0x800b DW LF_REAL48 DF real48 real48 48-bit floating point value 64 Bit Float LF_REAL64 0x8006 DW LF_REAL64 DQ real64 real64 64-bit floating-point value 80 Bit Float LF_REAL80 0x8007 DW LF_REAL80 DT real80 real80 80-bit floating-point value 128 Bit Float LF_REAL128 0x8008 DW LF_REAL128 DT,DF real128 real128 128-bit floating-point value Signed Quadword LF_QUADWORD 0x8009 DW LF_QUADWORD DQ quadword quadword 64-bit signed value Unsigned Quadword LF_UQUADWORD 0x800a DW LF_UQUADWORD DQ uquadword uquadword 64-bit unsigned value Predefined Primitive Types Format of Reserved Types Types 0-4095 (0 - 0x1000) are reserved. These values are interpreted as bit fields with the following sizes and meanings. size :3 reserved1 :1 type :4 mode :3 reserved2 :5 type Type 0x00 Special 0x01 Signed integral value 0x02 Unsigned integral value 0x03 Boolean 0x04 Real 0x05 Complex 0x06 Special2 0x07 Really int value 0x08 Reserved 0x09 Reserved 0x0a Reserved 0x0b Reserved 0x0c Reserved 0x0d Reserved 0x0e Reserved 0x0f Reserved for Code View expression evaluator use size Enumerated value for each of the types (Type = special) 0x00 No type 0x01 Absolute symbol 0x02 Segment 0x03 Void 0x04 Basic 8-byte currency value 0x05 Near Basic string 0x06 Far Basic string 0x07 Untranslated type from CV 3.x format (Type=signed/unsigned integral and Boolean values) 0x00 1 byte 0x01 2 byte 0x02 4 byte 0x03 8 byte 0x04 Reserved 0x05 Reserved 0x06 Reserved 0x07 Reserved (Type=real and complex) 0x00 32 bit 0x01 64 bit 0x02 80 bit 0x03 128 bit 0x04 48 bit 0x05 Reserved 0x06 Reserved 0x07 Reserved (Type=special2) 0x00 Bit 0x01 Pascal CHAR (Type=Really int) 0x00 Char 0x01 Wide character 0x02 2 byte signed integer 0x03 2 byte unsigned integer 0x04 4 byte signed integer 0x05 4 byte unsigned integer 0x06 8 byte signed integer 0x07 8 byte unsigned integer mode Mode 0x00 Direct; not a pointer 0x01 Near pointer 0x02 Far pointer 0x03 Huge pointer 0x04 32 bit near pointer 0x05 32 bit far pointer 0x06 64 bit near pointer 0x07 Reserved /* Special Types */ #define T_NOTYPE 0x0000 // Uncharacterized type (no type) #define T_ABS 0x0001 // Absolute symbol #define T_SEGMENT 0x0002 // Segment type #define T_VOID 0x0003 // Void #define T_PVOID 0x0103 // Near pointer to void #define T_PFVOID 0x0203 // Far pointer to void #define T_PHVOID 0x0303 // Huge #define T_CURRENCY 0x0004 // Basic 8 byte currency value #define T_NBASICSTR 0x0005 // Near Basic string #define T_FBASICSTR 0x0006 // Far Basic string #define T_NOTTRANS 0x0007 // Untranslated type record from // CV 3.x format #define T-BIT 0x0060 // Bit #define T_PASCHAR 0x0061 // Pascal CHAR /* Primitive Type Listing */ /* Character types */ #define T_CHAR 0x0010 // 8-bit signed #define T_UCHAR 0x0020 // 8-bit unsigned #define T_PCHAR 0x0110 // Near pointer to 8-bit signed #define T_PUCHAR 0x0120 // Near pointer to 8-bit unsigned #define T_PFCHAR 0x0210 // Far pointer to 8-bit signed #define T_PFUCHAR 0x0220 // Far pointer to 8-bit unsigned #define T_PHCHAR 0x0310 // Huge pointer to 8-bit signed #define T_PHUCHAR 0x0320 // Huge pointer to 8-bit unsigned #define T_32PCHAR 0x0410 // 16:32 near pointer to 8-bit signed #define T_32PUCHAR 0x0420 // 16:32 near pointer to 8-bit unsigned #define T_32PFCHAR 0x0510 // 16:32 far pointer to 8-bit signed #define T_32PFUCHAR 0x0520 // 16:32 far pointer to 8-bit unsigned /* Really a character types */ #define T_RCHAR 0x0070 // Real char #define T_PRCHAR 0x0170 // Near pointer to a real char #define T_PFRCHAR 0x0270 // Far pointer to a real char #define T_PHRCHAR 0x0370 // Huge pointer to a real char #define T_32PRCHAR 0x0470 // 16:32 near pointer to a real char #define T_32PFRCHAR 0x0570 // 16:32 far pointer to a real char /* Wide character types */ #define T_WCHAR 0x0071 // wide char #define T_PWCHAR 0x0171 // Near pointer to a wide char #define T_PFWCHAR 0x0271 // Far pointer to a wide char #define T_PHWCHAR 0x0371 // Huge pointer to a wide char #define T_32PWCHAR 0x0471 // 16:32 near pointer to a wide char #define T_32PFWCHAR 0x0571 // 16:32 far pointer to a wide char /* Really 16 bit integer types */ #define T_INT2 0x0072 // really 16-bit signed int #define T_UINT2 0x0073 // really 16-bit unsigned int #define T_PINT2 0x0172 // Near pointer to 16-bit signed int #define T_PUINT2 0x0173 // Near pointer to 16-bit unsigned int #define T_PFINT2 0x0272 // Far pointer to 16-bit signed int #define T_PFUINT2 0x0273 // Far pointer to 16-bit unsigned int #define T_PHINT2 0x0372 // Huge pointer to 16-bit signed int #define T_PHUINT2 0x0373 // Huge pointer to 16-bit unsigned int #define T_32PINT2 0x0472 // 16:32 near pointer to 16-bit signed // int #define T_32PUINT2 0x0473 // 16:32 near pointer to 16-bit // unsigned int #define T_32PFINT2 0x0572 // 16:32 far pointer to 16-bit signed // int #define T_32PFUINT2 0x0573 // 16:32 far pointer to 16-bit // unsigned int /* 16-bit short types */ #define T_SHORT 0x0011 // 16-bit signed #define T_USHORT 0x0021 // 16-bit unsigned #define T_PSHORT 0x0111 // Near pointer to 16-bit signed #define T_PUSHORT 0x0121 // Near pointer to 16-bit unsigned #define T_PFSHORT 0x0211 // Far pointer to 16-bit signed #define T_PFUSHORT 0x0221 // Far pointer to 16-bit unsigned #define T_PHSHORT 0x0311 // Huge pointer to 16-bit signed #define T_PHUSHORT 0x0321 // Huge pointer to 16-bit unsigned #define T_32PSHORT 0x0411 // 16:32 near pointer to 16-bit signed #define T_32PUSHORT 0x0421 // 16:32 near pointer to 16-bit unsigned #define T_32PFSHORT 0x0511 // 16:32 far pointer to 16-bit signed #define T_32PFUSHORT 0x0521 // 16:32 far pointer to 16-bit unsigned /* Really 32 bit integer types */ #define T_INT4 0x0074 // really 32-bit signed int #define T_UINT4 0x0075 // really 32-bit unsigned int #define T_PINT4 0x0174 // Near pointer to 32-bit signed int #define T_PUINT4 0x0175 // Near pointer to 32-bit unsigned int #define T_PFINT4 0x0274 // Far pointer to 32-bit signed int #define T_PFUINT4 0x0275 // Far pointer to 32-bit unsigned int #define T_PHINT4 0x0374 // Huge pointer to 32-bit signed int #define T_PHUINT4 0x0375 // Huge pointer to 32-bit unsigned int #define T_32PINT4 0x0474 // 16:32 near pointer to 32-bit signed // int #define T_32PUINT4 0x0475 // 16:32 near pointer to 32-bit // unsigned int #define T_32PFINT4 0x0574 // 16:32 far pointer to 32-bit signed // int #define T_32PFUINT4 0x0575 // 16:32 far pointer to 32-bit // unsigned int /* 32-bit long types */ #define T_LONG 0x0012 // 32-bit signed #define T_ULONG 0x0022 // 32-bit unsigned #define T_PLONG 0x0112 // Near pointer to 32-bit signed #define T_PULONG 0x0122 // Near pointer to 32-bit unsigned #define T_PFLONG 0x0212 // Far pointer to 32-bit signed #define T_PFULONG 0x0222 // Far pointer to 32-bit unsigned #define T_PHLONG 0x0312 // Huge pointer to 32-bit signed #define T_PHULONG 0x0322 // Huge pointer to 32-bit unsigned #define T_32PLONG 0x0412 // 16:32 near pointer to 32-bit signed #define T_32PULONG 0x0422 // 16:32 near pointer to 32-bit unsigned #define T_32PFLONG 0x0512 // 16:32 far pointer to 32-bit signed #define T_32PFULONG 0x0522 // 16:32 far pointer to 32-bit unsigned /* Really 64-bit int types */ #define T_INT8 0x0076 // 64-bit signed int #define T _UINT8 0x0077 // 64-bit unsigned int #define T_PINT8 0x0176 // Near pointer to 64-bit signed int #define T_PUINT8 0x0177 // Near pointer to 64-bit unsigned int #define T_PFINT8 0x0276 // Far pointer to 64-bit signed int #define T_PFUINT8 0x0277 // Far pointer to 64-bit unsigned int #define T_PHINT8 0x0376 // Huge pointer to 64-bit signed int #define T_PHUINT8 0x0377 // Huge pointer to 64-bit unsigned int #define T_32PINT8 0x0476 // 16:32 near pointer to 64-bit signed // int #define T_32PUINT8 0x0477 // 16:32 near pointer to 64-bit unsigned // int #define T_32PFINT8 0x0576 // 16:32 far pointer to 64-bit signed int #define T_32PFUINT8 0x0577 // 16:32 far pointer to 64-bit unsigned // int /* 64-bit integral types */ #define T_QUAD 0x0013 // 64-bit signed #define T_UQUAD 0x0023 // 64-bit unsigned #define T_PQUAD 0x0113 // Near pointer to 64-bit signed #define T_PUQUAD 0x0123 // Near pointer to 64-bit unsigned #define T_PFQUAD 0x0213 // Far pointer to 64-bit signed #define T_PFUQUAD 0x0223 // Far pointer to 64-bit unsigned #define T_PHQUAD 0x0313 // Huge pointer to 64-bit signed #define T_PHUQUAD 0x0323 // Huge pointer to 64-bit unsigned #define T_32PQUAD 0x0413 // 16:32 near pointer to 64-bit signed #define T_32PUQUAD 0x0423 // 16:32 near pointer to 64-bit unsigned #define T_32PFQUAD 0x0513 // 16:32 far pointer to 64-bit signed #define T_32PFUQUAD 0x0523 // 16:32 far pointer to 64-bit unsigned /* 32-bit integral types */ #define T_REAL32 0x0040 // 32-bit real #define T_PREAL32 0x0140 // Near pointer to 32-bit real #define T_PFREAL32 0x0240 // Far pointer to 32-bit real #define T_PHREAL32 0x0340 // Huge pointer to 32-bit real #define T_32PREAL32 0x0440 // 16:32 near pointer to 32-bit real #define T_32PFREAL32 0x0540 // 16:32 far pointer to 32-bit real /* 48-bit real types */ #define T_REAL48 0x0044 // 48-bit real #define T_PREAL48 0x0144 // Near pointer to 48-bit real #define T_PFREAL48 0x0244 // Far pointer to 48-bit real #define T_PHREAL48 0x0344 // Huge pointer to 48-bit real #define T_32PREAL48 0x0444 // 16:32 near pointer to 48-bit real #define T_32PFREAL48 0x0544 // 16:32 far pointer to 48-bit real /* 64-bit real types */ #define T_REAL64 0x0041 // 64-bit real #define T_PREAL64 0x0141 // Near pointer to 64-bit real #define T_PFREAL64 0x0241 // Far pointer to 64-bit real #define T_PHREAL64 0x0341 // Huge pointer to 64-bit real #define T_32PREAL64 0x0441 // 16:32 near pointer to 64-bit real #define T_32PFREAL64 0x0541 // 16:32 far pointer to 64-bit real /* 80-bit real types */ #define T_REAL80 0x0042 // 80-bit real #define T_PREAL80 0x0142 // Near pointer to 80-bit real #define T_PFREAL80 0x0242 // Far pointer to 80-bit real #define T_PHREAL80 0x0342 // Huge pointer to 80-bit real #define T_32PREAL80 0x0442 // 16:32 near pointer to 80-bit real #define T_32PFREAL80 0x0542 // 16:32 far pointer to 80-bit real /* 128-bit real types */ #define T_REAL128 0x0043 // 128-bit real #define T_PREAL128 0x0143 // Near pointer to 128-bit real #define T_PFREAL128 0x0243 // Far pointer to 128-bit real #define T_PHREAL128 0x0343 // Huge pointer to 128-bit real #define T_32PREAL128 0x0443 // 16:32 near pointer to 128-bit real #define T_32PFREAL128 0x0543 // 16:32 far pointer to 128-bit real */ 32-bit complex types */ #define T_CPLX32 0x0050 // 32-bit complex #define T_PCPLX32 0x0150 // Near pointer to 32-bit complex #define T_PFCPLX32 0x0250 // Far pointer to 32-bit complex #define T_PHCPLX32 0x0350 // Huge pointer to 32-bit complex #define T_32PCPLX32 0x0450 // 16:32 near pointer to 32-bit complex #define T_32PFCPLX32 0x0550 // 16:32 far pointer to 32-bit complex /* 64-bit complex types */ #define T_CPLX64 0x0051 // 64-bit complex #define T_PCPLX64 0x0151 // Near pointer to 64-bit complex #define T_PFCPLX64 0x0251 // Far pointer to 64-bit complex #define T_PHCPLX64 0x0351 // Huge pointer to 64-bit complex #define T_32PCPLX64 0x0451 // 16:32 near pointer to 64-bit complex #define T_32PFCPLX64 0x0551 // 16:32 far pointer to 64-bit complex /* 80-bit complex types */ #define T_CPLX80 0x0052 // 80-bit complex #define T_PCPLX80 0x0152 // Near pointer to 80-bit complex #define T_PFCPLX80 0x0252 // Far pointer to 80-bit complex #define T_PHCPLX80 0x0352 // Huge pointer to 80-bit complex #define T_32PCPLX80 0x0452 // 16:32 near pointer to 80-bit complex #define T_32PFCPLX80 0x0552 // 16:32 far pointer to 80-bit complex /* 128-bit complex types */ #define T_CPLX128 0x0053 // 128-bit complex #define T_PCPLX128 0x0153 // Near pointer to 128-bit complex #define T_PFCPLX128 0x0253 // Far pointer to 128-bit complex #define T_PHCPLX128 0x0353 // Huge pointer to 128-bit complex #define T_32PCPLX128 0x0453 // 16:32 near pointer to 128-bit complex #define T_32PFCPLX128 0x0553 // 16:32 far pointer to 128-bit complex /* Boolean types */ #define T_BOOL08 0x0030 // 8-bit boolean #define T_BOOL16 0x0031 // 16-bit boolean #define T_BOOL32 0x0032 // 32-bit boolean #define T_PBOOL08 0x0130 // Near pointer to 8-bit boolean #define T_PBOOL16 0x0131 // Near pointer to 16-bit boolean #define T_PBOOL32 0x0132 // Near pointer to 32-bit boolean #define T_PFBOOL08 0x0230 // Far pointer to 8-bit boolean #define T_PFBOOL16 0x0231 // Far pointer to 16-bit boolean #define T_PFBOOL32 0x0232 // Far pointer to 32-bit boolean #define T_PHBOOL08 0x0330 // Huge pointer to 8-bit boolean #define T_PHBOOL16 0x0331 // Huge pointer to 16-bit boolean #define T_PHBOOL32 0x0332 // Huge pointer to 32-bit boolean #define T_32PBOOL08 0x0430 // 16:32 near pointer to 8-bit boolean #define T_32PFBOOL08 0x0530 // 16:32 far pointer to 8-bit boolean #define T_32PBOOL16 0x0431 // 16:32 near pointer to 16-bit boolean #define T_32PFBOOL16 0x0531 // 16:32 far pointer to 16-bit boolean #define T_32PBOOL32 0x0432 // 16:32 near pointer to 32-bit boolean #define T_32PFBOOL32 0x0532 // 16:32 far pointer to 32-bit boolean Codes for Register Variables When the compiler emits a symbol that has been unregistered, the symbol record specifies the register by a register enumeration value. The enumeration is unique to each hardware architecture supported. Intel 80x86/80x87 Architectures 0 none 8-bit registers 1 AL 2 CL 3 DL 4 BL 5 AH 6 CH 7 DH 8 BH 16-bit registers 9 AX 10 CX 11 DX 12 BX 13 SP 14 BP 15 SI 16 DI 32-bit resisters 17 EAX 18 ECX 19 EDX 20 EBX 21 ESP 22 EBP 23 ESI 24 EDI Segment registers 25 ES 26 CS 27 SS 28 DS 29 FS 30 GS Special cases 31 IP 32 FLAGS 33 EIP PCODE Registers 40 PCODE TEMP 41 PCODE TEMPH 42 PCODE QUOTE 43-47 Reserved Register extensions for 80x87 128 ST(0) 129 ST(1) 130 ST(2) 131 ST(3) 132 ST(4) 133 ST(5) 134 ST(6) 135 ST(7) 136 CONTROL 137 STATUS 138 TAG 139 FPIP 140 FPCS 141 FPDO 142 FPDS 143 ISEM MIPS4000 Architectures Indices not yet specified. [-----------------------------------------------------------------------] [ Symbol and Type OMF Format Borland Executable Files ] [-----------------------------------------------------------------------] Introduction This section describes the format used to embed debugging information into the executable file. Debug Information Format The format encompasses a block of data which goes at the end of the .EXE file, i.e., after the header plus load image, overlays, and Windows/Presentation Manager resource compiler information. The lower portion of the file is unaffected by the additional data. The last eight bytes of the file contain a signature and a long file offset from the end of the file (lfoBase). The signature is FBxx, where xx is the version number. The long offset indicates the position in the file (relative to the end of the file) of the base address. For the LX format executables, the base address is determined by looking at the executable header. The signatures have the following meanings: FB09 The signature for a Borland 32 bit symbol file. The value lfaBase=length of the file - lfoBase gives the base address of the start of the Symbol and Type OMF information relative to the beginning of the file. All other file offsets in the Symbol and Type OMF are relative to the lfaBase. At the base address the signature is repeated, followed by the long displacement to the subsection directory (lfoDir). All subsections start on a long word boundary and are designed to maintain natural alignment internally in each subsection and within the subsection directory. Subsection Directory The subsection directory has the format Directory header Directory entry 0 Directory entry 1 . . . Directory entry n The subsection directory is prefixed with a directory header structure indicating size and number of subsection directory entries that follow. DW cbDirHeader DW cbDirEntry DD cDir DD lfoNextDir DD flags cbDirHeader Length of this structure cbDirEntry Length of each directory entry cDir Number of directory entries lfoNextDir Offset from lfoBase of next directory. This field is used by the incremental linker to point to the next directory containing Symbol and Type OMF information from an incremental link. It is always set to 0 for FB07 headers. flags Flags describing directory and subsection tables. No values have been defined for this field. The directory header structure is followed by the directory entries which specify the subsection type, module index, file offset, and size. The subsection directory gives the location (LFO) and size of each subsection, as well as its type and module number if applicable. DW subsection DW iMod DD lfo DD cb subsection Subdirectory indes. See the table below for a listing of the valid subsection indices. iMod Module index. This number is based on 1, and zero is never a valid index. The index 0xffff is reserved for tables that are not associated with a specific module. These tables include sstLibraries, sstGlobalSym, sstGlobalPub and sstGlobalTypes. lfo Offset from the base offset lfoBase cb Number of bytes in subsection There is no requirement for a particular subsection of a particular module to exist. The following is the layout of the FB09 debug information in the image: FB09 Header sstModule [1] . . . sstModule [n] sstAlignSym [1] sstSrcModule [1] . . . sstAlignSym [n] sstSrcModule [n] sstGlobalSym sstGlobalTypes sstNames SubSection Directory FB09 Trailer Subsection Types (sst...) sstModule 0x120 sstTypes 0x121 sstSymbols 0x124 sstAlignSym 0x125 sstSrcModule 0x127 sstGlobalSym 0x129 sstGlobalTypes 0x12b sstNames 0x130 sstModule 0x120 This describes the basic information about an object module including code segments, module name, and the number of segments for the modules that follow. Directory entries for sstModules precede all other subsection directory entries. DW ovlNumber DW iLib DW cSeg DW Style DD @name DD timeStamp DD*3 reserved * SegInfo ovlNumber Overlay numer iLib Index into sstLibraries subsection if this module was linked from a library cSeg Count of the number of code segments this module contributes to Style Debugging style for this module. Currently only "CV" is defined. A module can have only one debugging style. If a module contains debugging information in an unrecognized style, the information will be discarded. @name Name index of module. timeStamp Time stamp from the OBJ file. reserved Set to 0. SegInfo Detailed information about each segment that code is contributed to. This is an array of cSeg count segment information descriptor structures. SegInfo is a structure that describes each segment to which a module contributes code. It is formatted as follows: DW Seg DW flags DD offset DD cbSeg Seg Segment that this structure describes flags Attributes for the logical segment. The following attributes are defined: 0x0000 Data segment 0x0001 Code segment offset Offset in segment where the code starts cbSeg Count of the number of bytes of code in the segment sstAlignSym 0x0125 The linker writes the remaining unpacked symbols for a module back to the executable in a subsection of this type. All symbols have been padded to fall on a long word boundary and the lexical scope linkage fields have been initialized. sstSrcModule 0x0127 This table describes the source line number to addressing mapping information for a module. The table permits the description of a module containing multiple source files with each source file contributing code to one or more code segments. The base addresses of the tables described below are all relative to the beginning of the sstSrcModule table. Module header Information for source file 1 Information for segment 1 . . . Information for segment n . . . Information for source file n Information for segment 1 . . . Information for segment n The module header structure describes the source file and code segment organization of the module. Each module header has the following format: DW cFile DW cSeg 4*cFile baseSrcFile 8*cSeg start/end 2*cSeg seg cFile The number of source file scontributing code to segments cSeg The number of code segments receiving code from this module baseSrcFile This is an array of base offsets from the beginning of the sstSrcModule table start/end An array of two 32-bit offsets per segment that receives code from this module. The first offset is the offset within the segment of the first byte of code from this module. The second offset is the ending address of the code from this module. The order of these pairs corresponds to the ordering of the segments in the seg array. Zeros in these entries means that the information is not known and the file and line tables described below need to be examined to determine if an address of interest is contained within the code from this module. seg An array of segment indices that receive code from this module. If the number of segments is not even, a pad word is inserted to maintain natural alignment. The file table describes the code segments that receive code from this source file. Source file entries have the following format: DW cSeg DD @name 4*cSeg baseSrcLn 8*cSeg start/end * cbName cSeg Number of segments that receive code from this source file. If the source file contributes code multiple times to a segment, this is reflected in this count. @name Name index of Source file name. This can be a fully or partially qualified path name. baseSrcLn An array of offsets for the line/address mapping tables for each of the segments that receive code from this source file. start/end An array of two 32-bit offsets per segment that receives code from this module. The first offset is the offset within the segment of the first byte of code from this module. The second offset is the ending address of the code from this module. The order of these pairs corresponds to the ordering of the segments in the seg array. Zeros in these entries means that the information is not known and the file and line tables described below need to be examined to determine if an address of interest is contained within the code from this module. cbName Count of the number of bytes in source file name The line number to address mapping information is contained in a table with the following format: DW Seg DW cPair 4*cPair offset 2*cPair linenumber Seg Segment index for this table cPair Count of the number of source line pairs to follow offset An array of 32-bit offsets for the offset within the code segment of the start of ine contained in the parallel array linenumber. linenumber This is an array of 16-bit line numbers of the lines in the source file that cause code to be emitted to the code segment. This array is parallel to the offset array. If cPair is not even, then a zero word is emitted to maintain natural alignment in the sstSrcModule table. sstGlobalSym 0x129 This section contains globally compacted symbols. The format of the table is a header specifying the symbol and address hash functions, the length of the symbol information, the length of the symbol hash function data, and the length of address hash function data. This is followed by the symbol information followed by the symbol hash tables followed by the address hash tables. When the pack utility writes the sstGlobals subsection, each symbol is zero-padded such that the following symbol starts on a long boundary. The length field is adjusted by the pad count. Note that symbol and/or address hash data can be discarded and the globally packed symbols be linearly searched. Hash function index 0 means no hash data. The format of the table header structure is the same as the header of the sstGlobalPub table. The global symbols are sorted by address, with S_UDT symbols being sorted to the front of the sstGlobalSym section. If an S_ENTRYxx symbol was encountered (there can only be one), it is placed at the front of the sstGlobalSym section before the S_UDT symbols. The cOtherSym field in the header does not include the S_ENTRYxx symbol. sstGlobalTypes 0x12b This subsection contains the packed type records for the executable file. The first long word of the subsection contains the number of types in the table. This count is followed by a count-sized array of long offsets to the corresponding type record. As the sstGlobalTypes subsection is written, each type record is forced to start on a long word boundary. However, the length of the type string is NOT adjusted by the pad count. The remainder of the subsection contains the type records. cType offType[cType] type string 0 type string 1 type string n count of the number of types offset of each type string from the beginning of table type string for type index 0x1000 type string for type index 0x1001 type string for type index 0x1000 + n sstNames 0x130 All names will be placed by the translators into a $$NAMES segment in the OBJs. The linker will coalesce these names into a single global name pool of length preceeded null terminated names. The names as they appear in the OBJs will be length preceeded names. The length byte will be used by the linker for efficient hashing. The debugger wants the null termination. Name indices in all of the symbol and type records are 1 based indices which reference a name in this table. [End of document]