+ ELF linker: support writing DT_PREINIT_ARRAY/DT_INIT_ARRAY/DT_FINI_ARRAY dynamic tags. Still misses a lot of sanity checks, and does not sort entries.

git-svn-id: trunk@29561 -
This commit is contained in:
sergei 2015-01-26 20:34:16 +00:00
parent 2efa348b19
commit 53c943c5a1

View File

@ -254,7 +254,9 @@ interface
hashobjsec: TElfObjSection;
neededlist: TFPHashList;
dyncopysyms: TFPObjectList;
preinitarraysec,
initarraysec,
finiarraysec: TObjSection;
function AttachSection(objsec:TObjSection):TElfExeSection;
function CreateSegment(atype,aflags,aalign:longword):TElfSegment;
procedure WriteHeader;
@ -2347,12 +2349,15 @@ implementation
procedure TElfExeOutput.Order_end;
procedure set_oso_keep(const s:string);
procedure set_oso_keep(const s:string;out firstsec:TObjSection);
var
exesec:TExeSection;
objsec:TObjSection;
i:longint;
sz: aword;
begin
firstsec:=nil;
sz:=0;
exesec:=TExeSection(ExeSectionList.Find(s));
if assigned(exesec) then
begin
@ -2361,23 +2366,33 @@ implementation
objsec:=TObjSection(exesec.ObjSectionList[i]);
{ ignore sections used for symbol definition }
if oso_data in objsec.SecOptions then
objsec.SecOptions:=[oso_keep];
begin
if firstsec=nil then
firstsec:=objsec;
objsec.SecOptions:=[oso_keep];
inc(sz,objsec.size);
end;
end;
exesec.size:=sz;
end;
end;
var
dummy: TObjSection;
begin
OrderOrphanSections;
inherited Order_end;
set_oso_keep('.init');
set_oso_keep('.fini');
set_oso_keep('.jcr');
set_oso_keep('.ctors');
set_oso_keep('.dtors');
set_oso_keep('.preinit_array');
set_oso_keep('.init_array');
set_oso_keep('.fini_array');
set_oso_keep('.eh_frame');
set_oso_keep('.init',dummy);
set_oso_keep('.fini',dummy);
set_oso_keep('.jcr',dummy);
set_oso_keep('.ctors',dummy);
set_oso_keep('.dtors',dummy);
set_oso_keep('.preinit_array',preinitarraysec);
if assigned(preinitarraysec) and IsSharedLibrary then
Comment(v_error,'.preinit_array section is not allowed in shared libraries');
set_oso_keep('.init_array',initarraysec);
set_oso_keep('.fini_array',finiarraysec);
set_oso_keep('.eh_frame',dummy);
{ let .dynamic reference other dynamic sections so they aren't marked
for removal as unused }
@ -2394,7 +2409,7 @@ implementation
exesec:TExeSection;
opts:TObjSectionOptions;
s:string;
newsections,tmp:TFPHashObjectList;
newsections:TFPHashObjectList;
allsections:TFPList;
inserts:array[0..6] of TExeSection;
idx,inspos:longint;
@ -3214,6 +3229,24 @@ implementation
end;
end;
if assigned(preinitarraysec) then
begin
WriteDynTag(DT_PREINIT_ARRAY,preinitarraysec,0);
WriteDynTag(DT_PREINIT_ARRAYSZ,preinitarraysec.exesection.size);
end;
if assigned(initarraysec) then
begin
WriteDynTag(DT_INIT_ARRAY,initarraysec,0);
WriteDynTag(DT_INIT_ARRAYSZ,initarraysec.exesection.size);
end;
if assigned(finiarraysec) then
begin
WriteDynTag(DT_FINI_ARRAY,finiarraysec,0);
WriteDynTag(DT_FINI_ARRAYSZ,finiarraysec.exesection.size);
end;
writeDynTag(DT_HASH,hashobjsec);
writeDynTag(DT_STRTAB,dynsymtable.fstrsec);
writeDynTag(DT_SYMTAB,dynsymtable);