* 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:
sergei 2012-12-09 08:02:58 +00:00
parent a771d68685
commit 00ca4a74a3
2 changed files with 41 additions and 35 deletions

View File

@ -382,11 +382,19 @@ interface
function VTableRef(VTableIdx:Longint):TObjRelocation;
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)
ObjSymbol : TObjSymbol;
State : TSymbolState;
used : boolean;
{ Used for vmt references optimization }
VTable : TExeVTable;
{ fields for ELF linking }
@ -497,6 +505,7 @@ interface
SectionMemAlign : aword;
ComdatGroups : TFPHashList;
FixedSectionAlign : boolean;
AllowUndefinedSymbols : boolean;
function writeData:boolean;virtual;abstract;
property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
property CObjData:TObjDataClass read FCObjData write FCObjData;
@ -2230,7 +2239,7 @@ implementation
for i:=0 to UnresolvedExeSymbols.count-1 do
begin
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
if exesym.State<>symstate_undefined then
if not (exesym.State in [symstate_undefined,symstate_undefweak]) then
UnresolvedExeSymbols[i]:=nil;
end;
UnresolvedExeSymbols.Pack;
@ -2333,13 +2342,19 @@ implementation
{ Register unresolved symbols only the first time they
are registered }
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;
AB_COMMON :
begin
{ A COMMON definition overrides weak one.
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
begin
exesym.ObjSymbol:=objsym;
@ -2357,11 +2372,14 @@ implementation
begin
ExternalObjSymbols.add(objsym);
if exesym.ObjSymbol=objsym then
UnresolvedExeSymbols.Add(exesym);
begin
UnresolvedExeSymbols.Add(exesym);
exesym.state:=symstate_undefweak;
end;
end
else { a weak definition }
begin
if exesym.State=symstate_undefined then
if exesym.State in [symstate_undefined,symstate_undefweak] then
begin
exesym.ObjSymbol:=objsym;
exesym.state:=symstate_defweak;
@ -2390,7 +2408,7 @@ implementation
begin
exesym:=TExeSymbol(UnresolvedExeSymbols[j]);
{ 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
if lib.ArReader.OpenFile(exesym.name) then
begin
@ -2678,13 +2696,13 @@ implementation
exesym : TExeSymbol;
begin
{ Print list of Unresolved External symbols }
for i:=0 to UnresolvedExeSymbols.count-1 do
begin
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
if (exesym.State<>symstate_defined) and
(exesym.objsymbol.bind<>AB_WEAK_EXTERNAL) then
Comment(V_Error,'Undefined symbol: '+exesym.name);
end;
if not AllowUndefinedSymbols then
for i:=0 to UnresolvedExeSymbols.count-1 do
begin
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
if (exesym.State=symstate_undefined) then
Comment(V_Error,'Undefined symbol: '+exesym.name);
end;
{
Fixing up symbols is done in the following steps:
@ -2997,16 +3015,13 @@ implementation
objsym:=objreloc.symbol;
if objsym.bind<>AB_LOCAL then
begin
if not(assigned(objsym.exesymbol) and
(objsym.exesymbol.State in [symstate_defined,symstate_dynamic,symstate_defweak])) then
if not assigned(objsym.exesymbol) then
internalerror(200603063);
objsym.exesymbol.used:=true;
objsym:=objsym.exesymbol.objsymbol;
end;
if not assigned(objsym.objsection) then
begin
objsym.exesymbol.state:=symstate_dynamic;
exit;
end
exit
else
refobjsec:=objsym.objsection;
end

View File

@ -2089,7 +2089,7 @@ implementation
for i:=0 to UnresolvedExeSymbols.Count-1 do
begin
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
if exesym.State<>symstate_undefined then
if not (exesym.State in [symstate_undefined,symstate_undefweak]) then
continue;
objsym:=TObjSymbol(objdata.ObjSymbolList.Find(exesym.name));
if assigned(objsym) then
@ -2167,14 +2167,14 @@ implementation
objsym:TObjSymbol;
objsec: TObjSection;
begin
{ Unused section removal changes state of referenced exesymbols
to symstate_dynamic. Remaining ones can be removed. }
{ Unused section removal sets Used property of referenced exesymbols.
Remaining ones can be removed. }
for i:=0 to dynsymlist.count-1 do
begin
exesym:=TExeSymbol(dynsymlist[i]);
if assigned(exesym.ObjSymbol.ObjSection) then // an exported symbol
continue;
if exesym.state<>symstate_dynamic then
if not exesym.used then
begin
dynsymlist[i]:=nil;
exesym.dynindex:=0;
@ -2194,7 +2194,7 @@ implementation
for i:=0 to UnresolvedExeSymbols.Count-1 do
begin
exesym:=TExeSymbol(UnresolvedExeSymbols[i]);
if exesym.state=symstate_dynamic then
if exesym.used then
begin
if exesym.dynindex<>0 then
InternalError(2012062301);
@ -2809,6 +2809,7 @@ implementation
exportlist: TCmdStrList;
sym: TExeSymbol;
begin
AllowUndefinedSymbols:=IsSharedLibrary;
{ add exported symbols to dynamic list }
exportlist:=texportlibunix(exportlib).exportedsymnames;
if not exportlist.empty then
@ -2823,16 +2824,6 @@ implementation
else
InternalError(2012071801);
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;