From 7f8306fad71a7fd9f1890d0d7b4d3efbe3c8fc0e Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 23 Jun 2019 11:14:24 +0000 Subject: [PATCH] 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 - --- components/fpdebug/fpdbgdwarf.pas | 26 +- components/fpdebug/fpdbgdwarfdataclasses.pas | 407 ++++++++++--------- components/fpdebug/fpdmemorytools.pas | 1 + 3 files changed, 224 insertions(+), 210 deletions(-) diff --git a/components/fpdebug/fpdbgdwarf.pas b/components/fpdebug/fpdbgdwarf.pas index 59023af79b..f933c4d559 100644 --- a/components/fpdebug/fpdbgdwarf.pas +++ b/components/fpdebug/fpdbgdwarf.pas @@ -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); diff --git a/components/fpdebug/fpdbgdwarfdataclasses.pas b/components/fpdebug/fpdbgdwarfdataclasses.pas index 37ee8a335b..df916deae8 100644 --- a/components/fpdebug/fpdbgdwarfdataclasses.pas +++ b/components/fpdebug/fpdbgdwarfdataclasses.pas @@ -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 } diff --git a/components/fpdebug/fpdmemorytools.pas b/components/fpdebug/fpdmemorytools.pas index 260e5220e1..389c2458b5 100644 --- a/components/fpdebug/fpdmemorytools.pas +++ b/components/fpdebug/fpdmemorytools.pas @@ -260,6 +260,7 @@ type Address: TDbgPtr; MType: TFpDbgMemLocationType; end; + PFpDbgMemLocation = ^TFpDbgMemLocation; { TFpDbgMemManager }