mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-28 19:34:09 +02:00
1471 lines
39 KiB
ObjectPascal
1471 lines
39 KiB
ObjectPascal
unit FpDbgInfo;
|
|
(*
|
|
About TFpDbgValue and TFpDbgSymbol
|
|
|
|
* TFpDbgSymbol
|
|
Represents a Symbol or Identifier (stType or stValue)
|
|
|
|
* TFpDbgValue
|
|
Holds the Value of a Symbol according to its type.
|
|
|
|
TFpDbgSymbol should not hold any Data, except for information that is in the
|
|
debug info (dwarf/stabs).
|
|
All Data read from the target must be in TFpDbgValue.
|
|
Target adta includes Address (can be indirect via ref or pointer, Size and
|
|
Boundaries (Sub range / Array).
|
|
|
|
This means that TFpDbgSymbol (stType or stValue) should be re-usable. There can
|
|
be multiple TFpDbgValue for each TFpDbgSymbol. (even for stValue, as in an
|
|
Array the Symbol itself is repeated / Array of record: the same member occurs
|
|
over and over)
|
|
|
|
---
|
|
A Variable value in the target typically consists of:
|
|
- TFpDbgSymbol (stValue)
|
|
- TFpDbgSymbol (stType)
|
|
- TFpDbgValue
|
|
|
|
*)
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, DbgIntfBaseTypes, FpDbgLoader, FpdMemoryTools, FpErrorMessages,
|
|
LazLoggerBase, LazClasses;
|
|
|
|
type
|
|
{ TFpDbgCircularRefCountedObject }
|
|
|
|
TFpDbgCircularRefCountedObject = class(TRefCountedObject)
|
|
private
|
|
FCircleRefCount: Integer;
|
|
protected
|
|
(* InOrder to activate, and use an interited class must override
|
|
DoReferenceAdded; and DoReferenceReleased;
|
|
And Point then to
|
|
DoPlainReferenceAdded; and DoPlainReferenceReleased;
|
|
*)
|
|
procedure DoPlainReferenceAdded; inline;
|
|
procedure DoPlainReferenceReleased; inline;
|
|
|
|
// Receive the *strong* reference (always set)
|
|
// The circle back ref will only be set, if this is also referenced by others
|
|
procedure AddCirclularReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr: Pointer = nil; DebugIdTxt: String = ''){$ENDIF};
|
|
procedure ReleaseCirclularReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr: Pointer = nil; DebugIdTxt: String = ''){$ENDIF};
|
|
|
|
procedure MakePlainRefToCirclular;
|
|
procedure MakeCirclularRefToPlain;
|
|
|
|
function CircleBackRefsActive: Boolean; inline;
|
|
procedure CircleBackRefActiveChanged({%H-}NewActive: Boolean); virtual;
|
|
end;
|
|
|
|
{ TFpDbgCircularRefCntObjList }
|
|
|
|
TFpDbgCircularRefCntObjList = class(TRefCntObjList)
|
|
protected
|
|
procedure Notify(Ptr: Pointer; Action: TListNotification); override;
|
|
end;
|
|
|
|
TDbgSymbolType = (
|
|
stNone,
|
|
stValue, // The symbol has a value (var, field, function, procedure (value is address of func/proc, so it can be called)
|
|
stType // The Symbol is a type (including proc/func declaration / without DW_AT_low_pc)
|
|
);
|
|
|
|
TDbgSymbolMemberVisibility =(
|
|
svPrivate,
|
|
svProtected,
|
|
svPublic
|
|
);
|
|
|
|
TDbgSymbolFlag =(
|
|
sfSubRange, // This is a subrange, e.g 3..99
|
|
sfDynArray, // skArray is known to be a dynamic array
|
|
sfStatArray, // skArray is known to be a static array
|
|
sfVirtual, // skProcedure,skFunction: virtual function (or overriden)
|
|
sfParameter, // Parameter to a function
|
|
// unimplemented:
|
|
sfInternalRef, // TODO: (May not always be present) Internal ref/pointer e.g. var/constref parameters
|
|
sfConst, // The sym is a constant and cannot be modified
|
|
sfVar,
|
|
sfOut,
|
|
sfpropGet,
|
|
sfPropSet,
|
|
sfPropStored
|
|
);
|
|
TDbgSymbolFlags = set of TDbgSymbolFlag;
|
|
|
|
TFpDbgSymbolField = (
|
|
sfiName, sfiKind, sfiSymType, sfiAddress, sfiSize,
|
|
sfiTypeInfo, sfiMemberVisibility,
|
|
sfiForwardToSymbol
|
|
);
|
|
TFpDbgSymbolFields = set of TFpDbgSymbolField;
|
|
|
|
TFpDbgSymbol = class;
|
|
|
|
TFpDbgSymbolBase = class(TFpDbgCircularRefCountedObject)
|
|
end;
|
|
|
|
TFpDbgValueFieldFlag = (
|
|
// svfAddress, svfDataAddress this symbol does have an address, but it may still be nil
|
|
svfAddress, svfSize, svfSizeOfPointer,
|
|
svfDataAddress, svfDataSize, svfDataSizeOfPointer,
|
|
svfInteger, svfCardinal, svfFloat,
|
|
svfString, svfWideString,
|
|
svfBoolean,
|
|
svfIdentifier, // returned via AsString: a named value (enum, set-member)
|
|
svfMembers,
|
|
//svfParent, // TODO: for members, get the parent (object/record-fields, enum/set-members
|
|
svfOrdinal // AsCardinal ruturns an ordinal value, but the value is not represented as cardinal (e.g. bool, enum)
|
|
// if size > 8, then ordinal (if present) is based on a part only
|
|
);
|
|
TFpDbgValueFieldFlags = set of TFpDbgValueFieldFlag;
|
|
|
|
{ TFpDbgValue }
|
|
|
|
TFpDbgValue = class(TFpDbgSymbolBase)
|
|
protected
|
|
function GetKind: TDbgSymbolKind; virtual;
|
|
function GetFieldFlags: TFpDbgValueFieldFlags; virtual;
|
|
|
|
function GetAsBool: Boolean; virtual;
|
|
function GetAsCardinal: QWord; virtual;
|
|
function GetAsInteger: Int64; virtual;
|
|
function GetAsString: AnsiString; virtual;
|
|
function GetAsWideString: WideString; virtual;
|
|
function GetAsFloat: Extended; virtual;
|
|
|
|
function GetAddress: TFpDbgMemLocation; virtual;
|
|
function GetSize: Integer; virtual; // returns -1, if not available
|
|
function GetDataAddress: TFpDbgMemLocation; virtual;
|
|
function GetDataSize: Integer; virtual;
|
|
|
|
function GetHasBounds: Boolean; virtual;
|
|
function GetOrdHighBound: Int64; virtual;
|
|
function GetOrdLowBound: Int64; virtual;
|
|
|
|
function GetMember({%H-}AIndex: Int64): TFpDbgValue; virtual;
|
|
function GetMemberByName({%H-}AIndex: String): TFpDbgValue; virtual;
|
|
function GetMemberCount: Integer; virtual;
|
|
function GetIndexType({%H-}AIndex: Integer): TFpDbgSymbol; virtual;
|
|
function GetIndexTypeCount: Integer; virtual;
|
|
function GetMemberCountEx(const AIndex: array of Int64): Integer; virtual;
|
|
function GetMemberEx(const AIndex: Array of Int64): TFpDbgValue; virtual;
|
|
|
|
function GetDbgSymbol: TFpDbgSymbol; virtual;
|
|
function GetTypeInfo: TFpDbgSymbol; virtual;
|
|
function GetContextTypeInfo: TFpDbgSymbol; virtual;
|
|
|
|
function GetLastError: TFpError; virtual;
|
|
public
|
|
constructor Create;
|
|
property RefCount;
|
|
|
|
// Kind: determines which types of value are available
|
|
property Kind: TDbgSymbolKind read GetKind;
|
|
property FieldFlags: TFpDbgValueFieldFlags read GetFieldFlags;
|
|
|
|
property AsInteger: Int64 read GetAsInteger;
|
|
property AsCardinal: QWord read GetAsCardinal;
|
|
property AsBool: Boolean read GetAsBool;
|
|
property AsString: AnsiString read GetAsString;
|
|
property AsWideString: WideString read GetAsWideString;
|
|
property AsFloat: Extended read GetAsFloat;
|
|
|
|
(* * Address/Size
|
|
Address of the variable (as returned by the "@" address of operator
|
|
* DataAddress/DataSize
|
|
Address of Data, if avail and diff from Address (e.g. String, TObject, DynArray, ..., BUT NOT record)
|
|
Otherwise same as Address/Size
|
|
For pointers, this is the address of the pointed-to data
|
|
*)
|
|
property Address: TFpDbgMemLocation read GetAddress;
|
|
property Size: Integer read GetSize;
|
|
property DataAddress: TFpDbgMemLocation read GetDataAddress; //
|
|
property DataSize: Integer read GetDataSize;
|
|
|
|
property HasBounds: Boolean read GetHasBounds;
|
|
property OrdLowBound: Int64 read GetOrdLowBound; // need typecast for QuadWord
|
|
property OrdHighBound: Int64 read GetOrdHighBound; // need typecast for QuadWord
|
|
// memdump
|
|
public
|
|
function GetTypeCastedValue(ADataVal: TFpDbgValue): TFpDbgValue; virtual; // only if Symbol is a type
|
|
// base class? Or Member includes member from base
|
|
(* Member:
|
|
* skClass, skStructure:
|
|
stType: it excludes BaseClass (TODO: decide?)
|
|
stValue: includes
|
|
* skSet
|
|
stType: all members
|
|
stValue: only members set in value (Only impremented for DbgSymbolValue)
|
|
* skArray: (differs from TFpDbgSymbol)
|
|
The values. The type of each Index-dimension is avail via IndexType
|
|
* skPointer: deref the pointer, with index (0 = normal deref)
|
|
NOTE: Values returned by Member/MemberByName are volatile.
|
|
They maybe released or changed when Member is called again.
|
|
To keep a returned Value a reference can be added (AddReference)
|
|
*)
|
|
property MemberCount: Integer read GetMemberCount;
|
|
property Member[AIndex: Int64]: TFpDbgValue read GetMember;
|
|
property MemberByName[AIndex: String]: TFpDbgValue read GetMemberByName; // Includes inheritance
|
|
// For Arrays (TODO pointers) only, the values stored in the array
|
|
property IndexTypeCount: Integer read GetIndexTypeCount;
|
|
property IndexType[AIndex: Integer]: TFpDbgSymbol read GetIndexType;
|
|
|
|
(* DbgSymbol: The TFpDbgSymbol from which this value came, maybe nil.
|
|
Maybe a stType, then there is no Value *)
|
|
property DbgSymbol: TFpDbgSymbol read GetDbgSymbol;
|
|
property TypeInfo: TFpDbgSymbol read GetTypeInfo;
|
|
property ContextTypeInfo: TFpDbgSymbol read GetContextTypeInfo; // For members, the class in which this member is declared
|
|
|
|
property LastError: TFpError read GetLastError;
|
|
end;
|
|
|
|
{ TFpDbgValueConstNumber }
|
|
|
|
TFpDbgValueConstNumber = class(TFpDbgValue)
|
|
private
|
|
FValue: QWord;
|
|
FSigned: Boolean;
|
|
protected
|
|
property Value: QWord read FValue write FValue;
|
|
property Signed: Boolean read FSigned write FSigned;
|
|
function GetKind: TDbgSymbolKind; override;
|
|
function GetFieldFlags: TFpDbgValueFieldFlags; override;
|
|
function GetAsCardinal: QWord; override;
|
|
function GetAsInteger: Int64; override;
|
|
public
|
|
constructor Create(AValue: QWord; ASigned: Boolean = True);
|
|
end;
|
|
|
|
{ TFpDbgValueConstChar }
|
|
|
|
TFpDbgValueConstChar = class(TFpDbgValue) // skChar / Not for strings
|
|
private
|
|
FValue: String;
|
|
FSigned: Boolean;
|
|
protected
|
|
property Value: String read FValue write FValue;
|
|
function GetKind: TDbgSymbolKind; override;
|
|
function GetFieldFlags: TFpDbgValueFieldFlags; override;
|
|
function GetAsString: AnsiString; override;
|
|
public
|
|
constructor Create(AValue: AnsiString);
|
|
end;
|
|
|
|
{ TFpDbgValueConstWideChar }
|
|
|
|
TFpDbgValueConstWideChar = class(TFpDbgValue) // skChar / Not for strings
|
|
private
|
|
FValue: String;
|
|
FSigned: Boolean;
|
|
protected
|
|
property Value: String read FValue write FValue;
|
|
function GetKind: TDbgSymbolKind; override;
|
|
function GetFieldFlags: TFpDbgValueFieldFlags; override;
|
|
function GetAsString: AnsiString; override;
|
|
public
|
|
constructor Create(AValue: AnsiString);
|
|
end;
|
|
|
|
{ TFpDbgValueConstFloat }
|
|
|
|
TFpDbgValueConstFloat = class(TFpDbgValue)
|
|
private
|
|
FValue: Extended;
|
|
protected
|
|
property Value: Extended read FValue write FValue;
|
|
function GetKind: TDbgSymbolKind; override;
|
|
function GetFieldFlags: TFpDbgValueFieldFlags; override;
|
|
function GetAsFloat: Extended; override;
|
|
public
|
|
constructor Create(AValue: Extended);
|
|
end;
|
|
|
|
{ TFpDbgValueConstBool}
|
|
|
|
TFpDbgValueConstBool = class(TFpDbgValue)
|
|
private
|
|
FValue: Boolean;
|
|
protected
|
|
property Value: Boolean read FValue write FValue;
|
|
function GetKind: TDbgSymbolKind; override;
|
|
function GetFieldFlags: TFpDbgValueFieldFlags; override;
|
|
function GetAsBool: Boolean; override;
|
|
function GetAsCardinal: QWord; override;
|
|
public
|
|
constructor Create(AValue: Boolean);
|
|
end;
|
|
|
|
{ TFpDbgValueConstAddress }
|
|
|
|
TFpDbgValueConstAddress = class(TFpDbgValue)
|
|
private
|
|
FAddress: TFpDbgMemLocation;
|
|
protected
|
|
property Address: TFpDbgMemLocation read FAddress write FAddress;
|
|
function GetKind: TDbgSymbolKind; override; // skAddress
|
|
function GetFieldFlags: TFpDbgValueFieldFlags; override;
|
|
function GetAddress: TFpDbgMemLocation; override;
|
|
public
|
|
constructor Create(AnAddress: TFpDbgMemLocation);
|
|
end;
|
|
|
|
{ TFpDbgValueTypeDefinition }
|
|
|
|
TFpDbgValueTypeDefinition = class(TFpDbgValue)
|
|
private
|
|
FSymbol: TFpDbgSymbol; // stType
|
|
protected
|
|
function GetKind: TDbgSymbolKind; override;
|
|
function GetDbgSymbol: TFpDbgSymbol; override;
|
|
public
|
|
constructor Create(ASymbol: TFpDbgSymbol); // Only for stType
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
{ TFpDbgSymbol }
|
|
|
|
TFpDbgSymbol = class(TFpDbgSymbolBase)
|
|
private
|
|
FEvaluatedFields: TFpDbgSymbolFields;
|
|
FLastError: TFpError;
|
|
|
|
// Cached fields
|
|
FName: String;
|
|
FKind: TDbgSymbolKind;
|
|
FSymbolType: TDbgSymbolType;
|
|
FAddress: TFpDbgMemLocation;
|
|
FSize: Integer;
|
|
FTypeInfo: TFpDbgSymbol;
|
|
FMemberVisibility: TDbgSymbolMemberVisibility; // Todo: not cached
|
|
|
|
function GetSymbolType: TDbgSymbolType; inline;
|
|
function GetKind: TDbgSymbolKind; inline;
|
|
function GetName: String; inline;
|
|
function GetSize: Integer; inline;
|
|
function GetAddress: TFpDbgMemLocation; inline;
|
|
function GetTypeInfo: TFpDbgSymbol; inline;
|
|
function GetMemberVisibility: TDbgSymbolMemberVisibility; inline;
|
|
protected
|
|
function GetLastError: TFpError; virtual;
|
|
procedure SetLastError(AnError: TFpError);
|
|
// NOT cached fields
|
|
function GetChild({%H-}AIndex: Integer): TFpDbgSymbol; virtual;
|
|
function GetColumn: Cardinal; virtual;
|
|
function GetCount: Integer; virtual;
|
|
function GetFile: String; virtual;
|
|
function GetFlags: TDbgSymbolFlags; virtual;
|
|
function GetLine: Cardinal; virtual;
|
|
function GetParent: TFpDbgSymbol; virtual;
|
|
|
|
function GetValueObject: TFpDbgValue; virtual;
|
|
function GetHasOrdinalValue: Boolean; virtual;
|
|
function GetOrdinalValue: Int64; virtual;
|
|
|
|
function GetHasBounds: Boolean; virtual;
|
|
function GetOrdHighBound: Int64; virtual;
|
|
function GetOrdLowBound: Int64; virtual;
|
|
|
|
function GetMember({%H-}AIndex: Int64): TFpDbgSymbol; virtual;
|
|
function GetMemberByName({%H-}AIndex: String): TFpDbgSymbol; virtual;
|
|
function GetMemberCount: Integer; virtual;
|
|
protected
|
|
property EvaluatedFields: TFpDbgSymbolFields read FEvaluatedFields write FEvaluatedFields;
|
|
// Cached fields
|
|
procedure SetName(AValue: String); inline;
|
|
procedure SetKind(AValue: TDbgSymbolKind); inline;
|
|
procedure SetSymbolType(AValue: TDbgSymbolType); inline;
|
|
procedure SetAddress(AValue: TFpDbgMemLocation); inline;
|
|
procedure SetSize(AValue: Integer); inline;
|
|
procedure SetTypeInfo(AValue: TFpDbgSymbol); inline;
|
|
procedure SetMemberVisibility(AValue: TDbgSymbolMemberVisibility); inline;
|
|
|
|
procedure KindNeeded; virtual;
|
|
procedure NameNeeded; virtual;
|
|
procedure SymbolTypeNeeded; virtual;
|
|
procedure AddressNeeded; virtual;
|
|
procedure SizeNeeded; virtual;
|
|
procedure TypeInfoNeeded; virtual;
|
|
procedure MemberVisibilityNeeded; virtual;
|
|
//procedure Needed; virtual;
|
|
public
|
|
constructor Create(const AName: String);
|
|
constructor Create(const AName: String; AKind: TDbgSymbolKind; AAddress: TFpDbgMemLocation);
|
|
destructor Destroy; override;
|
|
// Basic info
|
|
property Name: String read GetName;
|
|
property SymbolType: TDbgSymbolType read GetSymbolType;
|
|
property Kind: TDbgSymbolKind read GetKind;
|
|
// Memory; Size is also part of type (byte vs word vs ...)
|
|
// HasAddress // (register does not have)
|
|
property Address: TFpDbgMemLocation read GetAddress; // used by Proc/func
|
|
property Size: Integer read GetSize; // In Bytes
|
|
// TypeInfo used by
|
|
// stValue (Variable): Type
|
|
// stType: Pointer: type pointed to / Array: Element Type / Func: Result / Class: itheritance
|
|
property TypeInfo: TFpDbgSymbol read GetTypeInfo;
|
|
// Location
|
|
property FileName: String read GetFile;
|
|
property Line: Cardinal read GetLine;
|
|
property Column: Cardinal read GetColumn;
|
|
// Methods for structures (record / class / enum)
|
|
// array: each member represents an index (enum or subrange) and has low/high bounds
|
|
property MemberVisibility: TDbgSymbolMemberVisibility read GetMemberVisibility;
|
|
property MemberCount: Integer read GetMemberCount;
|
|
(* Member:
|
|
* skClass, skStructure:
|
|
stType: it excludes BaseClass (TODO: decide?)
|
|
includes
|
|
* skSet
|
|
stType: all members
|
|
stValue: only members set in value (Only impremented for DbgSymbolValue)
|
|
* skArray:
|
|
The type of each Index-dimension
|
|
The count is the amount of dimensions
|
|
NOTE: Values returned by Member/MemberByName are volatile.
|
|
They maybe released or changed when Member is called again.
|
|
To keep a returned Value a reference can be added (AddReference)
|
|
*)
|
|
property Member[AIndex: Int64]: TFpDbgSymbol read GetMember;
|
|
property MemberByName[AIndex: String]: TFpDbgSymbol read GetMemberByName; // Includes inheritance
|
|
//
|
|
property Flags: TDbgSymbolFlags read GetFlags;
|
|
property Count: Integer read GetCount; deprecated 'use MemberCount instead';
|
|
property Parent: TFpDbgSymbol read GetParent; deprecated;
|
|
// for Subranges
|
|
property HasBounds: Boolean read GetHasBounds;
|
|
property OrdLowBound: Int64 read GetOrdLowBound; //deprecated 'xxxx'; // need typecast for QuadWord
|
|
property OrdHighBound: Int64 read GetOrdHighBound; //deprecated 'xxxx'; // need typecast for QuadWord
|
|
// VALUE
|
|
property Value: TFpDbgValue read GetValueObject; //deprecated 'rename / create';
|
|
property HasOrdinalValue: Boolean read GetHasOrdinalValue;
|
|
property OrdinalValue: Int64 read GetOrdinalValue; //deprecated 'xxxx'; // need typecast for QuadWord
|
|
|
|
// TypeCastValue| only fon stType symbols, may return nil
|
|
// Returns a reference to caller / caller must release
|
|
function TypeCastValue({%H-}AValue: TFpDbgValue): TFpDbgValue; virtual;
|
|
|
|
property LastError: TFpError read GetLastError; experimental;
|
|
end;
|
|
|
|
{ TDbgSymbolForwarder }
|
|
|
|
TDbgSymbolForwarder = class(TFpDbgSymbol)
|
|
private
|
|
FForwardToSymbol: TFpDbgSymbol;
|
|
protected
|
|
procedure SetForwardToSymbol(AValue: TFpDbgSymbol); inline;
|
|
procedure ForwardToSymbolNeeded; virtual;
|
|
function GetForwardToSymbol: TFpDbgSymbol; inline;
|
|
protected
|
|
function GetLastError: TFpError; override;
|
|
procedure KindNeeded; override;
|
|
procedure NameNeeded; override;
|
|
procedure SymbolTypeNeeded; override;
|
|
procedure SizeNeeded; override;
|
|
procedure TypeInfoNeeded; override;
|
|
procedure MemberVisibilityNeeded; override;
|
|
|
|
function GetFlags: TDbgSymbolFlags; override;
|
|
function GetValueObject: TFpDbgValue; override;
|
|
function GetHasOrdinalValue: Boolean; override;
|
|
function GetOrdinalValue: Int64; override;
|
|
function GetHasBounds: Boolean; override;
|
|
function GetOrdLowBound: Int64; override;
|
|
function GetOrdHighBound: Int64; override;
|
|
function GetMember(AIndex: Int64): TFpDbgSymbol; override;
|
|
function GetMemberByName(AIndex: String): TFpDbgSymbol; override;
|
|
function GetMemberCount: Integer; override;
|
|
end;
|
|
|
|
{ TFpDbgInfoContext }
|
|
|
|
TFpDbgInfoContext = class(TFpDbgAddressContext)
|
|
protected
|
|
function GetSymbolAtAddress: TFpDbgSymbol; virtual;
|
|
function GetProcedureAtAddress: TFpDbgValue; virtual;
|
|
function GetMemManager: TFpDbgMemManager; virtual;
|
|
public
|
|
property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress;
|
|
property ProcedureAtAddress: TFpDbgValue read GetProcedureAtAddress;
|
|
// search this, and all parent context
|
|
function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual;
|
|
property MemManager: TFpDbgMemManager read GetMemManager;
|
|
end;
|
|
|
|
{ TDbgInfo }
|
|
|
|
TDbgInfo = class(TObject)
|
|
private
|
|
FHasInfo: Boolean;
|
|
protected
|
|
procedure SetHasInfo;
|
|
public
|
|
constructor Create({%H-}ALoaderList: TDbgImageLoaderList); virtual;
|
|
(* Context should be searched by Thread, and StackFrame. The Address can be
|
|
derived from this.
|
|
However a different Address may be froced.
|
|
TODO: for now address may be needed, as stack decoding is not done yet
|
|
*)
|
|
function FindContext(AThreadId, AStackFrame: Integer; {%H-}AAddress: TDbgPtr = 0): TFpDbgInfoContext; virtual;
|
|
function FindContext({%H-}AAddress: TDbgPtr): TFpDbgInfoContext; virtual; deprecated 'use FindContextFindContext(thread,stack,address)';
|
|
function FindSymbol(const {%H-}AName: String): TFpDbgSymbol; virtual; deprecated;
|
|
function FindSymbol({%H-}AAddress: TDbgPtr): TFpDbgSymbol; virtual; deprecated;
|
|
property HasInfo: Boolean read FHasInfo;
|
|
function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray): Boolean; virtual;
|
|
//property MemManager: TFpDbgMemReaderBase read GetMemManager write SetMemManager;
|
|
end;
|
|
|
|
function dbgs(ADbgSymbolKind: TDbgSymbolKind): String; overload;
|
|
|
|
implementation
|
|
|
|
function dbgs(ADbgSymbolKind: TDbgSymbolKind): String;
|
|
begin
|
|
Result := '';
|
|
WriteStr(Result, ADbgSymbolKind);
|
|
end;
|
|
|
|
{ TFpDbgValueConstChar }
|
|
|
|
function TFpDbgValueConstChar.GetKind: TDbgSymbolKind;
|
|
begin
|
|
Result := skChar;
|
|
end;
|
|
|
|
function TFpDbgValueConstChar.GetFieldFlags: TFpDbgValueFieldFlags;
|
|
begin
|
|
Result := [svfString]
|
|
end;
|
|
|
|
function TFpDbgValueConstChar.GetAsString: AnsiString;
|
|
begin
|
|
Result := Value;
|
|
end;
|
|
|
|
constructor TFpDbgValueConstChar.Create(AValue: AnsiString);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
{ TFpDbgValueConstWideChar }
|
|
|
|
function TFpDbgValueConstWideChar.GetKind: TDbgSymbolKind;
|
|
begin
|
|
Result := skChar;
|
|
end;
|
|
|
|
function TFpDbgValueConstWideChar.GetFieldFlags: TFpDbgValueFieldFlags;
|
|
begin
|
|
Result := [svfString]
|
|
end;
|
|
|
|
function TFpDbgValueConstWideChar.GetAsString: AnsiString;
|
|
begin
|
|
Result := Value;
|
|
end;
|
|
|
|
constructor TFpDbgValueConstWideChar.Create(AValue: AnsiString);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
{ TFpDbgCircularRefCountedObject }
|
|
|
|
procedure TFpDbgCircularRefCountedObject.DoPlainReferenceAdded;
|
|
begin
|
|
if (RefCount = FCircleRefCount + 1) then
|
|
CircleBackRefActiveChanged(True);
|
|
end;
|
|
|
|
procedure TFpDbgCircularRefCountedObject.DoPlainReferenceReleased;
|
|
begin
|
|
if (RefCount = FCircleRefCount) then
|
|
CircleBackRefActiveChanged(False);
|
|
end;
|
|
|
|
procedure TFpDbgCircularRefCountedObject.AddCirclularReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr: Pointer = nil; DebugIdTxt: String = ''){$ENDIF};
|
|
begin
|
|
if CircleBackRefsActive then begin
|
|
AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr, DebugIdTxt){$ENDIF};
|
|
inc(FCircleRefCount);
|
|
end
|
|
else begin
|
|
inc(FCircleRefCount);
|
|
AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr, DebugIdTxt){$ENDIF};
|
|
end;
|
|
end;
|
|
|
|
procedure TFpDbgCircularRefCountedObject.ReleaseCirclularReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr: Pointer = nil; DebugIdTxt: String = ''){$ENDIF};
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Assert(FCircleRefCount > 0, 'ReleaseCirclularReference > 0');
|
|
if CircleBackRefsActive then begin
|
|
dec(FCircleRefCount);
|
|
ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr, DebugIdTxt){$ENDIF};
|
|
end
|
|
else begin
|
|
i := RefCount;
|
|
ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(DebugIdAdr, DebugIdTxt){$ENDIF};
|
|
if i > 1 then // if i was 1, then self is destroyed
|
|
dec(FCircleRefCount);
|
|
end;
|
|
end;
|
|
|
|
procedure TFpDbgCircularRefCountedObject.MakePlainRefToCirclular;
|
|
begin
|
|
Assert(FCircleRefCount < RefCount, 'MakePlainRefToCirclular < max');
|
|
inc(FCircleRefCount);
|
|
if (RefCount = FCircleRefCount) then
|
|
CircleBackRefActiveChanged(False);
|
|
end;
|
|
|
|
procedure TFpDbgCircularRefCountedObject.MakeCirclularRefToPlain;
|
|
begin
|
|
Assert(FCircleRefCount > 0, 'MakeCirclularRefToPlain > 0');
|
|
dec(FCircleRefCount);
|
|
if (RefCount = FCircleRefCount + 1) then
|
|
CircleBackRefActiveChanged(True);
|
|
end;
|
|
|
|
function TFpDbgCircularRefCountedObject.CircleBackRefsActive: Boolean;
|
|
begin
|
|
Result := (RefCount > FCircleRefCount);
|
|
end;
|
|
|
|
procedure TFpDbgCircularRefCountedObject.CircleBackRefActiveChanged(NewActive: Boolean);
|
|
begin
|
|
//
|
|
end;
|
|
|
|
{ TFpDbgCircularRefCntObjList }
|
|
|
|
procedure TFpDbgCircularRefCntObjList.Notify(Ptr: Pointer; Action: TListNotification);
|
|
begin
|
|
// Do NOT call inherited
|
|
case Action of
|
|
lnAdded: TFpDbgCircularRefCountedObject(Ptr).AddCirclularReference;
|
|
lnExtracted,
|
|
lnDeleted: TFpDbgCircularRefCountedObject(Ptr).ReleaseCirclularReference;
|
|
end;
|
|
end;
|
|
|
|
{ TDbgSymbolValue }
|
|
|
|
function TFpDbgValue.GetAsString: AnsiString;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TFpDbgValue.GetAsWideString: WideString;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TFpDbgValue.GetDbgSymbol: TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
constructor TFpDbgValue.Create;
|
|
begin
|
|
inherited Create;
|
|
AddReference;
|
|
end;
|
|
|
|
function TFpDbgValue.GetTypeCastedValue(ADataVal: TFpDbgValue): TFpDbgValue;
|
|
begin
|
|
assert(False, 'TFpDbgValue.GetTypeCastedValue: False');
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgValue.GetTypeInfo: TFpDbgSymbol;
|
|
begin
|
|
if (DbgSymbol <> nil) and (DbgSymbol.SymbolType = stValue) then
|
|
Result := DbgSymbol.TypeInfo
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgValue.GetFieldFlags: TFpDbgValueFieldFlags;
|
|
begin
|
|
Result := [];
|
|
end;
|
|
|
|
function TFpDbgValue.GetIndexType(AIndex: Integer): TFpDbgSymbol;
|
|
begin
|
|
Result := nil;;
|
|
end;
|
|
|
|
function TFpDbgValue.GetIndexTypeCount: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgValue.GetMemberEx(const AIndex: array of Int64): TFpDbgValue;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgValue.GetMemberCountEx(const AIndex: array of Int64): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgValue.GetAsFloat: Extended;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgValue.GetContextTypeInfo: TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgValue.GetLastError: TFpError;
|
|
begin
|
|
Result := NoError;
|
|
end;
|
|
|
|
function TFpDbgValue.GetHasBounds: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TFpDbgValue.GetOrdHighBound: Int64;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgValue.GetOrdLowBound: Int64;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgValue.GetKind: TDbgSymbolKind;
|
|
begin
|
|
Result := skNone;
|
|
end;
|
|
|
|
function TFpDbgValue.GetMember(AIndex: Int64): TFpDbgValue;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgValue.GetMemberByName(AIndex: String): TFpDbgValue;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgValue.GetMemberCount: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgValue.GetAddress: TFpDbgMemLocation;
|
|
begin
|
|
Result := InvalidLoc;
|
|
end;
|
|
|
|
function TFpDbgValue.GetDataAddress: TFpDbgMemLocation;
|
|
begin
|
|
Result := Address;
|
|
end;
|
|
|
|
function TFpDbgValue.GetDataSize: Integer;
|
|
begin
|
|
Result := Size;
|
|
end;
|
|
|
|
function TFpDbgValue.GetSize: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TFpDbgValue.GetAsBool: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TFpDbgValue.GetAsCardinal: QWord;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgValue.GetAsInteger: Int64;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
{ TPasParserConstNumberSymbolValue }
|
|
|
|
function TFpDbgValueConstNumber.GetKind: TDbgSymbolKind;
|
|
begin
|
|
if FSigned then
|
|
Result := skInteger
|
|
else
|
|
Result := skCardinal;
|
|
end;
|
|
|
|
function TFpDbgValueConstNumber.GetFieldFlags: TFpDbgValueFieldFlags;
|
|
begin
|
|
if FSigned then
|
|
Result := [svfOrdinal, svfInteger]
|
|
else
|
|
Result := [svfOrdinal, svfCardinal];
|
|
end;
|
|
|
|
function TFpDbgValueConstNumber.GetAsCardinal: QWord;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TFpDbgValueConstNumber.GetAsInteger: Int64;
|
|
begin
|
|
Result := Int64(FValue);
|
|
end;
|
|
|
|
constructor TFpDbgValueConstNumber.Create(AValue: QWord; ASigned: Boolean);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
FSigned := ASigned;
|
|
end;
|
|
|
|
{ TFpDbgValueConstFloat }
|
|
|
|
function TFpDbgValueConstFloat.GetKind: TDbgSymbolKind;
|
|
begin
|
|
Result := skFloat;
|
|
end;
|
|
|
|
function TFpDbgValueConstFloat.GetFieldFlags: TFpDbgValueFieldFlags;
|
|
begin
|
|
Result := [svfFloat];
|
|
end;
|
|
|
|
function TFpDbgValueConstFloat.GetAsFloat: Extended;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
constructor TFpDbgValueConstFloat.Create(AValue: Extended);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
{ TFpDbgValueConstBool }
|
|
|
|
function TFpDbgValueConstBool.GetKind: TDbgSymbolKind;
|
|
begin
|
|
Result := skBoolean;
|
|
end;
|
|
|
|
function TFpDbgValueConstBool.GetFieldFlags: TFpDbgValueFieldFlags;
|
|
begin
|
|
Result := [svfOrdinal, svfBoolean];
|
|
end;
|
|
|
|
function TFpDbgValueConstBool.GetAsBool: Boolean;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TFpDbgValueConstBool.GetAsCardinal: QWord;
|
|
begin
|
|
if FValue then
|
|
Result := 1
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
constructor TFpDbgValueConstBool.Create(AValue: Boolean);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
{ TDbgSymbolValueConstAddress }
|
|
|
|
function TFpDbgValueConstAddress.GetKind: TDbgSymbolKind;
|
|
begin
|
|
Result := skAddress;
|
|
end;
|
|
|
|
function TFpDbgValueConstAddress.GetFieldFlags: TFpDbgValueFieldFlags;
|
|
begin
|
|
Result := [svfAddress]
|
|
end;
|
|
|
|
function TFpDbgValueConstAddress.GetAddress: TFpDbgMemLocation;
|
|
begin
|
|
Result := FAddress;
|
|
end;
|
|
|
|
constructor TFpDbgValueConstAddress.Create(AnAddress: TFpDbgMemLocation);
|
|
begin
|
|
inherited Create;
|
|
FAddress := AnAddress;
|
|
end;
|
|
|
|
{ TFpDbgValueTypeDeclaration }
|
|
|
|
function TFpDbgValueTypeDefinition.GetKind: TDbgSymbolKind;
|
|
begin
|
|
Result := skNone;
|
|
end;
|
|
|
|
function TFpDbgValueTypeDefinition.GetDbgSymbol: TFpDbgSymbol;
|
|
begin
|
|
Result := FSymbol;
|
|
end;
|
|
|
|
constructor TFpDbgValueTypeDefinition.Create(ASymbol: TFpDbgSymbol);
|
|
begin
|
|
inherited Create;
|
|
FSymbol := ASymbol;
|
|
FSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSymbol, 'TFpDbgValueTypeDeclaration'){$ENDIF};
|
|
end;
|
|
|
|
destructor TFpDbgValueTypeDefinition.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
FSymbol.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSymbol, 'TFpDbgValueTypeDeclaration'){$ENDIF};
|
|
end;
|
|
|
|
{ TDbgInfoAddressContext }
|
|
|
|
function TFpDbgInfoContext.GetMemManager: TFpDbgMemManager;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgInfoContext.GetProcedureAtAddress: TFpDbgValue;
|
|
begin
|
|
Result := SymbolAtAddress.Value;
|
|
end;
|
|
|
|
function TFpDbgInfoContext.GetSymbolAtAddress: TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgInfoContext.FindSymbol(const AName: String): TFpDbgValue;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
{ TFpDbgSymbol }
|
|
|
|
constructor TFpDbgSymbol.Create(const AName: String);
|
|
begin
|
|
inherited Create;
|
|
AddReference;
|
|
if AName <> '' then
|
|
SetName(AName);
|
|
end;
|
|
|
|
constructor TFpDbgSymbol.Create(const AName: String; AKind: TDbgSymbolKind;
|
|
AAddress: TFpDbgMemLocation);
|
|
begin
|
|
Create(AName);
|
|
SetKind(AKind);
|
|
FAddress := AAddress;
|
|
end;
|
|
|
|
destructor TFpDbgSymbol.Destroy;
|
|
begin
|
|
SetTypeInfo(nil);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TFpDbgSymbol.TypeCastValue(AValue: TFpDbgValue): TFpDbgValue;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetAddress: TFpDbgMemLocation;
|
|
begin
|
|
if not(sfiAddress in FEvaluatedFields) then
|
|
AddressNeeded;
|
|
Result := FAddress;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetTypeInfo: TFpDbgSymbol;
|
|
begin
|
|
if not(sfiTypeInfo in FEvaluatedFields) then
|
|
TypeInfoNeeded;
|
|
Result := FTypeInfo;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetMemberVisibility: TDbgSymbolMemberVisibility;
|
|
begin
|
|
if not(sfiMemberVisibility in FEvaluatedFields) then
|
|
MemberVisibilityNeeded;
|
|
Result := FMemberVisibility;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetValueObject: TFpDbgValue;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetKind: TDbgSymbolKind;
|
|
begin
|
|
if not(sfiKind in FEvaluatedFields) then
|
|
KindNeeded;
|
|
Result := FKind;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetName: String;
|
|
begin
|
|
if not(sfiName in FEvaluatedFields) then
|
|
NameNeeded;
|
|
Result := FName;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetSize: Integer;
|
|
begin
|
|
if not(sfiSize in FEvaluatedFields) then
|
|
SizeNeeded;
|
|
Result := FSize;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetSymbolType: TDbgSymbolType;
|
|
begin
|
|
if not(sfiSymType in FEvaluatedFields) then
|
|
SymbolTypeNeeded;
|
|
Result := FSymbolType;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetLastError: TFpError;
|
|
begin
|
|
Result := FLastError;
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetLastError(AnError: TFpError);
|
|
begin
|
|
FLastError := AnError;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetHasBounds: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetOrdHighBound: Int64;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetOrdLowBound: Int64;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetHasOrdinalValue: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetOrdinalValue: Int64;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetMember(AIndex: Int64): TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetMemberByName(AIndex: String): TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetMemberCount: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetAddress(AValue: TFpDbgMemLocation);
|
|
begin
|
|
FAddress := AValue;
|
|
Include(FEvaluatedFields, sfiAddress);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetKind(AValue: TDbgSymbolKind);
|
|
begin
|
|
FKind := AValue;
|
|
Include(FEvaluatedFields, sfiKind);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetSymbolType(AValue: TDbgSymbolType);
|
|
begin
|
|
FSymbolType := AValue;
|
|
Include(FEvaluatedFields, sfiSymType);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetSize(AValue: Integer);
|
|
begin
|
|
FSize := AValue;
|
|
Include(FEvaluatedFields, sfiSize);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetTypeInfo(AValue: TFpDbgSymbol);
|
|
begin
|
|
if FTypeInfo <> nil then begin
|
|
//Assert((FTypeInfo.Reference = self) or (FTypeInfo.Reference = nil), 'FTypeInfo.Reference = self|nil');
|
|
{$IFDEF WITH_REFCOUNT_DEBUG}FTypeInfo.ReleaseReference(@FTypeInfo, 'SetTypeInfo'); FTypeInfo := nil;{$ENDIF}
|
|
ReleaseRefAndNil(FTypeInfo);
|
|
end;
|
|
FTypeInfo := AValue;
|
|
Include(FEvaluatedFields, sfiTypeInfo);
|
|
if FTypeInfo <> nil then begin
|
|
FTypeInfo.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FTypeInfo, 'SetTypeInfo'){$ENDIF};
|
|
end;
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetMemberVisibility(AValue: TDbgSymbolMemberVisibility);
|
|
begin
|
|
FMemberVisibility := AValue;
|
|
Include(FEvaluatedFields, sfiMemberVisibility);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SetName(AValue: String);
|
|
begin
|
|
FName := AValue;
|
|
Include(FEvaluatedFields, sfiName);
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetChild(AIndex: Integer): TFpDbgSymbol;
|
|
begin
|
|
result := nil;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetColumn: Cardinal;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetCount: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetFile: String;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetFlags: TDbgSymbolFlags;
|
|
begin
|
|
Result := [];
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetLine: Cardinal;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TFpDbgSymbol.GetParent: TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.KindNeeded;
|
|
begin
|
|
SetKind(skNone);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.NameNeeded;
|
|
begin
|
|
SetName('');
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SymbolTypeNeeded;
|
|
begin
|
|
SetSymbolType(stNone);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.AddressNeeded;
|
|
begin
|
|
SetAddress(InvalidLoc);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.SizeNeeded;
|
|
begin
|
|
SetSize(0);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.TypeInfoNeeded;
|
|
begin
|
|
SetTypeInfo(nil);
|
|
end;
|
|
|
|
procedure TFpDbgSymbol.MemberVisibilityNeeded;
|
|
begin
|
|
SetMemberVisibility(svPrivate);
|
|
end;
|
|
|
|
{ TDbgSymbolForwarder }
|
|
|
|
procedure TDbgSymbolForwarder.SetForwardToSymbol(AValue: TFpDbgSymbol);
|
|
begin
|
|
FForwardToSymbol := AValue;
|
|
EvaluatedFields := EvaluatedFields + [sfiForwardToSymbol];
|
|
end;
|
|
|
|
procedure TDbgSymbolForwarder.ForwardToSymbolNeeded;
|
|
begin
|
|
SetForwardToSymbol(nil);
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetForwardToSymbol: TFpDbgSymbol;
|
|
begin
|
|
if TMethod(@ForwardToSymbolNeeded).Code = Pointer(@TDbgSymbolForwarder.ForwardToSymbolNeeded) then
|
|
exit(nil);
|
|
|
|
if not(sfiForwardToSymbol in EvaluatedFields) then
|
|
ForwardToSymbolNeeded;
|
|
Result := FForwardToSymbol;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetLastError: TFpError;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
Result := inherited GetLastError;
|
|
if IsError(Result) then
|
|
exit;
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.LastError;
|
|
end;
|
|
|
|
procedure TDbgSymbolForwarder.KindNeeded;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
SetKind(p.Kind)
|
|
else
|
|
SetKind(skNone); // inherited KindNeeded;
|
|
end;
|
|
|
|
procedure TDbgSymbolForwarder.NameNeeded;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
SetName(p.Name)
|
|
else
|
|
SetName(''); // inherited NameNeeded;
|
|
end;
|
|
|
|
procedure TDbgSymbolForwarder.SymbolTypeNeeded;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
SetSymbolType(p.SymbolType)
|
|
else
|
|
SetSymbolType(stNone); // inherited SymbolTypeNeeded;
|
|
end;
|
|
|
|
procedure TDbgSymbolForwarder.SizeNeeded;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
SetSize(p.Size)
|
|
else
|
|
SetSize(0); // inherited SizeNeeded;
|
|
end;
|
|
|
|
procedure TDbgSymbolForwarder.TypeInfoNeeded;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
SetTypeInfo(p.TypeInfo)
|
|
else
|
|
SetTypeInfo(nil); // inherited TypeInfoNeeded;
|
|
end;
|
|
|
|
procedure TDbgSymbolForwarder.MemberVisibilityNeeded;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
SetMemberVisibility(p.MemberVisibility)
|
|
else
|
|
SetMemberVisibility(svPrivate); // inherited MemberVisibilityNeeded;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetFlags: TDbgSymbolFlags;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.Flags
|
|
else
|
|
Result := []; // Result := inherited GetFlags;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetValueObject: TFpDbgValue;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.Value
|
|
else
|
|
Result := nil; // Result := inherited Value;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetHasOrdinalValue: Boolean;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.HasOrdinalValue
|
|
else
|
|
Result := False; // Result := inherited GetHasOrdinalValue;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetOrdinalValue: Int64;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.OrdinalValue
|
|
else
|
|
Result := 0; // Result := inherited GetOrdinalValue;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetHasBounds: Boolean;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.HasBounds
|
|
else
|
|
Result := False; // Result := inherited GetHasBounds;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetOrdLowBound: Int64;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.OrdLowBound
|
|
else
|
|
Result := 0; // Result := inherited GetOrdLowBound;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetOrdHighBound: Int64;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.OrdHighBound
|
|
else
|
|
Result := 0; // Result := inherited GetOrdHighBound;
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetMember(AIndex: Int64): TFpDbgSymbol;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.Member[AIndex]
|
|
else
|
|
Result := nil; // Result := inherited GetMember(AIndex);
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetMemberByName(AIndex: String): TFpDbgSymbol;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.MemberByName[AIndex]
|
|
else
|
|
Result := nil; // Result := inherited GetMemberByName(AIndex);
|
|
end;
|
|
|
|
function TDbgSymbolForwarder.GetMemberCount: Integer;
|
|
var
|
|
p: TFpDbgSymbol;
|
|
begin
|
|
p := GetForwardToSymbol;
|
|
if p <> nil then
|
|
Result := p.MemberCount
|
|
else
|
|
Result := 0; // Result := inherited GetMemberCount;
|
|
end;
|
|
|
|
{ TDbgInfo }
|
|
|
|
constructor TDbgInfo.Create(ALoaderList: TDbgImageLoaderList);
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
function TDbgInfo.FindContext(AThreadId, AStackFrame: Integer;
|
|
AAddress: TDbgPtr): TFpDbgInfoContext;
|
|
begin
|
|
Result := nil;;
|
|
end;
|
|
|
|
function TDbgInfo.FindContext(AAddress: TDbgPtr): TFpDbgInfoContext;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TDbgInfo.FindSymbol(const AName: String): TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TDbgInfo.FindSymbol(AAddress: TDbgPtr): TFpDbgSymbol;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TDbgInfo.GetLineAddresses(const AFileName: String; ALine: Cardinal;
|
|
var AResultList: TDBGPtrArray): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TDbgInfo.SetHasInfo;
|
|
begin
|
|
FHasInfo := True;
|
|
end;
|
|
|
|
end.
|
|
|