+ Declare AT_TLS and AT_GNU_IFUNC symbol types, these are needed to handle object files created by gcc in ELF internal linker.

* TExeOutput.FixupSymbols:
  + Collect AT_GNU_IFUNC symbols in IndirectObjSymbols list for further processing by ELF back-end.
  * Do not overwrite bind and size while fixing AB_COMMON symbols, this removes need in storing symbol size in every relocation and dedicated handling of oso_common section.
  * Remove symbols with objsection<>nil from lists, so calling FixupSymbols several times skips already processed symbols.

git-svn-id: trunk@22393 -
This commit is contained in:
sergei 2012-09-14 17:22:48 +00:00
parent 404e1a34a4
commit fde944bf5d
3 changed files with 33 additions and 32 deletions

View File

@ -48,7 +48,11 @@ interface
the address of this code label is taken somewhere in the code
so it must be taken care of it when creating pic
}
AT_ADDR
AT_ADDR,
{ Thread-local symbol (ELF targets) }
AT_TLS,
{ GNU indirect function (ELF targets) }
AT_GNU_IFUNC
);
{ is the label only there for getting an DataOffset (e.g. for i/o

View File

@ -126,8 +126,8 @@ interface
oso_executable,
{ Never discard section }
oso_keep,
{ Special common symbols }
oso_common,
{ Procedure Linkage Table specific treatment }
oso_plt,
{ Contains debug info and can be stripped }
oso_debug,
{ Contains only strings }
@ -178,7 +178,6 @@ interface
typ : TObjRelocationType;
size : byte;
constructor CreateSymbol(ADataOffset:aword;s:TObjSymbol;Atyp:TObjRelocationType);
constructor CreateSymbolSize(ADataOffset:aword;s:TObjSymbol;Aorgsize:aword;Atyp:TObjRelocationType);
constructor CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
end;
@ -441,6 +440,7 @@ interface
FExternalObjSymbols,
FCommonObjSymbols : TFPObjectList;
FProvidedObjSymbols : TFPObjectList;
FIndirectObjSymbols : TFPObjectList;
FEntryName : string;
FExeVTableList : TFPObjectList;
{ Objects }
@ -524,6 +524,7 @@ interface
property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
property ExternalObjSymbols:TFPObjectList read FExternalObjSymbols;
property CommonObjSymbols:TFPObjectList read FCommonObjSymbols;
property IndirectObjSymbols:TFPObjectList read FIndirectObjSymbols;
property ExeVTableList:TFPObjectList read FExeVTableList;
property EntryName:string read FEntryName write FEntryName;
property ImageBase:aword read FImageBase write FImageBase;
@ -628,18 +629,6 @@ implementation
end;
constructor TObjRelocation.CreateSymbolSize(ADataOffset:aword;s:TObjSymbol;Aorgsize:aword;Atyp:TObjRelocationType);
begin
if not assigned(s) then
internalerror(200603035);
DataOffset:=ADataOffset;
Symbol:=s;
OrgSize:=Aorgsize;
ObjSection:=nil;
Typ:=Atyp;
end;
constructor TObjRelocation.CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
begin
if not assigned(aobjsec) then
@ -1625,6 +1614,7 @@ implementation
FExternalObjSymbols:=TFPObjectList.Create(false);
FCommonObjSymbols:=TFPObjectList.Create(false);
FProvidedObjSymbols:=TFPObjectList.Create(false);
FIndirectObjSymbols:=TFPObjectList.Create(false);
FExeVTableList:=TFPObjectList.Create(false);
{ sections }
FExeSectionList:=TFPHashObjectList.Create(true);
@ -1647,6 +1637,7 @@ implementation
UnresolvedExeSymbols.free;
ExternalObjSymbols.free;
FProvidedObjSymbols.free;
FIndirectObjSymbols.free;
CommonObjSymbols.free;
ExeVTableList.free;
FExeSectionList.free;
@ -1703,8 +1694,6 @@ implementation
AddObjData(internalObjData);
{ Common Data section }
commonObjSection:=internalObjData.createsection(sec_bss,'');
{ setting SecOptions acts as 'include' }
commonObjSection.SecOptions:=[oso_common];
end;
@ -2604,15 +2593,22 @@ implementation
Fixing up symbols is done in the following steps:
1. Update common references
2. Update external references
Symbols with objsection<>nil are removed from the lists,
remaining ones can be processed later by calling this method again.
}
{ Step 1, Update commons }
{ Step 1, Update commons. Preserve the original symbol size and bind,
this is needed for correct relocation of DJCOFF files. }
for i:=0 to CommonObjSymbols.count-1 do
begin
objsym:=TObjSymbol(CommonObjSymbols[i]);
if objsym.bind<>AB_COMMON then
internalerror(200606241);
UpdateSymbol(objsym);
objsym.ObjSection:=objsym.ExeSymbol.ObjSymbol.ObjSection;
objsym.offset:=objsym.ExeSymbol.ObjSymbol.offset;
objsym.typ:=objsym.ExeSymbol.ObjSymbol.typ;
end;
{ Step 2, Update externals }
@ -2622,7 +2618,15 @@ implementation
if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
internalerror(200606242);
UpdateSymbol(objsym);
{ Collect symbols that resolve to indirect functions,
they will need additional target-specific processing. }
if objsym.typ=AT_GNU_IFUNC then
IndirectObjSymbols.Add(objsym)
else if assigned(objsym.objsection) then
ExternalObjSymbols[i]:=nil;
end;
CommonObjSymbols.Clear;
ExternalObjSymbols.Pack;
end;

View File

@ -108,7 +108,6 @@ interface
coffrelocpos : aword;
public
constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
procedure addsymsizereloc(ofs:aword;p:TObjSymbol;symsize:aword;reloctype:TObjRelocationType);
procedure writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);override;
end;
@ -806,12 +805,6 @@ const pemagic : array[0..3] of byte = (
end;
procedure TCoffObjSection.addsymsizereloc(ofs:aword;p:TObjSymbol;symsize:aword;reloctype:TObjRelocationType);
begin
ObjRelocations.Add(TObjRelocation.createsymbolsize(ofs,p,symsize,reloctype));
end;
procedure TCoffObjSection.writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);
begin
AddSectionReloc(size,aTarget,reltype);
@ -877,7 +870,7 @@ const pemagic : array[0..3] of byte = (
RELOC_RELATIVE :
begin
address:=address-objsec.mempos+relocval;
if TCoffObjData(objsec.objdata).win32 then
if win32 then
dec(address,objreloc.dataoffset+4);
end;
RELOC_RVA:
@ -940,10 +933,10 @@ const pemagic : array[0..3] of byte = (
{$endif x86_64}
RELOC_ABSOLUTE :
begin
if oso_common in relocsec.secoptions then
if (not win32) and assigned(objreloc.symbol) and
(objreloc.symbol.bind=AB_COMMON) then
begin
if (not win32) then
dec(address,objreloc.orgsize);
dec(address,objreloc.symbol.size);
end
else
begin
@ -1584,7 +1577,7 @@ const pemagic : array[0..3] of byte = (
p:=FSymTbl^[rel.sym];
if assigned(p) then
s.addsymsizereloc(rel.address-s.mempos,p,p.size,rel_type)
s.addsymreloc(rel.address-s.mempos,p,rel_type)
else
begin
InputError('Failed reading coff file, can''t resolve symbol of relocation');