📄 jcltd32.pas
字号:
{**************************************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
{ License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
{ and limitations under the License. }
{ }
{ The Original Code is JclTD32.pas. }
{ }
{ The Initial Developer of the Original Code is Flier Lu (<flier_lu att yahoo dott com dott cn>). }
{ Portions created by Flier Lu are Copyright (C) Flier Lu. All Rights Reserved. }
{ }
{ Contributors: }
{ Flier Lu (flier) }
{ Olivier Sannier (obones) }
{ Petr Vones (pvones) }
{ Heinz Zastrau (heinzz) }
{ }
{**************************************************************************************************}
{ }
{ Borland TD32 symbolic debugging information support routines and classes. }
{ }
{ Unit owner: Flier Lu }
{ }
{**************************************************************************************************}
// Last modified: $Date: 2005/03/08 08:33:23 $
// For history see end of file
unit JclTD32;
interface
{$I jcl.inc}
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF MSWINDOWS}
Classes, SysUtils, Contnrs,
JclBase, JclFileUtils, JclPeImage;
{ TODO -cDOC : Original code: "Flier Lu" <flier_lu att yahoo dott com dott cn> }
// TD32 constants and structures
{*******************************************************************************
[-----------------------------------------------------------------------]
[ 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
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
*******************************************************************************}
const
Borland32BitSymbolFileSignatureForDelphi = $39304246; // 'FB09'
Borland32BitSymbolFileSignatureForBCB = $41304246; // 'FB0A'
type
{ Signature structure }
PJclTD32FileSignature = ^TJclTD32FileSignature;
TJclTD32FileSignature = packed record
Signature: DWORD;
Offset: DWORD;
end;
const
{ Subsection Types }
SUBSECTION_TYPE_MODULE = $120;
SUBSECTION_TYPE_TYPES = $121;
SUBSECTION_TYPE_SYMBOLS = $124;
SUBSECTION_TYPE_ALIGN_SYMBOLS = $125;
SUBSECTION_TYPE_SOURCE_MODULE = $127;
SUBSECTION_TYPE_GLOBAL_SYMBOLS = $129;
SUBSECTION_TYPE_GLOBAL_TYPES = $12B;
SUBSECTION_TYPE_NAMES = $130;
type
{ Subsection directory header structure }
{ 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. }
PDirectoryEntry = ^TDirectoryEntry;
TDirectoryEntry = packed record
SubsectionType: Word; // Subdirectory type
ModuleIndex: Word; // Module index
Offset: DWORD; // Offset from the base offset lfoBase
Size: DWORD; // Number of bytes in subsection
end;
{ The subsection directory is prefixed with a directory header structure
indicating size and number of subsection directory entries that follow. }
PDirectoryHeader = ^TDirectoryHeader;
TDirectoryHeader = packed record
Size: Word; // Length of this structure
DirEntrySize: Word; // Length of each directory entry
DirEntryCount: DWORD; // Number of directory entries
lfoNextDir: DWORD; // Offset from lfoBase of next directory.
Flags: DWORD; // Flags describing directory and subsection tables.
DirEntries: array [0..0] of TDirectoryEntry;
end;
{*******************************************************************************
SUBSECTION_TYPE_MODULE $120
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.
*******************************************************************************}
type
PSegmentInfo = ^TSegmentInfo;
TSegmentInfo = packed record
Segment: Word; // Segment that this structure describes
Flags: Word; // Attributes for the logical segment.
// The following attributes are defined:
// $0000 Data segment
// $0001 Code segment
Offset: DWORD; // Offset in segment where the code starts
Size: DWORD; // Count of the number of bytes of code in the segment
end;
PSegmentInfoArray = ^TSegmentInfoArray;
TSegmentInfoArray = array [0..32767] of TSegmentInfo;
PModuleInfo = ^TModuleInfo;
TModuleInfo = packed record
OverlayNumber: Word; // Overlay number
LibraryIndex: Word; // Index into sstLibraries subsection
// if this module was linked from a library
SegmentCount: Word; // Count of the number of code segments
// this module contributes to
DebuggingStyle: Word; // Debugging style for this module.
NameIndex: DWORD; // Name index of module.
TimeStamp: DWORD; // Time stamp from the OBJ file.
Reserved: array [0..2] of DWORD; // Set to 0.
Segments: array [0..0] of TSegmentInfo;
// Detailed information about each segment
// that code is contributed to.
// This is an array of cSeg count segment
// information descriptor structures.
end;
{*******************************************************************************
SUBSECTION_TYPE_SOURCE_MODULE $0127
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
*******************************************************************************}
type
{ The line number to address mapping information is contained in a table with
the following format: }
PLineMappingEntry = ^TLineMappingEntry;
TLineMappingEntry = packed record
SegmentIndex: Word; // Segment index for this table
PairCount: Word; // Count of the number of source line pairs to follow
Offsets: array [0..0] of DWORD;
// An array of 32-bit offsets for the offset
// within the code segment ofthe start of ine contained
// in the parallel array 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. }
LineNumbers: array [0..PairCount - 1] of Word;
*)
end;
TOffsetPair = packed record
StartOffset: DWORD;
EndOffset: DWORD;
end;
POffsetPairArray = ^TOffsetPairArray;
TOffsetPairArray = array [0..32767] of TOffsetPair;
{ The file table describes the code segments that receive code from this
source file. Source file entries have the following format: }
PSourceFileEntry = ^TSourceFileEntry;
TSourceFileEntry = packed record
SegmentCount: Word; // Number of segments that receive code from this source file.
NameIndex: DWORD; // Name index of Source file name.
BaseSrcLines: array [0..0] of DWORD;
// An array of offsets for the line/address mapping
// tables for each of the segments that receive code
// from this source file.
(*
{ 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. }
SegmentAddress: array [0..SegmentCount - 1] of TOffsetPair;
Name: ShortString; // Count of the number of bytes in source file name
*)
end;
{ The module header structure describes the source file and code segment
organization of the module. Each module header has the following format: }
PSourceModuleInfo = ^TSourceModuleInfo;
TSourceModuleInfo = packed record
FileCount: Word; // The number of source file scontributing code to segments
SegmentCount: Word; // The number of code segments receiving code from this module
BaseSrcFiles: array [0..0] of DWORD;
(*
// This is an array of base offsets from the beginning of the sstSrcModule table
BaseSrcFiles: array [0..FileCount - 1] of DWORD;
{ 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. }
SegmentAddress: array [0..SegmentCount - 1] of TOffsetPair;
{ 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. }
SegmentIndexes: array [0..SegmentCount - 1] of Word;
*)
end;
{*******************************************************************************
SUBSECTION_TYPE_GLOBAL_TYPES $12b
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.
*******************************************************************************}
type
PGlobalTypeInfo = ^TGlobalTypeInfo;
TGlobalTypeInfo = packed record
Count: DWORD; // count of the number of types
// offset of each type string from the beginning of table
Offsets: array [0..0] of DWORD;
end;
const
{ Symbol type defines }
SYMBOL_TYPE_COMPILE = $0001; // Compile flags symbol
SYMBOL_TYPE_REGISTER = $0002; // Register variable
SYMBOL_TYPE_CONST = $0003; // Constant symbol
SYMBOL_TYPE_UDT = $0004; // User-defined Type
SYMBOL_TYPE_SSEARCH = $0005; // Start search
SYMBOL_TYPE_END = $0006; // End block, procedure, with, or thunk
SYMBOL_TYPE_SKIP = $0007; // Skip - Reserve symbol space
SYMBOL_TYPE_CVRESERVE = $0008; // Reserved for Code View internal use
SYMBOL_TYPE_OBJNAME = $0009; // Specify name of object file
SYMBOL_TYPE_BPREL16 = $0100; // BP relative 16:16
SYMBOL_TYPE_LDATA16 = $0101; // Local data 16:16
SYMBOL_TYPE_GDATA16 = $0102; // Global data 16:16
SYMBOL_TYPE_PUB16 = $0103; // Public symbol 16:16
SYMBOL_TYPE_LPROC16 = $0104; // Local procedure start 16:16
SYMBOL_TYPE_GPROC16 = $0105; // Global procedure start 16:16
SYMBOL_TYPE_THUNK16 = $0106; // Thunk start 16:16
SYMBOL_TYPE_BLOCK16 = $0107; // Block start 16:16
SYMBOL_TYPE_WITH16 = $0108; // With start 16:16
SYMBOL_TYPE_LABEL16 = $0109; // Code label 16:16
SYMBOL_TYPE_CEXMODEL16 = $010A; // Change execution model 16:16
SYMBOL_TYPE_VFTPATH16 = $010B; // Virtual function table path descriptor 16:16
SYMBOL_TYPE_BPREL32 = $0200; // BP relative 16:32
SYMBOL_TYPE_LDATA32 = $0201; // Local data 16:32
SYMBOL_TYPE_GDATA32 = $0202; // Global data 16:32
SYMBOL_TYPE_PUB32 = $0203; // Public symbol 16:32
SYMBOL_TYPE_LPROC32 = $0204; // Local procedure start 16:32
SYMBOL_TYPE_GPROC32 = $0205; // Global procedure start 16:32
SYMBOL_TYPE_THUNK32 = $0206; // Thunk start 16:32
SYMBOL_TYPE_BLOCK32 = $0207; // Block start 16:32
SYMBOL_TYPE_WITH32 = $0208; // With start 16:32
SYMBOL_TYPE_LABEL32 = $0209; // Label 16:32
SYMBOL_TYPE_CEXMODEL32 = $020A; // Change execution model 16:32
SYMBOL_TYPE_VFTPATH32 = $020B; // Virtual function table path descriptor 16:32
{*******************************************************************************
Global and Local Procedure Start 16:32
SYMBOL_TYPE_LPROC32 $0204
SYMBOL_TYPE_GPROC32 $0205
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 SYMBOL_TYPE_GPROC32 emitted, an SYMBOL_TYPE_GPROCREF symbol
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -