FPDebug: testcase

git-svn-id: trunk@43867 -
This commit is contained in:
martin 2014-02-02 23:33:29 +00:00
parent 627e03971e
commit 513a42d90d
7 changed files with 2943 additions and 210 deletions

1
.gitattributes vendored
View File

@ -1276,6 +1276,7 @@ components/fpdebug/test/asmtest.lpi svneol=native#text/plain
components/fpdebug/test/asmtest.lpr svneol=native#text/pascal
components/fpdebug/test/asmtestunit.lfm svneol=native#text/plain
components/fpdebug/test/asmtestunit.pas svneol=native#text/pascal
components/fpdebug/test/testdwarfsetup1.pas svneol=native#text/pascal
components/fpdebug/test/testhelperclasses.pas svneol=native#text/pascal
components/fpdebug/test/testpascalparser.pas svneol=native#text/pascal
components/fpdebug/test/testtypeinfo.pas svneol=native#text/pascal

View File

@ -299,6 +299,7 @@ type
FData: PByte;
FMaxData: PByte;
public
//TODO: caller keeps data, and determines livetime of data
constructor Create(AExpressionData: Pointer; AMaxCount: Integer; ACU: TDwarfCompilationUnit);
procedure Evaluate;
function ResultKind: TDwarfLocationStackEntryKind;

View File

@ -42,7 +42,7 @@
<PackageName Value="FCL"/>
</Item4>
</RequiredPackages>
<Units Count="3">
<Units Count="5">
<Unit0>
<Filename Value="FpTest.lpr"/>
<IsPartOfProject Value="True"/>
@ -58,6 +58,16 @@
<IsPartOfProject Value="True"/>
<UnitName Value="TestTypeInfo"/>
</Unit2>
<Unit3>
<Filename Value="testhelperclasses.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="TestHelperClasses"/>
</Unit3>
<Unit4>
<Filename Value="testdwarfsetup1.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="TestDwarfSetup1"/>
</Unit4>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -3,7 +3,8 @@ program FpTest;
{$mode objfpc}{$H+}
uses
Interfaces, Forms, GuiTestRunner, TestPascalParser, TestTypeInfo, TestHelperClasses;
Interfaces, Forms, GuiTestRunner, TestPascalParser, TestTypeInfo, TestHelperClasses,
TestDwarfSetup1;
{$R *.res}

File diff suppressed because one or more lines are too long

View File

@ -5,10 +5,23 @@ unit TestHelperClasses;
interface
uses
Classes, SysUtils, FpImgReaderBase, FpDbgDwarfConst, FpDbgLoader;
Classes, SysUtils, FpImgReaderBase, FpDbgDwarfConst, FpDbgLoader, FpDbgInfo;
const
TestAddrSize = sizeof(Pointer);
type
{ TTestMemReader }
TTestMemReader = class(TFpDbgMemReaderBase)
public
RegisterValues: array[0..30] of TDbgPtr;
function ReadMemory(AnAddress: FpDbgInfo.TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace: FpDbgInfo.TDbgPtr; {%H-}ASize: Cardinal; {%H-}ADest: Pointer): Boolean; override;
function ReadRegister(ARegNum: Integer; out AValue: FpDbgInfo.TDbgPtr): Boolean; override;
end;
TTestDwarfAbbrev = class;
TTestDwarfInfoEntry = class;
@ -20,56 +33,6 @@ type
procedure CreateSectionData; virtual;
end;
{ TTestDummySectionAbbrevs }
TTestDummySectionAbbrevs = class(TTestDummySection)
private
FCurrentID: Cardinal;
FList: TList;
function GetNextID: Cardinal;
public
constructor Create;
destructor Destroy; override;
function GetNewAbbrevObj: TTestDwarfAbbrev;
procedure CreateSectionData; override;
end;
(*
TDwarfCUHeader32 = record
Length: LongWord;
Version: Word;
AbbrevOffset: LongWord;
AddressSize: Byte;
end;
TDwarfCUHeader64 = record
Signature: LongWord;
Length: QWord;
Version: Word;
AbbrevOffset: QWord;
AddressSize: Byte;
end;
*)
{ TTestDummySectionInfoEntries }
TTestDummySectionInfoEntries = class(TTestDummySection)
private
FAddrSize: Byte;
FFirstEntry: TTestDwarfInfoEntry;
FVersion: Word;
protected
function CreateInfoEntryObj: TTestDwarfInfoEntry;
public
AbbrevSection: TTestDummySectionAbbrevs;
constructor Create;
destructor Destroy; override;
property Version: Word read FVersion write FVersion;
property AddrSize: Byte read FAddrSize write FAddrSize;
function GetFirstInfoEntryObj: TTestDwarfInfoEntry;
procedure CreateSectionData; override;
end;
{ TTestDummyFileSource }
TTestDummyFileSource = class(TDbgImageReader)
@ -95,10 +58,42 @@ type
FImgReader: TTestDummyFileSource;
protected
public
constructor Create; virtual;
constructor Create; override;
property TestImgReader: TTestDummyFileSource read FImgReader;
end;
{ TTestDummySectionAbbrevs }
TTestDummySectionAbbrevs = class(TTestDummySection)
private
FCurrentID: Cardinal;
FList: TList;
function GetNextID: Cardinal;
public
constructor Create;
destructor Destroy; override;
function GetNewAbbrevObj: TTestDwarfAbbrev;
procedure CreateSectionData; override;
end;
{ TTestDummySectionInfoEntries }
TTestDummySectionInfoEntries = class(TTestDummySection)
private
FAddrSize: Byte;
FFirstEntry: TTestDwarfInfoEntry;
FVersion: Word;
protected
function CreateInfoEntryObj: TTestDwarfInfoEntry;
public
AbbrevSection: TTestDummySectionAbbrevs;
constructor Create;
destructor Destroy; override;
property Version: Word read FVersion write FVersion;
property AddrSize: Byte read FAddrSize write FAddrSize;
function GetFirstInfoEntryObj: TTestDwarfInfoEntry;
procedure CreateSectionData; override;
end;
{ TTestDwarfAbbrev }
@ -122,6 +117,7 @@ type
{ TTestDwarfInfoEntry }
PTestDwarfInfoEntry = ^TTestDwarfInfoEntry;
TTestDwarfInfoEntry = class
private
FAbbrevObj: TTestDwarfAbbrev;
@ -131,6 +127,7 @@ type
FRefList: array of record
Index, FSize: Integer;
AData: TTestDwarfInfoEntry;
ADataRef: PTestDwarfInfoEntry;
end;
function GetChildren: Byte;
function GetTag: Cardinal;
@ -155,6 +152,7 @@ type
procedure AddAddr(AnAttrib, AForm: Cardinal; AData: QWord);
procedure Add(AnAttrib, AForm: Cardinal; AData: QWord); // ULEB
function AddRef(AnAttrib, AForm: Cardinal; AData: TTestDwarfInfoEntry): Integer;
function AddRef(AnAttrib, AForm: Cardinal; AData: PTestDwarfInfoEntry): Integer;
procedure SetRef(AIndex: Integer; AData: TTestDwarfInfoEntry);
@ -163,8 +161,105 @@ type
function Data: Pointer;
end;
function ULEB(ANum: QWord): TBytes;
function SLEB(ANum: Int64): TBytes;
function AddrB(ANum: Int64): TBytes;
function NumS(ANum: Int64; ASize: Integer): TBytes;
function NumU(ANum: QWord; ASize: Integer): TBytes;
function Bytes(a: Array of TBytes): TBytes;
function BytesLen1(a: Array of TBytes): TBytes;
function BytesLen2(a: Array of TBytes): TBytes;
function BytesLen4(a: Array of TBytes): TBytes;
function BytesLen8(a: Array of TBytes): TBytes;
function BytesLenU(a: Array of TBytes): TBytes;
operator := (a: Smallint) b: TBytes;
implementation
operator := (a: Smallint)b: TBytes;
begin
assert( (a>= -128) and (a<=255));
SetLength(b, 1);
b[0] := Byte(a and 255);
end;
function Bytes(a: array of TBytes): TBytes;
var
i, l, p: Integer;
begin
l := 0;
for i := low(a) to high(a) do
l := l + Length(a[i]);
SetLength(Result, l);
p := 0;
for i := low(a) to high(a) do begin
l := Length(a[i]);
if l > 0 then
move(a[i][0], Result[p], l*SizeOf(Result[0]));
inc(p, l);
end;
end;
function BytesLen1(a: array of TBytes): TBytes;
var
l: Integer;
d: TBytes;
begin
d := Bytes(a);
l := Length(d);
assert(l <= $ff);
Result := Bytes([Byte(l), d]);
end;
function BytesLen2(a: array of TBytes): TBytes;
var
l: Integer;
b: array[0..1] of Byte;
d: TBytes;
begin
d := Bytes(a);
l := Length(d);
assert(l <= $ffff);
PWord(@b[0])^ := Word(l);
Result := Bytes([b[0], b[1], Bytes(d)]);
end;
function BytesLen4(a: array of TBytes): TBytes;
var
l: Integer;
b: array[0..3] of Byte;
d: TBytes;
begin
d := Bytes(a);
l := Length(d);
assert(l <= $ffff);
PDWord(@b[0])^ := DWord(l);
Result := Bytes([b[0], b[1], b[2], b[3], Bytes(d)]);
end;
function BytesLen8(a: array of TBytes): TBytes;
var
l: Integer;
b: array[0..7] of Byte;
d: TBytes;
begin
d := Bytes(a);
l := Length(d);
assert(l <= $ffff);
PQWord(@b[0])^ := QWord(l);
Result := Bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], Bytes(d)]);
end;
function BytesLenU(a: array of TBytes): TBytes;
var
l: Integer;
begin
l := Length(a);
Result := Bytes([ULEB(l), Bytes(a)]);
end;
procedure WriteULEB128(ANum: QWord; var ADest: TBytes; ADestIdx: Integer);
procedure AddByte(AByte: Byte);
begin
@ -197,30 +292,32 @@ procedure WriteSLEB128(ANum: Int64; var ADest: TBytes; ADestIdx: Integer);
var
n: Integer;
c: Boolean;
UNum: QWord;
begin
if ANum = 0 then begin
AddByte(0);
exit;
end;
if ANum < 0 then begin;
n := 10*7;
if ANum < 0 then begin
UNum := QWord(ANum);
n := 9*7;
while n > 0 do begin
if (ANum and ($7f shl n) = (Int64(-1) and ($7f shl n)) ) and
(ANum and (int64(1) shl (n-1)) <> 0)
if ( (UNum and (QWord($7f) shl n)) = (high(QWord) and (QWord($7f) shl n)) ) and
( (UNum and (QWord(1) shl (n-1))) <> 0 )
then
ANum := ANum and not(-1 shl n)
UNum := UNum and not(high(QWord) shl n)
else
break;
dec(n, 7);
end;
while ANum <> 0 do begin
if ANum > $7f then
AddByte((ANum and $7f) + $80)
while UNum <> 0 do begin
if UNum > $7f then
AddByte((UNum and $7f) + $80)
else
AddByte((ANum and $7f));
ANum := ANum shr 7;
AddByte((UNum and $7f));
UNum := UNum shr 7;
end;
end
@ -232,13 +329,76 @@ begin
AddByte((ANum and $7f) + $80)
else
AddByte((ANum and $7f));
c := (ANum and $40) <> 0; // write extra 0, to prlevent sign extend
c := (ANum and $40) <> 0; // write extra 0, to prevent sign extend
ANum := ANum shr 7;
end;
end;
end;
function ULEB(ANum: QWord): TBytes;
begin
SetLength(Result, 0);
WriteULEB128(ANum, Result, 0);
end;
function SLEB(ANum: Int64): TBytes;
begin
SetLength(Result, 0);
WriteSLEB128(ANum, Result, 0);
end;
function AddrB(ANum: Int64): TBytes;
begin
SetLength(Result, TestAddrSize);
if TestAddrSize = 4
then PInteger(@Result[0])^ := Integer(ANum)
else PInt64(@Result[0])^ := Int64(ANum);
end;
function NumS(ANum: Int64; ASize: Integer): TBytes;
begin
SetLength(Result, ASize);
case ASize of
1: PShortInt(@Result[0])^ := ShortInt(ANum);
2: PSmallInt(@Result[0])^ := SmallInt(ANum);
4: PInteger(@Result[0])^ := Integer(ANum);
8: PInt64(@Result[0])^ := Int64(ANum);
end;
end;
function NumU(ANum: QWord; ASize: Integer): TBytes;
begin
SetLength(Result, ASize);
case ASize of
1: PByte(@Result[0])^ := Byte(ANum);
2: PWord(@Result[0])^ := Word(ANum);
4: PDWord(@Result[0])^ := DWord(ANum);
8: PQWord(@Result[0])^ := QWord(ANum);
end;
end;
{ TTestMemReader }
function TTestMemReader.ReadMemory(AnAddress: FpDbgInfo.TDbgPtr; ASize: Cardinal;
ADest: Pointer): Boolean;
begin
Result := True;
Move(Pointer(AnAddress)^, ADest^, ASize);
end;
function TTestMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: FpDbgInfo.TDbgPtr;
ASize: Cardinal; ADest: Pointer): Boolean;
begin
Result := False;
end;
function TTestMemReader.ReadRegister(ARegNum: Integer; out AValue: FpDbgInfo.TDbgPtr): Boolean;
begin
Result := True;
AValue := RegisterValues[ARegNum];
end;
{ TTestDwarfInfoEntry }
procedure TTestDwarfInfoEntry.InitEncoded;
@ -302,9 +462,14 @@ procedure TTestDwarfInfoEntry.WriteToSectionFIxRef(ASectionMem: PByte);
var
i: Integer;
v: Integer;
o: TTestDwarfInfoEntry;
begin
for i := 0 to Length(FRefList) - 1 do begin
v := FRefList[i].AData.FWrittenAtIndex;
assert((FRefList[i].AData <> nil) xor (FRefList[i].ADataRef <> nil));
o := FRefList[i].AData;
if (o = nil) then
o := FRefList[i].ADataRef^;
v := o.FWrittenAtIndex;
case FRefList[i].FSize of
1: PByte(ASectionMem + FWrittenAtIndex + FRefList[i].Index)^ := v;
2: PWord(ASectionMem + FWrittenAtIndex + FRefList[i].Index)^ := v;
@ -405,7 +570,7 @@ begin
Result := length(FRefList);
SetLength(FRefList, Result + 1);
l := 4;
l := TestAddrSize;
case AForm of
DW_FORM_ref1: l := 1;
DW_FORM_ref2: l := 2;
@ -430,6 +595,43 @@ begin
end;
end;
function TTestDwarfInfoEntry.AddRef(AnAttrib, AForm: Cardinal;
AData: PTestDwarfInfoEntry): Integer;
var
c: Integer;
l: Integer;
begin
if Length(FEncoded) = 0 then InitEncoded;
FAbbrevObj.Add(AnAttrib, AForm);
Result := length(FRefList);
SetLength(FRefList, Result + 1);
l := TestAddrSize;
case AForm of
DW_FORM_ref1: l := 1;
DW_FORM_ref2: l := 2;
DW_FORM_ref4: l := 4;
DW_FORM_ref8: l := 8;
DW_FORM_ref_addr: l := FSection.AddrSize;
//DW_FORM_ref_udata: l := 1;
else Assert(false);
end;
FRefList[Result].ADataRef := AData;
FRefList[Result].FSize := l;
FRefList[Result].Index := length(FEncoded);
c := Length(FEncoded);
SetLength(FEncoded, c + l);
case l of
1: PByte(@FEncoded[c])^ := 0;
2: PWord(@FEncoded[c])^ := 0;
4: PCardinal(@FEncoded[c])^ := 0;
8: PQWord(@FEncoded[c])^ := 0;
end;
end;
procedure TTestDwarfInfoEntry.SetRef(AIndex: Integer; AData: TTestDwarfInfoEntry);
begin
FRefList[AIndex].AData := AData;
@ -467,7 +669,7 @@ end;
constructor TTestDummySectionInfoEntries.Create;
begin
FVersion := 2;
FAddrSize := 4;
FAddrSize := TestAddrSize;
end;
destructor TTestDummySectionInfoEntries.Destroy;

View File

@ -5,12 +5,10 @@ unit TestTypeInfo;
interface
uses
Classes, SysUtils, FpPascalParser, FpDbgDwarf, FpDbgInfo, FpDbgLoader, FpPascalBuilder,
FpDbgUtil, FpDbgDwarfConst, FileUtil, LazLoggerBase, LazUTF8, fpcunit, testutils,
testregistry, TestHelperClasses;
FpPascalParser, FpDbgDwarf, FpDbgInfo,
FpDbgUtil, FpDbgDwarfConst, LazLoggerBase, LazUTF8, sysutils, fpcunit,
testregistry, TestHelperClasses, TestDwarfSetup1;
const
TESTPROG1_FUNC_BAR_LINE = 185;
type
@ -25,17 +23,6 @@ type
constructor Create(ATextExpression: String; AContext: TDbgInfoAddressContext);
end;
{ TTestMemReader }
TTestMemReader = class(TFpDbgMemReaderBase)
public
RegisterValues: array[0..30] of TDbgPtr;
function ReadMemory(AnAddress: FpDbgInfo.TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace: FpDbgInfo.TDbgPtr; {%H-}ASize: Cardinal; {%H-}ADest: Pointer): Boolean; override;
function ReadRegister(ARegNum: Integer; out AValue: FpDbgInfo.TDbgPtr): Boolean; override;
end;
{ TTestTypInfo }
TTestTypInfo = class(TTestCase)
@ -48,27 +35,6 @@ type
implementation
{ TTestMemReader }
function TTestMemReader.ReadMemory(AnAddress: FpDbgInfo.TDbgPtr; ASize: Cardinal;
ADest: Pointer): Boolean;
begin
Result := True;
Move(Pointer(AnAddress)^, ADest^, ASize);
end;
function TTestMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: FpDbgInfo.TDbgPtr;
ASize: Cardinal; ADest: Pointer): Boolean;
begin
Result := False;
end;
function TTestMemReader.ReadRegister(ARegNum: Integer; out AValue: FpDbgInfo.TDbgPtr): Boolean;
begin
Result := True;
AValue := RegisterValues[ARegNum];
end;
{ TTestPascalExpression }
function TTestPascalExpression.GetDbgSymbolForIdentifier(AnIdent: String): TDbgSymbol;
@ -97,132 +63,222 @@ end;
procedure TTestTypInfo.New1;
var
ImageLoader: TTestDummyImageLoader;
SectionDbgInfo: TTestDummySectionInfoEntries;
CompUnit, Prog1, Prog2,
GlobVar1, TypeInt, TypeIntDecl: TTestDwarfInfoEntry;
ImageLoader: TTestLoaderSetup1;
MemReader: TTestMemReader;
Ctx: TDbgInfoAddressContext;
sym: TDbgSymbol;
MemReader: TTestMemReader;
TestStackFrame: record
AVal: Integer; // -8
AVal2: Integer; // -4
EndPoint: Cardinal;
end;
obj1: TTestSetup1Class;
vobj1: TTestSetup1Object;
Expression: TTestPascalExpression;
begin
ImageLoader := TTestDummyImageLoader.Create;
SectionDbgInfo := ImageLoader.TestImgReader.TestSection['.debug_info'] as TTestDummySectionInfoEntries;
ImageLoader := TTestLoaderSetup1.Create;
{%region}
CompUnit := SectionDbgInfo.GetFirstInfoEntryObj;
CompUnit.Tag := DW_TAG_compile_unit;
CompUnit.Children := 1; //DW_CHILDREN_yes
CompUnit.Add(DW_AT_name, DW_FORM_string, 'testprog1.pas'+#0);
CompUnit.Add(DW_AT_producer, DW_FORM_string, 'Free Pascal 2.6.2 2013/02/16'+#0);
CompUnit.Add(DW_AT_comp_dir, DW_FORM_string, 'B:/lazarus_latest/components/fpdebug/test/testapps/'+#0);
CompUnit.Add(DW_AT_language, DW_FORM_data1, [$09]);
CompUnit.Add(DW_AT_identifier_case, DW_FORM_data1, [$03]);
CompUnit.Add(DW_AT_stmt_list, DW_FORM_data4, [$00, $00, $00, $00]);
CompUnit.AddAddr(DW_AT_low_pc, DW_FORM_addr, $00400000);
CompUnit.AddAddr(DW_AT_high_pc, DW_FORM_addr, $00501A50);
Prog1 := CompUnit.GetNewChild;
Prog1.Tag := DW_TAG_subprogram;
Prog1.Children := 1;
Prog1.Add(DW_AT_name, DW_FORM_string, 'BAR'+#0);
Prog1.Add(DW_AT_prototyped, DW_FORM_flag, [$01]);
Prog1.Add(DW_AT_calling_convention, DW_FORM_data1, [$41]);
Prog1.Add(DW_AT_external, DW_FORM_flag, [$01]);
Prog1.AddAddr(DW_AT_low_pc, DW_FORM_addr, $00401000);
Prog1.AddAddr(DW_AT_high_pc, DW_FORM_addr, $00402000);
Prog2 := CompUnit.GetNewChild;
Prog2.Tag := DW_TAG_subprogram;
Prog2.Children := 0;
Prog2.Add(DW_AT_name, DW_FORM_string, 'BAR2'+#0);
Prog2.Add(DW_AT_prototyped, DW_FORM_flag, [$01]);
Prog2.Add(DW_AT_calling_convention, DW_FORM_data1, [$41]);
Prog2.Add(DW_AT_external, DW_FORM_flag, [$01]);
Prog2.AddAddr(DW_AT_low_pc, DW_FORM_addr, $00403000);
Prog2.AddAddr(DW_AT_high_pc, DW_FORM_addr, $00404000);
obj1 := TTestSetup1Class.Create;
ImageLoader.TestStackFrame.Int1 := -299;
ImageLoader.TestStackFrame.Rec1.FWord := 1021;
ImageLoader.TestStackFrame.VObj1 := @vobj1;
ImageLoader.TestStackFrame.Obj1 := obj1;
TypeInt := CompUnit.GetNewChild;
TypeInt.Tag := DW_TAG_base_type;
TypeInt.Children := 0;
TypeInt.Add(DW_AT_name, DW_FORM_string, 'LONGINT'+#0);
TypeInt.Add(DW_AT_encoding, DW_FORM_data1, [$05]);
TypeInt.Add(DW_AT_byte_size, DW_FORM_data1, [$04]);
TypeIntDecl := CompUnit.GetNewChild;
TypeIntDecl.Tag := DW_TAG_typedef;
TypeIntDecl.Children := 0;
TypeIntDecl.Add(DW_AT_name, DW_FORM_string, 'LONGINT'+#0);
TypeIntDecl.AddRef(DW_AT_type, DW_FORM_ref4, TypeInt); // $7A, $06, $00, $00
GlobVar1 := CompUnit.GetNewChild;
GlobVar1.Tag := DW_TAG_variable;
GlobVar1.Children := 0;
GlobVar1.Add(DW_AT_name, DW_FORM_string, 'INT1'+#0);
GlobVar1.Add(DW_AT_location, DW_FORM_block1, [$02, $75, $78]); // DW_OP_breg5-8
GlobVar1.AddRef(DW_AT_type, DW_FORM_ref4, TypeIntDecl);
{%endregion}
TestStackFrame.AVal := -299;
SectionDbgInfo.CreateSectionData;
SectionDbgInfo.AbbrevSection.CreateSectionData;
MemReader := TTestMemReader.Create;
MemReader.RegisterValues[5] := TDbgPtr(@TestStackFrame.EndPoint);
//////////////////////////////////////////////////////////
MemReader.RegisterValues[5] := TDbgPtr(@ImageLoader.TestStackFrame.EndPoint);
Ctx := nil;
FDwarfInfo := TDbgDwarf.Create(ImageLoader);
FDwarfInfo.LoadCompilationUnits;
FDwarfInfo.MemReader := MemReader;
try
FDwarfInfo.LoadCompilationUnits;
FDwarfInfo.MemReader := MemReader;
//////////////////////////////////////////////////////////
Ctx := FDwarfInfo.FindContext($00401010);
AssertTrue('got ctx', Ctx <> nil);
Ctx := FDwarfInfo.FindContext($00401010);
AssertTrue('got ctx', Ctx <> nil);
sym := Ctx.FindSymbol('Int1');
AssertTrue('got sym', sym <> nil);
sym.ReleaseReference();
sym := Ctx.FindSymbol('Int1');
AssertTrue('got sym', sym <> nil);
sym.ReleaseReference();
Expression := TTestPascalExpression.Create('Int1', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(Expression.ResultValue.AsInteger, -299 );
Expression.Free;
Expression := TTestPascalExpression.Create('Int1', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(-299, Expression.ResultValue.AsInteger);
Expression.Free;
Expression := TTestPascalExpression.Create('@Int1', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(Expression.ResultValue.AsInteger, PtrInt(@TestStackFrame.AVal));
Expression.Free;
Expression := TTestPascalExpression.Create('@Int1', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(PtrInt(@ImageLoader.TestStackFrame.Int1), Expression.ResultValue.AsInteger);
Expression.Free;
Expression := TTestPascalExpression.Create('@Int1^', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(Expression.ResultValue.AsInteger, -299 );
Expression.Free;
Expression := TTestPascalExpression.Create('@Int1^', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(-299, Expression.ResultValue.AsInteger);
Expression.Free;
Expression := TTestPascalExpression.Create('(@Int1)^', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(Expression.ResultValue.AsInteger, -299 );
Expression.Free;
Expression := TTestPascalExpression.Create('(@Int1)^', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(-299, Expression.ResultValue.AsInteger);
Expression.Free;
// Class/Object
Expression := TTestPascalExpression.Create('Obj1', Ctx);
AssertTrue(Expression.Valid);
Expression.ResultValue; // just access it
Expression.Free;
Obj1.FWord := 1019;
Expression := TTestPascalExpression.Create('Obj1.FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('TTestSetup1Class(Obj1).FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('Obj1.FTest', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
Expression.Free;
Expression := TTestPascalExpression.Create('TTestSetup1Class(Obj1).FTest', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
Expression.Free;
obj1.FTest := obj1;
Expression := TTestPascalExpression.Create('Obj1.FTest.FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('TTestSetup1Class(Obj1).FTest.FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('TTestSetup1Class(TTestSetup1Class(Obj1).FTest).FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('Obj1.NotExisting', Ctx);
if Expression.Valid then;
Expression.ResultValue; // just access it
Expression.Free;
Expression := TTestPascalExpression.Create('TObject(Obj1).FWord', Ctx);
if Expression.Valid then;
Expression.ResultValue; // just access it
Expression.Free;
// @
Expression := TTestPascalExpression.Create('@Obj1', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
//TODO
//AssertEquals(PtrUint(@obj1), Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('@Obj1.FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(PtrUint(@obj1.FWord), Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('@Obj1.FTest', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
//TODO
//AssertEquals(PtrUint(@obj1), Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('@Obj1.FWord^', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('(@Obj1^).FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('@(Obj1.FWord)^', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1019, Expression.ResultValue.AsCardinal);
Expression.Free;
// Record
Expression := TTestPascalExpression.Create('Rec1', Ctx);
AssertTrue(Expression.Valid);
Expression.ResultValue; // just access it
Expression.Free;
Expression := TTestPascalExpression.Create('Rec1.FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1021, Expression.ResultValue.AsInteger);
Expression.Free;
// var param // old style object
vobj1.FWord := 1122;
vobj1.FInt := -122;
Expression := TTestPascalExpression.Create('vobj1', Ctx);
AssertTrue(Expression.Valid);
Expression.ResultValue; // just access it
Expression.Free;
Expression := TTestPascalExpression.Create('vobj1.FWord', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(1122, Expression.ResultValue.AsCardinal);
Expression.Free;
Expression := TTestPascalExpression.Create('vobj1.FInt', Ctx);
AssertTrue(Expression.Valid);
AssertTrue(Expression.ResultValue <> nil);
AssertEquals(-122, Expression.ResultValue.AsInteger);
Expression.Free;
// Not existing
Expression := TTestPascalExpression.Create('NotExisting1399', Ctx);
//AssertTrue(Expression.Valid);
if Expression.Valid then;
Expression.ResultValue; // just access it
Expression.Free;
// Not Existing Typecast
Expression := TTestPascalExpression.Create('TNotExisting1399(Int1)', Ctx);
//AssertTrue(Expression.Valid);
if Expression.Valid then;
Expression.ResultValue; // just access it
Expression.Free;
Ctx.ReleaseReference;
///////////////////////////
FDwarfInfo.Free;
ImageLoader.Free;
MemReader.Free;
finally
Ctx.ReleaseReference;
FDwarfInfo.Free;
ImageLoader.Free;
MemReader.Free;
obj1.Free;
end;
end;