+ Internal linker support for weak symbols.

+ Allow unresolved external symbols in RemoveUnreferencedSections, such symbols are marked as 'dynamic' if referenced. This approach allows to collect unused sections early and generate import structures only for actually used symbols.

git-svn-id: trunk@22312 -
This commit is contained in:
sergei 2012-09-04 13:16:56 +00:00
parent d63ebe6464
commit b1b175dacc

View File

@ -346,7 +346,7 @@ interface
function VTableRef(VTableIdx:Longint):TObjRelocation; function VTableRef(VTableIdx:Longint):TObjRelocation;
end; end;
TSymbolState = (symstate_undefined,symstate_defined,symstate_common); TSymbolState = (symstate_undefined,symstate_defined,symstate_common,symstate_defweak,symstate_dynamic);
TExeSymbol = class(TFPHashObject) TExeSymbol = class(TFPHashObject)
ObjSymbol : TObjSymbol; ObjSymbol : TObjSymbol;
@ -2242,7 +2242,10 @@ implementation
end; end;
AB_COMMON : AB_COMMON :
begin begin
if exesym.State=symstate_undefined then { A COMMON definition overrides weak one.
Also select the symbol with largest size. }
if (exesym.State in [symstate_undefined,symstate_defweak]) or
((exesym.State=symstate_common) and (objsym.size>exesym.ObjSymbol.size)) then
begin begin
exesym.ObjSymbol:=objsym; exesym.ObjSymbol:=objsym;
exesym.State:=symstate_common; exesym.State:=symstate_common;
@ -2253,6 +2256,23 @@ implementation
else else
CommonObjSymbols.add(objsym); CommonObjSymbols.add(objsym);
end; end;
AB_WEAK_EXTERNAL :
begin
if objsym.objsection=nil then { a weak reference }
begin
ExternalObjSymbols.add(objsym);
if exesym.ObjSymbol=objsym then
UnresolvedExeSymbols.Add(exesym);
end
else { a weak definition }
begin
if exesym.State=symstate_undefined then
begin
exesym.ObjSymbol:=objsym;
exesym.state:=symstate_defweak;
end;
end;
end;
end; end;
end; end;
end; end;
@ -2562,7 +2582,8 @@ 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_defined then if (exesym.State<>symstate_defined) and
(exesym.objsymbol.bind<>AB_WEAK_EXTERNAL) then
Comment(V_Error,'Undefined symbol: '+exesym.name); Comment(V_Error,'Undefined symbol: '+exesym.name);
end; end;
@ -2585,7 +2606,7 @@ implementation
for i:=0 to ExternalObjSymbols.count-1 do for i:=0 to ExternalObjSymbols.count-1 do
begin begin
objsym:=TObjSymbol(ExternalObjSymbols[i]); objsym:=TObjSymbol(ExternalObjSymbols[i]);
if objsym.bind<>AB_EXTERNAL then if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
internalerror(200606242); internalerror(200606242);
UpdateSymbol(objsym); UpdateSymbol(objsym);
end; end;
@ -2863,12 +2884,16 @@ implementation
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) and
(objsym.exesymbol.State=symstate_defined)) then (objsym.exesymbol.State in [symstate_defined,symstate_dynamic,symstate_defweak])) then
internalerror(200603063); internalerror(200603063);
objsym:=objsym.exesymbol.objsymbol; objsym:=objsym.exesymbol.objsymbol;
end; end;
if not assigned(objsym.objsection) then if not assigned(objsym.objsection) then
internalerror(200603062); begin
objsym.exesymbol.state:=symstate_dynamic;
exit;
end
else
refobjsec:=objsym.objsection; refobjsec:=objsym.objsection;
end end
else else
@ -3045,7 +3070,9 @@ implementation
for i:=0 to ExeSymbolList.Count-1 do for i:=0 to ExeSymbolList.Count-1 do
begin begin
sym:=TExeSymbol(ExeSymbolList[i]); sym:=TExeSymbol(ExeSymbolList[i]);
if not sym.ObjSymbol.objsection.Used then { an unresolved weak symbol has objsection=nil }
if assigned(sym.ObjSymbol.objsection) and
(not sym.ObjSymbol.objsection.Used) then
ExeSymbolList[i]:=nil; ExeSymbolList[i]:=nil;
end; end;
ExeSymbolList.Pack; ExeSymbolList.Pack;