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

View File

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

View File

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

View File

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

View File

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