File: fpimgreadermachofile.pas

package info (click to toggle)
lazarus 2.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 214,460 kB
  • sloc: pascal: 1,862,622; xml: 265,709; cpp: 56,595; sh: 3,008; java: 609; makefile: 535; perl: 297; sql: 222; ansic: 137
file content (114 lines) | stat: -rw-r--r-- 2,490 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
unit FpImgReaderMachoFile;

{$mode objfpc}{$H+}

interface

//todo: powerpc, x86_64

uses
  Classes, SysUtils, macho, FpImgReaderBase;

type
  TMachOsection = class(TObject)
    is32   : Boolean;
    sec32  : section;
    sec64  : section_64;
  end;

  { TMachOFile }

  TMachOFile = class(TObject)
  private
    cmdbuf    : array of byte;
  public
    header    : mach_header;
    commands  : array of pload_command;
    sections  : TFPList;
    UUID      : TGuid;
    constructor Create;
    destructor Destroy; override;
    function  LoadFromFile(ALoader: TDbgFileLoader): Boolean;
  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
    hs := sizeof(mach_header_64)
  else
    hs := SizeOf(mach_header);
  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.