mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-11 17:55:55 +02:00
FpDebug: Allow LocationParser (dwarf loc expressions) to work with mlfSelfMem (for constants which have their value in the dwarf headers, rather than the process mem)
git-svn-id: trunk@61451 -
This commit is contained in:
parent
4d779b1188
commit
7f8306fad7
@ -2919,7 +2919,7 @@ begin
|
||||
debugln(FPDBG_DWARF_VERBOSE, ['TFpDwarfSymbol.InitLocationParser CurrentObjectAddress=', dbgs(AnInitLocParserData^.ObjectDataAddress), ' Push=',AnInitLocParserData^.ObjectDataAddrPush]);
|
||||
ALocationParser.CurrentObjectAddress := AnInitLocParserData^.ObjectDataAddress;
|
||||
if AnInitLocParserData^.ObjectDataAddrPush then
|
||||
ALocationParser.Push(AnInitLocParserData^.ObjectDataAddress, lseValue);
|
||||
ALocationParser.Push(AnInitLocParserData^.ObjectDataAddress);
|
||||
end
|
||||
else
|
||||
ALocationParser.CurrentObjectAddress := InvalidLoc;
|
||||
@ -2961,19 +2961,11 @@ begin
|
||||
if IsError(LocationParser.LastError) then
|
||||
SetLastError(LocationParser.LastError);
|
||||
|
||||
if LocationParser.ResultKind in [lseValue] then begin
|
||||
AnAddress := TargetLoc(LocationParser.ResultData);// TODO: wrong, if origin was selfmem
|
||||
if ATag=DW_AT_location then
|
||||
AnAddress.Address :=CompilationUnit.MapAddressToNewValue(AnAddress.Address);
|
||||
Result := True;
|
||||
end
|
||||
else
|
||||
if LocationParser.ResultKind in [lseRegister] then begin
|
||||
AnAddress := ConstLoc(LocationParser.ResultData);
|
||||
Result := True;
|
||||
end
|
||||
else
|
||||
debugln(['TDbgDwarfIdentifier.LocationFromTag FAILED']); // TODO
|
||||
AnAddress := LocationParser.ResultData;
|
||||
Result := IsValidLoc(AnAddress);
|
||||
if IsTargetAddr(AnAddress) and (ATag=DW_AT_location) then
|
||||
AnAddress.Address :=CompilationUnit.MapAddressToNewValue(AnAddress.Address);
|
||||
debugln(not Result, ['TDbgDwarfIdentifier.LocationFromTag FAILED']); // TODO
|
||||
|
||||
LocationParser.Free;
|
||||
end;
|
||||
@ -4761,6 +4753,7 @@ end;
|
||||
function TFpDwarfSymbolValueProc.GetFrameBase(ASender: TDwarfLocationExpression): TDbgPtr;
|
||||
var
|
||||
Val: TByteDynArray;
|
||||
rd: TFpDbgMemLocation;
|
||||
begin
|
||||
Result := 0;
|
||||
if FFrameBaseParser = nil then begin
|
||||
@ -4781,8 +4774,9 @@ begin
|
||||
FFrameBaseParser.Evaluate;
|
||||
end;
|
||||
|
||||
if FFrameBaseParser.ResultKind in [lseValue] then
|
||||
Result := FFrameBaseParser.ResultData;
|
||||
rd := FFrameBaseParser.ResultData;
|
||||
if IsValidLoc(rd) then
|
||||
Result := rd.Address;
|
||||
|
||||
if IsError(FFrameBaseParser.LastError) then begin
|
||||
SetLastError(FFrameBaseParser.LastError);
|
||||
|
@ -670,36 +670,26 @@ type
|
||||
|
||||
{ TDwarfLocationStack }
|
||||
|
||||
TDwarfLocationStackEntryKind = (
|
||||
lseRegister, // value copied from register (data is in register)
|
||||
lseValue, // unsigned number, or address at which value can be found
|
||||
lsePart, // partial data in next stack entry
|
||||
lseError
|
||||
);
|
||||
|
||||
TDwarfLocationStackEntry = record
|
||||
Value: TFpDbgMemLocation; // Address of data, unless lseRegister (in vhich case this holds the data (copy of register)
|
||||
Kind: TDwarfLocationStackEntryKind;
|
||||
end;
|
||||
|
||||
TDwarfLocationStack = object
|
||||
private const
|
||||
InvalidMem: TFpDbgMemLocation = (Address: 0; MType: mlfInvalid);
|
||||
private
|
||||
FList: array of TDwarfLocationStackEntry;
|
||||
FList: array of TFpDbgMemLocation; //TDwarfLocationStackEntry;
|
||||
FCount: Integer;
|
||||
procedure IncCapacity;
|
||||
public
|
||||
procedure Clear;
|
||||
function Count: Integer;
|
||||
function Pop: TDwarfLocationStackEntry;
|
||||
function Peek: TDwarfLocationStackEntry;
|
||||
function PeekKind: TDwarfLocationStackEntryKind;
|
||||
function Peek(AIndex: Integer): TDwarfLocationStackEntry;
|
||||
procedure Push(const AEntry: TDwarfLocationStackEntry);
|
||||
procedure Push(AValue: TFpDbgMemLocation; AKind: TDwarfLocationStackEntryKind);
|
||||
procedure Push(AValue: TDbgPtr; AKind: TDwarfLocationStackEntryKind); // mlfTargetMem
|
||||
procedure Modify(AIndex: Integer; const AEntry: TDwarfLocationStackEntry);
|
||||
procedure Modify(AIndex: Integer; AValue: TFpDbgMemLocation; AKind: TDwarfLocationStackEntryKind);
|
||||
procedure Modify(AIndex: Integer; AValue: TDbgPtr; AKind: TDwarfLocationStackEntryKind); // mlfTargetMem
|
||||
function Pop: TFpDbgMemLocation;
|
||||
procedure Push(const AEntry: TFpDbgMemLocation);
|
||||
procedure PushCopy(AFromIndex: Integer);
|
||||
procedure PushConst(const AVal: TDBGPtr);
|
||||
procedure PushTargetMem(const AVal: TDBGPtr);
|
||||
function Peek: PFpDbgMemLocation;
|
||||
function PeekKind: TFpDbgMemLocationType; // Can be called on empty stack
|
||||
function Peek(AIndex: Integer): PFpDbgMemLocation;
|
||||
procedure Modify(AIndex: Integer; const AEntry: TFpDbgMemLocation);
|
||||
procedure Copy(AFromIndex, AIndex: Integer);
|
||||
end;
|
||||
|
||||
{ TDwarfLocationExpression }
|
||||
@ -721,9 +711,8 @@ type
|
||||
constructor Create(AExpressionData: Pointer; AMaxCount: Integer; ACU: TDwarfCompilationUnit;
|
||||
AMemManager: TFpDbgMemManager; AContext: TFpDbgAddressContext);
|
||||
procedure Evaluate;
|
||||
function ResultKind: TDwarfLocationStackEntryKind;
|
||||
function ResultData: TDbgPtr;
|
||||
procedure Push(AValue: TFpDbgMemLocation; AKind: TDwarfLocationStackEntryKind);
|
||||
function ResultData: TFpDbgMemLocation;
|
||||
procedure Push(AValue: TFpDbgMemLocation);
|
||||
property FrameBase: TDbgPtr read FFrameBase write FFrameBase;
|
||||
property OnFrameBaseNeeded: TNotifyEvent read FOnFrameBaseNeeded write FOnFrameBaseNeeded;
|
||||
property LastError: TFpError read FLastError;
|
||||
@ -1757,44 +1746,14 @@ begin
|
||||
Result := FCount;
|
||||
end;
|
||||
|
||||
function TDwarfLocationStack.Pop: TDwarfLocationStackEntry;
|
||||
function TDwarfLocationStack.Pop: TFpDbgMemLocation;
|
||||
begin
|
||||
if FCount = 0 then begin
|
||||
Result.Kind := lseError;
|
||||
exit;
|
||||
end;
|
||||
Assert(0 < FCount);
|
||||
dec(FCount);
|
||||
Result := FList[FCount];
|
||||
end;
|
||||
|
||||
function TDwarfLocationStack.Peek: TDwarfLocationStackEntry;
|
||||
begin
|
||||
if FCount = 0 then begin
|
||||
Result.Kind := lseError;
|
||||
exit;
|
||||
end;
|
||||
Result := FList[FCount-1];
|
||||
end;
|
||||
|
||||
function TDwarfLocationStack.PeekKind: TDwarfLocationStackEntryKind;
|
||||
begin
|
||||
if FCount = 0 then begin
|
||||
Result := lseError;
|
||||
exit;
|
||||
end;
|
||||
Result := FList[FCount-1].Kind;
|
||||
end;
|
||||
|
||||
function TDwarfLocationStack.Peek(AIndex: Integer): TDwarfLocationStackEntry;
|
||||
begin
|
||||
if AIndex >= FCount then begin
|
||||
Result.Kind := lseError;
|
||||
exit;
|
||||
end;
|
||||
Result := FList[FCount-1-AIndex];
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationStack.Push(const AEntry: TDwarfLocationStackEntry);
|
||||
procedure TDwarfLocationStack.Push(const AEntry: TFpDbgMemLocation);
|
||||
begin
|
||||
if Length(FList) <= FCount then
|
||||
IncCapacity;
|
||||
@ -1802,47 +1761,69 @@ begin
|
||||
inc(FCount);
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationStack.Push(AValue: TFpDbgMemLocation;
|
||||
AKind: TDwarfLocationStackEntryKind);
|
||||
procedure TDwarfLocationStack.PushCopy(AFromIndex: Integer);
|
||||
begin
|
||||
Assert(AFromIndex < FCount);
|
||||
if Length(FList) <= FCount then
|
||||
IncCapacity;
|
||||
FList[FCount].Value := AValue;
|
||||
FList[FCount].Kind := AKind;
|
||||
FList[FCount] := FList[FCount-1-AFromIndex];
|
||||
inc(FCount);
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationStack.Push(AValue: TDbgPtr; AKind: TDwarfLocationStackEntryKind);
|
||||
procedure TDwarfLocationStack.PushConst(const AVal: TDBGPtr);
|
||||
begin
|
||||
Push(TargetLoc(AValue), AKind);
|
||||
if Length(FList) <= FCount then
|
||||
IncCapacity;
|
||||
with FList[FCount] do begin
|
||||
Address := AVal;
|
||||
MType := mlfConstant;
|
||||
end;
|
||||
inc(FCount);
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationStack.Modify(AIndex: Integer; const AEntry: TDwarfLocationStackEntry);
|
||||
procedure TDwarfLocationStack.PushTargetMem(const AVal: TDBGPtr);
|
||||
begin
|
||||
if Length(FList) <= FCount then
|
||||
IncCapacity;
|
||||
with FList[FCount] do begin
|
||||
Address := AVal;
|
||||
MType := mlfTargetMem;
|
||||
end;
|
||||
inc(FCount);
|
||||
end;
|
||||
|
||||
function TDwarfLocationStack.Peek: PFpDbgMemLocation;
|
||||
begin
|
||||
Assert(0 < FCount);
|
||||
Result := @FList[FCount-1];
|
||||
end;
|
||||
|
||||
function TDwarfLocationStack.PeekKind: TFpDbgMemLocationType;
|
||||
begin
|
||||
if FCount = 0 then
|
||||
Result := mlfInvalid
|
||||
else
|
||||
Result := FList[FCount-1].MType;
|
||||
end;
|
||||
|
||||
function TDwarfLocationStack.Peek(AIndex: Integer): PFpDbgMemLocation;
|
||||
begin
|
||||
Assert(AIndex < FCount);
|
||||
Result := @FList[FCount-1-AIndex];
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationStack.Modify(AIndex: Integer;
|
||||
const AEntry: TFpDbgMemLocation);
|
||||
begin
|
||||
Assert(AIndex < FCount);
|
||||
if AIndex >= FCount then
|
||||
exit;
|
||||
FList[FCount-1-AIndex] := AEntry;
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationStack.Modify(AIndex: Integer; AValue: TFpDbgMemLocation;
|
||||
AKind: TDwarfLocationStackEntryKind);
|
||||
procedure TDwarfLocationStack.Copy(AFromIndex, AIndex: Integer);
|
||||
begin
|
||||
Assert(AIndex < FCount);
|
||||
if AIndex >= FCount then
|
||||
exit;
|
||||
FList[FCount-1-AIndex].Value := AValue;
|
||||
FList[FCount-1-AIndex].Kind := AKind;
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationStack.Modify(AIndex: Integer; AValue: TDbgPtr;
|
||||
AKind: TDwarfLocationStackEntryKind);
|
||||
begin
|
||||
Assert(AIndex < FCount);
|
||||
if AIndex >= FCount then
|
||||
exit;
|
||||
FList[FCount-1-AIndex].Value := TargetLoc(AValue);
|
||||
FList[FCount-1-AIndex].Kind := AKind;
|
||||
Assert(AFromIndex < FCount);
|
||||
FList[FCount-1-AIndex] := FList[FCount-1-AFromIndex];
|
||||
end;
|
||||
|
||||
{ TDwarfLocationExpression }
|
||||
@ -1865,7 +1846,7 @@ var
|
||||
|
||||
procedure SetError(AnInternalErrorCode: TFpErrorCode = fpErrNoError);
|
||||
begin
|
||||
FStack.Push(InvalidLoc, lseError); // Mark as failed
|
||||
FStack.Push(InvalidLoc); // Mark as failed
|
||||
if IsError(FMemManager.LastError)
|
||||
then FLastError := CreateError(fpErrLocationParserMemRead, FMemManager.LastError, [])
|
||||
else FLastError := CreateError(fpErrLocationParser, []);
|
||||
@ -1879,7 +1860,7 @@ var
|
||||
|
||||
function AssertAddressOnStack: Boolean;
|
||||
begin
|
||||
Result := FStack.PeekKind in [lseValue, lseRegister]; // todo: allow register?
|
||||
Result := FStack.PeekKind in [mlfTargetMem, mlfSelfMem]; // allow const?
|
||||
if not Result then
|
||||
SetError(fpErrLocationParserNoAddressOnStack);
|
||||
end;
|
||||
@ -1898,6 +1879,10 @@ var
|
||||
Result := FMemManager.ReadAddress(AnAddress, ASize, AValue, FContext);
|
||||
if not Result then
|
||||
SetError;
|
||||
// // Deref SelfMem should simple not happer. Except to get const/values
|
||||
//else
|
||||
//if AnAddress.MType = mlfSelfMem then
|
||||
// AValue.MType := mlfSelfMem;
|
||||
end;
|
||||
|
||||
function ReadAddressFromMemoryEx(AnAddress: TFpDbgMemLocation; AnAddrSpace: TDbgPtr; ASize: Cardinal; out AValue: TFpDbgMemLocation): Boolean;
|
||||
@ -1908,6 +1893,9 @@ var
|
||||
Result := IsValidLoc(AValue);
|
||||
if not Result then
|
||||
SetError;
|
||||
//else
|
||||
//if AnAddress.MType = mlfSelfMem then
|
||||
// AValue.MType := mlfSelfMem;
|
||||
end;
|
||||
|
||||
function ReadUnsignedFromExpression(var CurInstr: Pointer; ASize: Integer): TDbgPtr;
|
||||
@ -1939,8 +1927,14 @@ var
|
||||
NewValue: TDbgPtr;
|
||||
i: TDbgPtr;
|
||||
x : integer;
|
||||
Entry, Entry2: TDwarfLocationStackEntry;
|
||||
Entry, Entry2: TFpDbgMemLocation;
|
||||
EntryP: PFpDbgMemLocation;
|
||||
begin
|
||||
(* Returns the address of the value.
|
||||
- Except for DW_OP_regN and DW_OP_piece, which return the value itself. (Not sure about DW_OP_constN)
|
||||
- Some tags override that, e.g.: DW_AT_upper_bound will allways interpret the result as a value.
|
||||
*)
|
||||
|
||||
AddrSize := FCU.FAddressSize;
|
||||
FMemManager.ClearLastError;
|
||||
FLastError := NoError;
|
||||
@ -1950,59 +1944,59 @@ begin
|
||||
inc(CurData);
|
||||
case CurInstr^ of
|
||||
DW_OP_nop: ;
|
||||
DW_OP_addr: FStack.Push(FCU.ReadTargetAddressFromDwarfSection(CurData, True), lseValue);
|
||||
DW_OP_addr: FStack.Push(FCU.ReadTargetAddressFromDwarfSection(CurData, True)); // always mlfTargetMem;
|
||||
DW_OP_deref: begin
|
||||
if not AssertAddressOnStack then exit;
|
||||
if not ReadAddressFromMemory(FStack.Pop.Value, AddrSize, NewLoc) then exit;
|
||||
FStack.Push(NewLoc, lseValue);
|
||||
if not ReadAddressFromMemory(FStack.Pop, AddrSize, NewLoc) then exit;
|
||||
FStack.Push(NewLoc); // mlfTargetMem;
|
||||
end;
|
||||
DW_OP_xderef: begin
|
||||
if not AssertAddressOnStack then exit;
|
||||
Loc := FStack.Pop.Value;
|
||||
Loc := FStack.Pop;
|
||||
if not AssertAddressOnStack then exit;
|
||||
// TODO check address is valid
|
||||
if not ReadAddressFromMemoryEx(Loc, FStack.Pop.Value.Address, AddrSize, NewLoc) then exit;
|
||||
FStack.Push(NewLoc, lseValue);
|
||||
if not ReadAddressFromMemoryEx(Loc, FStack.Pop.Address, AddrSize, NewLoc) then exit;
|
||||
FStack.Push(NewLoc); // mlfTargetMem;
|
||||
end;
|
||||
DW_OP_deref_size: begin
|
||||
if not AssertAddressOnStack then exit;
|
||||
if not ReadAddressFromMemory(FStack.Pop.Value, ReadUnsignedFromExpression(CurData, 1), NewLoc) then exit;
|
||||
FStack.Push(NewLoc, lseValue);
|
||||
if not ReadAddressFromMemory(FStack.Pop, ReadUnsignedFromExpression(CurData, 1), NewLoc) then exit;
|
||||
FStack.Push(NewLoc); // mlfTargetMem;
|
||||
end;
|
||||
DW_OP_xderef_size: begin
|
||||
if not AssertAddressOnStack then exit;
|
||||
Loc := FStack.Pop.Value;
|
||||
Loc := FStack.Pop;
|
||||
if not AssertAddressOnStack then exit;
|
||||
// TODO check address is valid
|
||||
if not ReadAddressFromMemoryEx(Loc, FStack.Pop.Value.Address, ReadUnsignedFromExpression(CurData, 1), NewLoc) then exit;
|
||||
FStack.Push(NewLoc, lseValue);
|
||||
if not ReadAddressFromMemoryEx(Loc, FStack.Pop.Address, ReadUnsignedFromExpression(CurData, 1), NewLoc) then exit;
|
||||
FStack.Push(NewLoc); // mlfTargetMem;
|
||||
end;
|
||||
|
||||
DW_OP_const1u: FStack.Push(ReadUnsignedFromExpression(CurData, 1), lseValue);
|
||||
DW_OP_const2u: FStack.Push(ReadUnsignedFromExpression(CurData, 2), lseValue);
|
||||
DW_OP_const4u: FStack.Push(ReadUnsignedFromExpression(CurData, 4), lseValue);
|
||||
DW_OP_const8u: FStack.Push(ReadUnsignedFromExpression(CurData, 8), lseValue);
|
||||
DW_OP_constu: FStack.Push(ReadUnsignedFromExpression(CurData, 0), lseValue);
|
||||
DW_OP_const1s: FStack.Push(ReadSignedFromExpression(CurData, 1), lseValue);
|
||||
DW_OP_const2s: FStack.Push(ReadSignedFromExpression(CurData, 2), lseValue);
|
||||
DW_OP_const4s: FStack.Push(ReadSignedFromExpression(CurData, 4), lseValue);
|
||||
DW_OP_const8s: FStack.Push(ReadSignedFromExpression(CurData, 8), lseValue);
|
||||
DW_OP_consts: FStack.Push(ReadSignedFromExpression(CurData, 0), lseValue);
|
||||
DW_OP_lit0..DW_OP_lit31: FStack.Push(CurInstr^-DW_OP_lit0, lseValue);
|
||||
DW_OP_const1u: FStack.PushConst(ReadUnsignedFromExpression(CurData, 1));
|
||||
DW_OP_const2u: FStack.PushConst(ReadUnsignedFromExpression(CurData, 2));
|
||||
DW_OP_const4u: FStack.PushConst(ReadUnsignedFromExpression(CurData, 4));
|
||||
DW_OP_const8u: FStack.PushConst(ReadUnsignedFromExpression(CurData, 8));
|
||||
DW_OP_constu: FStack.PushConst(ReadUnsignedFromExpression(CurData, 0));
|
||||
DW_OP_const1s: FStack.PushConst(ReadSignedFromExpression(CurData, 1));
|
||||
DW_OP_const2s: FStack.PushConst(ReadSignedFromExpression(CurData, 2));
|
||||
DW_OP_const4s: FStack.PushConst(ReadSignedFromExpression(CurData, 4));
|
||||
DW_OP_const8s: FStack.PushConst(ReadSignedFromExpression(CurData, 8));
|
||||
DW_OP_consts: FStack.PushConst(ReadSignedFromExpression(CurData, 0));
|
||||
DW_OP_lit0..DW_OP_lit31: FStack.PushConst(CurInstr^-DW_OP_lit0);
|
||||
|
||||
DW_OP_reg0..DW_OP_reg31: begin
|
||||
if not FMemManager.ReadRegister(CurInstr^-DW_OP_reg0, NewValue, FContext) then begin
|
||||
SetError;
|
||||
exit;
|
||||
end;
|
||||
FStack.Push(NewValue, lseRegister);
|
||||
FStack.PushConst(NewValue);
|
||||
end;
|
||||
DW_OP_regx: begin
|
||||
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue, FContext) then begin
|
||||
SetError;
|
||||
exit;
|
||||
end;
|
||||
FStack.Push(NewValue, lseRegister);
|
||||
FStack.PushConst(NewValue);
|
||||
end;
|
||||
|
||||
DW_OP_breg0..DW_OP_breg31: begin
|
||||
@ -2011,7 +2005,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
FStack.Push(NewValue+SLEB128toOrdinal(CurData), lseValue);
|
||||
FStack.PushTargetMem(NewValue+SLEB128toOrdinal(CurData));
|
||||
{$POP}
|
||||
end;
|
||||
DW_OP_bregx: begin
|
||||
@ -2020,7 +2014,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
FStack.Push(NewValue+SLEB128toOrdinal(CurData), lseValue);
|
||||
FStack.PushTargetMem(NewValue+SLEB128toOrdinal(CurData));
|
||||
{$POP}
|
||||
end;
|
||||
|
||||
@ -2031,13 +2025,13 @@ begin
|
||||
exit;
|
||||
end;
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
FStack.Push(FFrameBase+SLEB128toOrdinal(CurData), lseValue);
|
||||
FStack.PushTargetMem(FFrameBase+SLEB128toOrdinal(CurData));
|
||||
{$POP}
|
||||
end;
|
||||
|
||||
DW_OP_dup: begin
|
||||
if not AssertMinCount(1) then exit;
|
||||
FStack.Push(FStack.Peek);
|
||||
FStack.PushCopy(0);
|
||||
end;
|
||||
DW_OP_drop: begin
|
||||
if not AssertMinCount(1) then exit;
|
||||
@ -2045,127 +2039,151 @@ begin
|
||||
end;
|
||||
DW_OP_over: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
FStack.Push(FStack.Peek(1));
|
||||
FStack.PushCopy(1);
|
||||
end;
|
||||
DW_OP_pick: begin
|
||||
i := ReadUnsignedFromExpression(CurData, 1);
|
||||
if not AssertMinCount(i) then exit;
|
||||
FStack.Push(FStack.Peek(i));
|
||||
FStack.PushCopy(i);
|
||||
end;
|
||||
DW_OP_swap: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Peek(0);
|
||||
FStack.Modify(0, FStack.Peek(1));
|
||||
Entry := FStack.Peek^;
|
||||
FStack.Copy(1, 0);
|
||||
FStack.Modify(1, Entry);
|
||||
end;
|
||||
DW_OP_rot: begin
|
||||
if not AssertMinCount(3) then exit;
|
||||
Entry := FStack.Peek(0);
|
||||
FStack.Modify(0, FStack.Peek(1));
|
||||
FStack.Modify(1, FStack.Peek(2));
|
||||
Entry := FStack.Peek^;
|
||||
FStack.Copy(1, 0);
|
||||
FStack.Copy(2, 1);
|
||||
FStack.Modify(2, Entry);
|
||||
end;
|
||||
|
||||
DW_OP_abs: begin
|
||||
if not AssertMinCount(1) then exit;
|
||||
Entry := FStack.Peek(0);
|
||||
FStack.Modify(0, abs(int64(Entry.Value.Address)), Entry.Kind); // treat as signed
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := abs(int64(EntryP^.Address));
|
||||
end;
|
||||
DW_OP_neg: begin
|
||||
if not AssertMinCount(1) then exit;
|
||||
Entry := FStack.Peek(0);
|
||||
FStack.Modify(0, TDbgPtr(-(int64(Entry.Value.Address))), Entry.Kind); // treat as signed
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := TDbgPtr(-int64(EntryP^.Address));
|
||||
end;
|
||||
DW_OP_plus: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
EntryP := FStack.Peek;
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
//TODO: 32 bit overflow?
|
||||
FStack.Modify(0, Entry.Value.Address+Entry2.Value.Address, lseValue); // adding signed values works via overflow
|
||||
EntryP^.Address := Entry.Address+EntryP^.Address;
|
||||
{$POP}
|
||||
(* TargetMem may be a constant after deref. So if SelfMem is involved, keep it. *)
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_plus_uconst: begin
|
||||
if not AssertMinCount(1) then exit;
|
||||
Entry := FStack.Peek(0);
|
||||
EntryP := FStack.Peek;
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
FStack.Modify(0, Entry.Value.Address+ULEB128toOrdinal(CurData), lseValue);
|
||||
EntryP^.Address := EntryP^.Address + ULEB128toOrdinal(CurData);
|
||||
{$POP}
|
||||
end;
|
||||
DW_OP_minus: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
EntryP := FStack.Peek;
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
FStack.Modify(0, Entry2.Value.Address-Entry.Value.Address, lseValue); // adding signed values works via overflow
|
||||
//TODO: 32 bit overflow?
|
||||
EntryP^.Address := EntryP^.Address - Entry.Address;
|
||||
{$POP}
|
||||
(* TargetMem may be a constant after deref. So if SelfMem is involved, keep it. *)
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_mul: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
EntryP := FStack.Peek;
|
||||
//{$PUSH}{$R-}{$Q-}
|
||||
FStack.Modify(0, TDbgPtr(int64(Entry2.Value.Address)*int64(Entry.Value.Address)), lseValue);
|
||||
EntryP^.Address := TDbgPtr(int64(EntryP^.Address) * int64(Entry.Address));
|
||||
//{$POP}
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_div: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
EntryP := FStack.Peek;
|
||||
//{$PUSH}{$R-}{$Q-}
|
||||
FStack.Modify(0, TDbgPtr(int64(Entry2.Value.Address) div int64(Entry.Value.Address)), lseValue);
|
||||
EntryP^.Address := TDbgPtr(int64(EntryP^.Address) div int64(Entry.Address));
|
||||
//{$POP}
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_mod: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
EntryP := FStack.Peek;
|
||||
//{$PUSH}{$R-}{$Q-}
|
||||
FStack.Modify(0, TDbgPtr(int64(Entry2.Value.Address) mod int64(Entry.Value.Address)), lseValue);
|
||||
EntryP^.Address := TDbgPtr(int64(EntryP^.Address) mod int64(Entry.Address));
|
||||
//{$POP}
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
|
||||
DW_OP_and: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
FStack.Modify(0, Entry2.Value.Address and Entry.Value.Address, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := EntryP^.Address and Entry.Address;
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_not: begin
|
||||
if not AssertMinCount(1) then exit;
|
||||
Entry := FStack.Peek(0);
|
||||
FStack.Modify(0, not Entry2.Value.Address and Entry.Value.Address, Entry.Kind);
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := not EntryP^.Address;
|
||||
end;
|
||||
DW_OP_or: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
FStack.Modify(0, Entry2.Value.Address or Entry.Value.Address, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := EntryP^.Address or Entry.Address;
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_xor: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
FStack.Modify(0, Entry2.Value.Address xor Entry.Value.Address, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := EntryP^.Address xor Entry.Address;
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_shl: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
FStack.Modify(0, Entry2.Value.Address shl Entry.Value.Address, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := EntryP^.Address shl Entry.Address;
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_shr: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
FStack.Modify(0, Entry2.Value.Address shr Entry.Value.Address, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := EntryP^.Address shr Entry.Address;
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
DW_OP_shra: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
if Entry.Value.Address > 0 then
|
||||
FStack.Modify(0, Entry2.Value.Address div (1 shl (Entry.Value.Address - 1)), lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
EntryP^.Address := TDBGPtr( int64(EntryP^.Address) div int64(1 shl (Entry.Address - 1)) );
|
||||
if (EntryP^.MType <> mlfSelfMem) and (Entry.MType in [mlfTargetMem, mlfSelfMem]) then
|
||||
EntryP^.MType := Entry.MType;
|
||||
end;
|
||||
|
||||
DW_OP_skip: begin
|
||||
@ -2176,62 +2194,72 @@ begin
|
||||
if not AssertMinCount(1) then exit;
|
||||
Entry := FStack.Pop;
|
||||
x := ReadSignedFromExpression(CurData, 2);
|
||||
if Entry.Value.Address <> 0 then
|
||||
if Entry.Address <> 0 then
|
||||
CurData := CurData + x;
|
||||
end;
|
||||
|
||||
DW_OP_eq: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
if Entry.Value.Address = Entry2.Value.Address
|
||||
then FStack.Modify(0, 1, lseValue)
|
||||
else FStack.Modify(0, 0, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
if Entry.Address = EntryP^.Address
|
||||
then EntryP^.Address := 1
|
||||
else EntryP^.Address := 0;
|
||||
EntryP^.MType := mlfConstant;
|
||||
end;
|
||||
DW_OP_ge: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
if int64(Entry.Value.Address) >= int64(Entry2.Value.Address)
|
||||
then FStack.Modify(0, 1, lseValue)
|
||||
else FStack.Modify(0, 0, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
if int64(Entry.Address) >= int64(EntryP^.Address)
|
||||
then EntryP^.Address := 1
|
||||
else EntryP^.Address := 0;
|
||||
EntryP^.MType := mlfConstant;
|
||||
end;
|
||||
DW_OP_gt: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
if int64(Entry.Value.Address) > int64(Entry2.Value.Address)
|
||||
then FStack.Modify(0, 1, lseValue)
|
||||
else FStack.Modify(0, 0, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
if int64(Entry.Address) > int64(EntryP^.Address)
|
||||
then EntryP^.Address := 1
|
||||
else EntryP^.Address := 0;
|
||||
EntryP^.MType := mlfConstant;
|
||||
end;
|
||||
DW_OP_le: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
if int64(Entry.Value.Address) <= int64(Entry2.Value.Address)
|
||||
then FStack.Modify(0, 1, lseValue)
|
||||
else FStack.Modify(0, 0, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
if int64(Entry.Address) <= int64(EntryP^.Address)
|
||||
then EntryP^.Address := 1
|
||||
else EntryP^.Address := 0;
|
||||
EntryP^.MType := mlfConstant;
|
||||
end;
|
||||
DW_OP_lt: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
if int64(Entry.Value.Address) < int64(Entry2.Value.Address)
|
||||
then FStack.Modify(0, 1, lseValue)
|
||||
else FStack.Modify(0, 0, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
if int64(Entry.Address) < int64(EntryP^.Address)
|
||||
then EntryP^.Address := 1
|
||||
else EntryP^.Address := 0;
|
||||
EntryP^.MType := mlfConstant;
|
||||
end;
|
||||
DW_OP_ne: begin
|
||||
if not AssertMinCount(2) then exit;
|
||||
Entry := FStack.Pop;
|
||||
Entry2 := FStack.Peek(0);
|
||||
if Entry.Value.Address <> Entry2.Value.Address
|
||||
then FStack.Modify(0, 1, lseValue)
|
||||
else FStack.Modify(0, 0, lseValue);
|
||||
EntryP := FStack.Peek;
|
||||
if Entry.Address <> EntryP^.Address
|
||||
then EntryP^.Address := 1
|
||||
else EntryP^.Address := 0;
|
||||
EntryP^.MType := mlfConstant;
|
||||
end;
|
||||
|
||||
DW_OP_piece: begin
|
||||
if not AssertMinCount(1) then exit; // no piece avail
|
||||
FStack.Push(0, lsePart);
|
||||
x := ReadUnsignedFromExpression(CurData, 0);
|
||||
Entry := FStack.Pop;
|
||||
// TODO: assemble data // Not implemented
|
||||
// If entry is an address (not a register) then it points to the value
|
||||
SetError(fpErrLocationParser);
|
||||
exit;
|
||||
end;
|
||||
|
||||
@ -2241,7 +2269,7 @@ begin
|
||||
SetError;
|
||||
exit;
|
||||
end;
|
||||
Push(FCurrentObjectAddress, lseValue);
|
||||
Push(FCurrentObjectAddress);
|
||||
end;
|
||||
(*
|
||||
// --- DWARF3 ---
|
||||
@ -2262,26 +2290,17 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDwarfLocationExpression.ResultKind: TDwarfLocationStackEntryKind;
|
||||
function TDwarfLocationExpression.ResultData: TFpDbgMemLocation;
|
||||
begin
|
||||
if FStack.Count > 0 then
|
||||
Result := FStack.PeekKind
|
||||
Result := FStack.Pop
|
||||
else
|
||||
Result := lseError;
|
||||
Result := InvalidLoc;
|
||||
end;
|
||||
|
||||
function TDwarfLocationExpression.ResultData: TDbgPtr;
|
||||
procedure TDwarfLocationExpression.Push(AValue: TFpDbgMemLocation);
|
||||
begin
|
||||
if FStack.Count > 0 then
|
||||
Result := FStack.Peek.Value.Address
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
procedure TDwarfLocationExpression.Push(AValue: TFpDbgMemLocation;
|
||||
AKind: TDwarfLocationStackEntryKind);
|
||||
begin
|
||||
FStack.Push(AValue, AKind);
|
||||
FStack.Push(AValue);
|
||||
end;
|
||||
|
||||
{ TDwarfInformationEntry }
|
||||
|
@ -260,6 +260,7 @@ type
|
||||
Address: TDbgPtr;
|
||||
MType: TFpDbgMemLocationType;
|
||||
end;
|
||||
PFpDbgMemLocation = ^TFpDbgMemLocation;
|
||||
|
||||
{ TFpDbgMemManager }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user