+ 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 the address of this code label is taken somewhere in the code
so it must be taken care of it when creating pic 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 { is the label only there for getting an DataOffset (e.g. for i/o

View File

@ -126,8 +126,8 @@ interface
oso_executable, oso_executable,
{ Never discard section } { Never discard section }
oso_keep, oso_keep,
{ Special common symbols } { Procedure Linkage Table specific treatment }
oso_common, oso_plt,
{ Contains debug info and can be stripped } { Contains debug info and can be stripped }
oso_debug, oso_debug,
{ Contains only strings } { Contains only strings }
@ -178,7 +178,6 @@ interface
typ : TObjRelocationType; typ : TObjRelocationType;
size : byte; size : byte;
constructor CreateSymbol(ADataOffset:aword;s:TObjSymbol;Atyp:TObjRelocationType); 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); constructor CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
end; end;
@ -441,6 +440,7 @@ interface
FExternalObjSymbols, FExternalObjSymbols,
FCommonObjSymbols : TFPObjectList; FCommonObjSymbols : TFPObjectList;
FProvidedObjSymbols : TFPObjectList; FProvidedObjSymbols : TFPObjectList;
FIndirectObjSymbols : TFPObjectList;
FEntryName : string; FEntryName : string;
FExeVTableList : TFPObjectList; FExeVTableList : TFPObjectList;
{ Objects } { Objects }
@ -524,6 +524,7 @@ interface
property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols; property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
property ExternalObjSymbols:TFPObjectList read FExternalObjSymbols; property ExternalObjSymbols:TFPObjectList read FExternalObjSymbols;
property CommonObjSymbols:TFPObjectList read FCommonObjSymbols; property CommonObjSymbols:TFPObjectList read FCommonObjSymbols;
property IndirectObjSymbols:TFPObjectList read FIndirectObjSymbols;
property ExeVTableList:TFPObjectList read FExeVTableList; property ExeVTableList:TFPObjectList read FExeVTableList;
property EntryName:string read FEntryName write FEntryName; property EntryName:string read FEntryName write FEntryName;
property ImageBase:aword read FImageBase write FImageBase; property ImageBase:aword read FImageBase write FImageBase;
@ -628,18 +629,6 @@ implementation
end; 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); constructor TObjRelocation.CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
begin begin
if not assigned(aobjsec) then if not assigned(aobjsec) then
@ -1625,6 +1614,7 @@ implementation
FExternalObjSymbols:=TFPObjectList.Create(false); FExternalObjSymbols:=TFPObjectList.Create(false);
FCommonObjSymbols:=TFPObjectList.Create(false); FCommonObjSymbols:=TFPObjectList.Create(false);
FProvidedObjSymbols:=TFPObjectList.Create(false); FProvidedObjSymbols:=TFPObjectList.Create(false);
FIndirectObjSymbols:=TFPObjectList.Create(false);
FExeVTableList:=TFPObjectList.Create(false); FExeVTableList:=TFPObjectList.Create(false);
{ sections } { sections }
FExeSectionList:=TFPHashObjectList.Create(true); FExeSectionList:=TFPHashObjectList.Create(true);
@ -1647,6 +1637,7 @@ implementation
UnresolvedExeSymbols.free; UnresolvedExeSymbols.free;
ExternalObjSymbols.free; ExternalObjSymbols.free;
FProvidedObjSymbols.free; FProvidedObjSymbols.free;
FIndirectObjSymbols.free;
CommonObjSymbols.free; CommonObjSymbols.free;
ExeVTableList.free; ExeVTableList.free;
FExeSectionList.free; FExeSectionList.free;
@ -1703,8 +1694,6 @@ implementation
AddObjData(internalObjData); AddObjData(internalObjData);
{ Common Data section } { Common Data section }
commonObjSection:=internalObjData.createsection(sec_bss,''); commonObjSection:=internalObjData.createsection(sec_bss,'');
{ setting SecOptions acts as 'include' }
commonObjSection.SecOptions:=[oso_common];
end; end;
@ -2604,15 +2593,22 @@ implementation
Fixing up symbols is done in the following steps: Fixing up symbols is done in the following steps:
1. Update common references 1. Update common references
2. Update external 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 for i:=0 to CommonObjSymbols.count-1 do
begin begin
objsym:=TObjSymbol(CommonObjSymbols[i]); objsym:=TObjSymbol(CommonObjSymbols[i]);
if objsym.bind<>AB_COMMON then if objsym.bind<>AB_COMMON then
internalerror(200606241); internalerror(200606241);
UpdateSymbol(objsym);
objsym.ObjSection:=objsym.ExeSymbol.ObjSymbol.ObjSection;
objsym.offset:=objsym.ExeSymbol.ObjSymbol.offset;
objsym.typ:=objsym.ExeSymbol.ObjSymbol.typ;
end; end;
{ Step 2, Update externals } { Step 2, Update externals }
@ -2622,7 +2618,15 @@ implementation
if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
internalerror(200606242); internalerror(200606242);
UpdateSymbol(objsym); 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; end;
CommonObjSymbols.Clear;
ExternalObjSymbols.Pack;
end; end;

View File

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