Ver Fonte

* Improvements to PE executable output:
* Clear bits in section flags, that are only valid for object files
* Round section datasize up to filealignment (PECOFF v8 documentation requires this)
* Zero datapos and datasize for all sections w/o data, not just for .bss
* Produce IMPORT_ADDRESS_TABLE directory in exe header
* Entirely smartlink away unused DLLs (these used to have two terminating thunks left)

git-svn-id: trunk@17949 -

sergei há 14 anos atrás
pai
commit
2d96c34b06
1 ficheiros alterados com 61 adições e 10 exclusões
  1. 61 10
      compiler/ogcoff.pas

+ 61 - 10
compiler/ogcoff.pas

@@ -2107,12 +2107,18 @@ const pemagic : array[0..3] of byte = (
             else
             else
               sechdr.vsize:=mempos;
               sechdr.vsize:=mempos;
 
 
-            { sechdr.dataSize is size of initilized data. For .bss section it must be zero }
-            if (Name <> '.bss') then
-              sechdr.dataSize:=Size;
-            if (sechdr.dataSize>0) and
-               (oso_data in SecOptions) then
-              sechdr.datapos:=datapos;
+            { sechdr.dataSize is size of initilized data. Must be zero for sections that
+              do not contain one. In Windows, must be rounded up to FileAlignment
+             (so it can be greater than VirtualSize) }
+            if (oso_data in SecOptions) then
+              begin
+                if win32 then
+                  sechdr.dataSize:=Align(Size,SectionDataAlign)
+                else
+                  sechdr.dataSize:=Size;
+                if (Size>0) then
+                  sechdr.datapos:=datapos;
+              end;
             sechdr.nrelocs:=0;
             sechdr.nrelocs:=0;
             sechdr.relocpos:=0;
             sechdr.relocpos:=0;
             if win32 then
             if win32 then
@@ -2122,6 +2128,10 @@ const pemagic : array[0..3] of byte = (
                   sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign) or PE_SCN_MEM_NOT_PAGED
                   sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign) or PE_SCN_MEM_NOT_PAGED
                 else
                 else
                   sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign);
                   sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign);
+                { some flags are invalid in executables, reset them }
+                sechdr.flags:=sechdr.flags and
+                  not(PE_SCN_LNK_INFO or PE_SCN_LNK_REMOVE or
+                      PE_SCN_LNK_COMDAT or PE_SCN_ALIGN_MASK);
               end
               end
             else
             else
               sechdr.flags:=djencodesechdrflags(SecOptions);
               sechdr.flags:=djencodesechdrflags(SecOptions);
@@ -2250,6 +2260,49 @@ const pemagic : array[0..3] of byte = (
            end;
            end;
         end;
         end;
 
 
+        procedure UpdateImports;
+        var
+          exesec: TExeSection;
+          objsec, iat_start, iat_end, ilt_start: TObjSection;
+          i: longint;
+        begin
+          exesec:=FindExeSection('.idata');
+          if exesec=nil then
+            exit;
+          iat_start:=nil;
+          iat_end:=nil;
+          ilt_start:=nil;
+          for i:=0 to exesec.ObjSectionList.Count-1 do
+            begin
+              objsec:=TObjSection(exesec.ObjSectionList[i]);
+              if (ilt_start=nil) and (Pos('.idata$4',objsec.Name)=1) then
+                ilt_start:=objsec;
+              if Pos('.idata$5',objsec.Name)=1 then
+                begin
+                  if iat_start=nil then
+                    iat_start:=objsec;
+                end
+              else
+                if Assigned(iat_start) then
+                  begin
+                    iat_end:=objsec;
+                    Break;
+                  end;
+            end;
+
+          peoptheader.DataDirectory[PE_DATADIR_IDATA].vaddr:=exesec.mempos;
+          if Assigned(ilt_start) then
+            peoptheader.DataDirectory[PE_DATADIR_IDATA].size:=ilt_start.mempos-exesec.mempos
+          else  { should not happen }
+            peoptheader.DataDirectory[PE_DATADIR_IDATA].size:=exesec.Size;
+
+          if Assigned(iat_start) and Assigned(iat_end) then
+            begin
+              peoptheader.DataDirectory[PE_DATADIR_IMPORTADDRESSTABLE].vaddr:=iat_start.mempos;
+              peoptheader.DataDirectory[PE_DATADIR_IMPORTADDRESSTABLE].size:=iat_end.mempos-iat_start.mempos;
+            end;
+        end;
+
         procedure UpdateTlsDataDir;
         procedure UpdateTlsDataDir;
         var
         var
           {callbacksection : TExeSection;}
           {callbacksection : TExeSection;}
@@ -2404,7 +2457,7 @@ const pemagic : array[0..3] of byte = (
             peoptheader.SizeOfHeapReserve:=$100000;
             peoptheader.SizeOfHeapReserve:=$100000;
             peoptheader.SizeOfHeapCommit:=$1000;
             peoptheader.SizeOfHeapCommit:=$1000;
             peoptheader.NumberOfRvaAndSizes:=PE_DATADIR_ENTRIES;
             peoptheader.NumberOfRvaAndSizes:=PE_DATADIR_ENTRIES;
-            UpdateDataDir('.idata',PE_DATADIR_IDATA);
+            UpdateImports;
             UpdateTlsDataDir;
             UpdateTlsDataDir;
             UpdateDataDir('.edata',PE_DATADIR_EDATA);
             UpdateDataDir('.edata',PE_DATADIR_EDATA);
             UpdateDataDir('.rsrc',PE_DATADIR_RSRC);
             UpdateDataDir('.rsrc',PE_DATADIR_RSRC);
@@ -2545,6 +2598,7 @@ const pemagic : array[0..3] of byte = (
           emptyint : longint;
           emptyint : longint;
         begin
         begin
           emptyint:=0;
           emptyint:=0;
+          { These are referenced from idata2, oso_keep is not necessary. }
           idata4objsection:=internalobjdata.createsection(sec_idata4, basedllname+'_z_');
           idata4objsection:=internalobjdata.createsection(sec_idata4, basedllname+'_z_');
           internalobjdata.SymbolDefine('__imp_names_end_'+basedllname,AB_LOCAL,AT_DATA);
           internalobjdata.SymbolDefine('__imp_names_end_'+basedllname,AB_LOCAL,AT_DATA);
           idata5objsection:=internalobjdata.createsection(sec_idata5, basedllname+'_z_');
           idata5objsection:=internalobjdata.createsection(sec_idata5, basedllname+'_z_');
@@ -2559,9 +2613,6 @@ const pemagic : array[0..3] of byte = (
           internalobjdata.writebytes(emptyint,sizeof(emptyint));
           internalobjdata.writebytes(emptyint,sizeof(emptyint));
           if target_info.system=system_x86_64_win64 then
           if target_info.system=system_x86_64_win64 then
             internalobjdata.writebytes(emptyint,sizeof(emptyint));
             internalobjdata.writebytes(emptyint,sizeof(emptyint));
-          { be sure that this will not be removed }
-          idata4objsection.SecOptions:=idata4objsection.SecOptions + [oso_keep];
-          idata5objsection.SecOptions:=idata5objsection.SecOptions + [oso_keep];
         end;
         end;
 
 
         function AddImport(const afuncname,amangledname:string; AOrdNr:longint;isvar:boolean):TObjSymbol;
         function AddImport(const afuncname,amangledname:string; AOrdNr:longint;isvar:boolean):TObjSymbol;