Bladeren bron

+ Internal linker: process unreferenced .pdata sections on x86_64-win64, restores the possibility to use GAS on win64 (which got broken by introducing SEH).

git-svn-id: trunk@24235 -
sergei 12 jaren geleden
bovenliggende
commit
b86372ccec
2 gewijzigde bestanden met toevoegingen van 54 en 3 verwijderingen
  1. 9 3
      compiler/ogbase.pas
  2. 45 0
      compiler/ogcoff.pas

+ 9 - 3
compiler/ogbase.pas

@@ -3160,9 +3160,15 @@ implementation
         ProcessWorkList;
 
         { Handle stuff like .pdata, i.e. sections that are not referenced
-          but must be included if sections they reference are included. }
-        MarkTargetSpecificSections(ObjSectionWorkList);
-        ProcessWorkList;
+          but must be included if sections they reference are included.
+          Loop is necessary because .pdata can reference (via .xdata)
+          more text sections, VMTs of exception classes, etc. }
+        repeat
+          MarkTargetSpecificSections(ObjSectionWorkList);
+          if (ObjSectionWorkList.Count=0) then
+            break;
+          ProcessWorkList;
+        until False;
 
         ObjSectionWorkList.Free;
         ObjSectionWorkList:=nil;

+ 45 - 0
compiler/ogcoff.pas

@@ -232,6 +232,7 @@ interface
          procedure GenerateRelocs;
        public
          constructor create;override;
+         procedure MarkTargetSpecificSections(WorkList:TFPObjectList);override;
          procedure AfterUnusedSectionRemoval;override;
          procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);override;
          procedure MemPos_Start;override;
@@ -2472,6 +2473,50 @@ const pemagic : array[0..3] of byte = (
       end;
 
 
+    procedure TPECoffexeoutput.MarkTargetSpecificSections(WorkList:TFPObjectList);
+      var
+        exesec:TExeSection;
+        objsec,textsec:TObjSection;
+        objsym:TObjSymbol;
+        objreloc:TObjRelocation;
+        i,j:longint;
+      begin
+        if target_info.system<>system_x86_64_win64 then
+          exit;
+        exesec:=FindExeSection('.pdata');
+        if exesec=nil then
+          exit;
+        for i:=0 to exesec.ObjSectionList.Count-1 do
+          begin
+            objsec:=TObjSection(exesec.ObjSectionList[i]);
+            if objsec.Used then
+              continue;
+            j:=0;
+            while j<objsec.ObjRelocations.Count do
+              begin
+                objreloc:=TObjRelocation(objsec.ObjRelocations[j]);
+                if objreloc.symbol=nil then
+                  InternalError(2013041201);
+                textsec:=objreloc.symbol.objsection;
+                if textsec.used then
+                  begin
+                    WorkList.Add(objsec);
+                    objsec.used:=true;
+                    { The exact algorithm for non-smartlinked .pdata sections
+                      is subject for refinement. Extreme cases are:
+                      - several disjoint .pdata entries for a function, if function
+                        is complex or if compiler splits it into chunks,
+                      - single .pdata section referencing several .text sections,
+                        may need to remove irrelevant parts like BFD does for
+                        .eh_frame sections. }
+                    break;
+                  end;
+                inc(j,3);
+              end;
+          end;
+      end;
+
+
     procedure TPECoffexeoutput.AfterUnusedSectionRemoval;
       var
         basedllname : string;