mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 23:59:10 +02:00
* Reworked/fixed TExeSymbol.State behavior:
* Added symstate_undefweak for undefined symbols having only weak references to them, this state is removed when a normal reference to symbol is seen. * Use a separate boolean property to determine if ExeSymbol is referenced. * Use a separate property TExeOutput.AllowUndefinedSymbols to suppress error messages when linking dynamic shared objects. * Don't issue InternalError when an undefined symbol is encountered during unused section removal. git-svn-id: trunk@23127 -
This commit is contained in:
parent
a771d68685
commit
00ca4a74a3
@ -382,11 +382,19 @@ interface
|
|||||||
function VTableRef(VTableIdx:Longint):TObjRelocation;
|
function VTableRef(VTableIdx:Longint):TObjRelocation;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TSymbolState = (symstate_undefined,symstate_defined,symstate_common,symstate_defweak,symstate_dynamic);
|
TSymbolState = (
|
||||||
|
symstate_undefined,
|
||||||
|
symstate_undefweak, // undefined but has only weak refs - don't complain
|
||||||
|
symstate_defined,
|
||||||
|
symstate_defweak,
|
||||||
|
symstate_common,
|
||||||
|
symstate_dynamic // a matching symbol has been seen in .so
|
||||||
|
);
|
||||||
|
|
||||||
TExeSymbol = class(TFPHashObject)
|
TExeSymbol = class(TFPHashObject)
|
||||||
ObjSymbol : TObjSymbol;
|
ObjSymbol : TObjSymbol;
|
||||||
State : TSymbolState;
|
State : TSymbolState;
|
||||||
|
used : boolean;
|
||||||
{ Used for vmt references optimization }
|
{ Used for vmt references optimization }
|
||||||
VTable : TExeVTable;
|
VTable : TExeVTable;
|
||||||
{ fields for ELF linking }
|
{ fields for ELF linking }
|
||||||
@ -497,6 +505,7 @@ interface
|
|||||||
SectionMemAlign : aword;
|
SectionMemAlign : aword;
|
||||||
ComdatGroups : TFPHashList;
|
ComdatGroups : TFPHashList;
|
||||||
FixedSectionAlign : boolean;
|
FixedSectionAlign : boolean;
|
||||||
|
AllowUndefinedSymbols : boolean;
|
||||||
function writeData:boolean;virtual;abstract;
|
function writeData:boolean;virtual;abstract;
|
||||||
property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
|
property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
|
||||||
property CObjData:TObjDataClass read FCObjData write FCObjData;
|
property CObjData:TObjDataClass read FCObjData write FCObjData;
|
||||||
@ -2230,7 +2239,7 @@ implementation
|
|||||||
for i:=0 to UnresolvedExeSymbols.count-1 do
|
for i:=0 to UnresolvedExeSymbols.count-1 do
|
||||||
begin
|
begin
|
||||||
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
||||||
if exesym.State<>symstate_undefined then
|
if not (exesym.State in [symstate_undefined,symstate_undefweak]) then
|
||||||
UnresolvedExeSymbols[i]:=nil;
|
UnresolvedExeSymbols[i]:=nil;
|
||||||
end;
|
end;
|
||||||
UnresolvedExeSymbols.Pack;
|
UnresolvedExeSymbols.Pack;
|
||||||
@ -2333,13 +2342,19 @@ implementation
|
|||||||
{ Register unresolved symbols only the first time they
|
{ Register unresolved symbols only the first time they
|
||||||
are registered }
|
are registered }
|
||||||
if exesym.ObjSymbol=objsym then
|
if exesym.ObjSymbol=objsym then
|
||||||
UnresolvedExeSymbols.Add(exesym);
|
UnresolvedExeSymbols.Add(exesym)
|
||||||
|
{ Normal reference removes any existing "weakness" }
|
||||||
|
else if exesym.state=symstate_undefweak then
|
||||||
|
begin
|
||||||
|
exesym.state:=symstate_undefined;
|
||||||
|
exesym.ObjSymbol:=objsym;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
AB_COMMON :
|
AB_COMMON :
|
||||||
begin
|
begin
|
||||||
{ A COMMON definition overrides weak one.
|
{ A COMMON definition overrides weak one.
|
||||||
Also select the symbol with largest size. }
|
Also select the symbol with largest size. }
|
||||||
if (exesym.State in [symstate_undefined,symstate_defweak]) or
|
if (exesym.State in [symstate_undefined,symstate_undefweak,symstate_defweak]) or
|
||||||
((exesym.State=symstate_common) and (objsym.size>exesym.ObjSymbol.size)) then
|
((exesym.State=symstate_common) and (objsym.size>exesym.ObjSymbol.size)) then
|
||||||
begin
|
begin
|
||||||
exesym.ObjSymbol:=objsym;
|
exesym.ObjSymbol:=objsym;
|
||||||
@ -2357,11 +2372,14 @@ implementation
|
|||||||
begin
|
begin
|
||||||
ExternalObjSymbols.add(objsym);
|
ExternalObjSymbols.add(objsym);
|
||||||
if exesym.ObjSymbol=objsym then
|
if exesym.ObjSymbol=objsym then
|
||||||
UnresolvedExeSymbols.Add(exesym);
|
begin
|
||||||
|
UnresolvedExeSymbols.Add(exesym);
|
||||||
|
exesym.state:=symstate_undefweak;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else { a weak definition }
|
else { a weak definition }
|
||||||
begin
|
begin
|
||||||
if exesym.State=symstate_undefined then
|
if exesym.State in [symstate_undefined,symstate_undefweak] then
|
||||||
begin
|
begin
|
||||||
exesym.ObjSymbol:=objsym;
|
exesym.ObjSymbol:=objsym;
|
||||||
exesym.state:=symstate_defweak;
|
exesym.state:=symstate_defweak;
|
||||||
@ -2390,7 +2408,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
exesym:=TExeSymbol(UnresolvedExeSymbols[j]);
|
exesym:=TExeSymbol(UnresolvedExeSymbols[j]);
|
||||||
{ Check first if the symbol is still undefined }
|
{ Check first if the symbol is still undefined }
|
||||||
if (exesym.State=symstate_undefined) and (exesym.ObjSymbol.bind<>AB_WEAK_EXTERNAL) then
|
if (exesym.State=symstate_undefined) then
|
||||||
begin
|
begin
|
||||||
if lib.ArReader.OpenFile(exesym.name) then
|
if lib.ArReader.OpenFile(exesym.name) then
|
||||||
begin
|
begin
|
||||||
@ -2678,13 +2696,13 @@ implementation
|
|||||||
exesym : TExeSymbol;
|
exesym : TExeSymbol;
|
||||||
begin
|
begin
|
||||||
{ Print list of Unresolved External symbols }
|
{ Print list of Unresolved External symbols }
|
||||||
for i:=0 to UnresolvedExeSymbols.count-1 do
|
if not AllowUndefinedSymbols then
|
||||||
begin
|
for i:=0 to UnresolvedExeSymbols.count-1 do
|
||||||
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
begin
|
||||||
if (exesym.State<>symstate_defined) and
|
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
||||||
(exesym.objsymbol.bind<>AB_WEAK_EXTERNAL) then
|
if (exesym.State=symstate_undefined) then
|
||||||
Comment(V_Error,'Undefined symbol: '+exesym.name);
|
Comment(V_Error,'Undefined symbol: '+exesym.name);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
Fixing up symbols is done in the following steps:
|
Fixing up symbols is done in the following steps:
|
||||||
@ -2997,16 +3015,13 @@ implementation
|
|||||||
objsym:=objreloc.symbol;
|
objsym:=objreloc.symbol;
|
||||||
if objsym.bind<>AB_LOCAL then
|
if objsym.bind<>AB_LOCAL then
|
||||||
begin
|
begin
|
||||||
if not(assigned(objsym.exesymbol) and
|
if not assigned(objsym.exesymbol) then
|
||||||
(objsym.exesymbol.State in [symstate_defined,symstate_dynamic,symstate_defweak])) then
|
|
||||||
internalerror(200603063);
|
internalerror(200603063);
|
||||||
|
objsym.exesymbol.used:=true;
|
||||||
objsym:=objsym.exesymbol.objsymbol;
|
objsym:=objsym.exesymbol.objsymbol;
|
||||||
end;
|
end;
|
||||||
if not assigned(objsym.objsection) then
|
if not assigned(objsym.objsection) then
|
||||||
begin
|
exit
|
||||||
objsym.exesymbol.state:=symstate_dynamic;
|
|
||||||
exit;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
refobjsec:=objsym.objsection;
|
refobjsec:=objsym.objsection;
|
||||||
end
|
end
|
||||||
|
@ -2089,7 +2089,7 @@ implementation
|
|||||||
for i:=0 to UnresolvedExeSymbols.Count-1 do
|
for i:=0 to UnresolvedExeSymbols.Count-1 do
|
||||||
begin
|
begin
|
||||||
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
||||||
if exesym.State<>symstate_undefined then
|
if not (exesym.State in [symstate_undefined,symstate_undefweak]) then
|
||||||
continue;
|
continue;
|
||||||
objsym:=TObjSymbol(objdata.ObjSymbolList.Find(exesym.name));
|
objsym:=TObjSymbol(objdata.ObjSymbolList.Find(exesym.name));
|
||||||
if assigned(objsym) then
|
if assigned(objsym) then
|
||||||
@ -2167,14 +2167,14 @@ implementation
|
|||||||
objsym:TObjSymbol;
|
objsym:TObjSymbol;
|
||||||
objsec: TObjSection;
|
objsec: TObjSection;
|
||||||
begin
|
begin
|
||||||
{ Unused section removal changes state of referenced exesymbols
|
{ Unused section removal sets Used property of referenced exesymbols.
|
||||||
to symstate_dynamic. Remaining ones can be removed. }
|
Remaining ones can be removed. }
|
||||||
for i:=0 to dynsymlist.count-1 do
|
for i:=0 to dynsymlist.count-1 do
|
||||||
begin
|
begin
|
||||||
exesym:=TExeSymbol(dynsymlist[i]);
|
exesym:=TExeSymbol(dynsymlist[i]);
|
||||||
if assigned(exesym.ObjSymbol.ObjSection) then // an exported symbol
|
if assigned(exesym.ObjSymbol.ObjSection) then // an exported symbol
|
||||||
continue;
|
continue;
|
||||||
if exesym.state<>symstate_dynamic then
|
if not exesym.used then
|
||||||
begin
|
begin
|
||||||
dynsymlist[i]:=nil;
|
dynsymlist[i]:=nil;
|
||||||
exesym.dynindex:=0;
|
exesym.dynindex:=0;
|
||||||
@ -2194,7 +2194,7 @@ implementation
|
|||||||
for i:=0 to UnresolvedExeSymbols.Count-1 do
|
for i:=0 to UnresolvedExeSymbols.Count-1 do
|
||||||
begin
|
begin
|
||||||
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
||||||
if exesym.state=symstate_dynamic then
|
if exesym.used then
|
||||||
begin
|
begin
|
||||||
if exesym.dynindex<>0 then
|
if exesym.dynindex<>0 then
|
||||||
InternalError(2012062301);
|
InternalError(2012062301);
|
||||||
@ -2809,6 +2809,7 @@ implementation
|
|||||||
exportlist: TCmdStrList;
|
exportlist: TCmdStrList;
|
||||||
sym: TExeSymbol;
|
sym: TExeSymbol;
|
||||||
begin
|
begin
|
||||||
|
AllowUndefinedSymbols:=IsSharedLibrary;
|
||||||
{ add exported symbols to dynamic list }
|
{ add exported symbols to dynamic list }
|
||||||
exportlist:=texportlibunix(exportlib).exportedsymnames;
|
exportlist:=texportlibunix(exportlib).exportedsymnames;
|
||||||
if not exportlist.empty then
|
if not exportlist.empty then
|
||||||
@ -2823,16 +2824,6 @@ implementation
|
|||||||
else
|
else
|
||||||
InternalError(2012071801);
|
InternalError(2012071801);
|
||||||
until exportlist.empty;
|
until exportlist.empty;
|
||||||
|
|
||||||
{ Mark unresolved weak symbols as defined, they will become dynamic further on.
|
|
||||||
If compiling a .so, make all symbols dynamic, since shared library may reference
|
|
||||||
symbols from executable which does not participate in linking. }
|
|
||||||
for i:=0 to UnresolvedExeSymbols.Count-1 do
|
|
||||||
begin
|
|
||||||
sym:=TExeSymbol(UnresolvedExeSymbols[i]);
|
|
||||||
if (sym.objsymbol.bind=AB_WEAK_EXTERNAL) or IsSharedLibrary then
|
|
||||||
sym.state:=symstate_defined;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user