mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-12 10:59:20 +02:00
FpDebug: Disassembler, start disassembling at begin of current function, to provide some LinesBefore
This commit is contained in:
parent
e19b911ab7
commit
d56774da57
@ -1906,6 +1906,49 @@ var
|
||||
AOffset: longint;
|
||||
RealReadLen: Cardinal;
|
||||
|
||||
procedure AddInfoToRange(ALineAddr: TDBGPtr; ATargetRange: TDBGDisassemblerEntryRange);
|
||||
var
|
||||
j: integer;
|
||||
begin
|
||||
Sym := TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.FindProcSymbol(ALineAddr);
|
||||
// If this is the last statement for this source-code-line, fill the
|
||||
// SrcStatementCount from the prior statements.
|
||||
if (assigned(sym) and ((ASrcFileName<>sym.FileName) or (ASrcFileLine<>sym.Line))) or
|
||||
(not assigned(sym) and ((ASrcFileLine<>0) or (ASrcFileName<>''))) then
|
||||
begin
|
||||
for j := 0 to StatIndex-1 do
|
||||
ATargetRange.EntriesPtr[FirstIndex+j]^.SrcStatementCount:=StatIndex;
|
||||
StatIndex:=0;
|
||||
FirstIndex:=ATargetRange.Count;
|
||||
end;
|
||||
|
||||
if assigned(sym) then
|
||||
begin
|
||||
ASrcFileName:=sym.FileName;
|
||||
ASrcFileLine:=sym.Line;
|
||||
AFuncName := sym.Name;
|
||||
AOffset := int32(int64(ALineAddr) - int64(Sym.Address.Address));
|
||||
sym.ReleaseReference;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ASrcFileName:='';
|
||||
AFuncName := '';
|
||||
ASrcFileLine:=0;
|
||||
AOffset := -1;
|
||||
end;
|
||||
AnEntry.Addr := ALineAddr;
|
||||
AnEntry.Dump := ADump;
|
||||
AnEntry.Statement := AStatement;
|
||||
AnEntry.SrcFileLine:=ASrcFileLine;
|
||||
AnEntry.SrcFileName:=ASrcFileName;
|
||||
AnEntry.FuncName := AFuncName;
|
||||
AnEntry.SrcStatementIndex:=StatIndex;
|
||||
AnEntry.Offset := AOffset;
|
||||
ATargetRange.Append(@AnEntry);
|
||||
inc(StatIndex);
|
||||
end;
|
||||
|
||||
begin
|
||||
Result := False;
|
||||
if (Debugger = nil) or not(Debugger.State = dsPause) or FInPrepare then
|
||||
@ -1967,46 +2010,7 @@ begin
|
||||
DebugLn(DBG_VERBOSE, format('Disassembled: [%.8X: %s] %s',[tmpAddr, ADump, Astatement]));
|
||||
|
||||
Dec(tmpAddr, prevInstructionSize);
|
||||
Sym := TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.FindProcSymbol(tmpAddr);
|
||||
// If this is the last statement for this source-code-line, fill the
|
||||
// SrcStatementCount from the prior statements.
|
||||
if (assigned(sym) and ((ASrcFileName<>sym.FileName) or (ASrcFileLine<>sym.Line))) or
|
||||
(not assigned(sym) and ((ASrcFileLine<>0) or (ASrcFileName<>''))) then
|
||||
begin
|
||||
for j := 0 to StatIndex-1 do
|
||||
begin
|
||||
with AReversedRange.EntriesPtr[FirstIndex+j]^ do
|
||||
SrcStatementCount := StatIndex;
|
||||
end;
|
||||
StatIndex := 0;
|
||||
FirstIndex:=AReversedRange.Count;
|
||||
end;
|
||||
|
||||
if assigned(sym) then
|
||||
begin
|
||||
ASrcFileName:=sym.FileName;
|
||||
ASrcFileLine:=sym.Line;
|
||||
AFuncName := sym.Name;
|
||||
AOffset := int32(int64(tmpAddr) - int64(Sym.Address.Address));
|
||||
sym.ReleaseReference;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ASrcFileName:='';
|
||||
AFuncName := '';
|
||||
ASrcFileLine:=0;
|
||||
AOffset := -1;
|
||||
end;
|
||||
AnEntry.Addr := tmpAddr;
|
||||
AnEntry.Dump := ADump;
|
||||
AnEntry.Statement := AStatement;
|
||||
AnEntry.SrcFileLine:=ASrcFileLine;
|
||||
AnEntry.SrcFileName:=ASrcFileName;
|
||||
AnEntry.FuncName := AFuncName;
|
||||
AnEntry.SrcStatementIndex:=StatIndex; // should be inverted for reverse parsing
|
||||
AnEntry.Offset := AOffset;
|
||||
AReversedRange.Append(@AnEntry);
|
||||
inc(StatIndex);
|
||||
AddInfoToRange(tmpAddr, AReversedRange);
|
||||
end;
|
||||
|
||||
if AReversedRange.Count>0 then
|
||||
@ -2028,69 +2032,82 @@ begin
|
||||
end;
|
||||
// Entries are all pointers, don't free entries
|
||||
FreeAndNil(AReversedRange);
|
||||
end;
|
||||
end
|
||||
else
|
||||
if ALinesBefore > 0 then begin
|
||||
Sym := TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.FindProcSymbol(AnAddr);
|
||||
if Sym <> nil then begin
|
||||
tmpAddr := Sym.Address.Address;
|
||||
Sym.ReleaseReference;
|
||||
if tmpAddr < AnAddr then begin
|
||||
sz := AnAddr - tmpAddr + ADisassembler.MaxInstructionSize;
|
||||
SetLength(CodeBin, sz);
|
||||
bytesDisassembled := 0;
|
||||
if not TFpDebugDebugger(Debugger).ReadData(tmpAddr, sz, CodeBin[0], RealReadLen) then begin
|
||||
DebugLn(Format('Disassemble: Failed to read memory at %s.', [FormatAddress(tmpAddr)]));
|
||||
end
|
||||
else begin
|
||||
while tmpAddr < AnAddr do begin
|
||||
p := @CodeBin[bytesDisassembled];
|
||||
ADisassembler.Disassemble(p, ADump, AStatement);
|
||||
|
||||
prevInstructionSize := p - @CodeBin[bytesDisassembled];
|
||||
if prevInstructionSize = 0 then
|
||||
break;
|
||||
bytesDisassembled := bytesDisassembled + prevInstructionSize;
|
||||
if bytesDisassembled > RealReadLen then
|
||||
break;
|
||||
if tmpAddr + prevInstructionSize > AnAddr then
|
||||
break;
|
||||
|
||||
AddInfoToRange(tmpAddr, ARange);
|
||||
ALastAddr:=tmpAddr;
|
||||
Inc(tmpAddr, prevInstructionSize);
|
||||
end;
|
||||
if tmpAddr <> AnAddr then begin
|
||||
AnEntry.Addr := tmpAddr;
|
||||
AnEntry.Dump := '???';
|
||||
AnEntry.Statement := '???';
|
||||
AnEntry.SrcFileLine:=-1;
|
||||
AnEntry.SrcFileName:='';
|
||||
AnEntry.FuncName := '';
|
||||
AnEntry.SrcStatementIndex:=StatIndex;
|
||||
AnEntry.Offset := -1;
|
||||
ARange.Append(@AnEntry);
|
||||
inc(StatIndex);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if ALinesAfter > 0 then
|
||||
begin
|
||||
StatIndex:=0;
|
||||
FirstIndex:=ARange.Count;
|
||||
sz := ALinesAfter * ADisassembler.MaxInstructionSize;
|
||||
SetLength(CodeBin, sz);
|
||||
bytesDisassembled := 0;
|
||||
if not TFpDebugDebugger(Debugger).ReadData(AnAddr, sz, CodeBin[0], RealReadLen) then
|
||||
begin
|
||||
DebugLn(Format('Disassemble: Failed to read memory at %s.', [FormatAddress(AnAddr)]));
|
||||
inc(AnAddr);
|
||||
end
|
||||
else
|
||||
for i := 0 to ALinesAfter-1 do
|
||||
StatIndex:=0;
|
||||
FirstIndex:=ARange.Count;
|
||||
sz := ALinesAfter * ADisassembler.MaxInstructionSize;
|
||||
SetLength(CodeBin, sz);
|
||||
bytesDisassembled := 0;
|
||||
if not TFpDebugDebugger(Debugger).ReadData(AnAddr, sz, CodeBin[0], RealReadLen) then
|
||||
begin
|
||||
p := @CodeBin[bytesDisassembled];
|
||||
ADisassembler.Disassemble(p, ADump, AStatement);
|
||||
DebugLn(Format('Disassemble: Failed to read memory at %s.', [FormatAddress(AnAddr)]));
|
||||
inc(AnAddr);
|
||||
end
|
||||
else
|
||||
for i := 0 to ALinesAfter-1 do
|
||||
begin
|
||||
p := @CodeBin[bytesDisassembled];
|
||||
ADisassembler.Disassemble(p, ADump, AStatement);
|
||||
|
||||
prevInstructionSize := p - @CodeBin[bytesDisassembled];
|
||||
bytesDisassembled := bytesDisassembled + prevInstructionSize;
|
||||
if bytesDisassembled > RealReadLen then
|
||||
break; Sym := TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.FindProcSymbol(AnAddr);
|
||||
// If this is the last statement for this source-code-line, fill the
|
||||
// SrcStatementCount from the prior statements.
|
||||
if (assigned(sym) and ((ASrcFileName<>sym.FileName) or (ASrcFileLine<>sym.Line))) or
|
||||
(not assigned(sym) and ((ASrcFileLine<>0) or (ASrcFileName<>''))) then
|
||||
begin
|
||||
for j := 0 to StatIndex-1 do
|
||||
ARange.EntriesPtr[FirstIndex+j]^.SrcStatementCount:=StatIndex;
|
||||
StatIndex:=0;
|
||||
FirstIndex:=ARange.Count;
|
||||
end;
|
||||
prevInstructionSize := p - @CodeBin[bytesDisassembled];
|
||||
bytesDisassembled := bytesDisassembled + prevInstructionSize;
|
||||
if bytesDisassembled > RealReadLen then
|
||||
break;
|
||||
|
||||
if assigned(sym) then
|
||||
begin
|
||||
ASrcFileName:=sym.FileName;
|
||||
ASrcFileLine:=sym.Line;
|
||||
AFuncName := sym.Name;
|
||||
AOffset := int32(int64(AnAddr) - int64(Sym.Address.Address));
|
||||
sym.ReleaseReference;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ASrcFileName:='';
|
||||
AFuncName := '';
|
||||
ASrcFileLine:=0;
|
||||
AOffset := -1;
|
||||
AddInfoToRange(AnAddr, ARange);
|
||||
ALastAddr:=AnAddr;
|
||||
Inc(AnAddr, prevInstructionSize);
|
||||
end;
|
||||
AnEntry.Addr := AnAddr;
|
||||
AnEntry.Dump := ADump;
|
||||
AnEntry.Statement := AStatement;
|
||||
AnEntry.SrcFileLine:=ASrcFileLine;
|
||||
AnEntry.SrcFileName:=ASrcFileName;
|
||||
AnEntry.FuncName := AFuncName;
|
||||
AnEntry.SrcStatementIndex:=StatIndex;
|
||||
AnEntry.Offset := AOffset;
|
||||
ARange.Append(@AnEntry);
|
||||
ALastAddr:=AnAddr;
|
||||
inc(StatIndex);
|
||||
Inc(AnAddr, prevInstructionSize);
|
||||
end;
|
||||
end
|
||||
else
|
||||
ALastAddr := AnAddr;
|
||||
|
Loading…
Reference in New Issue
Block a user