diff options
author | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-09-04 13:16:56 +0000 |
---|---|---|
committer | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-09-04 13:16:56 +0000 |
commit | aa2c941afdf7fd94d8e09132f7b73cdfbbe34b74 (patch) | |
tree | 69dc58a6f07d524ba7a9a6d7cf3f17649ff159ce /compiler/ogbase.pas | |
parent | d9728eb1dc244eb18dae79324f36a05b4553acd2 (diff) | |
download | fpc-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.pas | 43 |
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; |