+ ELF linker: Support writing RELATIVE dynamic relocations ahead of the rest, and their number in DT_REL[A]COUNT dynamic tag (still needs changes in CPU-specific code to function properly).

* TElfObjInput.LoadSymbols: ignore STT_SECTION symbols for sections that were ignored in LoadSections().
* TElfObjInput: changed symtabndx (index of .symtab/.dynsym section) into field and its type to unsigned.

git-svn-id: trunk@22951 -
This commit is contained in:
sergei 2012-11-08 11:10:01 +00:00
parent d1440c7483
commit 277200e7ae

View File

@ -118,6 +118,7 @@ interface
shentsize: longword;
shoffset: aword;
shstrndx: longword;
symtabndx: longword;
shstrtab: PChar;
strtab: PChar;
shstrtablen: longword;
@ -216,7 +217,9 @@ interface
pltrelocsec,
ipltrelocsec,
dynrelocsec: TElfObjSection;
dynreloclist: TFPObjectList;
tlsseg: TElfSegment;
relative_reloc_count: longint;
procedure WriteDynRelocEntry(dataofs:aword;typ:byte;symidx:aword;addend:aword);
procedure WriteFirstPLTEntry;virtual;abstract;
procedure WritePLTEntry(exesym:TExeSymbol);virtual;
@ -315,6 +318,7 @@ implementation
{$endif x86_64}
SHN_UNDEF = 0;
SHN_LORESERVE = $FF00;
SHN_ABS = $fff1;
SHN_COMMON = $fff2;
@ -1568,16 +1572,8 @@ implementation
Continue
else if sym.st_shndx=SHN_COMMON then
bind:=AB_COMMON
else if (sym.st_shndx>=nsects) or
(
(sym.st_shndx>0) and
(FSecTbl[sym.st_shndx].sec=nil) and
(not dynobj)
) then
begin
writeln(objdata.name,' ',i);
InternalError(2012060206)
end
else if (sym.st_shndx>=nsects) then
InternalError(2012060206)
else
case (sym.st_info shr 4) of
STB_LOCAL:
@ -1593,6 +1589,19 @@ implementation
InternalError(2012060207);
end;
{ Ignore section symbol if we didn't create the corresponding objsection
(examples are SHT_GROUP or .note.GNU-stack sections). }
if (sym.st_shndx>0) and (sym.st_shndx<SHN_LORESERVE) and
(FSecTbl[sym.st_shndx].sec=nil) and
(not dynobj) then
if ((sym.st_info and $0F)=STT_SECTION) then
Continue
else
begin
writeln(objdata.name,' ',i);
InternalError(2012110701)
end;
case (sym.st_info and $0F) of
STT_NOTYPE:
typ:=AT_NONE;
@ -1802,7 +1811,7 @@ implementation
function TElfObjInput.ReadObjData(AReader:TObjectreader;objdata:TObjData):boolean;
var
i,j,symtabndx,strndx,dynndx,
i,j,strndx,dynndx,
versymndx,verdefndx,verneedndx: longint;
objsec: TElfObjSection;
shdrs: array of TElfsechdr;
@ -1854,7 +1863,7 @@ implementation
Note that is is legal to have no symtable.
For DSO, locate .dynsym instead, this one is near the beginning, but
overall number of sections won't be big. }
symtabndx:=-1;
symtabndx:=0;
for i:=nsects-1 downto 1 do
begin
if (shdrs[i].sh_type<>symsectypes[dynobj]) then
@ -1880,6 +1889,9 @@ implementation
break;
end;
if symtabndx=0 then
InternalError(2012110706);
if dynobj then
begin
{ Locate .dynamic and version sections. Expect a single one of a kind. }
@ -2031,6 +2043,7 @@ implementation
neededlist.Free;
segmentlist.Free;
dynsymlist.Free;
dynreloclist.Free;
if assigned(dynsymnames) then
FreeMem(dynsymnames);
inherited Destroy;
@ -2629,8 +2642,25 @@ implementation
i,j: longint;
exesec: TExeSection;
seg: TElfSegment;
objreloc: TObjRelocation;
begin
gotwritten:=true;
{ If target does not support sorted relocations, it is expected to write the
entire .rel[a].dyn section during FixupRelocations. Otherwise, only RELATIVE ones
should be written, space for non-relative relocations should remain. }
if assigned(dynrelocsec) and (relative_reloc_count>0) then
begin
if (dynrelocsec.size+(dynreloclist.count*dynrelocsec.shentsize)<>dynrelsize) then
InternalError(2012110601);
{ Write out non-RELATIVE dynamic relocations
TODO: additional sorting? }
for i:=0 to dynreloclist.count-1 do
begin
objreloc:=TObjRelocation(dynreloclist[i]);
WriteDynRelocEntry(objreloc.dataoffset,objreloc.ftype,objreloc.symbol.exesymbol.dynindex,0);
end;
end;
{ sanity checks }
if assigned(gotobjsec) and (gotsize<>gotobjsec.size) then
InternalError(2012092501);
@ -2743,6 +2773,8 @@ implementation
dynrelocsec:=TElfObjSection.create_reloc(internalObjData,'.dyn',true);
dynrelocsec.SecOptions:=[oso_keep];
dynreloclist:=TFPObjectList.Create(true);
end;
@ -2902,6 +2934,7 @@ implementation
pltreltags: array[boolean] of longword=(DT_REL,DT_RELA);
relsztags: array[boolean] of longword=(DT_RELSZ,DT_RELASZ);
relenttags: array[boolean] of longword=(DT_RELENT,DT_RELAENT);
relcnttags: array[boolean] of longword=(DT_RELCOUNT,DT_RELACOUNT);
procedure TElfExeOutput.FinishDynamicTags;
begin
@ -2924,6 +2957,8 @@ implementation
writeDynTag(relsztags[relocs_use_addend],dynrelocsec.Size);
writeDynTag(relenttags[relocs_use_addend],dynrelocsec.shentsize);
end;
if (relative_reloc_count>0) then
writeDynTag(relcnttags[relocs_use_addend],relative_reloc_count);
writeDynTag(DT_NULL,0);
end;