fpdebug / fp-lldb: runtime detection of 32/64bit arch. Issue #34225 Patch by David Jenkins

git-svn-id: trunk@58891 -
This commit is contained in:
martin 2018-09-06 11:24:43 +00:00
parent 687059072b
commit a44e814975
5 changed files with 171 additions and 84 deletions

View File

@ -597,6 +597,7 @@ type
private
FCompilationUnits: TList;
FImageBase: QWord;
FImage64Bit: Boolean;
FMemManager: TFpDbgMemManager;
FFiles: array of TDwarfDebugFile;
function GetCompilationUnit(AIndex: Integer): TDwarfCompilationUnit;
@ -620,6 +621,7 @@ type
property MemManager: TFpDbgMemManager read FMemManager write FMemManager;
property ImageBase: QWord read FImageBase;
property Image64Bit: Boolean read FImage64Bit;
end;
{ TDwarfLocationStack }
@ -2929,6 +2931,7 @@ var
i: Integer;
begin
inherited Create(ALoaderList);
FImage64Bit := ALoaderList.Image64Bit;
FCompilationUnits := TList.Create;
FImageBase := ALoaderList.ImageBase;

View File

@ -62,21 +62,26 @@ const
parentfp2: string = '$parentfp';
selfname: string = 'self';
// TODO: get reg num via memreader name-to-num
{$IFDEF cpu64}
RegFp = 6;
RegPc = 16;
{$ELSE}
RegFp = 5;
RegPc = 8;
{$ENDIF}
RegFp64 = 6;
RegPc64 = 16;
RegFp32 = 5;
RegPc32 = 8;
var
StartScopeIdx: Integer;
StartScopeIdx, RegFp, RegPc: Integer;
ParentFpVal: TFpDbgValue;
SearchCtx: TFpDwarfFreePascalAddressContext;
par_fp, cur_fp, prev_fp, pc: TDbgPtr;
d, i: Integer;
ParentFpSym: TFpDwarfSymbol;
begin
if Dwarf.Image64Bit then begin
RegFP := RegFp64;
RegPc := RegPc64;
end
else begin
RegFP := RegFp32;
RegPc := RegPc32;
end;
Result := False;
if (Length(AName) = length(selfname)) and (CompareUtf8BothCase(PNameUpper, PNameLower, @selfname[1])) then begin
ADbgValue := GetSelfParameter;

View File

@ -112,7 +112,7 @@ implementation
function TDbgImageLoaderList.GetImage64Bit: Boolean;
begin
if Count<0 then
if Count>0 then
result := Items[0].Image64Bit
else
{$ifdef CPU64}

View File

@ -56,6 +56,7 @@ uses
type
PnlistArray = ^nlist; // ^array[0..infinite] of nlist;
PnlistArray64 = ^nlist_64; // ^array[0..infinite] of nlist_64;
const
// Symbol-map section name
@ -184,7 +185,11 @@ var
p: PDbgImageSection;
ps: PDbgImageSection;
SymbolArr: PnlistArray;
SymbolArr64: PnlistArray64;
SymbolStr: pointer;
SymbolType: uint8_t;
StringOffset: uint32_t;
SymbolValue: TDBGPtr;
i: integer;
SymbolCount: integer;
begin
@ -192,18 +197,38 @@ begin
ps := Section[_symbolstrings];
if assigned(p) and assigned(ps) then
begin
SymbolArr:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolStr:=PDbgImageSectionEx(ps)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist);
if Image64Bit then
begin
SymbolArr64:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist_64);
end
else
begin
SymbolArr:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist);
end;
for i := 0 to SymbolCount-1 do
begin
if (SymbolArr[i].n_type and $e0)<>0 then
if Image64Bit then
begin
SymbolType := SymbolArr64[i].n_type;
StringOffset := SymbolArr64[i].n_un.n_strx;
SymbolValue := SymbolArr64[i].n_value;
end
else
begin
SymbolType := SymbolArr[i].n_type;
StringOffset := SymbolArr[i].n_un.n_strx;
SymbolValue := SymbolArr[i].n_value;
end;
if (SymbolType and $e0)<>0 then
// This is a stabs-entry. Ignore.
Continue;
if (SymbolArr[i].n_type and $0e)=$e then
if (SymbolType and $0e)=$e then
begin
// Section-index is ignored for now...
AfpSymbolInfo.AddObject(pchar(SymbolStr+SymbolArr[i].n_un.n_strx), TObject(PtrUInt(SymbolArr[i].n_value)));
AfpSymbolInfo.Add(pchar(SymbolStr+StringOffset), SymbolValue);
end
end;
end;
@ -258,7 +283,10 @@ begin
SectionSize := StabsCmd.strsize;
end else begin
SectionOffset := StabsCmd.symoff;
SectionSize := Int64(StabsCmd.nsyms * sizeof(nlist));
if Image64Bit then
SectionSize := Int64(StabsCmd.nsyms * sizeof(nlist_64))
else
SectionSize := Int64(StabsCmd.nsyms * sizeof(nlist));
end;
end;
@ -560,9 +588,13 @@ var
p: PDbgImageSection;
ps: PDbgImageSection;
SymbolArr: PnlistArray;
SymbolArr64: PnlistArray64;
SymbolStr: pointer;
i: integer;
SymbolCount: integer;
SymbolType, SymbolSect: uint8_t;
StringOffset: uint32_t;
SymbolValue: QWord;
State: TDebugTableState;
AddressMap: TDbgAddressMap;
ProcName: string;
@ -573,29 +605,51 @@ begin
ps := Section[_symbolstrings];
if assigned(p) and assigned(ps) then
begin
SymbolArr:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolStr:=PDbgImageSectionEx(ps)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist);
if Image64Bit then
begin
SymbolArr64:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist_64);
end
else
begin
SymbolArr:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist);
end;
state := dtsEnd;
for i := 0 to SymbolCount-1 do
begin
if Image64Bit then
begin
SymbolType := SymbolArr64[i].n_type;
StringOffset := SymbolArr64[i].n_un.n_strx;
SymbolValue := SymbolArr64[i].n_value;
SymbolSect := SymbolArr64[i].n_sect;
end
else
begin
SymbolType := SymbolArr[i].n_type;
StringOffset := SymbolArr[i].n_un.n_strx;
SymbolValue := SymbolArr[i].n_value;
SymbolSect := SymbolArr[i].n_sect;
end;
case state of
dtsEnd:
begin
if SymbolArr[i].n_type = N_SO then
if SymbolType = N_SO then
begin
if assigned(DwarfDebugMap) then
DwarfDebugMap.Free;
DwarfDebugMap := TAppleDwarfDebugMap.Create;
DwarfDebugMap.Dir := pchar(SymbolStr+SymbolArr[i].n_un.n_strx);
DwarfDebugMap.Dir := pchar(SymbolStr+StringOffset);
state := dtsDir;
end;
end;
dtsDir:
begin
if SymbolArr[i].n_type = N_SO then
if SymbolType = N_SO then
begin
DwarfDebugMap.SourceFile:=pchar(SymbolStr+SymbolArr[i].n_un.n_strx);
DwarfDebugMap.SourceFile:=pchar(SymbolStr+StringOffset);
inc(state);
end
else
@ -603,27 +657,27 @@ begin
end;
dtsSource:
begin
if SymbolArr[i].n_type = N_OSO then
if SymbolType = N_OSO then
begin
DwarfDebugMap.ObjectFile:=pchar(SymbolStr+SymbolArr[i].n_un.n_strx);
DwarfDebugMap.ObjFileAge:=SymbolArr[i].n_value;
DwarfDebugMap.ObjectFile:=pchar(SymbolStr+StringOffset);
DwarfDebugMap.ObjFileAge:=SymbolValue;
inc(state);
end;
end;
dtsObjectFile:
begin
if (SymbolArr[i].n_type = N_BNSYM) then
if (SymbolType = N_BNSYM) then
begin
inc(state);
end
else if (SymbolArr[i].n_type = N_STSYM) then
else if (SymbolType = N_STSYM) then
begin
AddressMap.NewAddr:=SymbolArr[i].n_value;
AddressMap.NewAddr:=SymbolValue;
AddressMap.OrgAddr:=0;
AddressMap.Length:=0;
DwarfDebugMap.GlobalList.Add(pchar(SymbolStr+SymbolArr[i].n_un.n_strx), AddressMap);
DwarfDebugMap.GlobalList.Add(pchar(SymbolStr+StringOffset), AddressMap);
end
else if (SymbolArr[i].n_type = N_SO) and (SymbolArr[i].n_sect=1) then
else if (SymbolType = N_SO) and (SymbolSect=1) then
begin
state := dtsEnd;
SubFiles.AddObject(DwarfDebugMap.ObjectFile, DwarfDebugMap);
@ -632,24 +686,24 @@ begin
end;
dtsProc:
begin
if (SymbolArr[i].n_type = N_FUN) and (SymbolArr[i].n_sect=1) then
if (SymbolType = N_FUN) and (SymbolSect=1) then
begin
AddressMap.NewAddr:=SymbolArr[i].n_value;
ProcName:=pchar(SymbolStr+SymbolArr[i].n_un.n_strx);
AddressMap.NewAddr:=SymbolValue;
ProcName:=pchar(SymbolStr+StringOffset);
inc(state);
end;
end;
dtsProcLen:
begin
if (SymbolArr[i].n_type = N_FUN) and (SymbolArr[i].n_sect=0) then
if (SymbolType = N_FUN) and (SymbolSect=0) then
begin
AddressMap.Length:=SymbolArr[i].n_value;
AddressMap.Length:=SymbolValue;
inc(state);
end;
end;
dtsProcEnd:
begin
if (SymbolArr[i].n_type = N_ENSYM) and (SymbolArr[i].n_sect=1) then
if (SymbolType = N_ENSYM) and (SymbolSect=1) then
begin
DwarfDebugMap.GlobalList.Add(ProcName, AddressMap);
state := dtsObjectFile;
@ -665,7 +719,11 @@ var
p: PDbgImageSection;
ps: PDbgImageSection;
SymbolArr: PnlistArray;
SymbolArr64: PnlistArray64;
SymbolStr: pointer;
SymbolType: uint8_t;
StringOffset: uint32_t;
SymbolValue: QWord;
i: integer;
SymbolCount: integer;
MainDwarfDebugMap: TAppleDwarfDebugMap;
@ -678,30 +736,50 @@ begin
ps := Section[_symbolstrings];
if assigned(p) and assigned(ps) then
begin
SymbolArr:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolStr:=PDbgImageSectionEx(ps)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist);
if Image64Bit then
begin
SymbolArr64:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist_64);
end
else
begin
SymbolArr:=PDbgImageSectionEx(p)^.Sect.RawData;
SymbolCount := PDbgImageSectionEx(p)^.Sect.Size div sizeof(nlist);
end;
for i := 0 to SymbolCount-1 do
begin
if SymbolArr[i].n_type = N_SECT then
if Image64Bit then
begin
s := pchar(SymbolStr+SymbolArr[i].n_un.n_strx);
SymbolType := SymbolArr64[i].n_type;
StringOffset := SymbolArr64[i].n_un.n_strx;
SymbolValue := SymbolArr64[i].n_value;
end
else
begin
SymbolType := SymbolArr[i].n_type;
StringOffset := SymbolArr[i].n_un.n_strx;
SymbolValue := SymbolArr[i].n_value;
end;
if SymbolType = N_SECT then
begin
s := pchar(SymbolStr+StringOffset);
ind := MainDwarfDebugMap.GlobalList.Find(s);
if assigned(ind) then
begin
AddressMap:=MainDwarfDebugMap.GlobalList.Items[s];
AddressMap.OrgAddr:=SymbolArr[i].n_value;
AddressMap.OrgAddr:=SymbolValue;
AddressMapList.Add(AddressMap);
end;
end;
if SymbolArr[i].n_type = N_SECT+N_EXT then
if SymbolType = N_SECT+N_EXT then
begin
s := pchar(SymbolStr+SymbolArr[i].n_un.n_strx);
s := pchar(SymbolStr+StringOffset);
ind := MainDwarfDebugMap.GlobalList.Find(s);
if assigned(ind) then
begin
AddressMap:=MainDwarfDebugMap.GlobalList.Items[s];
AddressMap.OrgAddr:=SymbolArr[i].n_value;
AddressMap.OrgAddr:=SymbolValue;
AddressMapList.Add(AddressMap);
end;
end;

View File

@ -430,44 +430,46 @@ var
begin
Result := False;
// WINDOWS gdb dwarf names
{$IFDEF cpu64}
case ARegNum of
0: rname := 'RAX'; // RAX
1: rname := 'RDX'; // RDX
2: rname := 'RCX'; // RCX
3: rname := 'RBX'; // RBX
4: rname := 'RSI';
5: rname := 'RDI';
6: rname := 'RBP';
7: rname := 'RSP';
8: rname := 'R8'; // R8D , but gdb uses R8
9: rname := 'R9';
10: rname := 'R10';
11: rname := 'R11';
12: rname := 'R12';
13: rname := 'R13';
14: rname := 'R14';
15: rname := 'R15';
16: rname := 'RIP';
else
exit;
if FDebugger.FDwarfInfo.Image64Bit then begin
case ARegNum of
0: rname := 'RAX'; // RAX
1: rname := 'RDX'; // RDX
2: rname := 'RCX'; // RCX
3: rname := 'RBX'; // RBX
4: rname := 'RSI';
5: rname := 'RDI';
6: rname := 'RBP';
7: rname := 'RSP';
8: rname := 'R8'; // R8D , but gdb uses R8
9: rname := 'R9';
10: rname := 'R10';
11: rname := 'R11';
12: rname := 'R12';
13: rname := 'R13';
14: rname := 'R14';
15: rname := 'R15';
16: rname := 'RIP';
else
exit;
end;
end
else begin
case ARegNum of
0: rname := 'EAX'; // RAX
1: rname := 'ECX'; // RDX
2: rname := 'EDX'; // RCX
3: rname := 'EBX'; // RBX
4: rname := 'ESP';
5: rname := 'EBP';
6: rname := 'ESI';
7: rname := 'EDI';
8: rname := 'EIP';
else
exit;
end;
end;
{$ELSE}
case ARegNum of
0: rname := 'EAX'; // RAX
1: rname := 'ECX'; // RDX
2: rname := 'EDX'; // RCX
3: rname := 'EBX'; // RBX
4: rname := 'ESP';
5: rname := 'EBP';
6: rname := 'ESI';
7: rname := 'EDI';
8: rname := 'EIP';
else
exit;
end;
{$ENDIF}
assert(AContext <> nil, 'TFpLldbDbgMemReader.ReadRegister: AContext <> nil');
Reg := FDebugger.Registers.CurrentRegistersList[AContext.ThreadId, AContext.StackFrame];
@ -493,11 +495,10 @@ end;
function TFpLldbDbgMemReader.RegisterSize(ARegNum: Cardinal): Integer;
begin
{$IFDEF cpu64}
Result := 8; // for the very few supported...
{$ELSE}
Result := 4; // for the very few supported...
{$ENDIF}
if FDebugger.FDwarfInfo.Image64Bit then
Result := 8 // for the very few supported...
else
Result := 4; // for the very few supported...
end;
{ TFpLldbDbgMemCacheManagerSimple }