mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 01:36:06 +02:00
FPDebug: start using mem-manager
git-svn-id: trunk@44028 -
This commit is contained in:
parent
1dfc8873d3
commit
2978fbf036
@ -430,7 +430,7 @@ procedure DebugLoop;
|
||||
end;
|
||||
|
||||
WriteLn(sym.FileName, ' ', sym.Line, ':', sym.Column, ' ', sym.Name);
|
||||
Write(' [', FormatAddress(sym.Address), '+', a-sym.Address, '] ');
|
||||
Write(' [', FormatAddress(LocToAddrOrNil(sym.Address)), '+', a-LocToAddrOrNil(sym.Address), '] ');
|
||||
|
||||
Name := sym.Filename;
|
||||
if not FileExistsUTF8(Name)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -141,9 +141,9 @@ type
|
||||
function GetAsString: AnsiString; virtual;
|
||||
function GetAsWideString: WideString; virtual;
|
||||
|
||||
function GetAddress: TDbgPtr; virtual;
|
||||
function GetAddress: TFpDbgMemLocation; virtual;
|
||||
function GetSize: Integer; virtual; // returns -1, if not available
|
||||
function GetDataAddress: TDbgPtr; virtual;
|
||||
function GetDataAddress: TFpDbgMemLocation; virtual;
|
||||
function GetDataSize: Integer; virtual;
|
||||
|
||||
function GetMember(AIndex: Integer): TDbgSymbolValue; virtual;
|
||||
@ -172,9 +172,9 @@ type
|
||||
// complex
|
||||
// double
|
||||
|
||||
property Address: TDbgPtr read GetAddress; // Address of variable
|
||||
property Address: TFpDbgMemLocation read GetAddress; // Address of variable
|
||||
property Size: Integer read GetSize; // Size of variable
|
||||
property DataAddress: TDbgPtr read GetDataAddress; // Address of Data, if avail (e.g. String, TObject, ..., BUT NOT record)
|
||||
property DataAddress: TFpDbgMemLocation read GetDataAddress; // Address of Data, if avail (e.g. String, TObject, ..., BUT NOT record)
|
||||
property DataSize: Integer read GetDataSize; // Sive of Data, if avail (e.g. String, TObject, ..., BUT NOT record)
|
||||
// memdump
|
||||
public
|
||||
@ -228,14 +228,14 @@ type
|
||||
|
||||
TDbgSymbolValueConstAddress = class(TDbgSymbolValue)
|
||||
private
|
||||
FAddress: TDbgPtr;
|
||||
FAddress: TFpDbgMemLocation;
|
||||
protected
|
||||
property Address: QWord read FAddress write FAddress;
|
||||
property Address: TFpDbgMemLocation read FAddress write FAddress;
|
||||
//function GetKind: TDbgSymbolKind; override; // no kind
|
||||
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
||||
function GetAddress: TDbgPtr; override;
|
||||
function GetAddress: TFpDbgMemLocation; override;
|
||||
public
|
||||
constructor Create(AnAddress: TDbgPtr);
|
||||
constructor Create(AnAddress: TFpDbgMemLocation);
|
||||
end;
|
||||
|
||||
{ TDbgSymbol }
|
||||
@ -248,7 +248,7 @@ type
|
||||
FName: String;
|
||||
FKind: TDbgSymbolKind;
|
||||
FSymbolType: TDbgSymbolType;
|
||||
FAddress: TDbgPtr;
|
||||
FAddress: TFpDbgMemLocation;
|
||||
FSize: Integer;
|
||||
FTypeInfo: TDbgSymbol;
|
||||
FMemberVisibility: TDbgSymbolMemberVisibility; // Todo: not cached
|
||||
@ -257,7 +257,7 @@ type
|
||||
function GetKind: TDbgSymbolKind; inline;
|
||||
function GetName: String; inline;
|
||||
function GetSize: Integer; inline;
|
||||
function GetAddress: TDbgPtr; inline;
|
||||
function GetAddress: TFpDbgMemLocation; inline;
|
||||
function GetTypeInfo: TDbgSymbol; inline;
|
||||
function GetMemberVisibility: TDbgSymbolMemberVisibility; inline;
|
||||
protected
|
||||
@ -287,7 +287,7 @@ type
|
||||
procedure SetName(AValue: String); inline;
|
||||
procedure SetKind(AValue: TDbgSymbolKind); inline;
|
||||
procedure SetSymbolType(AValue: TDbgSymbolType); inline;
|
||||
procedure SetAddress(AValue: TDbgPtr); inline;
|
||||
procedure SetAddress(AValue: TFpDbgMemLocation); inline;
|
||||
procedure SetSize(AValue: Integer); inline;
|
||||
procedure SetTypeInfo(AValue: TDbgSymbol); inline;
|
||||
procedure SetMemberVisibility(AValue: TDbgSymbolMemberVisibility); inline;
|
||||
@ -302,7 +302,7 @@ type
|
||||
//procedure Needed; virtual;
|
||||
public
|
||||
constructor Create(const AName: String);
|
||||
constructor Create(const AName: String; AKind: TDbgSymbolKind; AAddress: TDbgPtr);
|
||||
constructor Create(const AName: String; AKind: TDbgSymbolKind; AAddress: TFpDbgMemLocation);
|
||||
destructor Destroy; override;
|
||||
// Basic info
|
||||
property Name: String read GetName;
|
||||
@ -310,7 +310,7 @@ type
|
||||
property Kind: TDbgSymbolKind read GetKind;
|
||||
// Memory; Size is also part of type (byte vs word vs ...)
|
||||
// HasAddress // (register does not have)
|
||||
property Address: TDbgPtr read GetAddress;
|
||||
property Address: TFpDbgMemLocation read GetAddress;
|
||||
property Size: Integer read GetSize; // In Bytes
|
||||
// TypeInfo used by
|
||||
// stValue (Variable): Type
|
||||
@ -393,14 +393,14 @@ type
|
||||
protected
|
||||
function GetAddress: TDbgPtr; virtual; abstract;
|
||||
function GetSymbolAtAddress: TDbgSymbol; virtual;
|
||||
function GetMemReader: TFpDbgMemReaderBase; virtual;
|
||||
function GetMemManager: TFpDbgMemManager; virtual;
|
||||
function GetSizeOfAddress: Integer; virtual;
|
||||
public
|
||||
property Address: TDbgPtr read GetAddress;
|
||||
property SymbolAtAddress: TDbgSymbol read GetSymbolAtAddress;
|
||||
// search this, and all parent context
|
||||
function FindSymbol(const {%H-}AName: String): TDbgSymbol; virtual;
|
||||
property MemReader: TFpDbgMemReaderBase read GetMemReader;
|
||||
property MemManager: TFpDbgMemManager read GetMemManager;
|
||||
property SizeOfAddress: Integer read GetSizeOfAddress;
|
||||
end;
|
||||
|
||||
@ -418,6 +418,7 @@ type
|
||||
function FindSymbol({%H-}AAddress: TDbgPtr): TDbgSymbol; virtual; deprecated;
|
||||
property HasInfo: Boolean read FHasInfo;
|
||||
function GetLineAddress(const {%H-}AFileName: String; {%H-}ALine: Cardinal): TDbgPtr; virtual;
|
||||
//property MemManager: TFpDbgMemReaderBase read GetMemManager write SetMemManager;
|
||||
end;
|
||||
|
||||
function dbgs(ADbgSymbolKind: TDbgSymbolKind): String; overload;
|
||||
@ -437,12 +438,12 @@ begin
|
||||
Result := [svfAddress, svfSizeOfPointer]
|
||||
end;
|
||||
|
||||
function TDbgSymbolValueConstAddress.GetAddress: TDbgPtr;
|
||||
function TDbgSymbolValueConstAddress.GetAddress: TFpDbgMemLocation;
|
||||
begin
|
||||
Result := FAddress;
|
||||
end;
|
||||
|
||||
constructor TDbgSymbolValueConstAddress.Create(AnAddress: TDbgPtr);
|
||||
constructor TDbgSymbolValueConstAddress.Create(AnAddress: TFpDbgMemLocation);
|
||||
begin
|
||||
inherited Create;
|
||||
FAddress := AnAddress;
|
||||
@ -601,14 +602,14 @@ begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TDbgSymbolValue.GetAddress: TDbgPtr;
|
||||
function TDbgSymbolValue.GetAddress: TFpDbgMemLocation;
|
||||
begin
|
||||
Result := 0;
|
||||
Result := InvalidLoc;
|
||||
end;
|
||||
|
||||
function TDbgSymbolValue.GetDataAddress: TDbgPtr;
|
||||
function TDbgSymbolValue.GetDataAddress: TFpDbgMemLocation;
|
||||
begin
|
||||
Result := 0;
|
||||
Result := InvalidLoc;
|
||||
end;
|
||||
|
||||
function TDbgSymbolValue.GetDataSize: Integer;
|
||||
@ -673,7 +674,7 @@ end;
|
||||
|
||||
{ TDbgInfoAddressContext }
|
||||
|
||||
function TDbgInfoAddressContext.GetMemReader: TFpDbgMemReaderBase;
|
||||
function TDbgInfoAddressContext.GetMemManager: TFpDbgMemManager;
|
||||
begin
|
||||
Result := nil;
|
||||
end;
|
||||
@ -703,7 +704,8 @@ begin
|
||||
SetName(AName);
|
||||
end;
|
||||
|
||||
constructor TDbgSymbol.Create(const AName: String; AKind: TDbgSymbolKind; AAddress: TDbgPtr);
|
||||
constructor TDbgSymbol.Create(const AName: String; AKind: TDbgSymbolKind;
|
||||
AAddress: TFpDbgMemLocation);
|
||||
begin
|
||||
Create(AName);
|
||||
SetKind(AKind);
|
||||
@ -721,7 +723,7 @@ begin
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
function TDbgSymbol.GetAddress: TDbgPtr;
|
||||
function TDbgSymbol.GetAddress: TFpDbgMemLocation;
|
||||
begin
|
||||
if not(sfiAddress in FEvaluatedFields) then
|
||||
AddressNeeded;
|
||||
@ -815,7 +817,7 @@ begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
procedure TDbgSymbol.SetAddress(AValue: TDbgPtr);
|
||||
procedure TDbgSymbol.SetAddress(AValue: TFpDbgMemLocation);
|
||||
begin
|
||||
FAddress := AValue;
|
||||
Include(FEvaluatedFields, sfiAddress);
|
||||
@ -917,7 +919,7 @@ end;
|
||||
|
||||
procedure TDbgSymbol.AddressNeeded;
|
||||
begin
|
||||
SetAddress(0);
|
||||
SetAddress(InvalidLoc);
|
||||
end;
|
||||
|
||||
procedure TDbgSymbol.SizeNeeded;
|
||||
|
@ -8,7 +8,7 @@ uses
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
TDbgPtr = QWord; // PtrUInt;
|
||||
TDbgPtr = QWord; // TODO, use from IdeDebuggerInterface, once that is done.
|
||||
|
||||
TFpDbgMemReaderBase = class
|
||||
public
|
||||
@ -20,6 +20,7 @@ type
|
||||
end;
|
||||
|
||||
// Todo, cpu/language specific operations, endianess, sign extend, float .... default int value for bool
|
||||
// TODO: currently it assumes target and own mem are in the same format
|
||||
TFpDbgMemConvertor = class
|
||||
public
|
||||
(* To copy a smaller int/cardinal (e.g. word) into a bigger (e.g. dword),
|
||||
@ -62,12 +63,13 @@ type
|
||||
* TODO: allow to pre-read and cache Target mem (e.g. before reading all fields of a record
|
||||
*)
|
||||
TFpDbgMemLocationType = (
|
||||
mlfInvalid,
|
||||
mlfTargetMem, // an address in the target (debuggee) process
|
||||
mlfSelfMem, // an address in this(the debuggers) process memory
|
||||
mlfSelfMem, // an address in this(the debuggers) process memory; the data is in TARGET format (endian, ...)
|
||||
// the below will be mapped (and extended) according to endianess
|
||||
mlfTargetRegister, // reads from the register
|
||||
mlfTargetRegisterSigned, // reads from the register and sign extends if needed (may be limited to 8 bytes)
|
||||
mlfConstant // an (up to) SizeOf(TDbgPtr) (=8) Bytes Value
|
||||
mlfConstant // an (up to) SizeOf(TDbgPtr) (=8) Bytes Value (endian in format of debug process)
|
||||
);
|
||||
|
||||
TFpDbgMemLocation = record
|
||||
@ -88,20 +90,46 @@ type
|
||||
function ReadMemoryEx(ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
||||
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean;
|
||||
|
||||
function ReadAddress(ALocation: TFpDbgMemLocation; ASize: Cardinal): TFpDbgMemLocation;
|
||||
function ReadAddressEx(ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal): TFpDbgMemLocation;
|
||||
|
||||
property MemConvertor: TFpDbgMemConvertor read FMemConvertor;
|
||||
end;
|
||||
|
||||
function NilLoc: TFpDbgMemLocation; inline;
|
||||
function InvalidLoc: TFpDbgMemLocation; inline;
|
||||
function TargetLoc(AnAddress: TDbgPtr): TFpDbgMemLocation; inline;
|
||||
function RegisterLoc(ARegNum: Cardinal): TFpDbgMemLocation; inline;
|
||||
function RegisterSignedLoc(ARegNum: Cardinal): TFpDbgMemLocation; inline;
|
||||
function SelfLoc(AnAddress: TDbgPtr): TFpDbgMemLocation; inline;
|
||||
function SelfLoc(AnAddress: Pointer): TFpDbgMemLocation; inline;
|
||||
function ConstLoc(AValue: QWord): TFpDbgMemLocation; inline;
|
||||
|
||||
function IsTargetAddr(ALocation: TFpDbgMemLocation): Boolean; inline;
|
||||
function LocToAddr(ALocation: TFpDbgMemLocation): TDbgPtr; inline;
|
||||
function IsValidLoc(ALocation: TFpDbgMemLocation): Boolean; inline; // Valid, Nil allowed
|
||||
function IsReadableLoc(ALocation: TFpDbgMemLocation): Boolean; inline; // Valid and not Nil
|
||||
function IsTargetNil(ALocation: TFpDbgMemLocation): Boolean; inline; // valid targed = nil
|
||||
function IsTargetNotNil(ALocation: TFpDbgMemLocation): Boolean; inline; // valid targed <> nil
|
||||
|
||||
function LocToAddr(ALocation: TFpDbgMemLocation): TDbgPtr; inline; // does not check valid
|
||||
function LocToAddrOrNil(ALocation: TFpDbgMemLocation): TDbgPtr; inline; // save version
|
||||
|
||||
function dbgs(ALocation: TFpDbgMemLocation): String; overload;
|
||||
|
||||
implementation
|
||||
|
||||
function NilLoc: TFpDbgMemLocation;
|
||||
begin
|
||||
Result.Address := 0;
|
||||
Result.MType := mlfTargetMem;
|
||||
end;
|
||||
|
||||
function InvalidLoc: TFpDbgMemLocation;
|
||||
begin
|
||||
Result.Address := 0;
|
||||
Result.MType := mlfInvalid;
|
||||
end;
|
||||
|
||||
function TargetLoc(AnAddress: TDbgPtr): TFpDbgMemLocation;
|
||||
begin
|
||||
Result.Address := AnAddress;
|
||||
@ -126,6 +154,12 @@ begin
|
||||
Result.MType := mlfSelfMem;
|
||||
end;
|
||||
|
||||
function SelfLoc(AnAddress: Pointer): TFpDbgMemLocation;
|
||||
begin
|
||||
Result.Address := TDbgPtr(AnAddress);
|
||||
Result.MType := mlfSelfMem;
|
||||
end;
|
||||
|
||||
function ConstLoc(AValue: QWord): TFpDbgMemLocation;
|
||||
begin
|
||||
Result.Address := AValue;
|
||||
@ -137,12 +171,52 @@ begin
|
||||
Result := ALocation.MType = mlfTargetMem;
|
||||
end;
|
||||
|
||||
function IsValidLoc(ALocation: TFpDbgMemLocation): Boolean;
|
||||
begin
|
||||
Result := (ALocation.MType <> mlfInvalid);
|
||||
end;
|
||||
|
||||
function IsReadableLoc(ALocation: TFpDbgMemLocation): Boolean;
|
||||
begin
|
||||
Result := (ALocation.MType <> mlfInvalid) and
|
||||
( (not(ALocation.MType in [mlfTargetMem, mlfSelfMem])) or
|
||||
(ALocation.Address <> 0)
|
||||
);
|
||||
end;
|
||||
|
||||
function IsTargetNil(ALocation: TFpDbgMemLocation): Boolean;
|
||||
begin
|
||||
Result := (ALocation.MType = mlfTargetMem) and (ALocation.Address = 0);
|
||||
end;
|
||||
|
||||
function IsTargetNotNil(ALocation: TFpDbgMemLocation): Boolean;
|
||||
begin
|
||||
Result := (ALocation.MType = mlfTargetMem) and (ALocation.Address <> 0);
|
||||
end;
|
||||
|
||||
function LocToAddr(ALocation: TFpDbgMemLocation): TDbgPtr;
|
||||
begin
|
||||
assert(ALocation.MType = mlfTargetMem, 'LocToAddr for other than mlfTargetMem');
|
||||
Result := ALocation.Address;
|
||||
end;
|
||||
|
||||
function LocToAddrOrNil(ALocation: TFpDbgMemLocation): TDbgPtr;
|
||||
begin
|
||||
if (ALocation.MType = mlfTargetMem) then
|
||||
Result := ALocation.Address
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function dbgs(ALocation: TFpDbgMemLocation): String;
|
||||
begin
|
||||
Result := '';
|
||||
if not (ALocation.MType in [low(TFpDbgMemLocationType)..high(TFpDbgMemLocationType)]) then
|
||||
Result := 'Location=out-of-range'
|
||||
else
|
||||
WriteStr(Result, 'Location=', ALocation.Address, ',', ALocation.MType)
|
||||
end;
|
||||
|
||||
{ TFpDbgMemConvertorLittleEndian }
|
||||
|
||||
procedure TFpDbgMemConvertorLittleEndian.AdjustIntPointer(var ADestPointer: Pointer;
|
||||
@ -194,6 +268,7 @@ var
|
||||
begin
|
||||
Result := False;
|
||||
case ALocation.MType of
|
||||
mlfInvalid: ;
|
||||
mlfTargetMem:
|
||||
Result := FMemReader.ReadMemory(ALocation.Address, ASize, ADest);
|
||||
mlfSelfMem:
|
||||
@ -252,5 +327,45 @@ begin
|
||||
Result := FMemReader.ReadRegister(ARegNum, AValue);
|
||||
end;
|
||||
|
||||
function TFpDbgMemManager.ReadAddress(ALocation: TFpDbgMemLocation;
|
||||
ASize: Cardinal): TFpDbgMemLocation;
|
||||
var
|
||||
Dest: PQWord;
|
||||
begin
|
||||
Assert(ASize < SizeOf(Result.Address), 'TFpDbgMemManager.ReadAddress');
|
||||
if ASize > SizeOf(Result.Address) then begin
|
||||
Result := InvalidLoc;
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result.Address := 0;
|
||||
Dest := @Result.Address;
|
||||
MemConvertor.AdjustIntPointer(Dest, ASize, SizeOf(Result.Address));
|
||||
if ReadMemory(ALocation, ASize, Dest) then
|
||||
Result.MType := mlfTargetMem
|
||||
else
|
||||
Result := InvalidLoc;
|
||||
end;
|
||||
|
||||
function TFpDbgMemManager.ReadAddressEx(ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr;
|
||||
ASize: Cardinal): TFpDbgMemLocation;
|
||||
var
|
||||
Dest: PQWord;
|
||||
begin
|
||||
Assert(ASize < SizeOf(Result.Address), 'TFpDbgMemManager.ReadAddress');
|
||||
if ASize > SizeOf(Result.Address) then begin
|
||||
Result := InvalidLoc;
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result.Address := 0;
|
||||
Dest := @Result.Address;
|
||||
MemConvertor.AdjustIntPointer(Dest, ASize, SizeOf(Result.Address));
|
||||
if ReadMemoryEx(ALocation, AnAddressSpace, ASize, Dest) then
|
||||
Result.MType := mlfTargetMem
|
||||
else
|
||||
Result := InvalidLoc;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -447,7 +447,7 @@ type
|
||||
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
||||
function GetTypeInfo: TDbgSymbol; override;
|
||||
function GetAsCardinal: QWord; override;
|
||||
function GetDataAddress: TDbgPtr; override;
|
||||
function GetDataAddress: TFpDbgMemLocation; override;
|
||||
public
|
||||
constructor Create(AValue: TDbgSymbolValue; ATypeInfo: TDbgSymbol);
|
||||
destructor Destroy; override;
|
||||
@ -477,13 +477,13 @@ type
|
||||
private
|
||||
FValue: TDbgSymbolValue;
|
||||
FExpression: TFpPascalExpression; // MemReader / AddrSize
|
||||
FCardinal: QWord;
|
||||
FCardinal: QWord; // todo: TFpDbgMemLocation ?
|
||||
FCardinalRead: Boolean;
|
||||
protected
|
||||
function DebugText(AIndent: String): String; override;
|
||||
protected
|
||||
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
||||
function GetAddress: TDbgPtr; override;
|
||||
function GetAddress: TFpDbgMemLocation; override;
|
||||
function GetSize: Integer; override;
|
||||
function GetAsCardinal: QWord; override; // reads men
|
||||
function GetTypeInfo: TDbgSymbol; override;
|
||||
@ -509,7 +509,7 @@ type
|
||||
function GetAsInteger: Int64; override;
|
||||
function GetAsCardinal: QWord; override;
|
||||
function GetTypeInfo: TDbgSymbol; override;
|
||||
function GetDataAddress: TDbgPtr; override;
|
||||
function GetDataAddress: TFpDbgMemLocation; override;
|
||||
public
|
||||
constructor Create(AValue: TDbgSymbolValue);
|
||||
destructor Destroy; override;
|
||||
@ -574,9 +574,9 @@ begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TPasParserSymbolValueCastToPointer.GetDataAddress: TDbgPtr;
|
||||
function TPasParserSymbolValueCastToPointer.GetDataAddress: TFpDbgMemLocation;
|
||||
begin
|
||||
Result := TDbgPtr(FValue.AsCardinal);
|
||||
Result := TargetLoc(TDbgPtr(FValue.AsCardinal));
|
||||
end;
|
||||
|
||||
constructor TPasParserSymbolValueCastToPointer.Create(AValue: TDbgSymbolValue;
|
||||
@ -656,13 +656,13 @@ begin
|
||||
if t <> nil then
|
||||
if t.Kind = skPointer then begin
|
||||
//Result := Result + [svfSizeOfPointer];
|
||||
Result := Result + [svfSizeOfPointer, svfCardinal, svfOrdinal];
|
||||
Result := Result + [svfSizeOfPointer, svfCardinal, svfOrdinal]; // TODO: svfCardinal ???
|
||||
end
|
||||
else
|
||||
Result := Result + [svfSize];
|
||||
end;
|
||||
|
||||
function TPasParserSymbolValueDerefPointer.GetAddress: TDbgPtr;
|
||||
function TPasParserSymbolValueDerefPointer.GetAddress: TFpDbgMemLocation;
|
||||
begin
|
||||
Result := FValue.DataAddress;
|
||||
end;
|
||||
@ -681,8 +681,8 @@ end;
|
||||
|
||||
function TPasParserSymbolValueDerefPointer.GetAsCardinal: QWord;
|
||||
var
|
||||
m: TFpDbgMemReaderBase;
|
||||
Addr: TDbgPtr;
|
||||
m: TFpDbgMemManager;
|
||||
Addr: TFpDbgMemLocation;
|
||||
Ctx: TDbgInfoAddressContext;
|
||||
AddrSize: Integer;
|
||||
begin
|
||||
@ -693,14 +693,14 @@ begin
|
||||
if Ctx = nil then exit;
|
||||
AddrSize := Ctx.SizeOfAddress;
|
||||
if (AddrSize <= 0) or (AddrSize > SizeOf(FCardinal)) then exit;
|
||||
m := Ctx.MemReader;
|
||||
m := Ctx.MemManager;
|
||||
if m = nil then exit;
|
||||
|
||||
FCardinal := 0;
|
||||
FCardinalRead := True;
|
||||
Addr := GetAddress;
|
||||
if Addr = 0 then exit;
|
||||
m.ReadMemory(Addr, Ctx.SizeOfAddress, @FCardinal);
|
||||
if not IsReadableLoc(Addr) then exit;
|
||||
FCardinal := LocToAddrOrNil(m.ReadAddress(Addr, Ctx.SizeOfAddress));
|
||||
|
||||
Result := FCardinal;
|
||||
end;
|
||||
@ -758,12 +758,12 @@ end;
|
||||
|
||||
function TPasParserSymbolValueAddressOf.GetAsInteger: Int64;
|
||||
begin
|
||||
Result := Int64(FValue.Address);
|
||||
Result := Int64(LocToAddrOrNil(FValue.Address));
|
||||
end;
|
||||
|
||||
function TPasParserSymbolValueAddressOf.GetAsCardinal: QWord;
|
||||
begin
|
||||
Result := QWord(FValue.Address);
|
||||
Result := QWord(LocToAddrOrNil(FValue.Address));
|
||||
end;
|
||||
|
||||
function TPasParserSymbolValueAddressOf.GetTypeInfo: TDbgSymbol;
|
||||
@ -779,7 +779,7 @@ begin
|
||||
Result := FTypeInfo;
|
||||
end;
|
||||
|
||||
function TPasParserSymbolValueAddressOf.GetDataAddress: TDbgPtr;
|
||||
function TPasParserSymbolValueAddressOf.GetDataAddress: TFpDbgMemLocation;
|
||||
begin
|
||||
Result := FValue.Address;
|
||||
end;
|
||||
@ -1878,7 +1878,7 @@ begin
|
||||
if Count <> 1 then exit;
|
||||
|
||||
tmp := Items[0].ResultValue;
|
||||
if (tmp = nil) or (tmp.Address = 0) then
|
||||
if (tmp = nil) or not IsTargetAddr(tmp.Address) then
|
||||
exit;
|
||||
|
||||
Result := TPasParserSymbolValueAddressOf.Create(tmp);
|
||||
@ -1958,7 +1958,7 @@ begin
|
||||
end
|
||||
else
|
||||
if tmp.Kind = skPointer then begin
|
||||
if (svfDataAddress in tmp.FieldFlags) and (tmp.DataAddress <> 0) and
|
||||
if (svfDataAddress in tmp.FieldFlags) and (IsReadableLoc(tmp.DataAddress)) and
|
||||
(tmp.TypeInfo <> nil) //and (tmp.TypeInfo.TypeInfo <> nil)
|
||||
then begin
|
||||
//TODO: maybe introduce a method TypeCastFromAddress, so we can skip the twp2 object
|
||||
|
@ -25,6 +25,7 @@ type
|
||||
FExpression: TFpPascalExpression;
|
||||
FImageLoader: TTestDummyImageLoader;
|
||||
FMemReader: TTestMemReader;
|
||||
FMemManager: TFpDbgMemManager;
|
||||
|
||||
procedure AssertEqualsQW(const AMessage: string; Expected, Actual: QWord);
|
||||
|
||||
@ -163,9 +164,9 @@ begin
|
||||
ExpFlags([Field]);
|
||||
WriteStr(s, FCurrentTestName, Field);
|
||||
case Field of
|
||||
svfAddress: AssertEqualsQW('VAlue for '+s, ExpValue, AVal.Address);
|
||||
svfAddress: AssertEqualsQW('VAlue for '+s, ExpValue, LocToAddrOrNil(AVal.Address));
|
||||
svfSize: AssertEqualsQW('VAlue for '+s, ExpValue, AVal.Size);
|
||||
svfDataAddress: AssertEqualsQW('VAlue for '+s, ExpValue, AVal.DataAddress);
|
||||
svfDataAddress: AssertEqualsQW('VAlue for '+s, ExpValue, LocToAddrOrNil(AVal.DataAddress));
|
||||
svfDataSize: AssertEqualsQW('VAlue for '+s, ExpValue, AVal.DataSize);
|
||||
svfInteger: AssertEqualsQW('VAlue for '+s, ExpValue, AVal.AsInteger);
|
||||
svfCardinal: AssertEqualsQW('VAlue for '+s, ExpValue, AVal.AsCardinal);
|
||||
@ -182,9 +183,9 @@ begin
|
||||
ExpFlags([Field]);
|
||||
WriteStr(s, FCurrentTestName, Field);
|
||||
case Field of
|
||||
svfAddress: AssertEquals('VAlue for '+s, ExpValue, AVal.Address);
|
||||
svfAddress: AssertEquals('VAlue for '+s, ExpValue, LocToAddrOrNil(AVal.Address));
|
||||
svfSize: AssertEquals('VAlue for '+s, ExpValue, AVal.Size);
|
||||
svfDataAddress: AssertEquals('VAlue for '+s, ExpValue, AVal.DataAddress);
|
||||
svfDataAddress: AssertEquals('VAlue for '+s, ExpValue, LocToAddrOrNil(AVal.DataAddress));
|
||||
svfDataSize: AssertEquals('VAlue for '+s, ExpValue, AVal.DataSize);
|
||||
svfInteger: AssertEquals('VAlue for '+s, ExpValue, AVal.AsInteger);
|
||||
svfCardinal: AssertEquals('VAlue for '+s, ExpValue, AVal.AsCardinal);
|
||||
@ -314,9 +315,10 @@ procedure TTestTypeInfo.InitDwarf(ALoaderClass: TTestDummyImageLoaderClass);
|
||||
begin
|
||||
FImageLoader := ALoaderClass.Create;
|
||||
FMemReader := TTestMemReader.Create;
|
||||
FMemManager := TFpDbgMemManager.Create(FMemReader, TFpDbgMemConvertorLittleEndian.Create);
|
||||
FDwarfInfo := TDbgDwarf.Create(FImageLoader);
|
||||
FDwarfInfo.MemManager := FMemManager;
|
||||
FDwarfInfo.LoadCompilationUnits;
|
||||
FDwarfInfo.MemReader := FMemReader;
|
||||
end;
|
||||
|
||||
procedure TTestTypeInfo.SetUp;
|
||||
@ -324,6 +326,7 @@ begin
|
||||
inherited SetUp;
|
||||
FImageLoader := nil;
|
||||
FMemReader := nil;
|
||||
FMemManager := nil;
|
||||
FDwarfInfo := nil;
|
||||
FCurrentTestName := '';
|
||||
FCurrentContext := nil;
|
||||
@ -337,6 +340,9 @@ begin
|
||||
FDwarfInfo.Free;
|
||||
FImageLoader.Free;
|
||||
FMemReader.Free;
|
||||
if FMemManager <> nil then
|
||||
FMemManager.MemConvertor.Free;
|
||||
FreeAndNil(FMemManager);
|
||||
inherited TearDown;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user