From f81a1f3ea6035fd2cb2bd7dc4399e34dc4aa6b5e Mon Sep 17 00:00:00 2001 From: joost Date: Sun, 25 May 2014 16:38:40 +0000 Subject: [PATCH] LazDebuggerFp (pure): Read macho-64 binaries git-svn-id: trunk@45173 - --- components/fpdebug/fpdbgclasses.pp | 6 ++++ components/fpdebug/fpdbgloader.pp | 17 +++++++++-- components/fpdebug/fpimgreadermacho.pas | 5 ++-- components/fpdebug/fpimgreadermachofile.pas | 32 +++++++++++++++------ components/fpdebug/macho.pas | 19 ++++++++++++ 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/components/fpdebug/fpdbgclasses.pp b/components/fpdebug/fpdbgclasses.pp index bfbb7107b9..c7e783e2f7 100644 --- a/components/fpdebug/fpdbgclasses.pp +++ b/components/fpdebug/fpdbgclasses.pp @@ -202,6 +202,7 @@ type TDbgInstance = class(TObject) private + FMode: TFPDMode; FName: String; FOnDebugInfoLoaded: TNotifyEvent; FProcess: TDbgProcess; @@ -226,6 +227,7 @@ type property DbgInfo: TDbgInfo read FDbgInfo; property SymbolTableInfo: TFpSymbolInfo read FSymbolTableInfo; property OnDebugInfoLoaded: TNotifyEvent read FOnDebugInfoLoaded write FOnDebugInfoLoaded; + property Mode: TFPDMode read FMode; end; { TDbgLibrary } @@ -620,6 +622,10 @@ end; procedure TDbgInstance.LoadInfo; begin FLoader := InitializeLoader; + if FLoader.Image64Bit then + FMode:=dm64 + else + FMode:=dm32; FDbgInfo := TFpDwarfInfo.Create(FLoader); TFpDwarfInfo(FDbgInfo).LoadCompilationUnits; FSymbolTableInfo := TFpSymbolInfo.Create(FLoader); diff --git a/components/fpdebug/fpdbgloader.pp b/components/fpdebug/fpdbgloader.pp index 51c9e698a3..3ea6182841 100644 --- a/components/fpdebug/fpdbgloader.pp +++ b/components/fpdebug/fpdbgloader.pp @@ -56,12 +56,11 @@ type private FFileLoader: TDbgFileLoader; FImgReader: TDbgImageReader; + function GetImage64Bit: Boolean; protected - FImage64Bit: Boolean unimplemented; FImageBase: QWord unimplemented; function GetSection(const AName: String): PDbgImageSection; virtual; //procedure SetImageBase(ABase: QWord); - //procedure SetImage64Bit(AValue: Boolean); property ImgReader: TDbgImageReader read FImgReader write FImgReader; public constructor Create; virtual; @@ -73,7 +72,7 @@ type destructor Destroy; override; function IsValid: Boolean; property ImageBase: QWord read FImageBase; unimplemented; - Property Image64Bit: Boolean read FImage64Bit; unimplemented; + Property Image64Bit: Boolean read GetImage64Bit; property Section[const AName: String]: PDbgImageSection read GetSection; end; @@ -83,6 +82,18 @@ implementation { TDbgImageLoader } +function TDbgImageLoader.GetImage64Bit: Boolean; +begin + if not assigned(ImgReader) then + {$ifdef cpui386} + result := false + {$else} + result := true + {$endif} + else + result := ImgReader.Image64Bit; +end; + function TDbgImageLoader.GetSection(const AName: String): PDbgImageSection; begin if FImgReader <> nil then diff --git a/components/fpdebug/fpimgreadermacho.pas b/components/fpdebug/fpimgreadermacho.pas index 367ccaddbf..01c21b4355 100644 --- a/components/fpdebug/fpimgreadermacho.pas +++ b/components/fpdebug/fpimgreadermacho.pas @@ -57,10 +57,10 @@ begin try Result := Assigned(ASource); if not Result then Exit; - //Result := stream.Read(header, sizeof(header)) = sizeof(header); Result := ASource.Read(0, sizeof(header), @header) = sizeof(header); if not Result then Exit; - Result := (header.magic = MH_CIGAM) or (header.magic = MH_MAGIC); + Result := (header.magic = MH_CIGAM) or (header.magic = MH_MAGIC) or + (header.magic = MH_CIGAM_64) or (header.magic = MH_MAGIC_64); except Result := false; end; @@ -133,6 +133,7 @@ begin Break; end; end; + SetImage64Bit((fFile.header.cputype and CPU_ARCH_ABI64)=CPU_ARCH_ABI64); fileRead := true; end; diff --git a/components/fpdebug/fpimgreadermachofile.pas b/components/fpdebug/fpimgreadermachofile.pas index bf7f082092..3b1bba0a20 100644 --- a/components/fpdebug/fpimgreadermachofile.pas +++ b/components/fpdebug/fpimgreadermachofile.pas @@ -55,17 +55,23 @@ var i : Integer; j : Integer; ofs : Integer; - sc : psection; + sc32: psection; + sc64: psection_64; s : TMachOsection; + hs : integer; + i64 : boolean; begin - //Stream.Read(header, sizeof(header)); Result := ALoader.Read(0, sizeof(header), @header) = sizeof(header); if not Result then Exit; - Result := (header.magic = MH_MAGIC) or (header.magic = MH_CIGAM); + i64 := (header.magic = MH_CIGAM_64) or (header.magic = MH_MAGIC_64); + Result := (header.magic = MH_MAGIC) or (header.magic = MH_CIGAM) or i64; + if i64 then + hs := sizeof(mach_header_64) + else + hs := SizeOf(mach_header); SetLength(cmdbuf, header.sizeofcmds); - //Stream.Read(cmdbuf[0], header.sizeofcmds); - ALoader.Read(sizeof(header), header.sizeofcmds, @cmdbuf[0]); + ALoader.Read(hs, header.sizeofcmds, @cmdbuf[0]); SetLength(commands, header.ncmds); ofs := 0; @@ -73,13 +79,23 @@ begin commands[i] := @cmdbuf[ofs]; if commands[i]^.cmd = LC_SEGMENT then begin - sc := @cmdbuf[ofs+sizeof(segment_command)]; + sc32 := @cmdbuf[ofs+sizeof(segment_command)]; for j := 0 to psegment_command(commands[i])^.nsects- 1 do begin s := TMachOSection.Create; s.is32:=true; - s.sec32:=sc^; + s.sec32:=sc32^; sections.add(s); - inc(sc); + inc(sc32); + end; + end + else if commands[i]^.cmd = LC_SEGMENT_64 then begin + sc64 := @cmdbuf[ofs+sizeof(segment_command_64)]; + for j := 0 to psegment_command_64(commands[i])^.nsects- 1 do begin + s := TMachOSection.Create; + s.is32:=False; + s.sec64:=sc64^; + sections.add(s); + inc(sc64); end; end; diff --git a/components/fpdebug/macho.pas b/components/fpdebug/macho.pas index 7f7d1ef782..ba2154a9d9 100644 --- a/components/fpdebug/macho.pas +++ b/components/fpdebug/macho.pas @@ -390,6 +390,7 @@ type reserved2 : uint32_t; { reserved (for count or sizeof) } reserved3 : uint32_t; { reserved } end; + psection_64 = ^section_64; {* The flags field of a section structure is separated into two parts a section * type and section attributes. The section types are mutually exclusive (it @@ -1138,6 +1139,24 @@ const FAT_MAGIC = $cafebabe; FAT_CIGAM = $bebafeca; +const + CPU_ARCH_MASK = $ff000000; { mask for architecture bits } + CPU_ARCH_ABI64 = $01000000; { 64 bit ABI } + + CPU_TYPE_VAX = 1; + CPU_TYPE_MC680x0 = 6; + CPU_TYPE_X86 = 7; + CPU_TYPE_I386 = CPU_TYPE_X86; + CPU_TYPE_X86_64 = CPU_TYPE_X86 and CPU_ARCH_ABI64; + CPU_TYPE_MC98000 = 10; + CPU_TYPE_HPPA = 11; + CPU_TYPE_ARM = 12; + CPU_TYPE_MC88000 = 13; + CPU_TYPE_SPARC = 14; + CPU_TYPE_I860 = 15; + CPU_TYPE_POWERPC = 18; + CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC and CPU_ARCH_ABI64; + type fat_header = record magic : uint32_t; { FAT_MAGIC }