From fde944bf5d4d3be3f83d0d45aad24d4f51ff89ee Mon Sep 17 00:00:00 2001 From: sergei Date: Fri, 14 Sep 2012 17:22:48 +0000 Subject: [PATCH] + 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 - --- compiler/aasmbase.pas | 6 +++++- compiler/ogbase.pas | 42 +++++++++++++++++++++++------------------- compiler/ogcoff.pas | 17 +++++------------ 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/compiler/aasmbase.pas b/compiler/aasmbase.pas index 9fe07535fb..9f02a47118 100644 --- a/compiler/aasmbase.pas +++ b/compiler/aasmbase.pas @@ -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 diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas index 4bc72b89ed..1bf6264bcb 100644 --- a/compiler/ogbase.pas +++ b/compiler/ogbase.pas @@ -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; diff --git a/compiler/ogcoff.pas b/compiler/ogcoff.pas index 7db976a65c..e82a14f2d8 100644 --- a/compiler/ogcoff.pas +++ b/compiler/ogcoff.pas @@ -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');