summaryrefslogtreecommitdiff
path: root/compiler/ogbase.pas
diff options
context:
space:
mode:
authorsergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-09-04 13:16:56 +0000
committersergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-09-04 13:16:56 +0000
commitaa2c941afdf7fd94d8e09132f7b73cdfbbe34b74 (patch)
tree69dc58a6f07d524ba7a9a6d7cf3f17649ff159ce /compiler/ogbase.pas
parentd9728eb1dc244eb18dae79324f36a05b4553acd2 (diff)
downloadfpc-aa2c941afdf7fd94d8e09132f7b73cdfbbe34b74.tar.gz
+ 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: http://svn.freepascal.org/svn/fpc/trunk@22312 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/ogbase.pas')
-rw-r--r--compiler/ogbase.pas43
1 files changed, 35 insertions, 8 deletions
diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas
index f43de1cc85..d61ba14b0b 100644
--- a/compiler/ogbase.pas
+++ b/compiler/ogbase.pas
@@ -346,7 +346,7 @@ interface
function VTableRef(VTableIdx:Longint):TObjRelocation;
end;
- TSymbolState = (symstate_undefined,symstate_defined,symstate_common);
+ TSymbolState = (symstate_undefined,symstate_defined,symstate_common,symstate_defweak,symstate_dynamic);
TExeSymbol = class(TFPHashObject)
ObjSymbol : TObjSymbol;
@@ -2242,7 +2242,10 @@ implementation
end;
AB_COMMON :
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
exesym.ObjSymbol:=objsym;
exesym.State:=symstate_common;
@@ -2253,6 +2256,23 @@ implementation
else
CommonObjSymbols.add(objsym);
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;
@@ -2562,7 +2582,8 @@ implementation
for i:=0 to UnresolvedExeSymbols.count-1 do
begin
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);
end;
@@ -2585,7 +2606,7 @@ implementation
for i:=0 to ExternalObjSymbols.count-1 do
begin
objsym:=TObjSymbol(ExternalObjSymbols[i]);
- if objsym.bind<>AB_EXTERNAL then
+ if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
internalerror(200606242);
UpdateSymbol(objsym);
end;
@@ -2863,13 +2884,17 @@ implementation
if objsym.bind<>AB_LOCAL then
begin
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);
objsym:=objsym.exesymbol.objsymbol;
end;
if not assigned(objsym.objsection) then
- internalerror(200603062);
- refobjsec:=objsym.objsection;
+ begin
+ objsym.exesymbol.state:=symstate_dynamic;
+ exit;
+ end
+ else
+ refobjsec:=objsym.objsection;
end
else
if assigned(objreloc.objsection) then
@@ -3045,7 +3070,9 @@ implementation
for i:=0 to ExeSymbolList.Count-1 do
begin
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;
end;
ExeSymbolList.Pack;