Browse Source

+ 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 -

sergei 13 years ago
parent
commit
b1b175dacc
1 changed files with 35 additions and 8 deletions
  1. 35 8
      compiler/ogbase.pas

+ 35 - 8
compiler/ogbase.pas

@@ -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,13 +2884,17 @@ 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);
-              refobjsec:=objsym.objsection;
+                begin
+                  objsym.exesymbol.state:=symstate_dynamic;
+                  exit;
+                end
+              else
+                refobjsec:=objsym.objsection;
             end
             end
           else
           else
             if assigned(objreloc.objsection) then
             if assigned(objreloc.objsection) then
@@ -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;