12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466 |
- {
- Copyright (c) 2009-2010 by Dmitry Boyarintsev
- Contains utility routines and types for handling mach-o structure and types.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- unit machoutils;
- interface
- {$mode objfpc}{$h+}
- uses
- macho;
- type
- TRawWriter=class(TObject)
- public
- procedure WriteRaw(const data; datasize: Integer); virtual; abstract;
- end;
- TRawReader=class(TObject)
- public
- function ReadRaw(var data; datasize: Integer): Integer; virtual; abstract;
- function Seek(pos: qword): Boolean; virtual; abstract;
- function ReadPos: qword; virtual; abstract;
- end;
- TMachHeader=record
- cputype : cpu_type_t;
- cpusubtype : cpu_subtype_t;
- filetype : longword;
- ncmds : longword;
- sizeofcmds : longword;
- flags : longword;
- end;
- TSegmentName=string[16];
- TSectionName=TSegmentName;
- TMachoSegment=record
- segname : TSegmentName;
- vmaddr : qword;
- vmsize : qword;
- fileoff : qword;
- filesize : qword;
- maxprot : vm_prot_t;
- initprot : vm_prot_t;
- nsects : longword;
- flags : longword;
- end;
- TMachoSection=record
- sectname : TSectionName;
- segname : TSegmentName;
- addr : uint64_t;
- size : uint64_t;
- offset : uint32_t;
- align : uint32_t;
- reloff : uint32_t;
- nreloc : uint32_t;
- flags : uint32_t;
- indirectIndex : Integer; // reserved1 for LAZY and NON_LAZY pointers
- stubSize : Integer; // reserved2 for S_SYMBOL_STUBS
- end;
- TMachoRoutine=record
- init_address : uint64_t; { address of initialization routine }
- init_module : uint64_t; { index into the module table that }
- end;
- { TMachoWriter }
- TMachoWriter=class(TObject)
- private
- fwriter : TRawWriter;
- fown : Boolean;
- protected
- public
- constructor Create(ARawWriter: TRawWriter; AllowFreeWriter: Boolean);
- destructor Destroy; override;
- { non platform specific writer }
- procedure WriteData(const data; dataSize: Integer);
- procedure WriteUint8(i: uint8_t);
- { endian specific writer }
- procedure WriteUint16(i: uint16_t); virtual; abstract;
- procedure WriteUint32(i: uint32_t); virtual; abstract;
- procedure WriteUint64(i: uint64_t); virtual; abstract;
- { endian and ptr-size specific writer }
- procedure WritePtr(ofs: QWord); virtual; abstract; // ptr is 32 bit for 32-bit platforms
- { macro utility methods }
- procedure WriteHeader(const hdr: TMachHeader); virtual; abstract;
- procedure WriteSegmentCmd(const seg: TMachoSegment; cmdSize: LongWord); virtual; abstract;
- procedure WriteSection(const sec: TMachoSection); virtual; abstract;
- procedure WriteRoutineCmd(const rt: TMachoRoutine); virtual; abstract;
- procedure WriteLoadCommand(const cmd: load_command); virtual; abstract; overload;
- procedure WriteLoadCommand(cmd, cmdsize: Integer); overload;
- procedure WriteRelocation(const ri: relocation_info); virtual; abstract;
- procedure WriteScatterReloc(const ri: scattered_relocation_info); virtual; abstract;
- procedure WriteNList(const list: nlist_64); virtual; abstract;
- end;
- { TLE32MachoWriter }
- TLE32MachoWriter=class(TMachoWriter)
- public
- procedure WriteUint16(i: uint16_t); override;
- procedure WriteUint32(i: uint32_t); override;
- procedure WriteUint64(i: uint64_t); override;
- procedure WritePtr(ofs: QWord); override;
- procedure WriteHeader(const hdr: TMachHeader); override;
- procedure WriteSegmentCmd(const seg: TMachoSegment; ACmdSize: LongWord); override;
- procedure WriteSection(const sec: TMachoSection); override;
- procedure WriteRoutineCmd(const rt: TMachoRoutine); override;
- procedure WriteLoadCommand(const cmd: load_command); override;
- procedure WriteRelocation(const ri: relocation_info); override;
- procedure WriteScatterReloc(const ri: scattered_relocation_info); override;
- procedure WriteNList(const list: nlist_64); override;
- end;
- { TLE64MachoWriter }
- TLE64MachoWriter=class(TLE32MachoWriter)
- public
- procedure WritePtr(ofs: QWord); override;
- procedure WriteHeader(const hdr: TMachHeader); override;
- procedure WriteSegmentCmd(const seg: TMachoSegment; acmdSize: LongWord); override;
- procedure WriteSection(const sec: TMachoSection); override;
- procedure WriteRoutineCmd(const rt: TMachoRoutine); override;
- procedure WriteNList(const list: nlist_64); override;
- end;
- { TBE32MachoWriter }
- TBE32MachoWriter=class(TMachoWriter)
- public
- procedure WriteUint16(i: uint16_t); override;
- procedure WriteUint32(i: uint32_t); override;
- procedure WriteUint64(i: uint64_t); override;
- procedure WritePtr(ofs: QWord); override;
- procedure WriteHeader(const hdr: TMachHeader); override;
- procedure WriteSegmentCmd(const seg: TMachoSegment; acmdSize: LongWord); override;
- procedure WriteSection(const sec: TMachoSection); override;
- procedure WriteRoutineCmd(const rt: TMachoRoutine); override;
- procedure WriteLoadCommand(const cmd: load_command); override;
- procedure WriteRelocation(const ri: relocation_info); override;
- procedure WriteScatterReloc(const ri: scattered_relocation_info); override;
- procedure WriteNList(const list: nlist_64); override;
- end;
- { TBE64MachoWriter }
- TBE64MachoWriter=class(TBE32MachoWriter)
- public
- procedure WritePtr(ofs: QWord); override;
- procedure WriteHeader(const hdr: TMachHeader); override;
- procedure WriteSegmentCmd(const seg: TMachoSegment; acmdSize: LongWord); override;
- procedure WriteSection(const sec: TMachoSection); override;
- procedure WriteRoutineCmd(const rt: TMachoRoutine); override;
- procedure WriteNList(const list: nlist_64); override;
- end;
- { TLEMachoStructConverter }
- { converter for Little-endian structures to Host }
- TLEMachoStructConverter = class(TObject)
- public
- procedure ConvertMachoHeader(const mh: mach_header; var hdr: TMachHeader); virtual;
- procedure ConvertMachoHeader64(const mh: mach_header_64; var hdr: TMachHeader); virtual;
- procedure ConvertLoadCommand(var cmd: load_command); virtual;
- procedure ConvertSegment(const segcmd: segment_command; var segment: TMachoSegment); virtual;
- procedure ConvertSegment64(const segcmd: segment_command_64; var segment: TMachoSegment); virtual;
- procedure ConvertSection(const sec: section; var section: TMachoSection); virtual;
- procedure ConvertSection64(const sec: section_64; var section: TMachoSection); virtual;
- procedure ConvertUInt16(var v: Word); virtual;
- procedure ConvertUInt32(var v: LongWord); virtual;
- procedure ConvertUInt64(var v: qWord); virtual;
- end;
- { converter for Big-endian structures to Host }
- TBEMachoStructConverter = class(TLEMachoStructConverter);
- {common}
- TMachoStructConverter = TLEMachoStructConverter;
- { TMachoReader }
- TMachoReader=class(TObject)
- private
- fReader : TRawReader;
- HdrOfs : qword;
- fCnv : TMachoStructConverter;
- fHdr : TMachHeader;
- is64 : Boolean;
- cmdofs : array of qword;
- cmds : array of load_command;
- protected
- function IntReadStruct: Boolean;
- public
- constructor Create(ARawReader: TRawReader; StartOfs: QWord=0);
- function ReadHeader(var hdr: TMachHeader): Boolean;
- function ReadCommandID(index: LongWord; var cmd: load_command): Boolean;
- function GetCmdOfs(index: LongWord): qword;
- function ReadSegmentCommand(cmdindex: LongWord; var segment: TMachoSegment): Boolean;
- function ReadSection(segindex, secindex: LongWord; var machsection: TMachoSection): Boolean;
- function ReadSymTabCmd(var symcmd: symtab_command): Boolean;
- function ReadUInt32(var v: LongWord): Boolean;
- function ReadData(var data; dataSize: Integer): Integer;
- {todo: ReadNList - using index of symbol, instead of file offset?}
- function GetNListSize: Integer;
- function ReadNList(fileofs: qword; var nsym: nlist_64): Boolean;
- procedure Seek(apos: qword);
- end;
- const
- seg_TEXT : TSegmentName = '__TEXT';
- seg_DATA : TSegmentName = '__DATA';
- seg_OBJC : TSegmentName = '__OBJC';
- seg_IMPORT : TSegmentName = '__IMPORT';
- seg_DWARF : TSegmentName = '__DWARF';
- function AllocMachoWriter(cputarget: cpu_type_t; ARawWriter: TRawWriter; AllowFreeWriter: Boolean): TMachoWriter;
- function sizeMachHeader(cputarget: cpu_type_t): integer; inline;
- function sizeSegment(cputarget: cpu_type_t): integer; inline;
- function sizeSection(cputarget: cpu_type_t): integer; inline;
- function sizeNList(cputarget: cpu_type_t): integer; inline;
- function AlignAddr(cputarget: cpu_type_t; addr: qword): qword;
- procedure InitSegment(var seg: TMachoSegment);
- function MakeSectionName(const segName, secName: shortstring): shortstring;
- function GetSegmentSectionName(const objSecName: shortstring; var segName, secName: shortstring): shortstring;
- function GetSectionFlags(const segName, secName: shortstring): LongWord;
- type
- TRelocInfoLength = (ril_byte = 0, ril_word = 1, ril_long = 2, ril_quad = 3);
- procedure RelocInfo(addr, symnum, reltype: integer; len: TRelocInfoLength; pcrel, extern: Boolean; var info: relocation_info);
- procedure ScatterRelocInfo(value, addr, reltype: integer; len: TRelocInfoLength; pcrel: Boolean; var info: scattered_relocation_info);
- function GetReserved1(const macho: TMachoSection): integer;
- function GetReserved2(const macho: TMachoSection): integer;
- function GetStubSize(cputarget: Integer; Pic: Boolean): Integer;
- function MachoAlign(al: integer): integer;
- implementation
- function MachoAlign(al: integer): integer;
- begin
- Result:=0;
- al:=al shr 1;
- while al>0 do
- begin
- inc(Result);
- al:=al shr 1;
- end;
- end;
- function AllocConverter(magic: LongWord): TMachoStructConverter;
- begin
- {$ifdef ENDIAN_BIG}
- if magic=MH_MAGIC then
- Result:=TBEMachoStructConverter.Create
- else
- Result:=TLEMachoStructConverter.Create;
- {$else}
- if magic=MH_MAGIC then
- Result:=TLEMachoStructConverter.Create
- else
- Result:=TBEMachoStructConverter.Create;
- {$endif}
- end;
- {result values are used from aggas.pas, see TGNUAssembler.WriteSection }
- function GetStubSize(cputarget: Integer; Pic: Boolean): Integer;
- begin
- case cputarget of
- CPU_TYPE_I386, CPU_TYPE_X86_64:
- Result:=5;
- CPU_TYPE_POWERPC, CPU_TYPE_POWERPC64:
- if Pic then
- Result:=32
- else
- Result:=16;
- CPU_TYPE_ARM:
- if Pic then
- Result:=16
- else
- Result:=12;
- else
- Result:=-1;
- end;
- end;
- function GetReserved1(const macho: TMachoSection): integer;
- begin
- case macho.flags and SECTION_TYPE of
- S_NON_LAZY_SYMBOL_POINTERS, S_LAZY_SYMBOL_POINTERS:
- Result:=macho.indirectIndex;
- else
- Result:=0;
- end;
- end;
- function GetReserved2(const macho: TMachoSection): integer;
- begin
- case macho.flags and SECTION_TYPE of
- S_SYMBOL_STUBS:
- Result:=macho.stubSize
- else
- Result:=0;
- end;
- end;
- procedure RelocInfo(addr, symnum, reltype: integer; len: TRelocInfoLength; pcrel, extern: Boolean; var info: relocation_info);
- {$ifdef ENDIAN_BIG}
- const
- relbit : array [Boolean] of Integer = (0, 1 shl 7);
- extbit : array [Boolean] of Integer = (0, 1 shl 4);
- ri_len_mask : array [TRelocInfoLength] of Integer = (0 shl 5, 1 shl 5, 2 shl 5, 3 shl 5);
- begin
- info.r_address:=addr;
- info.r_info:=((symnum and $FFFFFF) shl 8) or // r_symbolnum:24
- relbit[pcrel] or // r_pcrel:1;
- ri_len_mask[len] or // r_length:2;
- extbit[extern] or // r_extern:1;
- (reltype and $F); // r_type:4;
- end;
- {$else}
- const
- relbit : array [Boolean] of Integer = (0, 1 shl 24);
- extbit : array [Boolean] of Integer = (0, 1 shl 27);
- ri_len_mask : array [TRelocInfoLength] of Integer = (0 shl 25, 1 shl 25, 2 shl 25, 3 shl 25);
- begin
- info.r_address:=addr;
- info.r_info:=(symnum and $FFFFFF) or // r_symbolnum:24
- relbit[pcrel] or // r_pcrel:1;
- extbit[extern] or // r_length:2;
- ri_len_mask[len] or // r_extern:1;
- (reltype shl 28); // r_type:4;
- end;
- {$endif}
- const
- si_len_mask: array [TRelocInfoLength] of Integer = (0 shl 28, 1 shl 28, 2 shl 28, 3 shl 28);
- si_type_ofs = 24;
- si_pcrel_bit = 1 shl 30;
- si_scatter_bit = 1 shl 31;
- si_addr_ofs = 0;
- procedure ScatterRelocInfo(value, addr, reltype: integer; len: TRelocInfoLength; pcrel: Boolean; var info: scattered_relocation_info);
- const
- relbit : array [Boolean] of Integer = (0, si_pcrel_bit);
- begin
- // big endian
- info.r_info:=si_scatter_bit or // r_scattered:1, /* 1=scattered, 0=non-scattered (see above) */
- relbit[pcrel] or // r_pcrel:1, /* was relocated pc relative already */
- si_len_mask[len] or // r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
- ((reltype and $F) shl si_type_ofs) or // r_type:4, /* if not 0, machine specific relocation type */
- ((addr and $FFFFFF) shl si_addr_ofs); // r_address:24; /* offset in the section to what is being relocated */}
- info.r_value:=value;
- // little endian
- // r_address:24, /* offset in the section to what is being relocated */
- // r_type:4, /* if not 0, machine specific relocation type */
- // r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
- // r_pcrel:1, /* was relocated pc relative already */
- // r_scattered:1; /* 1=scattered, 0=non-scattered (see above) */ *}
- end;
- function GetSectionFlags(const segName, secName: shortstring): LongWord;
- begin
- Result:=0;
- if segName = seg_DATA then
- begin
- if secName = '__nl_symbol_ptr' then
- Result:=Result or S_NON_LAZY_SYMBOL_POINTERS
- else if secName = '__la_symbol_ptr' then
- Result:=Result or S_LAZY_SYMBOL_POINTERS
- else if secName = '__common' then
- Result:=Result or S_ZEROFILL
- end
- else if segName = seg_TEXT then
- begin
- if (secName = '__text') then
- Result:=Result or S_ATTR_PURE_INSTRUCTIONS or S_ATTR_SOME_INSTRUCTIONS
- else if secName = '__textcoal_nt' then
- Result:=Result or S_ATTR_PURE_INSTRUCTIONS or S_ATTR_SOME_INSTRUCTIONS or S_COALESCED
- else if secName = '.fpc' then
- Result:=Result or S_ATTR_NO_DEAD_STRIP
- else if secName = '__cstring' then
- Result:=Result or S_CSTRING_LITERALS;
- end
- else if (segName = seg_IMPORT) then
- begin
- if (secName = '__jump_table') then
- Result:=Result or S_SYMBOL_STUBS or S_ATTR_SELF_MODIFYING_CODE or S_ATTR_SOME_INSTRUCTIONS
- end
- else if (segName=seg_OBJC) then
- begin
- Result:=S_ATTR_NO_DEAD_STRIP;
- if secName='__message_refs' then
- Result:=Result or S_ATTR_NO_DEAD_STRIP or S_LITERAL_POINTERS
- else if secName='__cls_refs' then
- Result:=Result or S_ATTR_NO_DEAD_STRIP or S_LITERAL_POINTERS;
- end;
- end;
- function MakeSectionName(const segName, secName: shortstring): shortstring;
- begin
- if segName = '' then
- Result:=secName
- else
- Result:=segName+' '+secName;
- end;
- function GetSegmentSectionName(const objSecName: shortstring; var segName, secName: shortstring): shortstring;
- var
- i : integer;
- begin
- i:=Pos(' ', objSecName);
- if i>0 then
- begin
- segName:=copy(objsecName, 1, i-1);
- secName:=copy(objsecName, i+1, length(objsecName)-i);
- end
- else
- begin
- segName:='';
- secName:=objSecName;
- end;
- Result:=objSecName;
- end;
- procedure InitSegment(var seg: TMachoSegment);
- begin
- FillChar(seg, sizeof(seg), 0);
- seg.initprot:=VM_PROT_ALL;
- seg.maxprot:=VM_PROT_ALL;
- end;
- const
- is64MachHeaderSize : array [Boolean] of Integer = ( sizeof(mach_header), sizeof(mach_header_64));
- is64SectionSize : array [Boolean] of Integer = ( sizeof(section), sizeof(section_64));
- is64SegmentSize : array [Boolean] of Integer = ( sizeof(segment_command), sizeof(segment_command_64));
- is64NListSize : array [Boolean] of Integer = (sizeof(nlist), sizeof(nlist_64));
- function AlignAddr(cputarget: cpu_type_t; addr: qword): qword;
- var
- md : array [Boolean] of integer = (4, 8);
- p : PtrUInt;
- begin
- p:=addr;
- p:=align(p, md[cputarget and CPU_ARCH_ABI64 > 0]);
- Result:=qword(p);
- end;
- function sizeMachHeader(cputarget: cpu_type_t): integer;
- begin
- Result:=is64MachHeaderSize[ cputarget and CPU_ARCH_ABI64 > 0];
- end;
- function sizeSegment(cputarget: cpu_type_t): integer;
- begin
- Result:=is64SegmentSize[ cputarget and CPU_ARCH_ABI64 > 0];
- end;
- function sizeSection(cputarget: cpu_type_t): integer;
- begin
- Result:=is64SectionSize[ cputarget and CPU_ARCH_ABI64 > 0];
- end;
- function sizeNList(cputarget: cpu_type_t): integer; inline;
- begin
- Result:=is64NlistSize[ cputarget and CPU_ARCH_ABI64 > 0];
- end;
- function AllocMachoWriter(cputarget: cpu_type_t; ARawWriter: TRawWriter; AllowFreeWriter: Boolean): TMachoWriter;
- begin
- case cputarget of
- CPU_TYPE_I386,
- CPU_TYPE_ARM: Result:=TLE32MachoWriter.Create(ARawWriter, AllowFreeWriter);
- CPU_TYPE_X86_64: Result:=TLE64MachoWriter.Create(ARawWriter, AllowFreeWriter);
- CPU_TYPE_POWERPC: Result:=TBE32MachoWriter.Create(ARawWriter, AllowFreeWriter);
- CPU_TYPE_POWERPC64: Result:=TBE64MachoWriter.Create(ARawWriter, AllowFreeWriter);
- else
- begin
- if AllowFreeWriter then
- ARawWriter.Free;
- Result:=nil;
- end;
- end;
- end;
- { TMachoWriter }
- procedure TMachoWriter.WriteData(const data; dataSize: Integer);
- begin
- if not assigned(fwriter) then
- Exit;
- fwriter.WriteRaw(data, dataSize);
- end;
- procedure TMachoWriter.WriteUint8(i: uint8_t);
- begin
- WriteData(i, sizeof(i));
- end;
- procedure TMachoWriter.WriteLoadCommand(cmd, cmdsize: Integer);
- var
- m : load_command;
- begin
- m.cmd:=cmd;
- m.cmdsize:=cmdsize;
- WriteLoadCommand(m);
- end;
- constructor TMachoWriter.Create(ARawWriter: TRawWriter; AllowFreeWriter: Boolean);
- begin
- inherited Create;
- fwriter:=ARawWriter;
- fown:=AllowFreeWriter;
- end;
- destructor TMachoWriter.Destroy;
- begin
- if fown then
- fwriter.Free;
- inherited Destroy;
- end;
- { TLE32MachoWriter }
- procedure TLE32MachoWriter.WriteHeader(const hdr: TMachHeader);
- var
- m : mach_header;
- begin
- with m do
- begin
- magic:=NtoLE(MH_MAGIC);
- cputype:=NtoLE(hdr.cputype);
- cpusubtype:=NtoLE(hdr.cpusubtype);
- filetype:=NtoLE(hdr.filetype);
- ncmds:=NtoLE(hdr.ncmds);
- sizeofcmds:=NtoLE(hdr.sizeofcmds);
- flags:=NtoLE(hdr.flags);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteSegmentCmd(const seg: TMachoSegment; ACmdSize: LongWord);
- var
- m : segment_command;
- begin
- with m do
- begin
- cmd:=NtoLE(LC_SEGMENT);
- cmdsize:=NtoLE(ACmdSize);
- segname:=seg.segname;
- vmaddr:=NtoLE(uint32_t(seg.vmaddr));
- vmsize:=NtoLE(uint32_t(seg.vmsize));
- fileoff:=NtoLE(uint32_t(seg.fileoff));
- filesize:=NtoLE(uint32_t(seg.filesize));
- maxprot:=NtoLE(seg.maxprot);
- initprot:=NtoLE(seg.initprot);
- nsects:=NtoLE(seg.nsects);
- flags:=NtoLE(seg.flags);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteSection(const sec: TMachoSection);
- var
- m : section;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- sectname:=sec.sectname;
- segname:=sec.segname;
- addr:=NtoLE(sec.addr);
- size:=NtoLE(sec.size);
- offset:=NtoLE(sec.offset);
- align:=NtoLE(sec.align);
- reloff:=NtoLE(sec.reloff);
- nreloc:=NtoLE(sec.nreloc);
- flags:=NtoLE(sec.flags);
- reserved1:=NtoLE( GetReserved1(sec));
- reserved2:=NtoLE( GetReserved2(sec));
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteRoutineCmd(const rt: TMachoRoutine);
- var
- m : routines_command;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- cmd:=NtoLE(LC_ROUTINES);
- cmdsize:=NtoLE(sizeof(m));
- init_address:=NtoLE(rt.init_address);
- init_module:=NtoLE(rt.init_module);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteLoadCommand(const cmd: load_command);
- var
- m : load_command;
- begin
- m.cmd:=NtoLE(cmd.cmd);
- m.cmdsize:=NtoLE(cmd.cmdsize);
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteRelocation(const ri: relocation_info);
- var
- m : relocation_info;
- begin
- m.r_address:=NtoLE(ri.r_address);
- m.r_info:=NtoLE(ri.r_info);
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteScatterReloc(const ri: scattered_relocation_info);
- var
- m : LongWord;
- begin
- m:=LongWord(ri.r_info);
- WriteUint32(NtoLE(m));
- m:=LongWord(ri.r_value);
- WriteUint32(NtoLE(m));
- end;
- procedure TLE32MachoWriter.WriteNList(const list: nlist_64);
- var
- m : nlist;
- begin
- m.n_un.n_strx:=NtoLe(list.n_un.n_strx);
- m.n_type:=NtoLe(list.n_type);
- m.n_sect:=NtoLe(list.n_sect);
- m.n_desc:=NtoLe(list.n_desc);
- m.n_value:=NtoLe(list.n_value);
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteUint16(i: uint16_t);
- var
- m: uint16_t;
- begin
- m:=NtoLE(i);
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteUint32(i: uint32_t);
- var
- m: uint32_t;
- begin
- m:=NtoLE(i);
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WriteUint64(i: uint64_t);
- var
- m: uint64_t;
- begin
- m:=NtoLE(i);
- WriteData(m, sizeof(m));
- end;
- procedure TLE32MachoWriter.WritePtr(ofs: QWord);
- var
- m: uint32_t;
- begin
- m:=NtoLE(ofs);
- WriteData(m, sizeof(m));
- end;
- { TLE64MachoWriter }
- procedure TLE64MachoWriter.WritePtr(ofs: QWord);
- var
- m : uint64_t;
- begin
- m:=NtoLE(ofs);
- Writedata(m, sizeof(m));
- end;
- procedure TLE64MachoWriter.WriteHeader(const hdr: TMachHeader);
- var
- m : mach_header_64;
- begin
- with m do
- begin
- magic:=NtoLE(MH_MAGIC_64);
- cputype:=NtoLE(hdr.cputype);
- cpusubtype:=NtoLE(hdr.cpusubtype);
- filetype:=NtoLE(hdr.filetype);
- ncmds:=NtoLE(hdr.ncmds);
- sizeofcmds:=NtoLE(hdr.sizeofcmds);
- flags:=NtoLE(hdr.flags);
- reserved:=0;
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE64MachoWriter.WriteSegmentCmd(const seg: TMachoSegment; acmdSize: LongWord);
- var
- m : segment_command_64;
- begin
- with m do
- begin
- cmd:=NtoLE(LC_SEGMENT_64);
- cmdsize:=NtoLE(acmdSize);
- segname:=seg.segname;
- vmaddr:=NtoLE(seg.vmaddr);
- vmsize:=NtoLE(seg.vmsize);
- fileoff:=NtoLE(seg.fileoff);
- filesize:=NtoLE(seg.filesize);
- maxprot:=NtoLE(seg.maxprot);
- initprot:=NtoLE(seg.initprot);
- nsects:=NtoLE(seg.nsects);
- flags:=NtoLE(seg.flags);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE64MachoWriter.WriteSection(const sec: TMachoSection);
- var
- m : section_64;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- sectname:=sec.sectname;
- segname:=sec.segname;
- addr:=NtoLE(sec.addr);
- size:=NtoLE(sec.size);
- offset:=NtoLE(sec.offset);
- align:=NtoLE(sec.align);
- reloff:=NtoLE(sec.reloff);
- nreloc:=NtoLE(sec.nreloc);
- flags:=NtoLE(sec.flags);
- reserved1:=NtoLE( GetReserved1(sec));
- reserved2:=NtoLE( GetReserved2(sec));
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE64MachoWriter.WriteRoutineCmd(const rt: TMachoRoutine);
- var
- m : routines_command_64;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- cmd:=NtoLE(LC_ROUTINES);
- cmdsize:=NtoLE(sizeof(m));
- init_address:=NtoLE(rt.init_address);
- init_module:=NtoLE(rt.init_module);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TLE64MachoWriter.WriteNList(const list: nlist_64);
- var
- m : nlist_64;
- begin
- m.n_un.n_strx:=NtoLe(list.n_un.n_strx);
- m.n_type:=NtoLe(list.n_type);
- m.n_sect:=NtoLe(list.n_sect);
- m.n_desc:=NtoLe(list.n_desc);
- m.n_value:=NtoLe(list.n_value);
- WriteData(m, sizeof(m));
- end;
- { TBE32MachoWriter }
- procedure TBE32MachoWriter.WriteHeader(const hdr: TMachHeader);
- var
- m : mach_header;
- begin
- with m do
- begin
- magic:=NtoBE(MH_MAGIC);
- cputype:=NtoBE(hdr.cputype);
- cpusubtype:=NtoBE(hdr.cpusubtype);
- filetype:=NtoBE(hdr.filetype);
- ncmds:=NtoBE(hdr.ncmds);
- sizeofcmds:=NtoBE(hdr.sizeofcmds);
- flags:=NtoBE(hdr.flags);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteSegmentCmd(const seg: TMachoSegment; acmdSize: LongWord);
- var
- m : segment_command;
- begin
- with m do
- begin
- cmd:=NtoBE(LC_SEGMENT);
- cmdsize:=NtoBE(acmdSize);
- segname:=seg.segname;
- vmaddr:=NtoBE(uint32_t(seg.vmaddr));
- vmsize:=NtoBE(uint32_t(seg.vmsize));
- fileoff:=NtoBE(uint32_t(seg.fileoff));
- filesize:=NtoBE(uint32_t(seg.filesize));
- maxprot:=NtoBE(seg.maxprot);
- initprot:=NtoBE(seg.initprot);
- nsects:=NtoBE(seg.nsects);
- flags:=NtoBE(seg.flags);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteSection(const sec: TMachoSection);
- var
- m : section;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- sectname:=sec.sectname;
- segname:=sec.segname;
- addr:=NtoBE(sec.addr);
- size:=NtoBE(sec.size);
- offset:=NtoBE(sec.offset);
- align:=NtoBE(sec.align);
- reloff:=NtoBE(sec.reloff);
- nreloc:=NtoBE(sec.nreloc);
- flags:=NtoBE(sec.flags);
- reserved1:=NtoBE( GetReserved1(sec));
- reserved2:=NtoBE( GetReserved2(sec));
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteRoutineCmd(const rt: TMachoRoutine);
- var
- m : routines_command;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- cmd:=NtoBE(LC_ROUTINES);
- cmdsize:=NtoBE(sizeof(m));
- init_address:=NtoBE(rt.init_address);
- init_module:=NtoBE(rt.init_module);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteLoadCommand(const cmd: load_command);
- var
- m : load_command;
- begin
- m.cmd:=NtoBE(cmd.cmd);
- m.cmdsize:=NtoBE(cmd.cmdsize);
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteRelocation(const ri: relocation_info);
- var
- m : relocation_info;
- begin
- m.r_address:=NtoBE(ri.r_address);
- m.r_info:=NtoBE(ri.r_info);
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteScatterReloc(const ri: scattered_relocation_info);
- var
- m : LongWord;
- begin
- m:=LongWord(ri.r_info);
- WriteUint32(NtoBE(m));
- m:=LongWord(ri.r_value);
- WriteUint32(NtoBE(m));
- end;
- procedure TBE32MachoWriter.WriteNList(const list: nlist_64);
- var
- m : nlist;
- begin
- m.n_un.n_strx:=NtoBe(list.n_un.n_strx);
- m.n_type:=NtoBe(list.n_type);
- m.n_sect:=NtoBe(list.n_sect);
- m.n_desc:=NtoBe(list.n_desc);
- m.n_value:=NtoBe(list.n_value);
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteUint16(i: uint16_t);
- var
- m: uint16_t;
- begin
- m:=NtoBE(i);
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteUint32(i: uint32_t);
- var
- m: uint32_t;
- begin
- m:=NtoBE(i);
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WriteUint64(i: uint64_t);
- var
- m: uint64_t;
- begin
- m:=NtoBE(i);
- WriteData(m, sizeof(m));
- end;
- procedure TBE32MachoWriter.WritePtr(ofs: QWord);
- var
- m: uint32_t;
- begin
- m:=NtoBE(ofs);
- WriteData(m, sizeof(m));
- end;
- { TBE64MachoWriter }
- procedure TBE64MachoWriter.WritePtr(ofs: QWord);
- var
- m : uint64_t;
- begin
- m:=NtoBE(ofs);
- Writedata(m, sizeof(m));
- end;
- procedure TBE64MachoWriter.WriteHeader(const hdr: TMachHeader);
- var
- m : mach_header_64;
- begin
- with m do
- begin
- magic:=NtoBE(MH_MAGIC_64);
- cputype:=NtoBE(hdr.cputype);
- cpusubtype:=NtoBE(hdr.cpusubtype);
- filetype:=NtoBE(hdr.filetype);
- ncmds:=NtoBE(hdr.ncmds);
- sizeofcmds:=NtoBE(hdr.sizeofcmds);
- flags:=NtoBE(hdr.flags);
- reserved:=0;
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE64MachoWriter.WriteSegmentCmd(const seg: TMachoSegment; acmdSize: LongWord);
- var
- m : segment_command_64;
- begin
- with m do
- begin
- cmd:=NtoBE(LC_SEGMENT_64);
- cmdsize:=NtoBE(acmdSize);
- segname:=seg.segname;
- vmaddr:=NtoBE(seg.vmaddr);
- vmsize:=NtoBE(seg.vmsize);
- fileoff:=NtoBE(seg.fileoff);
- filesize:=NtoBE(seg.filesize);
- maxprot:=NtoBE(seg.maxprot);
- initprot:=NtoBE(seg.initprot);
- nsects:=NtoBE(seg.nsects);
- flags:=NtoBE(seg.flags);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE64MachoWriter.WriteSection(const sec: TMachoSection);
- var
- m : section_64;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- sectname:=sec.sectname;
- segname:=sec.segname;
- addr:=NtoBE(sec.addr);
- size:=NtoBE(sec.size);
- offset:=NtoBE(sec.offset);
- align:=NtoBE(sec.align);
- reloff:=NtoBE(sec.reloff);
- nreloc:=NtoBE(sec.nreloc);
- flags:=NtoBE(sec.flags);
- reserved1:=NtoBE( GetReserved1(sec));
- reserved2:=NtoBE( GetReserved2(sec));
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE64MachoWriter.WriteRoutineCmd(const rt: TMachoRoutine);
- var
- m : routines_command_64;
- begin
- FillChar(m, sizeof(m), 0);
- with m do
- begin
- cmd:=NtoBE(LC_ROUTINES);
- cmdsize:=NtoBE(sizeof(m));
- init_address:=NtoBE(rt.init_address);
- init_module:=NtoBE(rt.init_module);
- end;
- WriteData(m, sizeof(m));
- end;
- procedure TBE64MachoWriter.WriteNList(const list: nlist_64);
- var
- m : nlist_64;
- begin
- m.n_un.n_strx:=NtoBe(list.n_un.n_strx);
- m.n_type:=NtoBe(list.n_type);
- m.n_sect:=NtoBe(list.n_sect);
- m.n_desc:=NtoBe(list.n_desc);
- m.n_value:=NtoBe(list.n_value);
- WriteData(m, sizeof(m));
- end;
- { TMachoReader }
- constructor TMachoReader.Create(ARawReader: TRawReader; StartOfs: QWord=0);
- begin
- inherited Create;
- fReader:=ARawReader;
- hdrofs:=StartOfs;
- end;
- function TMachoReader.IntReadStruct: Boolean;
- var
- m : mach_header_64;
- i : Integer;
- p : qword;
- begin
- Result:=false;
- if not fReader.Seek(hdrofs) then
- Exit;
- //todo:
- fReader.ReadRaw(m, sizeof(mach_header_64));
- fCnv:=AllocConverter(m.magic);
- fCnv.ConvertMachoHeader(pmach_header(@m)^, fhdr);
- is64:=fhdr.cputype and CPU_ARCH_ABI64>0;
- Result:=true;
- SetLength(cmds, fHdr.ncmds);
- if fHdr.ncmds>0 then
- begin
- if is64 then
- p:=sizeof(mach_header_64)
- else
- p:=sizeof(mach_header);
- SetLength(cmdofs, fHdr.ncmds);
- for i:=0 to fHdr.ncmds - 1 do
- begin
- cmdofs[i]:=p;
- fReader.Seek(p);
- fReader.ReadRaw(cmds[i], sizeof(cmds[i]));
- fCnv.ConvertLoadCommand(cmds[i]);
- inc(p, cmds[i].cmdsize);
- end;
- end;
- end;
- function TMachoReader.ReadHeader(var hdr: TMachHeader): Boolean;
- begin
- if not Assigned(fCnv) then
- Result:=IntReadStruct
- else
- Result:=true;
- hdr:=fhdr;
- end;
- function TMachoReader.ReadCommandID(index: LongWord; var cmd: load_command): Boolean;
- begin
- if not Assigned(fCnv) then
- IntReadStruct;
- Result:={(index>=0) and }(index<fHdr.ncmds);
- if not Result then
- Exit;
- Result:=true;
- cmd:=cmds[index];
- end;
- function TMachoReader.ReadSegmentCommand(cmdindex: LongWord; var segment: TMachoSegment): Boolean;
- var
- seg64 : segment_command_64;
- seg32 : segment_command;
- begin
- if not Assigned(fCnv) then
- IntReadStruct;
- Result:={(cmdindex>=0) and }
- (cmdindex<fHdr.ncmds) and
- (cmds[cmdindex].cmd in [LC_SEGMENT, LC_SEGMENT_64]);
- if Result then
- begin
- fReader.Seek(cmdofs[cmdindex]);
- if is64 then
- begin
- Result:=fReader.ReadRaw(seg64, sizeof(seg64))=sizeof(seg64);
- if Result then
- fCnv.ConvertSegment64(seg64, segment);
- end
- else
- begin
- Result:=fReader.ReadRaw(seg32, sizeof(seg32))=sizeof(seg32);
- if Result then
- fCnv.ConvertSegment(seg32, segment);
- end;
- end;
- end;
- function TMachoReader.GetCmdOfs(index: LongWord): qword;
- begin
- if not Assigned(fCnv) then
- IntReadStruct;
- if {(index<0) or}
- (index>=longword(length(cmdofs))) then
- Result:=0
- else
- Result:=cmdofs[index];
- end;
- function TMachoReader.ReadSection(segindex, secindex: LongWord; var machsection: TMachoSection): Boolean;
- var
- ofs : qword;
- is64bit : Boolean;
- buf : array [0..sizeof(section_64)-1] of byte;
- const
- sectsize : array[Boolean] of LongWord = ( sizeof(macho.section), sizeof(macho.section_64));
- segsize : array[Boolean] of LongWord = ( sizeof(macho.segment_command), sizeof(macho.segment_command_64));
- begin
- if not Assigned(fCnv) then
- IntReadStruct;
- Result:={(secindex>=0) and (segindex>=0) and }(segindex<fHdr.ncmds) and (cmds[segindex].cmd in [LC_SEGMENT, LC_SEGMENT_64]);
- if not Result then
- Exit;
- is64bit:=cmds[segindex].cmd=LC_SEGMENT_64;
- Result:=secindex<(cmds[segindex].cmdsize-segsize[is64bit]) div sectsize[is64bit];
- if not Result then
- Exit;
- ofs:=cmdofs[segindex]+segsize[is64bit]+sectsize[is64]*secindex;
- fReader.Seek(ofs);
- fReader.ReadRaw(buf, segsize[is64bit]);
- if is64bit then
- fCnv.ConvertSection64( psection_64(@buf)^, machsection)
- else
- fCnv.ConvertSection( psection(@buf)^, machsection);
- end;
- function TMachoReader.ReadUInt32(var v: LongWord): Boolean;
- begin
- if not Assigned(fCnv) then
- IntReadStruct;
- Result:=Assigned(fCnv) and (fReader.ReadRaw(v, sizeof(v))=sizeof(v));
- if Result then
- fCnv.ConvertUint32(v);
- end;
- function TMachoReader.ReadData(var data; dataSize: Integer): Integer;
- begin
- Result:=fReader.ReadRaw(data, dataSize);
- end;
- function TMachoReader.GetNListSize: Integer;
- begin
- if is64 then
- Result:=sizeof(nlist_64)
- else
- Result:=sizeof(nlist);
- end;
- function TMachoReader.ReadNList(fileofs: qword; var nsym: nlist_64): Boolean;
- var
- n32 : nlist;
- begin
- fReader.Seek(fileofs);
- if is64 then
- Result:=fReader.ReadRaw(nsym, sizeof(nlist_64))=sizeof(nlist_64)
- else
- begin
- Result:=fReader.ReadRaw(n32, sizeof(nlist))=sizeof(nlist);
- nsym.n_un.n_strx:=n32.n_un.n_strx;
- nsym.n_desc:=n32.n_desc;
- nsym.n_sect:=n32.n_sect;
- nsym.n_type:=n32.n_type;
- nsym.n_value:=n32.n_value;
- end;
- fCnv.ConvertUInt32(nsym.n_un.n_strx);
- fCnv.ConvertUInt16(nsym.n_desc);
- fCnv.ConvertUInt64(nsym.n_value);
- end;
- function TMachoReader.ReadSymTabCmd(var symcmd: symtab_command): Boolean;
- var
- i : Integer;
- p : qword;
- begin
- if not Assigned(fCnv) then
- IntReadStruct;
- for i:=0 to length(cmds)-1 do
- if cmds[i].cmd=LC_SYMTAB then
- begin
- p:=fReader.ReadPos;
- fReader.Seek(cmdofs[i]);
- fReader.ReadRaw(symcmd, sizeof(symcmd));
- fCnv.ConvertUInt32(symcmd.cmd);
- fCnv.ConvertUInt32(symcmd.cmdsize);
- fCnv.ConvertUInt32(symcmd.symoff);
- fCnv.ConvertUInt32(symcmd.nsyms);
- fCnv.ConvertUInt32(symcmd.stroff);
- fCnv.ConvertUInt32(symcmd.strsize);
- fReader.Seek(p);
- Result:=true;
- Exit;
- end;
- Result:=false;
- end;
- procedure TMachoReader.Seek(apos: qword);
- begin
- fReader.Seek(apos);
- end;
- { TLEMachoStructConverter }
- procedure TLEMachoStructConverter.ConvertMachoHeader(const mh: mach_header; var hdr: TMachHeader);
- begin
- hdr.cputype:=LEToN(mh.cputype);
- hdr.cpusubtype:=LEtoN(mh.cpusubtype);
- hdr.filetype:=LEToN(mh.filetype);
- hdr.ncmds:=LEToN(mh.ncmds);
- hdr.sizeofcmds:=LEToN(mh.ncmds);
- hdr.flags:=LEToN(mh.flags);
- end;
- procedure TLEMachoStructConverter.ConvertMachoHeader64(const mh: mach_header_64; var hdr: TMachHeader);
- begin
- hdr.cputype:=LEToN(mh.cputype);
- hdr.cpusubtype:=LEtoN(mh.cpusubtype);
- hdr.filetype:=LEToN(mh.filetype);
- hdr.ncmds:=LEToN(mh.ncmds);
- hdr.sizeofcmds:=LEToN(mh.ncmds);
- hdr.flags:=LEToN(mh.flags);
- end;
- procedure TLEMachoStructConverter.ConvertLoadCommand(var cmd: load_command);
- begin
- cmd.cmd:=LEToN(cmd.cmd);
- cmd.cmdsize:=LEToN(cmd.cmdsize);
- end;
- procedure TLEMachoStructConverter.ConvertSegment(const segcmd: segment_command; var segment: TMachoSegment);
- begin
- FillChar(segment, sizeof(segment), 0);
- segment.segname:=segcmd.segname;
- segment.vmaddr:=LEToN(segcmd.vmaddr);
- segment.vmsize:=LEToN(segcmd.vmsize);
- segment.fileoff:=LEToN(segcmd.fileoff);
- segment.filesize:=LEToN(segcmd.filesize);
- segment.maxprot:=LEToN(segcmd.maxprot);
- segment.initprot:=LEToN(segcmd.initprot);
- writelN('segcmd.nsects = ', segcmd.nsects);
- segment.nsects:=LEToN(segcmd.nsects);
- segment.flags:=LEToN(segcmd.flags);
- //todo: reserved!?
- end;
- procedure TMachoStructConverter.ConvertSegment64(const segcmd: segment_command_64; var segment: TMachoSegment);
- begin
- FillChar(segment, sizeof(segment), 0);
- segment.segname:=segcmd.segname;
- segment.vmaddr:=LEToN(segcmd.vmaddr);
- segment.vmsize:=LEToN(segcmd.vmsize);
- segment.fileoff:=LEToN(segcmd.fileoff);
- segment.filesize:=LEToN(segcmd.filesize);
- segment.maxprot:=LEToN(segcmd.maxprot);
- segment.initprot:=LEToN(segcmd.initprot);
- segment.nsects:=LEToN(segcmd.nsects);
- segment.flags:=LEToN(segcmd.flags);
- //todo: reserved!?
- end;
- procedure TMachoStructConverter.ConvertSection(const sec: section; var section: TMachoSection);
- begin
- FillChar(section, sizeof(section), 0);
- section.sectname:=sec.sectname;
- section.segname:=sec.segname;
- section.addr:=LEToN(sec.addr);
- section.size:=LEToN(sec.size);
- section.offset:=LEToN(sec.offset);
- section.align:=LEToN(sec.align);
- section.reloff:=LEToN(sec.reloff);
- section.nreloc:=LEToN(sec.nreloc);
- section.flags:=LEToN(sec.flags);
- //todo:
- //section.indirectIndex : Integer; // reserved1 for LAZY and NON_LAZY pointers
- //section.stubSize : Integer; // reserved2 for S_SYMBOL_STUBS
- end;
- procedure TMachoStructConverter.ConvertSection64(const sec: section_64; var section: TMachoSection);
- begin
- FillChar(section, sizeof(section), 0);
- section.sectname:=sec.sectname;
- section.segname:=sec.segname;
- section.addr:=LEToN(sec.addr);
- section.size:=LEToN(sec.size);
- section.offset:=LEToN(sec.offset);
- section.align:=LEToN(sec.align);
- section.reloff:=LEToN(sec.reloff);
- section.nreloc:=LEToN(sec.nreloc);
- section.flags:=LEToN(sec.flags);
- //todo:
- //section.indirectIndex : Integer; // reserved1 for LAZY and NON_LAZY pointers
- //section.stubSize : Integer; // reserved2 for S_SYMBOL_STUBS
- end;
- procedure TMachoStructConverter.ConvertUInt32(var v: LongWord);
- begin
- v:=LEtoN(v);
- end;
- procedure TMachoStructConverter.ConvertUInt64(var v: qword);
- begin
- v:=LEtoN(v);
- end;
- procedure TMachoStructConverter.ConvertUInt16(var v: Word);
- begin
- v:=LEToN(v);
- end;
- end.
|