mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 10:57:55 +02:00
138 lines
3.2 KiB
ObjectPascal
138 lines
3.2 KiB
ObjectPascal
unit FpImgReaderMachoFile;
|
|
|
|
{$T-} // TODO: Fix compilation with -Sy.
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
//todo: powerpc, x86_64
|
|
|
|
uses
|
|
Classes, SysUtils, macho, FpImgReaderBase,
|
|
FpDbgCommon;
|
|
|
|
type
|
|
TMachOsection = class(TObject)
|
|
is32 : Boolean;
|
|
sec32 : section;
|
|
sec64 : section_64;
|
|
end;
|
|
|
|
{ TMachOFile }
|
|
|
|
TMachOFile = class(TObject)
|
|
private
|
|
cmdbuf : array of byte;
|
|
FTargetInfo : TTargetDescriptor;
|
|
public
|
|
header : mach_header;
|
|
commands : array of pload_command;
|
|
sections : TFPList;
|
|
UUID : TGuid;
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
function LoadFromFile(ALoader: TDbgFileLoader): Boolean;
|
|
property TargetInfo: TTargetDescriptor read FTargetInfo;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
{ TMachOFile }
|
|
|
|
constructor TMachOFile.Create;
|
|
begin
|
|
sections := TFPList.Create;
|
|
end;
|
|
|
|
destructor TMachOFile.Destroy;
|
|
var
|
|
i : integer;
|
|
begin
|
|
for i := 0 to sections.Count - 1 do TMachOsection(sections[i]).Free;
|
|
sections.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TMachOFile.LoadFromFile(ALoader: TDbgFileLoader): Boolean;
|
|
var
|
|
i : Integer;
|
|
j : Integer;
|
|
ofs : Integer;
|
|
sc32: psection;
|
|
sc64: psection_64;
|
|
idcm: puuid_command;
|
|
s : TMachOsection;
|
|
hs : integer;
|
|
i64 : boolean;
|
|
begin
|
|
Result := ALoader.Read(0, sizeof(header), @header) = sizeof(header);
|
|
if not Result then Exit;
|
|
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
|
|
begin
|
|
hs := sizeof(mach_header_64);
|
|
FTargetInfo.bitness := b64;
|
|
end
|
|
else
|
|
begin
|
|
hs := SizeOf(mach_header);
|
|
FTargetInfo.bitness := b32;
|
|
end;
|
|
case header.cputype of
|
|
CPU_TYPE_I386 : FTargetInfo.MachineType := mt386;
|
|
CPU_TYPE_ARM : FTargetInfo.MachineType := mtARM;
|
|
CPU_TYPE_SPARC : FTargetInfo.MachineType := mtSPARC;
|
|
//CPU_TYPE_ALPHA : FTargetInfo.MachineType := mtALPHA;
|
|
CPU_TYPE_POWERPC : FTargetInfo.MachineType := mtPPC;
|
|
CPU_TYPE_POWERPC64 : FTargetInfo.MachineType := mtPPC;
|
|
CPU_TYPE_X86_64 : FTargetInfo.MachineType := mtX86_64;
|
|
CPU_TYPE_ARM64 : FTargetInfo.MachineType := mtARM;
|
|
else
|
|
FTargetInfo.machineType := mtNone;
|
|
end;
|
|
|
|
SetLength(cmdbuf, header.sizeofcmds);
|
|
ALoader.Read(hs, header.sizeofcmds, @cmdbuf[0]);
|
|
|
|
SetLength(commands, header.ncmds);
|
|
ofs := 0;
|
|
for i := 0 to header.ncmds - 1 do begin
|
|
commands[i] := @cmdbuf[ofs];
|
|
|
|
if commands[i]^.cmd = LC_SEGMENT then begin
|
|
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:=sc32^;
|
|
sections.add(s);
|
|
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
|
|
else if commands[i]^.cmd = LC_UUID then begin
|
|
idcm := @cmdbuf[ofs];
|
|
UUID:=PGuid(@(idcm^.uuid))^;
|
|
end;
|
|
inc(ofs, commands[i]^.cmdsize);
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
end.
|
|
|