|
@@ -17,10 +17,11 @@ type
|
|
_TMachOSymbolTable_ = class(TMachOSymbolTable)
|
|
_TMachOSymbolTable_ = class(TMachOSymbolTable)
|
|
protected
|
|
protected
|
|
function AddSymbol(aName : string; sect : byte; addr : longword;
|
|
function AddSymbol(aName : string; sect : byte; addr : longword;
|
|
- glob : boolean) : integer; override;
|
|
|
|
|
|
+ glob, undef : boolean) : integer; override;
|
|
protected
|
|
protected
|
|
public
|
|
public
|
|
procedure WriteToStream(aStream : TStream); override;
|
|
procedure WriteToStream(aStream : TStream); override;
|
|
|
|
+ procedure SetSymbolOffset(symbolnum : integer; offset: longword); override;
|
|
end;
|
|
end;
|
|
|
|
|
|
_TMachOSubWriter_ = class(TAbstractMachOSubWriter)
|
|
_TMachOSubWriter_ = class(TAbstractMachOSubWriter)
|
|
@@ -43,13 +44,17 @@ type
|
|
{ _TMachOSymbolTable_ }
|
|
{ _TMachOSymbolTable_ }
|
|
|
|
|
|
function _TMachOSymbolTable_.AddSymbol(aName: string; sect: byte; addr: longword;
|
|
function _TMachOSymbolTable_.AddSymbol(aName: string; sect: byte; addr: longword;
|
|
- glob: boolean): integer;
|
|
|
|
|
|
+ glob, undef: boolean): integer;
|
|
var p : _PNlist_;
|
|
var p : _PNlist_;
|
|
begin
|
|
begin
|
|
p:=GetMem(sizeof(_TNlist_));
|
|
p:=GetMem(sizeof(_TNlist_));
|
|
p^.strx:=fStringTable.Add(aName);
|
|
p^.strx:=fStringTable.Add(aName);
|
|
- p^._type:=N_SECT;
|
|
|
|
- if glob then p^._type:=p^._type or N_EXT;
|
|
|
|
|
|
+ if not undef then
|
|
|
|
+ p^._type:=N_SECT
|
|
|
|
+ else
|
|
|
|
+ p^._type:=N_UNDF;
|
|
|
|
+ if glob then
|
|
|
|
+ p^._type:=p^._type or N_EXT;
|
|
p^.desc:=0;
|
|
p^.desc:=0;
|
|
p^.sect:=sect;
|
|
p^.sect:=sect;
|
|
p^.value:=addr;
|
|
p^.value:=addr;
|
|
@@ -60,10 +65,20 @@ end;
|
|
procedure _TMachOSymbolTable_.WriteToStream(aStream: TStream);
|
|
procedure _TMachOSymbolTable_.WriteToStream(aStream: TStream);
|
|
var nlist : _TNlist_;
|
|
var nlist : _TNlist_;
|
|
i : integer;
|
|
i : integer;
|
|
|
|
+ sawglobal: boolean;
|
|
begin
|
|
begin
|
|
|
|
+ { first write local symbols, then global ones, as ilocalsym is hardcoded to
|
|
|
|
+ be index 0. Can't reorder here because we may already have used symbol
|
|
|
|
+ numbers to generate relocations -> give an error if a global symbol
|
|
|
|
+ comes before any local symbols }
|
|
|
|
+ sawglobal:=false;
|
|
for i:=0 to fList.Count-1 do
|
|
for i:=0 to fList.Count-1 do
|
|
begin
|
|
begin
|
|
nlist:=_PNlist_(fList[i])^;
|
|
nlist:=_PNlist_(fList[i])^;
|
|
|
|
+ if (nlist._type and N_EXT)<>0 then
|
|
|
|
+ sawglobal:=true
|
|
|
|
+ else if sawglobal then
|
|
|
|
+ raise EMachOResourceWriterSymbolTableWrongOrderException.Create('');
|
|
if fOppositeEndianess then
|
|
if fOppositeEndianess then
|
|
begin
|
|
begin
|
|
nlist.strx:=SwapEndian(nlist.strx);
|
|
nlist.strx:=SwapEndian(nlist.strx);
|
|
@@ -74,6 +89,14 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure _TMachOSymbolTable_.SetSymbolOffset(symbolnum: integer; offset: longword);
|
|
|
|
+var
|
|
|
|
+ p : _PNlist_;
|
|
|
|
+begin
|
|
|
|
+ p:=_PNlist_(flist[symbolnum]);
|
|
|
|
+ p^.value:=offset;
|
|
|
|
+end;
|
|
|
|
+
|
|
{ _TMachOSubWriter_ }
|
|
{ _TMachOSubWriter_ }
|
|
|
|
|
|
procedure _TMachOSubWriter_.SwapSection(var aSection: _TSection_);
|
|
procedure _TMachOSubWriter_.SwapSection(var aSection: _TSection_);
|
|
@@ -108,8 +131,13 @@ begin
|
|
hdr.count:=aResources.Count;
|
|
hdr.count:=aResources.Count;
|
|
hdr.usedhandles:=0;
|
|
hdr.usedhandles:=0;
|
|
hdr.handles:=0;
|
|
hdr.handles:=0;
|
|
- fRelocations.Add(0,1);
|
|
|
|
- fRelocations.Add(sizeof(hdr.rootptr)+sizeof(hdr.count)+sizeof(hdr.usedhandles),2);
|
|
|
|
|
|
+ { the first pointer (rootptr at offset 0) goes to the root node, which comes
|
|
|
|
+ right after the header (the addend has been set to sizeof(hdr) -> add the
|
|
|
|
+ address of the fpc.resources section to it via a relocations}
|
|
|
|
+ fRelocations.Add(0,ffpcresourcessym);
|
|
|
|
+ { the last pointer (handles at offset sizeof(fields before it)) goes to the
|
|
|
|
+ fpc.reshandles section }
|
|
|
|
+ fRelocations.Add(sizeof(hdr.rootptr)+sizeof(hdr.count)+sizeof(hdr.usedhandles),ffpcreshandlessym);
|
|
if fOppositeEndianess then
|
|
if fOppositeEndianess then
|
|
begin
|
|
begin
|
|
hdr.rootptr:=SwapEndian(hdr.rootptr);
|
|
hdr.rootptr:=SwapEndian(hdr.rootptr);
|
|
@@ -123,6 +151,7 @@ end;
|
|
|
|
|
|
procedure _TMachOSubWriter_.WriteNodeInfos(aStream: TStream);
|
|
procedure _TMachOSubWriter_.WriteNodeInfos(aStream: TStream);
|
|
begin
|
|
begin
|
|
|
|
+ { offset inside the object }
|
|
fCurOfs:=sizeof(_TResHdr_);
|
|
fCurOfs:=sizeof(_TResHdr_);
|
|
WriteNodeInfo(aStream,fRoot);
|
|
WriteNodeInfo(aStream,fRoot);
|
|
WriteSubNodes(aStream,fRoot);
|
|
WriteSubNodes(aStream,fRoot);
|
|
@@ -137,7 +166,7 @@ begin
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
infonode.nameid:=fResStrTable.StartOfs+aNode.NameRVA;
|
|
infonode.nameid:=fResStrTable.StartOfs+aNode.NameRVA;
|
|
- fRelocations.Add(fCurOfs,1);
|
|
|
|
|
|
+ fRelocations.Add(fCurOfs,ffpcresourcessym);
|
|
end;
|
|
end;
|
|
infonode.ncount:=aNode.NamedCount;
|
|
infonode.ncount:=aNode.NamedCount;
|
|
if aNode.IsLeaf then
|
|
if aNode.IsLeaf then
|
|
@@ -153,7 +182,7 @@ begin
|
|
end;
|
|
end;
|
|
fRelocations.Add(
|
|
fRelocations.Add(
|
|
fCurOfs+sizeof(infonode.nameid)+sizeof(infonode.ncount)+
|
|
fCurOfs+sizeof(infonode.nameid)+sizeof(infonode.ncount)+
|
|
- sizeof(infonode.idcountsize),1);
|
|
|
|
|
|
+ sizeof(infonode.idcountsize),ffpcresourcessym);
|
|
if fOppositeEndianess then
|
|
if fOppositeEndianess then
|
|
begin
|
|
begin
|
|
infonode.nameid:=SwapEndian(infonode.nameid);
|
|
infonode.nameid:=SwapEndian(infonode.nameid);
|
|
@@ -170,7 +199,7 @@ var buf : pbyte;
|
|
begin
|
|
begin
|
|
fHeader.sizeofcmds:=
|
|
fHeader.sizeofcmds:=
|
|
//segment+res section+bss section
|
|
//segment+res section+bss section
|
|
- sizeof(_TSegmentCommand_)+sizeof(_TSection_)*2+
|
|
|
|
|
|
+ sizeof(_TSegmentCommand_)+sizeof(_TSection_)*3+
|
|
//symbol table and dynamic symbol table commands
|
|
//symbol table and dynamic symbol table commands
|
|
sizeof(TSymtabCommand)+sizeof(TDySymtabCommand)+
|
|
sizeof(TSymtabCommand)+sizeof(TDySymtabCommand)+
|
|
//common header of the three commands
|
|
//common header of the three commands
|
|
@@ -189,21 +218,35 @@ var ldcommand : TLoadCommand;
|
|
segcommand : _TSegmentCommand_;
|
|
segcommand : _TSegmentCommand_;
|
|
symcommand : TSymtabCommand;
|
|
symcommand : TSymtabCommand;
|
|
dysymcommand : TDySymtabCommand;
|
|
dysymcommand : TDySymtabCommand;
|
|
- ressection,bsssection : _TSection_;
|
|
|
|
|
|
+ ressection,bsssection,textsection : _TSection_;
|
|
begin
|
|
begin
|
|
ldcommand.cmd:=fSegType;
|
|
ldcommand.cmd:=fSegType;
|
|
- ldcommand.cmdsize:=sizeof(TLoadCommand)+sizeof(segcommand)+sizeof(ressection)*2;
|
|
|
|
|
|
+ ldcommand.cmdsize:=sizeof(TLoadCommand)+sizeof(segcommand)+sizeof(ressection)*3;
|
|
|
|
|
|
FillByte(segcommand.name[0],16,0);
|
|
FillByte(segcommand.name[0],16,0);
|
|
segcommand.vmaddr:=0;
|
|
segcommand.vmaddr:=0;
|
|
segcommand.vmsize:=fDataCurOfs+sizeof(_ptrtype_)*aResources.Count;
|
|
segcommand.vmsize:=fDataCurOfs+sizeof(_ptrtype_)*aResources.Count;
|
|
segcommand.fileoff:=fSectionStart;
|
|
segcommand.fileoff:=fSectionStart;
|
|
segcommand.filesize:=fDataCurOfs;
|
|
segcommand.filesize:=fDataCurOfs;
|
|
- segcommand.maxprot:=VM_PROT_READ or VM_PROT_WRITE;
|
|
|
|
- segcommand.initprot:=VM_PROT_READ or VM_PROT_WRITE;
|
|
|
|
- segcommand.nsects:=2;
|
|
|
|
|
|
+ segcommand.maxprot:=VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE;
|
|
|
|
+ segcommand.initprot:=VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE;
|
|
|
|
+ segcommand.nsects:=3;
|
|
segcommand.flags:=0;
|
|
segcommand.flags:=0;
|
|
|
|
|
|
|
|
+ fillbyte(textsection,sizeof(textsection),0);
|
|
|
|
+ textsection.sectname:='__text';
|
|
|
|
+ textsection.segname:='__TEXT';
|
|
|
|
+ textsection.addr:=0;
|
|
|
|
+ textsection.size:=0;
|
|
|
|
+ textsection.offset:=segcommand.fileoff;
|
|
|
|
+ textsection.align:=0;
|
|
|
|
+ textsection.reloff:=0;
|
|
|
|
+ textsection.nreloc:=0;
|
|
|
|
+ textsection.flags:=S_ATTR_PURE_INSTRUCTIONS;
|
|
|
|
+ textsection.reserved1:=0;
|
|
|
|
+ textsection.reserved2:=0;
|
|
|
|
+
|
|
|
|
+ fillbyte(ressection,sizeof(ressection),0);
|
|
ressection.sectname:=RsrcSectName;
|
|
ressection.sectname:=RsrcSectName;
|
|
ressection.segname:=DataSegName;
|
|
ressection.segname:=DataSegName;
|
|
ressection.addr:=0;
|
|
ressection.addr:=0;
|
|
@@ -216,6 +259,7 @@ begin
|
|
ressection.reserved1:=0;
|
|
ressection.reserved1:=0;
|
|
ressection.reserved2:=0;
|
|
ressection.reserved2:=0;
|
|
|
|
|
|
|
|
+ fillbyte(bsssection,sizeof(bsssection),0);
|
|
bsssection.sectname:=HandlesSectName;
|
|
bsssection.sectname:=HandlesSectName;
|
|
bsssection.segname:=DataSegName;
|
|
bsssection.segname:=DataSegName;
|
|
bsssection.addr:=fDataCurOfs;
|
|
bsssection.addr:=fDataCurOfs;
|
|
@@ -242,12 +286,14 @@ begin
|
|
segcommand.nsects:=SwapEndian(segcommand.nsects);
|
|
segcommand.nsects:=SwapEndian(segcommand.nsects);
|
|
segcommand.flags:=SwapEndian(segcommand.flags);
|
|
segcommand.flags:=SwapEndian(segcommand.flags);
|
|
|
|
|
|
|
|
+ SwapSection(textsection);
|
|
SwapSection(ressection);
|
|
SwapSection(ressection);
|
|
SwapSection(bsssection);
|
|
SwapSection(bsssection);
|
|
end;
|
|
end;
|
|
|
|
|
|
aStream.WriteBuffer(ldcommand,sizeof(ldcommand));
|
|
aStream.WriteBuffer(ldcommand,sizeof(ldcommand));
|
|
aStream.WriteBuffer(segcommand,sizeof(segcommand));
|
|
aStream.WriteBuffer(segcommand,sizeof(segcommand));
|
|
|
|
+ aStream.WriteBuffer(textsection,sizeof(textsection));
|
|
aStream.WriteBuffer(ressection,sizeof(ressection));
|
|
aStream.WriteBuffer(ressection,sizeof(ressection));
|
|
aStream.WriteBuffer(bsssection,sizeof(bsssection));
|
|
aStream.WriteBuffer(bsssection,sizeof(bsssection));
|
|
|
|
|