Borland Symbolic Debugging Information
Borland 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.
Logical segments
Field Linkage
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.
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.
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.
Name: $$BSYMS
Class: DEBSYM
Symbols
Data in the $$BSYMS segment is a series of symbol records with the 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.
Symbol Indices
Compile Flag
S_COMPILE 0x0001
DW Length
DW S_COMPILE
DB machine
DB,DW flags
* version
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
DW Length
DW S_REGISTER
DD @type
DW register
DD @name
DD reserved
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
User-defined type
S_UDT 0x0004
DW length
DW S_UDT
DD @type
DW property
DD @name
DD reserved
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)
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
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.
This symbol specifies the name of the object file for this module.
DW length
DW S_OBJNAME
DD signature
DD @name
DW length
DW S_GPROCREF
DD offset
DD @type
DD @name
DD reserved
DD coffset
DD segment
reserved 0
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.
DW length
DW S_GDATAREF
DD offset
DD @type
DD @name
DD reserved
DD doffset
DD segment
reserved 0
External Data
S_EDATA 0x022
DW length
DW S_EDATA
DD @type
DD @name
DW externalIndex
DD reserved
reserved 0
External Procedure
S_EPROC 0x023
DW length
DW S_EPROC
DD @type
DD @name
DW externalIndex
DD reserved
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
reserved 0
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
reserved 0
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.
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
reserved 0
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
0 notype
1 adjustor
2 vcall
3 native alias
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
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
DW length
DW S_LABEL16
DW offset
DW segment
DB NEAR/FAR
DD @name
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
DW Fcn Header
DW SPI
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
@root The type index of the class at the root of the path
DW 6 ; symbol length
DW 0x0110 ; S_ENTRY16
DD &entry ; 16:16 address of entry point
DW 4 + 6*n ; symbol-length
DW 0x0111 ; S_OPTVAR16
DW n ; number-of-ranges-that-follow
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
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
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.
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
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
DW length
DW S_BLOCK32
DD pParent
DD pEnd
DD length
DD offset
DW segment
DD @name
DW length
DW S_WITH32
DD pParent
DD pEnd
DW with length
DD offset
DW segment
DW value
DW length
DW S_LABEL32
DD offset
DW segment
DB NEAR/FAR
DD @name
The format of this symbol has not been defined for 16:32 addressing. The
symbol is defined as a placeholder.
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
DW 8 ; symbol length
DW 0x0210 ; S_ENTRY32
DP &entry ; 16:32 address of entry point
DW 4 + 10*n; symbol-length
DW 0x0211 ; S_OPTVAR32
DW n ; number-of-ranges-that-follow
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) ]
[-----------------------------------------------------------------------]
Type Record
DW length
* type string
Type String
DW leaf
* data
DW leaf
* data ...
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.
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
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
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
Several of the type records below reference a field attribute bit field.
This has the following format:
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
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
The union specifying the pointer to data member has the format:
DW format
DW @class
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.
DW mdisp
mdisp Displacement to data. NULL is 0xffff
DW mdisp
mdisp Displacement to data. NULL is 0
DW mdisp
DW pdisp
DW vdisp
* 16:32 near pointer to data member for a class with and without
virtual functions and no virtual bases.
DD mdisp
* 16:32 near pointer to data member for a class with virtual bases.
DD mdisp
DD pdisp
DD vdisp
DW off
DW off
DW disp
DW off
DW mdisp
DW pdisp
DW vdisp
DW off
DW disp
DW off
DW seg
DW disp
* 16:16 pointer to far member function for a class with virtual bases
DW off
DW seg
DW mdisp
DW pdisp
DW vdisp
DD off
DD off
DD seg
DD off
DD mdisp
DD pdisp
DD vdisp
Simple Array
LF_ARRAY 0x0003
DW LF_ARRAY
DD @elemtype
DD @idxtype
DD @name
* length
* nElts
DW leaf
DW count
DD @field
DW property
DD @cclass
DD @dList
DD @vshape
DD @name
* length
DW LF_UNION
DW count
DD @field
DW property
DD @cclass
DD @name
* length
Enumeration
LF_ENUM 0x0007
DW LF_ENUM
DW count
DD @type
DD @fList
DD @cclass
DD @name
Procedure
LF_PROCEDURE 0x0008
DW LF_PROCEDURE
DD @rvtype
DB call
DB reserved
DW #parms
DD @arglist
The value 0x80 can be combined with any of the other calling
convention values to specify 'fastthis' (methods only)
Member Function
LF_MFUNCTION 0x0009
DW LF_MFUNCTION
DD @rvtype
DD @class
DD @this
DB call
DB res
DW parms
DD @arglist
DD thisadjust
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
Label
LF_LABEL 0x000e
DW LF_LABEL
DW mode
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
DW LF_DIMARRAY
DW @utype
DW @diminfo
DW name
This record is used to describe the path to the virtual function table.
DW LF_VFTPATH
DW count
DW * count bases
Skip
LF_SKIP 0x0200
DW LF_SKIP
DW index
* pad
Argument List
LF_ARGLIST 0x0201
DW LF_ARGLIST
DW argcount
* indices
Default Argument
LF_DEFARG 0x0202
DW LF_DEFARG
DD @index
DD @name
Arbitrary List
LF_LIST 0x0203
DW LF_LIST
* data
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
Field List
LF_FIELDLIST 0x0204
DW leaf
* data
* pad
[repeats]
Bitfields
LF_BITFIELD 0x0206
DW LF_BITFIELD
DB length
DB position
DD @type
Method List
LF_MLIST 0x0207
DW LF_MLIST
DW attribute
DD @type
DD reserved
[repeat]
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.
DW LF_DIMCONU
DW rank
DW @index
s*rank bound
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
DW LF_DIMVARU
DW rank
DW @index
DW*rank @var
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
Referenced Symbol
LF_REFSYM 0x020c
DW LF_REFSYM
* sym
Currently, the only complex list that uses the following leaf indices is
the field list of a structure, class, union, or enumeration.
DW LF_INDEX
DD @index
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
DW type
DD @btype
DD @vbptype (void *)
DW attribute
* vbpoff
* vboff (-1)
Friend Class
LF_FRIENDCLS 0x040b
DW LF_FRIENDCLS
DD @type
Friend Function
LF_FRIENDFCN 0x0404
DW LF_FRIENDFCN
DD @type
DD @name
Data Member
LF_MEMBER 0x0406
DW LF_MEMBER
DD @type
DW attribute
DD @name
DD reserved
* offset
DW LF_STMEMBER
DD @type
DW attribute
DD @name
DD reserved
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.
DW LF_VFUNCTAB
DD @type
* offset
Member Function
LF_METHOD 0x0408
DW LF_METHOD
DW count
DD @mList
DD @name
DW LF_ENUMERATE
DW attribute
DD @name
DD reserved
* value
reserved 0
DW LF_NESTTYPE
DD @index
DD @name
DD reserved
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
Signed Short
LF_SHORT 0x8001
DW LF_SHORT
DW short
Unsigned Short
LF_USHORT 0x8002
DW LF_USHORT
DW ushort
Signed Long
LF_LONG 0x8003
DW LF_LONG
DD long
Unsigned Long
LF_ULONG 0x8004
DW LF_ULONG
DD ulong
32 Bit Float
LF_REAL32 0x8005
DW LF_REAL32
DD real32
DW LF_REAL48
DF real48
64 Bit Float
LF_REAL64 0x8006
DW LF_REAL64
DQ real64
80 Bit Float
LF_REAL80 0x8007
DW LF_REAL80
DT real80
DW LF_REAL128
DT,DF real128
Signed Quadword
LF_QUADWORD 0x8009
DW LF_QUADWORD
DQ quadword
Unsigned Quadword
LF_UQUADWORD 0x800a
DW LF_UQUADWORD
DQ uquadword
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
(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=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
/* Special Types */
/* Character types */
/* Boolean types */
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.
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
MIPS4000 Architectures
[-----------------------------------------------------------------------]
[ Symbol and Type OMF Format Borland Executable Files ]
[-----------------------------------------------------------------------]
Introduction
This section describes the format used to embed debugging information into
the executable file.
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.
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
Directory header
Directory entry 0
Directory entry 1
.
.
.
Directory entry n
DW cbDirHeader
DW cbDirEntry
DD cDir
DD lfoNextDir
DD flags
DW subsection
DW iMod
DD lfo
DD cb
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
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
reserved Set to 0.
DW Seg
DW flags
DD offset
DD cbSeg
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
Module header
.
.
.
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
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
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
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]