mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-16 04:39:22 +02:00
FpDebug: prepare mem-manager for context
git-svn-id: trunk@44627 -
This commit is contained in:
parent
0eaa8042c5
commit
03d6bdade7
@ -60,23 +60,26 @@ type
|
|||||||
public
|
public
|
||||||
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; override;
|
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; override;
|
||||||
class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; override;
|
class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; override;
|
||||||
class function CreateContext(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
|
class function CreateContext(AThreadId, AStackFrame: Integer; AnAddress:
|
||||||
ADwarf: TFpDwarfInfo): TDbgInfoAddressContext; override;
|
TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TFpDbgInfoContext; override;
|
||||||
class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
||||||
AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; override;
|
AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpDwarfInfoAddressContext }
|
{ TFpDwarfInfoAddressContext }
|
||||||
|
|
||||||
TFpDwarfInfoAddressContext = class(TDbgInfoAddressContext)
|
TFpDwarfInfoAddressContext = class(TFpDbgInfoContext)
|
||||||
private
|
private
|
||||||
FSymbol: TFpDbgSymbol;
|
FSymbol: TFpDbgSymbol;
|
||||||
FAddress: TDBGPtr;
|
FAddress: TDBGPtr;
|
||||||
|
FThreadId, FStackFrame: Integer;
|
||||||
FDwarf: TFpDwarfInfo;
|
FDwarf: TFpDwarfInfo;
|
||||||
FlastResult: TFpDbgValue;
|
FlastResult: TFpDbgValue;
|
||||||
protected
|
protected
|
||||||
function GetSymbolAtAddress: TFpDbgSymbol; override;
|
function GetSymbolAtAddress: TFpDbgSymbol; override;
|
||||||
function GetAddress: TDbgPtr; override;
|
function GetAddress: TDbgPtr; override;
|
||||||
|
function GetThreadId: Integer; override;
|
||||||
|
function GetStackFrame: Integer; override;
|
||||||
function GetSizeOfAddress: Integer; override;
|
function GetSizeOfAddress: Integer; override;
|
||||||
function GetMemManager: TFpDbgMemManager; override;
|
function GetMemManager: TFpDbgMemManager; override;
|
||||||
|
|
||||||
@ -96,7 +99,7 @@ type
|
|||||||
function FindLocalSymbol(const AName: String; PNameUpper, PNameLower: PChar;
|
function FindLocalSymbol(const AName: String; PNameUpper, PNameLower: PChar;
|
||||||
InfoEntry: TDwarfInformationEntry): TFpDbgValue; virtual;
|
InfoEntry: TDwarfInformationEntry): TFpDbgValue; virtual;
|
||||||
public
|
public
|
||||||
constructor Create(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo);
|
constructor Create(AThreadId, AStackFrame: Integer; AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function FindSymbol(const AName: String): TFpDbgValue; override;
|
function FindSymbol(const AName: String): TFpDbgValue; override;
|
||||||
end;
|
end;
|
||||||
@ -104,8 +107,6 @@ type
|
|||||||
TFpDwarfSymbol = class;
|
TFpDwarfSymbol = class;
|
||||||
TFpDwarfSymbolType = class;
|
TFpDwarfSymbolType = class;
|
||||||
TFpDwarfSymbolValue = class;
|
TFpDwarfSymbolValue = class;
|
||||||
TFpDwarfSymbolTypeStructure = class;
|
|
||||||
//TDbgDwarfIdentifierClass = class of TDbgDwarfIdentifier;
|
|
||||||
TFpDwarfSymbolValueClass = class of TFpDwarfSymbolValue;
|
TFpDwarfSymbolValueClass = class of TFpDwarfSymbolValue;
|
||||||
TFpDwarfSymbolTypeClass = class of TFpDwarfSymbolType;
|
TFpDwarfSymbolTypeClass = class of TFpDwarfSymbolType;
|
||||||
|
|
||||||
@ -115,9 +116,9 @@ type
|
|||||||
|
|
||||||
TFpDwarfValueBase = class(TFpDbgValue)
|
TFpDwarfValueBase = class(TFpDbgValue)
|
||||||
private
|
private
|
||||||
FContext: TDbgInfoAddressContext;
|
FContext: TFpDbgInfoContext;
|
||||||
public
|
public
|
||||||
property Context: TDbgInfoAddressContext read FContext;
|
property Context: TFpDbgInfoContext read FContext;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpDwarfValueTypeDefinition }
|
{ TFpDwarfValueTypeDefinition }
|
||||||
@ -918,10 +919,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TFpDwarfDefaultSymbolClassMap.CreateContext(AnAddress: TDbgPtr;
|
class function TFpDwarfDefaultSymbolClassMap.CreateContext(AThreadId, AStackFrame: Integer;
|
||||||
ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TDbgInfoAddressContext;
|
AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TFpDbgInfoContext;
|
||||||
begin
|
begin
|
||||||
Result := TFpDwarfInfoAddressContext.Create(AnAddress, ASymbol, ADwarf);
|
Result := TFpDwarfInfoAddressContext.Create(AThreadId, AStackFrame, AnAddress, ASymbol, ADwarf);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TFpDwarfDefaultSymbolClassMap.CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
class function TFpDwarfDefaultSymbolClassMap.CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
||||||
@ -942,6 +943,16 @@ begin
|
|||||||
Result := FAddress;
|
Result := FAddress;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDwarfInfoAddressContext.GetThreadId: Integer;
|
||||||
|
begin
|
||||||
|
Result := FThreadId;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDwarfInfoAddressContext.GetStackFrame: Integer;
|
||||||
|
begin
|
||||||
|
Result := FStackFrame;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDwarfInfoAddressContext.GetSizeOfAddress: Integer;
|
function TFpDwarfInfoAddressContext.GetSizeOfAddress: Integer;
|
||||||
begin
|
begin
|
||||||
assert(FSymbol is TFpDwarfSymbol, 'TDbgDwarfInfoAddressContext.GetSizeOfAddress');
|
assert(FSymbol is TFpDwarfSymbol, 'TDbgDwarfInfoAddressContext.GetSizeOfAddress');
|
||||||
@ -1106,12 +1117,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpDwarfInfoAddressContext.Create(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
|
constructor TFpDwarfInfoAddressContext.Create(AThreadId, AStackFrame: Integer;
|
||||||
ADwarf: TFpDwarfInfo);
|
AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
AddReference;
|
AddReference;
|
||||||
FAddress := AnAddress;
|
FAddress := AnAddress;
|
||||||
|
FThreadId := AThreadId;
|
||||||
|
FStackFrame := AStackFrame;
|
||||||
FDwarf := ADwarf;
|
FDwarf := ADwarf;
|
||||||
FSymbol := ASymbol;
|
FSymbol := ASymbol;
|
||||||
FSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSymbol, 'Context to Symbol'){$ENDIF};
|
FSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSymbol, 'Context to Symbol'){$ENDIF};
|
||||||
@ -2808,7 +2821,8 @@ begin
|
|||||||
//exit;
|
//exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
LocationParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit, AValueObj.MemManager);
|
LocationParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit,
|
||||||
|
AValueObj.MemManager, AValueObj.Context);
|
||||||
InitLocationParser(LocationParser, AValueObj, AnObjectDataAddress);
|
InitLocationParser(LocationParser, AValueObj, AnObjectDataAddress);
|
||||||
LocationParser.Evaluate;
|
LocationParser.Evaluate;
|
||||||
|
|
||||||
@ -3079,8 +3093,8 @@ begin
|
|||||||
if (ti = nil) or not (ti.SymbolType = stType) then exit;
|
if (ti = nil) or not (ti.SymbolType = stType) then exit;
|
||||||
|
|
||||||
FValueObject := TFpDwarfSymbolType(ti).GetTypedValueObject(False);
|
FValueObject := TFpDwarfSymbolType(ti).GetTypedValueObject(False);
|
||||||
{$IFDEF WITH_REFCOUNT_DEBUG}FValueObject.DbgRenameReference(@FValueObject, ClassName+'.FValueObject');{$ENDIF}
|
|
||||||
if FValueObject <> nil then begin
|
if FValueObject <> nil then begin
|
||||||
|
{$IFDEF WITH_REFCOUNT_DEBUG}FValueObject.DbgRenameReference(@FValueObject, ClassName+'.FValueObject');{$ENDIF}
|
||||||
FValueObject.MakePlainRefToCirclular;
|
FValueObject.MakePlainRefToCirclular;
|
||||||
FValueObject.SetValueSymbol(self);
|
FValueObject.SetValueSymbol(self);
|
||||||
end;
|
end;
|
||||||
@ -4437,7 +4451,8 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FFrameBaseParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit, ASender.MemManager);
|
FFrameBaseParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit,
|
||||||
|
ASender.MemManager, ASender.Context);
|
||||||
FFrameBaseParser.Evaluate;
|
FFrameBaseParser.Evaluate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -435,8 +435,8 @@ type
|
|||||||
public
|
public
|
||||||
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; virtual; abstract;
|
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; virtual; abstract;
|
||||||
class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; virtual; abstract;
|
class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; virtual; abstract;
|
||||||
class function CreateContext(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
|
class function CreateContext(AThreadId, AStackFrame: Integer; AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
|
||||||
ADwarf: TFpDwarfInfo): TDbgInfoAddressContext; virtual; abstract;
|
ADwarf: TFpDwarfInfo): TFpDbgInfoContext; virtual; abstract;
|
||||||
class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
||||||
AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; virtual; abstract;
|
AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; virtual; abstract;
|
||||||
end;
|
end;
|
||||||
@ -587,7 +587,8 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(ALoader: TDbgImageLoader); override;
|
constructor Create(ALoader: TDbgImageLoader); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function FindContext(AAddress: TDbgPtr): TDbgInfoAddressContext; override;
|
function FindContext(AThreadId, AStackFrame: Integer; AAddress: TDbgPtr = 0): TFpDbgInfoContext; override;
|
||||||
|
function FindContext(AAddress: TDbgPtr): TFpDbgInfoContext; override;
|
||||||
function FindSymbol(AAddress: TDbgPtr): TFpDbgSymbol; override;
|
function FindSymbol(AAddress: TDbgPtr): TFpDbgSymbol; override;
|
||||||
//function FindSymbol(const AName: String): TDbgSymbol; override;
|
//function FindSymbol(const AName: String): TDbgSymbol; override;
|
||||||
function GetLineAddress(const AFileName: String; ALine: Cardinal): TDbgPtr; override;
|
function GetLineAddress(const AFileName: String; ALine: Cardinal): TDbgPtr; override;
|
||||||
@ -641,6 +642,7 @@ type
|
|||||||
|
|
||||||
TDwarfLocationExpression = class
|
TDwarfLocationExpression = class
|
||||||
private
|
private
|
||||||
|
FContext: TFpDbgAddressContext;
|
||||||
FFrameBase: TDbgPtr;
|
FFrameBase: TDbgPtr;
|
||||||
FLastError: TFpError;
|
FLastError: TFpError;
|
||||||
FOnFrameBaseNeeded: TNotifyEvent;
|
FOnFrameBaseNeeded: TNotifyEvent;
|
||||||
@ -652,7 +654,7 @@ type
|
|||||||
public
|
public
|
||||||
//TODO: caller keeps data, and determines livetime of data
|
//TODO: caller keeps data, and determines livetime of data
|
||||||
constructor Create(AExpressionData: Pointer; AMaxCount: Integer; ACU: TDwarfCompilationUnit;
|
constructor Create(AExpressionData: Pointer; AMaxCount: Integer; ACU: TDwarfCompilationUnit;
|
||||||
AMemManager: TFpDbgMemManager);
|
AMemManager: TFpDbgMemManager; AContext: TFpDbgAddressContext);
|
||||||
procedure Evaluate;
|
procedure Evaluate;
|
||||||
function ResultKind: TDwarfLocationStackEntryKind;
|
function ResultKind: TDwarfLocationStackEntryKind;
|
||||||
function ResultData: TDbgPtr;
|
function ResultData: TDbgPtr;
|
||||||
@ -661,6 +663,7 @@ type
|
|||||||
property OnFrameBaseNeeded: TNotifyEvent read FOnFrameBaseNeeded write FOnFrameBaseNeeded;
|
property OnFrameBaseNeeded: TNotifyEvent read FOnFrameBaseNeeded write FOnFrameBaseNeeded;
|
||||||
property LastError: TFpError read FLastError;
|
property LastError: TFpError read FLastError;
|
||||||
property MemManager: TFpDbgMemManager read FMemManager;
|
property MemManager: TFpDbgMemManager read FMemManager;
|
||||||
|
property Context: TFpDbgAddressContext read FContext write FContext;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ULEB128toOrdinal(var p: PByte): QWord;
|
function ULEB128toOrdinal(var p: PByte): QWord;
|
||||||
@ -1713,12 +1716,14 @@ end;
|
|||||||
{ TDwarfLocationExpression }
|
{ TDwarfLocationExpression }
|
||||||
|
|
||||||
constructor TDwarfLocationExpression.Create(AExpressionData: Pointer; AMaxCount: Integer;
|
constructor TDwarfLocationExpression.Create(AExpressionData: Pointer; AMaxCount: Integer;
|
||||||
ACU: TDwarfCompilationUnit; AMemManager: TFpDbgMemManager);
|
ACU: TDwarfCompilationUnit; AMemManager: TFpDbgMemManager; AContext: TFpDbgAddressContext);
|
||||||
begin
|
begin
|
||||||
FStack.Clear;
|
FStack.Clear;
|
||||||
FCU := ACU;
|
FCU := ACU;
|
||||||
FData := AExpressionData;
|
FData := AExpressionData;
|
||||||
FMaxData := FData + AMaxCount;FMemManager := AMemManager;
|
FMaxData := FData + AMaxCount;
|
||||||
|
FMemManager := AMemManager;
|
||||||
|
FContext := AContext;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDwarfLocationExpression.Evaluate;
|
procedure TDwarfLocationExpression.Evaluate;
|
||||||
@ -1758,7 +1763,7 @@ var
|
|||||||
begin
|
begin
|
||||||
//TODO: zero fill / sign extend
|
//TODO: zero fill / sign extend
|
||||||
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
||||||
Result := FMemManager.ReadAddress(AnAddress, ASize, AValue);
|
Result := FMemManager.ReadAddress(AnAddress, ASize, AValue, FContext);
|
||||||
if not Result then
|
if not Result then
|
||||||
SetError;
|
SetError;
|
||||||
end;
|
end;
|
||||||
@ -1767,7 +1772,7 @@ var
|
|||||||
begin
|
begin
|
||||||
//TODO: zero fill / sign extend
|
//TODO: zero fill / sign extend
|
||||||
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
||||||
AValue := FMemManager.ReadAddressEx(AnAddress, AnAddrSpace, ASize);
|
AValue := FMemManager.ReadAddressEx(AnAddress, AnAddrSpace, ASize, FContext);
|
||||||
Result := IsValidLoc(AValue);
|
Result := IsValidLoc(AValue);
|
||||||
if not Result then
|
if not Result then
|
||||||
SetError;
|
SetError;
|
||||||
@ -1805,7 +1810,6 @@ var
|
|||||||
Entry, Entry2: TDwarfLocationStackEntry;
|
Entry, Entry2: TDwarfLocationStackEntry;
|
||||||
begin
|
begin
|
||||||
AddrSize := FCU.FAddressSize;
|
AddrSize := FCU.FAddressSize;
|
||||||
FMemManager := FCU.FOwner.FMemManager;
|
|
||||||
FMemManager.ClearLastError;
|
FMemManager.ClearLastError;
|
||||||
FLastError := NoError;
|
FLastError := NoError;
|
||||||
CurData := FData;
|
CurData := FData;
|
||||||
@ -1855,14 +1859,14 @@ begin
|
|||||||
DW_OP_lit0..DW_OP_lit31: FStack.Push(CurInstr^-DW_OP_lit0, lseValue);
|
DW_OP_lit0..DW_OP_lit31: FStack.Push(CurInstr^-DW_OP_lit0, lseValue);
|
||||||
|
|
||||||
DW_OP_reg0..DW_OP_reg31: begin
|
DW_OP_reg0..DW_OP_reg31: begin
|
||||||
if not FMemManager.ReadRegister(CurInstr^-DW_OP_reg0, NewValue) then begin
|
if not FMemManager.ReadRegister(CurInstr^-DW_OP_reg0, NewValue, FContext) then begin
|
||||||
SetError;
|
SetError;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
FStack.Push(NewValue, lseRegister);
|
FStack.Push(NewValue, lseRegister);
|
||||||
end;
|
end;
|
||||||
DW_OP_regx: begin
|
DW_OP_regx: begin
|
||||||
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue) then begin
|
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue, FContext) then begin
|
||||||
SetError;
|
SetError;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -1870,7 +1874,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
DW_OP_breg0..DW_OP_breg31: begin
|
DW_OP_breg0..DW_OP_breg31: begin
|
||||||
if not FMemManager.ReadRegister(CurInstr^-DW_OP_breg0, NewValue) then begin
|
if not FMemManager.ReadRegister(CurInstr^-DW_OP_breg0, NewValue, FContext) then begin
|
||||||
SetError;
|
SetError;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -1879,7 +1883,7 @@ begin
|
|||||||
{$POP}
|
{$POP}
|
||||||
end;
|
end;
|
||||||
DW_OP_bregx: begin
|
DW_OP_bregx: begin
|
||||||
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue) then begin
|
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue, FContext) then begin
|
||||||
SetError;
|
SetError;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -2798,7 +2802,8 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDwarfInfo.FindContext(AAddress: TDbgPtr): TDbgInfoAddressContext;
|
function TFpDwarfInfo.FindContext(AThreadId, AStackFrame: Integer;
|
||||||
|
AAddress: TDbgPtr): TFpDbgInfoContext;
|
||||||
var
|
var
|
||||||
Proc: TDbgDwarfSymbolBase;
|
Proc: TDbgDwarfSymbolBase;
|
||||||
begin
|
begin
|
||||||
@ -2807,10 +2812,16 @@ begin
|
|||||||
if Proc = nil then
|
if Proc = nil then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
Result := Proc.CompilationUnit.DwarfSymbolClassMap.CreateContext(AAddress, Proc, Self);
|
Result := Proc.CompilationUnit.DwarfSymbolClassMap.CreateContext
|
||||||
|
(AThreadId, AStackFrame, AAddress, Proc, Self);
|
||||||
Proc.ReleaseReference;
|
Proc.ReleaseReference;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDwarfInfo.FindContext(AAddress: TDbgPtr): TFpDbgInfoContext;
|
||||||
|
begin
|
||||||
|
FindContext(1, 0, AAddress);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDwarfInfo.FindSymbol(AAddress: TDbgPtr): TFpDbgSymbol;
|
function TFpDwarfInfo.FindSymbol(AAddress: TDbgPtr): TFpDbgSymbol;
|
||||||
begin
|
begin
|
||||||
Result := FindProcSymbol(AAddress);
|
Result := FindProcSymbol(AAddress);
|
||||||
|
@ -15,8 +15,8 @@ type
|
|||||||
public
|
public
|
||||||
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; override;
|
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; override;
|
||||||
//class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; override;
|
//class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; override;
|
||||||
class function CreateContext(AnAddress: TDBGPtr; ASymbol: TFpDbgSymbol;
|
class function CreateContext(AThreadId, AStackFrame: Integer; AnAddress: TDBGPtr; ASymbol: TFpDbgSymbol;
|
||||||
ADwarf: TFpDwarfInfo): TDbgInfoAddressContext; override;
|
ADwarf: TFpDwarfInfo): TFpDbgInfoContext; override;
|
||||||
//class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
//class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
|
||||||
// AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; override;
|
// AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; override;
|
||||||
end;
|
end;
|
||||||
@ -42,10 +42,10 @@ begin
|
|||||||
Result := pos('free pascal', s) > 0;
|
Result := pos('free pascal', s) > 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TFpDwarfFreePascalSymbolClassMap.CreateContext(AnAddress: TDbgPtr;
|
class function TFpDwarfFreePascalSymbolClassMap.CreateContext(AThreadId, AStackFrame: Integer;
|
||||||
ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TDbgInfoAddressContext;
|
AnAddress: TDBGPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TFpDbgInfoContext;
|
||||||
begin
|
begin
|
||||||
Result := TFpDwarfFreePascalAddressContext.Create(AnAddress, ASymbol, ADwarf);
|
Result := TFpDwarfFreePascalAddressContext.Create(AThreadId, AStackFrame, AnAddress, ASymbol, ADwarf);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpDwarfFreePascalAddressContext }
|
{ TFpDwarfFreePascalAddressContext }
|
||||||
|
@ -424,21 +424,17 @@ type
|
|||||||
function GetMemberCount: Integer; override;
|
function GetMemberCount: Integer; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgInfoAddressContext }
|
{ TFpDbgInfoContext }
|
||||||
|
|
||||||
TDbgInfoAddressContext = class(TRefCountedObject)
|
TFpDbgInfoContext = class(TFpDbgAddressContext)
|
||||||
protected
|
protected
|
||||||
function GetAddress: TDbgPtr; virtual; abstract;
|
|
||||||
function GetSymbolAtAddress: TFpDbgSymbol; virtual;
|
function GetSymbolAtAddress: TFpDbgSymbol; virtual;
|
||||||
function GetMemManager: TFpDbgMemManager; virtual;
|
function GetMemManager: TFpDbgMemManager; virtual;
|
||||||
function GetSizeOfAddress: Integer; virtual;
|
|
||||||
public
|
public
|
||||||
property Address: TDbgPtr read GetAddress;
|
|
||||||
property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress;
|
property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress;
|
||||||
// search this, and all parent context
|
// search this, and all parent context
|
||||||
function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual;
|
function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual;
|
||||||
property MemManager: TFpDbgMemManager read GetMemManager;
|
property MemManager: TFpDbgMemManager read GetMemManager;
|
||||||
property SizeOfAddress: Integer read GetSizeOfAddress;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgInfo }
|
{ TDbgInfo }
|
||||||
@ -450,7 +446,13 @@ type
|
|||||||
procedure SetHasInfo;
|
procedure SetHasInfo;
|
||||||
public
|
public
|
||||||
constructor Create({%H-}ALoader: TDbgImageLoader); virtual;
|
constructor Create({%H-}ALoader: TDbgImageLoader); virtual;
|
||||||
function FindContext({%H-}AAddress: TDbgPtr): TDbgInfoAddressContext; 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(const {%H-}AName: String): TFpDbgSymbol; virtual; deprecated;
|
||||||
function FindSymbol({%H-}AAddress: TDbgPtr): TFpDbgSymbol; virtual; deprecated;
|
function FindSymbol({%H-}AAddress: TDbgPtr): TFpDbgSymbol; virtual; deprecated;
|
||||||
property HasInfo: Boolean read FHasInfo;
|
property HasInfo: Boolean read FHasInfo;
|
||||||
@ -776,22 +778,17 @@ end;
|
|||||||
|
|
||||||
{ TDbgInfoAddressContext }
|
{ TDbgInfoAddressContext }
|
||||||
|
|
||||||
function TDbgInfoAddressContext.GetMemManager: TFpDbgMemManager;
|
function TFpDbgInfoContext.GetMemManager: TFpDbgMemManager;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgInfoAddressContext.GetSizeOfAddress: Integer;
|
function TFpDbgInfoContext.GetSymbolAtAddress: TFpDbgSymbol;
|
||||||
begin
|
|
||||||
Result := -1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TDbgInfoAddressContext.GetSymbolAtAddress: TFpDbgSymbol;
|
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgInfoAddressContext.FindSymbol(const AName: String): TFpDbgValue;
|
function TFpDbgInfoContext.FindSymbol(const AName: String): TFpDbgValue;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
@ -1267,7 +1264,13 @@ begin
|
|||||||
inherited Create;
|
inherited Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgInfo.FindContext(AAddress: TDbgPtr): TDbgInfoAddressContext;
|
function TDbgInfo.FindContext(AThreadId, AStackFrame: Integer;
|
||||||
|
AAddress: TDbgPtr): TFpDbgInfoContext;
|
||||||
|
begin
|
||||||
|
Result := nil;;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDbgInfo.FindContext(AAddress: TDbgPtr): TFpDbgInfoContext;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
@ -12,8 +12,8 @@ unit FpdMemoryTools;
|
|||||||
The code calls MemoryManager with an Address, a Size and a space for the data.
|
The code calls MemoryManager with an Address, a Size and a space for the data.
|
||||||
|
|
||||||
If the data needs to be extended (SizeOf(data) > TargetSize), then
|
If the data needs to be extended (SizeOf(data) > TargetSize), then
|
||||||
MemConvertor is called to decide where in rovided space the read data should
|
MemConvertor is called to decide where in the provided space the read data
|
||||||
initially be stored.
|
should initially be stored.
|
||||||
|
|
||||||
Then the data is read using MemReader.
|
Then the data is read using MemReader.
|
||||||
|
|
||||||
@ -24,17 +24,32 @@ unit FpdMemoryTools;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, math, DbgIntfBaseTypes, FpErrorMessages;
|
Classes, SysUtils, math, DbgIntfBaseTypes, FpErrorMessages, LazClasses;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
TFpDbgAddressContext = class(TRefCountedObject)
|
||||||
|
protected
|
||||||
|
function GetAddress: TDbgPtr; virtual; abstract;
|
||||||
|
function GetStackFrame: Integer; virtual; abstract;
|
||||||
|
function GetThreadId: Integer; virtual; abstract;
|
||||||
|
function GetSizeOfAddress: Integer; virtual; abstract;
|
||||||
|
public
|
||||||
|
property Address: TDbgPtr read GetAddress;
|
||||||
|
property ThreadId: Integer read GetThreadId; // experimental
|
||||||
|
property StackFrame: Integer read GetStackFrame; // experimental
|
||||||
|
property SizeOfAddress: Integer read GetSizeOfAddress;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
TFpDbgMemReaderBase = class
|
TFpDbgMemReaderBase = class
|
||||||
public
|
public
|
||||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual; abstract;
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual; abstract;
|
||||||
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual; abstract;
|
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual; abstract;
|
||||||
// ReadRegister may need TargetMemConvertor
|
// ReadRegister may need TargetMemConvertor
|
||||||
// Register with reduced size are treated as unsigned
|
// Register with reduced size are treated as unsigned
|
||||||
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean; virtual; abstract;
|
// TODO: ReadRegister should only take THREAD-ID, not context
|
||||||
|
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext): Boolean; virtual; abstract;
|
||||||
function RegisterSize(ARegNum: Cardinal): Integer; virtual; abstract;
|
function RegisterSize(ARegNum: Cardinal): Integer; virtual; abstract;
|
||||||
// Registernum from name
|
// Registernum from name
|
||||||
end;
|
end;
|
||||||
@ -183,6 +198,7 @@ type
|
|||||||
|
|
||||||
TFpDbgMemManager = class
|
TFpDbgMemManager = class
|
||||||
private
|
private
|
||||||
|
FDefaultContext: TFpDbgAddressContext;
|
||||||
FLastError: TFpError;
|
FLastError: TFpError;
|
||||||
FMemReader: TFpDbgMemReaderBase;
|
FMemReader: TFpDbgMemReaderBase;
|
||||||
FTargetMemConvertor: TFpDbgMemConvertor;
|
FTargetMemConvertor: TFpDbgMemConvertor;
|
||||||
@ -190,56 +206,64 @@ type
|
|||||||
protected
|
protected
|
||||||
function ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
function ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
||||||
const ALocation: TFpDbgMemLocation; ATargetSize: Cardinal;
|
const ALocation: TFpDbgMemLocation; ATargetSize: Cardinal;
|
||||||
ADest: Pointer; ADestSize: Cardinal): Boolean;
|
ADest: Pointer; ADestSize: Cardinal;
|
||||||
|
AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
public
|
public
|
||||||
constructor Create(AMemReader: TFpDbgMemReaderBase; AMemConvertor: TFpDbgMemConvertor);
|
constructor Create(AMemReader: TFpDbgMemReaderBase; AMemConvertor: TFpDbgMemConvertor);
|
||||||
constructor Create(AMemReader: TFpDbgMemReaderBase; ATargenMemConvertor, ASelfMemConvertor: TFpDbgMemConvertor);
|
constructor Create(AMemReader: TFpDbgMemReaderBase; ATargenMemConvertor, ASelfMemConvertor: TFpDbgMemConvertor);
|
||||||
procedure ClearLastError;
|
procedure ClearLastError;
|
||||||
|
|
||||||
function ReadMemory(const ALocation: TFpDbgMemLocation; ASize: Cardinal; ADest: Pointer): Boolean;
|
function ReadMemory(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
function ReadMemoryEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
ADest: Pointer; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean;
|
function ReadMemoryEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
|
(* ReadRegister needs a Context, to get the thread/stackframe
|
||||||
|
*)
|
||||||
|
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext {= nil}): Boolean;
|
||||||
|
|
||||||
// location will be invalid, if read failed
|
// location will be invalid, if read failed
|
||||||
function ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal): TFpDbgMemLocation;
|
function ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
function ReadAddressEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal): TFpDbgMemLocation;
|
AContext: TFpDbgAddressContext = nil): TFpDbgMemLocation;
|
||||||
|
function ReadAddressEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr;
|
||||||
|
ASize: Cardinal; AContext: TFpDbgAddressContext = nil): TFpDbgMemLocation;
|
||||||
|
|
||||||
// ALocation and AnAddress MUST NOT be the same variable on the callers side
|
// ALocation and AnAddress MUST NOT be the same variable on the callers side
|
||||||
function ReadAddress (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function ReadAddress (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AnAddress: TFpDbgMemLocation): Boolean; inline;
|
out AnAddress: TFpDbgMemLocation;
|
||||||
|
AContext: TFpDbgAddressContext = nil): Boolean; inline;
|
||||||
//function ReadAddress (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
//function ReadAddress (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
// out AnAddress: TFpDbgMemLocation;
|
// out AnAddress: TFpDbgMemLocation;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean;
|
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
function ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AValue: QWord): Boolean; inline;
|
out AValue: QWord; AContext: TFpDbgAddressContext = nil): Boolean; inline;
|
||||||
//function ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
//function ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
// out AValue: QWord;
|
// out AValue: QWord;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean;
|
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
function ReadSignedInt (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function ReadSignedInt (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AValue: Int64): Boolean; inline;
|
out AValue: Int64; AContext: TFpDbgAddressContext = nil): Boolean; inline;
|
||||||
//function ReadSignedInt (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
//function ReadSignedInt (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
// out AValue: Int64;
|
// out AValue: Int64;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean;
|
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
// //enum/set: may need bitorder swapped
|
// //enum/set: may need bitorder swapped
|
||||||
function ReadEnum (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function ReadEnum (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AValue: QWord): Boolean; inline;
|
out AValue: QWord; AContext: TFpDbgAddressContext = nil): Boolean; inline;
|
||||||
//function ReadEnum (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
//function ReadEnum (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
// out AValue: QWord;
|
// out AValue: QWord;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean;
|
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
function ReadSet (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function ReadSet (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AValue: TBytes): Boolean; inline;
|
out AValue: TBytes; AContext: TFpDbgAddressContext = nil): Boolean; inline;
|
||||||
//function ReadSet (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
//function ReadSet (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
// out AValue: TBytes;
|
// out AValue: TBytes;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean;
|
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AValue: Extended): Boolean; inline;
|
out AValue: Extended; AContext: TFpDbgAddressContext = nil): Boolean; inline;
|
||||||
//function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
//function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
// out AValue: Extended;
|
// out AValue: Extended;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean;
|
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
|
|
||||||
property TargetMemConvertor: TFpDbgMemConvertor read FTargetMemConvertor;
|
property TargetMemConvertor: TFpDbgMemConvertor read FTargetMemConvertor;
|
||||||
property SelfMemConvertor: TFpDbgMemConvertor read FSelfMemConvertor;
|
property SelfMemConvertor: TFpDbgMemConvertor read FSelfMemConvertor;
|
||||||
property LastError: TFpError read FLastError;
|
property LastError: TFpError read FLastError;
|
||||||
|
property DefaultContext: TFpDbgAddressContext read FDefaultContext write FDefaultContext;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function NilLoc: TFpDbgMemLocation; inline;
|
function NilLoc: TFpDbgMemLocation; inline;
|
||||||
@ -496,7 +520,7 @@ end;
|
|||||||
|
|
||||||
function TFpDbgMemManager.ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
function TFpDbgMemManager.ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
||||||
const ALocation: TFpDbgMemLocation; ATargetSize: Cardinal; ADest: Pointer;
|
const ALocation: TFpDbgMemLocation; ATargetSize: Cardinal; ADest: Pointer;
|
||||||
ADestSize: Cardinal): Boolean;
|
ADestSize: Cardinal; AContext: TFpDbgAddressContext): Boolean;
|
||||||
var
|
var
|
||||||
Addr2: Pointer;
|
Addr2: Pointer;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -505,6 +529,8 @@ var
|
|||||||
begin
|
begin
|
||||||
FLastError := NoError;
|
FLastError := NoError;
|
||||||
Result := False;
|
Result := False;
|
||||||
|
if AContext = nil then
|
||||||
|
AContext := FDefaultContext;
|
||||||
case ALocation.MType of
|
case ALocation.MType of
|
||||||
mlfInvalid, mlfUninitialized:
|
mlfInvalid, mlfUninitialized:
|
||||||
FLastError := CreateError(fpErrCanNotReadInvalidMem);
|
FLastError := CreateError(fpErrCanNotReadInvalidMem);
|
||||||
@ -545,7 +571,7 @@ begin
|
|||||||
i := FMemReader.RegisterSize(Cardinal(ALocation.Address));
|
i := FMemReader.RegisterSize(Cardinal(ALocation.Address));
|
||||||
if i = 0 then
|
if i = 0 then
|
||||||
exit; // failed
|
exit; // failed
|
||||||
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal) then
|
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal, AContext) then
|
||||||
exit; // failed
|
exit; // failed
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -593,7 +619,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadMemory(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function TFpDbgMemManager.ReadMemory(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
ADest: Pointer): Boolean;
|
ADest: Pointer; AContext: TFpDbgAddressContext): Boolean;
|
||||||
var
|
var
|
||||||
Addr2: Pointer;
|
Addr2: Pointer;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -602,6 +628,8 @@ var
|
|||||||
begin
|
begin
|
||||||
FLastError := NoError;
|
FLastError := NoError;
|
||||||
Result := False;
|
Result := False;
|
||||||
|
if AContext = nil then
|
||||||
|
AContext := FDefaultContext;
|
||||||
case ALocation.MType of
|
case ALocation.MType of
|
||||||
mlfInvalid, mlfUninitialized: ;
|
mlfInvalid, mlfUninitialized: ;
|
||||||
mlfTargetMem:
|
mlfTargetMem:
|
||||||
@ -626,7 +654,7 @@ begin
|
|||||||
i := FMemReader.RegisterSize(Cardinal(ALocation.Address));
|
i := FMemReader.RegisterSize(Cardinal(ALocation.Address));
|
||||||
if i = 0 then
|
if i = 0 then
|
||||||
exit; // failed
|
exit; // failed
|
||||||
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal) then
|
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal, AContext) then
|
||||||
exit; // failed
|
exit; // failed
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -651,79 +679,84 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadMemoryEx(const ALocation: TFpDbgMemLocation;
|
function TFpDbgMemManager.ReadMemoryEx(const ALocation: TFpDbgMemLocation;
|
||||||
AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer;
|
||||||
|
AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
FLastError := NoError;
|
FLastError := NoError;
|
||||||
// AnAddressSpace is ignored, when not actually reading from target address
|
// AnAddressSpace is ignored, when not actually reading from target address
|
||||||
case ALocation.MType of
|
case ALocation.MType of
|
||||||
mlfTargetMem: Result := FMemReader.ReadMemoryEx(ALocation.Address, AnAddressSpace, ASize, ADest);
|
mlfTargetMem: Result := FMemReader.ReadMemoryEx(ALocation.Address, AnAddressSpace, ASize, ADest);
|
||||||
else
|
else
|
||||||
Result := ReadMemory(ALocation, ASize, ADest);
|
Result := ReadMemory(ALocation, ASize, ADest, AContext);
|
||||||
end;
|
end;
|
||||||
if (not Result) and (not IsError(FLastError)) then
|
if (not Result) and (not IsError(FLastError)) then
|
||||||
FLastError := CreateError(fpErrFailedReadMem);
|
FLastError := CreateError(fpErrFailedReadMem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean;
|
function TFpDbgMemManager.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
|
||||||
|
AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
FLastError := NoError;
|
FLastError := NoError;
|
||||||
Result := FMemReader.ReadRegister(ARegNum, AValue);
|
// TODO: If stackframe <> 0 then get the register internally (unroll stack)
|
||||||
|
if AContext = nil then
|
||||||
|
AContext := FDefaultContext;
|
||||||
|
Result := FMemReader.ReadRegister(ARegNum, AValue, AContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadAddress(const ALocation: TFpDbgMemLocation;
|
function TFpDbgMemManager.ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
ASize: Cardinal): TFpDbgMemLocation;
|
AContext: TFpDbgAddressContext): TFpDbgMemLocation;
|
||||||
begin
|
begin
|
||||||
Result.MType := mlfTargetMem;
|
Result.MType := mlfTargetMem;
|
||||||
if not ReadMemory(rdtAddress, ALocation, ASize, @Result.Address, SizeOf(Result.Address)) then
|
if not ReadMemory(rdtAddress, ALocation, ASize, @Result.Address, SizeOf(Result.Address), AContext) then
|
||||||
Result := InvalidLoc;
|
Result := InvalidLoc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadAddressEx(const ALocation: TFpDbgMemLocation;
|
function TFpDbgMemManager.ReadAddressEx(const ALocation: TFpDbgMemLocation;
|
||||||
AnAddressSpace: TDbgPtr; ASize: Cardinal): TFpDbgMemLocation;
|
AnAddressSpace: TDbgPtr; ASize: Cardinal; AContext: TFpDbgAddressContext): TFpDbgMemLocation;
|
||||||
begin
|
begin
|
||||||
Result := InvalidLoc;
|
Result := InvalidLoc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
function TFpDbgMemManager.ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
||||||
AnAddress: TFpDbgMemLocation): Boolean;
|
AnAddress: TFpDbgMemLocation; AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ReadMemory(rdtAddress, ALocation, ASize, @AnAddress.Address, SizeOf(AnAddress.Address));
|
Result := ReadMemory(rdtAddress, ALocation, ASize, @AnAddress.Address, SizeOf(AnAddress.Address), AContext);
|
||||||
if Result
|
if Result
|
||||||
then AnAddress.MType := mlfTargetMem
|
then AnAddress.MType := mlfTargetMem
|
||||||
else AnAddress.MType := mlfInvalid;
|
else AnAddress.MType := mlfInvalid;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function TFpDbgMemManager.ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AValue: QWord): Boolean;
|
out AValue: QWord; AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ReadMemory(rdtUnsignedInt, ALocation, ASize, @AValue, SizeOf(AValue));
|
Result := ReadMemory(rdtUnsignedInt, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadSignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
function TFpDbgMemManager.ReadSignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
|
||||||
out AValue: Int64): Boolean;
|
out AValue: Int64; AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ReadMemory(rdtSignedInt, ALocation, ASize, @AValue, SizeOf(AValue));
|
Result := ReadMemory(rdtSignedInt, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadEnum(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
function TFpDbgMemManager.ReadEnum(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
||||||
AValue: QWord): Boolean;
|
AValue: QWord; AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ReadMemory(rdtEnum, ALocation, ASize, @AValue, SizeOf(AValue));
|
Result := ReadMemory(rdtEnum, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadSet(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
function TFpDbgMemManager.ReadSet(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
||||||
AValue: TBytes): Boolean;
|
AValue: TBytes; AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
SetLength(AValue, ASize);
|
SetLength(AValue, ASize);
|
||||||
Result := ASize > 0;
|
Result := ASize > 0;
|
||||||
if Result then
|
if Result then
|
||||||
Result := ReadMemory(rdtSet, ALocation, ASize, @AValue[0], ASize);
|
Result := ReadMemory(rdtSet, ALocation, ASize, @AValue[0], ASize, AContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadFloat(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
function TFpDbgMemManager.ReadFloat(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
|
||||||
AValue: Extended): Boolean;
|
AValue: Extended; AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ReadMemory(rdtfloat, ALocation, ASize, @AValue, SizeOf(AValue));
|
Result := ReadMemory(rdtfloat, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -50,7 +50,7 @@ type
|
|||||||
TFpPascalExpression = class
|
TFpPascalExpression = class
|
||||||
private
|
private
|
||||||
FError: TFpError;
|
FError: TFpError;
|
||||||
FContext: TDbgInfoAddressContext;
|
FContext: TFpDbgInfoContext;
|
||||||
FTextExpression: String;
|
FTextExpression: String;
|
||||||
FExpressionPart: TFpPascalExpressionPart;
|
FExpressionPart: TFpPascalExpressionPart;
|
||||||
FValid: Boolean;
|
FValid: Boolean;
|
||||||
@ -62,9 +62,9 @@ type
|
|||||||
protected
|
protected
|
||||||
function GetDbgSymbolForIdentifier({%H-}AnIdent: String): TFpDbgValue;
|
function GetDbgSymbolForIdentifier({%H-}AnIdent: String): TFpDbgValue;
|
||||||
property ExpressionPart: TFpPascalExpressionPart read FExpressionPart;
|
property ExpressionPart: TFpPascalExpressionPart read FExpressionPart;
|
||||||
property Context: TDbgInfoAddressContext read FContext;
|
property Context: TFpDbgInfoContext read FContext;
|
||||||
public
|
public
|
||||||
constructor Create(ATextExpression: String; AContext: TDbgInfoAddressContext);
|
constructor Create(ATextExpression: String; AContext: TFpDbgInfoContext);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function DebugDump(AWithResults: Boolean = False): String;
|
function DebugDump(AWithResults: Boolean = False): String;
|
||||||
property Error: TFpError read FError;
|
property Error: TFpError read FError;
|
||||||
@ -399,13 +399,13 @@ type
|
|||||||
private
|
private
|
||||||
FPointerLevels: Integer;
|
FPointerLevels: Integer;
|
||||||
FPointedTo: TFpDbgSymbol;
|
FPointedTo: TFpDbgSymbol;
|
||||||
FContext: TDbgInfoAddressContext;
|
FContext: TFpDbgInfoContext;
|
||||||
protected
|
protected
|
||||||
// NameNeeded // "^TPointedTo"
|
// NameNeeded // "^TPointedTo"
|
||||||
procedure TypeInfoNeeded; override;
|
procedure TypeInfoNeeded; override;
|
||||||
public
|
public
|
||||||
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TDbgInfoAddressContext; APointerLevels: Integer);
|
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TFpDbgInfoContext; APointerLevels: Integer);
|
||||||
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
|
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function TypeCastValue(AValue: TFpDbgValue): TFpDbgValue; override;
|
function TypeCastValue(AValue: TFpDbgValue): TFpDbgValue; override;
|
||||||
end;
|
end;
|
||||||
@ -432,12 +432,12 @@ type
|
|||||||
|
|
||||||
TFpPasParserValue = class(TFpDbgValue)
|
TFpPasParserValue = class(TFpDbgValue)
|
||||||
private
|
private
|
||||||
FContext: TDbgInfoAddressContext;
|
FContext: TFpDbgInfoContext;
|
||||||
protected
|
protected
|
||||||
function DebugText(AIndent: String): String; virtual;
|
function DebugText(AIndent: String): String; virtual;
|
||||||
public
|
public
|
||||||
constructor Create(AContext: TDbgInfoAddressContext);
|
constructor Create(AContext: TFpDbgInfoContext);
|
||||||
property Context: TDbgInfoAddressContext read FContext;
|
property Context: TFpDbgInfoContext read FContext;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpPasParserValueCastToPointer
|
{ TFpPasParserValueCastToPointer
|
||||||
@ -459,7 +459,7 @@ type
|
|||||||
function GetDataAddress: TFpDbgMemLocation; override;
|
function GetDataAddress: TFpDbgMemLocation; override;
|
||||||
function GetMember(AIndex: Int64): TFpDbgValue; override;
|
function GetMember(AIndex: Int64): TFpDbgValue; override;
|
||||||
public
|
public
|
||||||
constructor Create(AValue: TFpDbgValue; ATypeInfo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
|
constructor Create(AValue: TFpDbgValue; ATypeInfo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -474,7 +474,7 @@ type
|
|||||||
protected
|
protected
|
||||||
function GetDbgSymbol: TFpDbgSymbol; override; // returns a TPasParserSymbolPointer
|
function GetDbgSymbol: TFpDbgSymbol; override; // returns a TPasParserSymbolPointer
|
||||||
public
|
public
|
||||||
constructor Create(ATypeInfo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
|
constructor Create(ATypeInfo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure IncRefLevel;
|
procedure IncRefLevel;
|
||||||
function GetTypeCastedValue(ADataVal: TFpDbgValue): TFpDbgValue; override;
|
function GetTypeCastedValue(ADataVal: TFpDbgValue): TFpDbgValue; override;
|
||||||
@ -499,8 +499,8 @@ type
|
|||||||
function GetAsCardinal: QWord; override; // reads men
|
function GetAsCardinal: QWord; override; // reads men
|
||||||
function GetTypeInfo: TFpDbgSymbol; override; // TODO: Cardinal? Why? // TODO: does not handle AOffset
|
function GetTypeInfo: TFpDbgSymbol; override; // TODO: Cardinal? Why? // TODO: does not handle AOffset
|
||||||
public
|
public
|
||||||
constructor Create(AValue: TFpDbgValue; AContext: TDbgInfoAddressContext);
|
constructor Create(AValue: TFpDbgValue; AContext: TFpDbgInfoContext);
|
||||||
constructor Create(AValue: TFpDbgValue; AContext: TDbgInfoAddressContext; AOffset: Int64);
|
constructor Create(AValue: TFpDbgValue; AContext: TFpDbgInfoContext; AOffset: Int64);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -523,7 +523,7 @@ type
|
|||||||
function GetDataAddress: TFpDbgMemLocation; override;
|
function GetDataAddress: TFpDbgMemLocation; override;
|
||||||
function GetMember(AIndex: Int64): TFpDbgValue; override;
|
function GetMember(AIndex: Int64): TFpDbgValue; override;
|
||||||
public
|
public
|
||||||
constructor Create(AValue: TFpDbgValue; AContext: TDbgInfoAddressContext);
|
constructor Create(AValue: TFpDbgValue; AContext: TFpDbgInfoContext);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
property PointedToValue: TFpDbgValue read GetPointedToValue;
|
property PointedToValue: TFpDbgValue read GetPointedToValue;
|
||||||
end;
|
end;
|
||||||
@ -551,7 +551,7 @@ begin
|
|||||||
Result := AIndent + DbgSName(Self) + ' DbsSym='+DbgSName(DbgSymbol)+' Type='+DbgSName(TypeInfo) + LineEnding;
|
Result := AIndent + DbgSName(Self) + ' DbsSym='+DbgSName(DbgSymbol)+' Type='+DbgSName(TypeInfo) + LineEnding;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpPasParserValue.Create(AContext: TDbgInfoAddressContext);
|
constructor TFpPasParserValue.Create(AContext: TFpDbgInfoContext);
|
||||||
begin
|
begin
|
||||||
FContext := AContext;
|
FContext := AContext;
|
||||||
inherited Create;
|
inherited Create;
|
||||||
@ -638,7 +638,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpPasParserValueCastToPointer.Create(AValue: TFpDbgValue;
|
constructor TFpPasParserValueCastToPointer.Create(AValue: TFpDbgValue;
|
||||||
ATypeInfo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
|
ATypeInfo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
|
||||||
begin
|
begin
|
||||||
inherited Create(AContext);
|
inherited Create(AContext);
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
@ -676,7 +676,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpPasParserValueMakeReftype.Create(ATypeInfo: TFpDbgSymbol;
|
constructor TFpPasParserValueMakeReftype.Create(ATypeInfo: TFpDbgSymbol;
|
||||||
AContext: TDbgInfoAddressContext);
|
AContext: TFpDbgInfoContext);
|
||||||
begin
|
begin
|
||||||
inherited Create(AContext);
|
inherited Create(AContext);
|
||||||
FSourceTypeSymbol := ATypeInfo;
|
FSourceTypeSymbol := ATypeInfo;
|
||||||
@ -755,7 +755,7 @@ function TFpPasParserValueDerefPointer.GetAsCardinal: QWord;
|
|||||||
var
|
var
|
||||||
m: TFpDbgMemManager;
|
m: TFpDbgMemManager;
|
||||||
Addr: TFpDbgMemLocation;
|
Addr: TFpDbgMemLocation;
|
||||||
Ctx: TDbgInfoAddressContext;
|
Ctx: TFpDbgInfoContext;
|
||||||
AddrSize: Integer;
|
AddrSize: Integer;
|
||||||
begin
|
begin
|
||||||
Result := FCardinal;
|
Result := FCardinal;
|
||||||
@ -790,13 +790,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
|
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
|
||||||
AContext: TDbgInfoAddressContext);
|
AContext: TFpDbgInfoContext);
|
||||||
begin
|
begin
|
||||||
Create(AValue, AContext, 0);
|
Create(AValue, AContext, 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
|
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
|
||||||
AContext: TDbgInfoAddressContext; AOffset: Int64);
|
AContext: TFpDbgInfoContext; AOffset: Int64);
|
||||||
begin
|
begin
|
||||||
inherited Create(AContext);
|
inherited Create(AContext);
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
@ -897,7 +897,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpPasParserValueAddressOf.Create(AValue: TFpDbgValue;
|
constructor TFpPasParserValueAddressOf.Create(AValue: TFpDbgValue;
|
||||||
AContext: TDbgInfoAddressContext);
|
AContext: TFpDbgInfoContext);
|
||||||
begin
|
begin
|
||||||
inherited Create(AContext);
|
inherited Create(AContext);
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
@ -952,7 +952,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TPasParserSymbolPointer.Create(const APointedTo: TFpDbgSymbol;
|
constructor TPasParserSymbolPointer.Create(const APointedTo: TFpDbgSymbol;
|
||||||
AContext: TDbgInfoAddressContext; APointerLevels: Integer);
|
AContext: TFpDbgInfoContext; APointerLevels: Integer);
|
||||||
begin
|
begin
|
||||||
inherited Create('');
|
inherited Create('');
|
||||||
FContext := AContext;
|
FContext := AContext;
|
||||||
@ -966,7 +966,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TPasParserSymbolPointer.Create(const APointedTo: TFpDbgSymbol;
|
constructor TPasParserSymbolPointer.Create(const APointedTo: TFpDbgSymbol;
|
||||||
AContext: TDbgInfoAddressContext);
|
AContext: TFpDbgInfoContext);
|
||||||
begin
|
begin
|
||||||
Create(APointedTo, AContext, 1);
|
Create(APointedTo, AContext, 1);
|
||||||
end;
|
end;
|
||||||
@ -1613,7 +1613,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpPascalExpression.Create(ATextExpression: String;
|
constructor TFpPascalExpression.Create(ATextExpression: String;
|
||||||
AContext: TDbgInfoAddressContext);
|
AContext: TFpDbgInfoContext);
|
||||||
begin
|
begin
|
||||||
FContext := AContext;
|
FContext := AContext;
|
||||||
FTextExpression := ATextExpression;
|
FTextExpression := ATextExpression;
|
||||||
|
@ -22,7 +22,8 @@ type
|
|||||||
constructor Create;
|
constructor Create;
|
||||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
||||||
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace: TDbgPtr; {%H-}ASize: Cardinal; {%H-}ADest: Pointer): Boolean; override;
|
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace: TDbgPtr; {%H-}ASize: Cardinal; {%H-}ADest: Pointer): Boolean; override;
|
||||||
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean; override;
|
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
|
||||||
|
AContext: TFpDbgAddressContext): Boolean; override;
|
||||||
function RegisterSize(ARegNum: Cardinal): Integer; override;
|
function RegisterSize(ARegNum: Cardinal): Integer; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -413,7 +414,8 @@ begin
|
|||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTestMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean;
|
function TTestMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
|
||||||
|
AContext: TFpDbgAddressContext): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
AValue := RegisterValues[ARegNum];
|
AValue := RegisterValues[ARegNum];
|
||||||
|
@ -19,9 +19,9 @@ type
|
|||||||
|
|
||||||
TTestTypeInfo = class(TTestCase)
|
TTestTypeInfo = class(TTestCase)
|
||||||
protected
|
protected
|
||||||
FDwarfInfo: TDbgDwarf;
|
FDwarfInfo: TFpDwarfInfo;
|
||||||
FCurrentTestName: String;
|
FCurrentTestName: String;
|
||||||
FCurrentContext: TDbgInfoAddressContext;
|
FCurrentContext: TFpDbgInfoContext;
|
||||||
FExpression: TFpPascalExpression;
|
FExpression: TFpPascalExpression;
|
||||||
FImageLoader: TTestDummyImageLoader;
|
FImageLoader: TTestDummyImageLoader;
|
||||||
FMemReader: TTestMemReader;
|
FMemReader: TTestMemReader;
|
||||||
@ -322,7 +322,7 @@ begin
|
|||||||
FImageLoader := ALoaderClass.Create;
|
FImageLoader := ALoaderClass.Create;
|
||||||
FMemReader := TTestMemReader.Create;
|
FMemReader := TTestMemReader.Create;
|
||||||
FMemManager := TFpDbgMemManager.Create(FMemReader, TFpDbgMemConvertorLittleEndian.Create);
|
FMemManager := TFpDbgMemManager.Create(FMemReader, TFpDbgMemConvertorLittleEndian.Create);
|
||||||
FDwarfInfo := TDbgDwarf.Create(FImageLoader);
|
FDwarfInfo := TFpDwarfInfo.Create(FImageLoader);
|
||||||
FDwarfInfo.MemManager := FMemManager;
|
FDwarfInfo.MemManager := FMemManager;
|
||||||
FDwarfInfo.LoadCompilationUnits;
|
FDwarfInfo.LoadCompilationUnits;
|
||||||
end;
|
end;
|
||||||
|
@ -35,13 +35,13 @@ type
|
|||||||
FCmd: TGDBMIDebuggerCommandMemReader;
|
FCmd: TGDBMIDebuggerCommandMemReader;
|
||||||
protected
|
protected
|
||||||
// TODO: needs to be handled by memory manager
|
// TODO: needs to be handled by memory manager
|
||||||
FThreadId, FStackFrame: Integer;
|
//FThreadId, FStackFrame: Integer;
|
||||||
public
|
public
|
||||||
constructor Create(ADebugger: TFpGDBMIDebugger);
|
constructor Create(ADebugger: TFpGDBMIDebugger);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
||||||
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace:{%H-} TDbgPtr; ASize: {%H-}Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace:{%H-} TDbgPtr; ASize: {%H-}Cardinal; ADest: Pointer): Boolean; override;
|
||||||
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean; override;
|
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext): Boolean; override;
|
||||||
function RegisterSize({%H-}ARegNum: Cardinal): Integer; override;
|
function RegisterSize({%H-}ARegNum: Cardinal): Integer; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ type
|
|||||||
FMemManager: TFpDbgMemManager;
|
FMemManager: TFpDbgMemManager;
|
||||||
// cache last context
|
// cache last context
|
||||||
FlastStackFrame, FLastThread: Integer;
|
FlastStackFrame, FLastThread: Integer;
|
||||||
FLastContext: array [0..MAX_CTX_CACHE-1] of TDbgInfoAddressContext;
|
FLastContext: array [0..MAX_CTX_CACHE-1] of TFpDbgInfoContext;
|
||||||
protected
|
protected
|
||||||
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
|
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
|
||||||
function CreateLineInfo: TDBGLineInfo; override;
|
function CreateLineInfo: TDBGLineInfo; override;
|
||||||
@ -88,7 +88,7 @@ type
|
|||||||
|
|
||||||
procedure GetCurrentContext(out AThreadId, AStackFrame: Integer);
|
procedure GetCurrentContext(out AThreadId, AStackFrame: Integer);
|
||||||
function GetLocationForContext(AThreadId, AStackFrame: Integer): TDBGPtr;
|
function GetLocationForContext(AThreadId, AStackFrame: Integer): TDBGPtr;
|
||||||
function GetInfoContextForContext(AThreadId, AStackFrame: Integer): TDbgInfoAddressContext;
|
function GetInfoContextForContext(AThreadId, AStackFrame: Integer): TFpDbgInfoContext;
|
||||||
property CurrentCommand;
|
property CurrentCommand;
|
||||||
property TargetPID;
|
property TargetPID;
|
||||||
protected
|
protected
|
||||||
@ -320,8 +320,8 @@ begin
|
|||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpGDBMIDbgMemReader.ReadRegister(ARegNum: Cardinal; out
|
function TFpGDBMIDbgMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
|
||||||
AValue: TDbgPtr): Boolean;
|
AContext: TFpDbgAddressContext): Boolean;
|
||||||
var
|
var
|
||||||
rname: String;
|
rname: String;
|
||||||
v: String;
|
v: String;
|
||||||
@ -367,7 +367,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Reg := FDebugger.Registers.CurrentRegistersList[FThreadId, FStackFrame];
|
Reg := FDebugger.Registers.CurrentRegistersList[AContext.ThreadId, AContext.StackFrame];
|
||||||
for i := 0 to Reg.Count - 1 do
|
for i := 0 to Reg.Count - 1 do
|
||||||
if UpperCase(Reg[i].Name) = rname then
|
if UpperCase(Reg[i].Name) = rname then
|
||||||
begin
|
begin
|
||||||
@ -750,9 +750,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpGDBMIDebugger.GetInfoContextForContext(AThreadId,
|
function TFpGDBMIDebugger.GetInfoContextForContext(AThreadId,
|
||||||
AStackFrame: Integer): TDbgInfoAddressContext;
|
AStackFrame: Integer): TFpDbgInfoContext;
|
||||||
var
|
var
|
||||||
Addr: TDBGPtr;
|
Addr: TDBGPtr;
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
if FDwarfInfo = nil then
|
if FDwarfInfo = nil then
|
||||||
@ -769,17 +770,20 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (AStackFrame >= FlastStackFrame) and
|
i := AStackFrame - FlastStackFrame;
|
||||||
(AStackFrame - FlastStackFrame < MAX_CTX_CACHE) and
|
if (i >= 0) and
|
||||||
(FLastContext[AStackFrame - FlastStackFrame] <> nil) and
|
(i < MAX_CTX_CACHE) and
|
||||||
(FLastContext[AStackFrame - FlastStackFrame].Address = Addr)
|
(FLastContext[i] <> nil) and
|
||||||
|
(FLastContext[i].Address = Addr) and
|
||||||
|
(FLastContext[i].ThreadId = AThreadId) and
|
||||||
|
(FLastContext[i].StackFrame = AStackFrame)
|
||||||
then begin
|
then begin
|
||||||
Result := FLastContext[AStackFrame - FlastStackFrame];
|
Result := FLastContext[AStackFrame - FlastStackFrame];
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
DebugLn(['* FDwarfInfo.FindContext ', dbgs(Addr)]);
|
DebugLn(['* FDwarfInfo.FindContext ', dbgs(Addr)]);
|
||||||
Result := FDwarfInfo.FindContext(Addr);
|
Result := FDwarfInfo.FindContext(AThreadId, AStackFrame, Addr);
|
||||||
|
|
||||||
FLastThread := AThreadId;
|
FLastThread := AThreadId;
|
||||||
FlastStackFrame := AStackFrame;
|
FlastStackFrame := AStackFrame;
|
||||||
@ -802,7 +806,7 @@ function TFpGDBMIDebugger.EvaluateExpression(AWatchValue: TWatchValue;
|
|||||||
AExpression: String; var AResText: String; out ATypeInfo: TDBGType;
|
AExpression: String; var AResText: String; out ATypeInfo: TDBGType;
|
||||||
EvalFlags: TDBGEvaluateFlags): Boolean;
|
EvalFlags: TDBGEvaluateFlags): Boolean;
|
||||||
var
|
var
|
||||||
Ctx: TDbgInfoAddressContext;
|
Ctx: TFpDbgInfoContext;
|
||||||
PasExpr: TFpPascalExpression;
|
PasExpr: TFpPascalExpression;
|
||||||
ResValue: TFpDbgValue;
|
ResValue: TFpDbgValue;
|
||||||
|
|
||||||
@ -982,12 +986,12 @@ begin
|
|||||||
if AWatchValue <> nil then begin
|
if AWatchValue <> nil then begin
|
||||||
EvalFlags := AWatchValue.EvaluateFlags;
|
EvalFlags := AWatchValue.EvaluateFlags;
|
||||||
AExpression := AWatchValue.Expression;
|
AExpression := AWatchValue.Expression;
|
||||||
FMemReader.FThreadId := AWatchValue.ThreadId;
|
//FMemReader.FThreadId := AWatchValue.ThreadId;
|
||||||
FMemReader.FStackFrame := AWatchValue.StackFrame;
|
//FMemReader.FStackFrame := AWatchValue.StackFrame;
|
||||||
end
|
//end
|
||||||
else begin
|
//else begin
|
||||||
FMemReader.FThreadId := CurrentThreadId;
|
// FMemReader.FThreadId := CurrentThreadId;
|
||||||
FMemReader.FStackFrame := CurrentStackFrame;
|
// FMemReader.FStackFrame := CurrentStackFrame;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if AWatchValue <> nil then
|
if AWatchValue <> nil then
|
||||||
@ -995,6 +999,8 @@ begin
|
|||||||
else
|
else
|
||||||
Ctx := GetInfoContextForContext(CurrentThreadId, CurrentStackFrame);
|
Ctx := GetInfoContextForContext(CurrentThreadId, CurrentStackFrame);
|
||||||
if Ctx = nil then exit;
|
if Ctx = nil then exit;
|
||||||
|
|
||||||
|
FMemManager.DefaultContext := Ctx;
|
||||||
FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
|
FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
|
||||||
|
|
||||||
PasExpr := TFpPascalExpression.Create(AExpression, Ctx);
|
PasExpr := TFpPascalExpression.Create(AExpression, Ctx);
|
||||||
@ -1063,6 +1069,7 @@ DebugLn(ErrorHandler.ErrorAsString(PasExpr.Error));
|
|||||||
|
|
||||||
finally
|
finally
|
||||||
PasExpr.Free;
|
PasExpr.Free;
|
||||||
|
FMemManager.DefaultContext := nil;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user