mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 16:48:12 +02:00
+ 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:
parent
404e1a34a4
commit
fde944bf5d
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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');
|
||||
|
Loading…
Reference in New Issue
Block a user