FpDebug: Stack, CFI - For older FPC (broken CFI) always continue non-CFI eval.

This commit is contained in:
Martin 2022-10-27 15:42:59 +02:00
parent f469aeca4f
commit 8ef10902f3
3 changed files with 58 additions and 22 deletions

View File

@ -3042,6 +3042,7 @@ var
StackPtr: TDBGPtr;
Row: TDwarfCallFrameInformationRow;
CIE: TDwarfCIE;
CU: TDwarfCompilationUnit;
begin
// TODO: use AFrameRequired // check if already partly done
if FCallStackEntryList = nil then
@ -3116,28 +3117,36 @@ begin
while (CountNeeded > 0) do
begin
if (Process.DbgInfo as TFpDwarfInfo).FindCallFrameInfo(Address, CIE, Row) and
TDwarfCallFrameInformation.TryObtainNextCallFrame(AnEntry, CIE, Size, NextIdx, Self, Row, Process, NewEntry) then
begin
if not Assigned(NewEntry) then
// Done.
Break;
FCallStackEntryList.Add(NewEntry);
Address := NewEntry.AnAddress;
StackReg := NewEntry.RegisterValueList.FindRegisterByDwarfIndex(SP);
FrameReg := NewEntry.RegisterValueList.FindRegisterByDwarfIndex(BP);
StackPtr := 0;
if (StackReg <> nil) and (FrameReg <> nil) then begin
StackPtr := StackReg.FNumValue;
FrameBase := FrameReg.FNumValue;
end;
AnEntry := NewEntry;
Dec(CountNeeded);
inc(NextIdx);
If (NextIdx > MAX_FRAMES) then
Break;
TDwarfCallFrameInformation.TryObtainNextCallFrame(AnEntry, CIE, Size, NextIdx, Self, Row, Process, NewEntry)
then begin
if not Assigned(NewEntry) then begin
CU := (Process.DbgInfo as TFpDwarfInfo).CompilationUnitForAddr(Address);
if (CU = nil) or (CU.DwarfSymbolClassMap = nil) or (not CU.DwarfSymbolClassMap.IgnoreCfiStackEnd) then
// Done.
Break;
end
else if (FrameBase <> 0) and (FrameBase > LastFrameBase) then
begin
else begin
FCallStackEntryList.Add(NewEntry);
Address := NewEntry.AnAddress;
StackReg := NewEntry.RegisterValueList.FindRegisterByDwarfIndex(SP);
FrameReg := NewEntry.RegisterValueList.FindRegisterByDwarfIndex(BP);
StackPtr := 0;
if (StackReg <> nil) and (FrameReg <> nil) then begin
StackPtr := StackReg.FNumValue;
FrameBase := FrameReg.FNumValue;
end;
AnEntry := NewEntry;
Dec(CountNeeded);
inc(NextIdx);
If (NextIdx > MAX_FRAMES) then
Break;
Continue;
end;
end;
if (FrameBase <> 0) and (FrameBase > LastFrameBase)
then begin
if StackPtr = 0 then
break;
// CFI not available or contains unsupported structures. Fallback to
@ -3189,7 +3198,7 @@ begin
CodeReadErrCnt := 0;
If (NextIdx > MAX_FRAMES) then
break;
end
end
else
Break;
end;

View File

@ -556,6 +556,7 @@ type
class function ClassCanHandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; virtual; abstract;
public
constructor Create(ACU: TDwarfCompilationUnit; AHelperData: Pointer); virtual;
function IgnoreCfiStackEnd: boolean; virtual;
function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; virtual; abstract;
function CreateScopeForSymbol(ALocationContext: TFpDbgLocationContext; ASymbol: TFpSymbol;
ADwarf: TFpDwarfInfo): TFpDbgSymbolScope; virtual; abstract;
@ -811,6 +812,7 @@ type
function GetLineAddressMap(const AFileName: String): PDWarfLineMap;
procedure LoadCallFrameInstructions;
function LoadCompilationUnits: Integer;
function CompilationUnitForAddr(AnAddr: TDBGPtr): TDwarfCompilationUnit;
function CompilationUnitsCount: Integer; inline;
property CompilationUnits[AIndex: Integer]: TDwarfCompilationUnit read GetCompilationUnit;
@ -1061,6 +1063,11 @@ begin
GetExistingClassMap^ := nil;
end;
function TFpSymbolDwarfClassMap.IgnoreCfiStackEnd: boolean;
begin
Result := False;
end;
constructor TFpSymbolDwarfClassMap.Create(ACU: TDwarfCompilationUnit;
AHelperData: Pointer);
begin
@ -4167,6 +4174,20 @@ begin
TDwarfCompilationUnit(FCompilationUnits[i]).FComputeNameHashesWorker.MarkReadyToRun;
end;
function TFpDwarfInfo.CompilationUnitForAddr(AnAddr: TDBGPtr
): TDwarfCompilationUnit;
var
n: Integer;
begin
for n := 0 to FCompilationUnits.Count - 1 do
begin
Result := TDwarfCompilationUnit(FCompilationUnits[n]);
if Result.HasAddress(AnAddr, []) then
exit;
end;
Result := nil;
end;
function TFpDwarfInfo.CompilationUnitsCount: Integer;
begin
Result := FCompilationUnits.Count;

View File

@ -34,6 +34,7 @@ type
class function GetInstanceForDbgInfo(ADbgInfo: TDbgInfo):TFpDwarfFreePascalSymbolClassMap;
public
constructor Create(ACU: TDwarfCompilationUnit; AHelperData: Pointer); override;
function IgnoreCfiStackEnd: boolean; override;
function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; override;
function CreateScopeForSymbol(ALocationContext: TFpDbgLocationContext; ASymbol: TFpSymbol;
ADwarf: TFpDwarfInfo): TFpDbgSymbolScope; override;
@ -390,6 +391,11 @@ begin
inherited Create(ACU, AHelperData);
end;
function TFpDwarfFreePascalSymbolClassMap.IgnoreCfiStackEnd: boolean;
begin
Result := FCompilerVersion < $030301;
end;
function TFpDwarfFreePascalSymbolClassMap.GetDwarfSymbolClass(
ATag: Cardinal): TDbgDwarfSymbolBaseClass;
begin