Browse Source

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

sergei 12 năm trước cách đây
mục cha
commit
00ca4a74a3
2 tập tin đã thay đổi với 41 bổ sung35 xóa
  1. 35 20
      compiler/ogbase.pas
  2. 6 15
      compiler/ogelf.pas

+ 35 - 20
compiler/ogbase.pas

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

+ 6 - 15
compiler/ogelf.pas

@@ -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;