Browse Source

* tlinker object is now inherited for win32 and dos
* postprocessexecutable is now a method of tlinker

peter 26 năm trước cách đây
mục cha
commit
fc8211bbb8
8 tập tin đã thay đổi với 436 bổ sung156 xóa
  1. 8 4
      compiler/compiler.pas
  2. 157 0
      compiler/dos_targ.pas
  3. 10 12
      compiler/globals.pas
  4. 7 2
      compiler/globtype.pas
  5. 68 32
      compiler/link.pas
  6. 12 8
      compiler/options.pas
  7. 25 26
      compiler/pmodules.pas
  8. 149 72
      compiler/win_targ.pas

+ 8 - 4
compiler/compiler.pas

@@ -165,12 +165,12 @@ begin
      doneparser;
      DoneImport;
      DoneExport;
+     DoneLinker;
    end;
 { Free memory for the others }
   CompilerInited:=false;
   DoneSymtable;
   DoneGlobals;
-  linker.done;
 {$ifdef USEEXCEPT}
   recoverpospointer:=nil;
   longjump_used:=false;
@@ -193,7 +193,6 @@ begin
 {$endif BrowserCol}
   InitGlobals;
   InitSymtable;
-  linker.init;
   CompilerInited:=true;
 { read the arguments }
   read_arguments(cmd);
@@ -201,6 +200,7 @@ begin
   initparser;
   InitImport;
   InitExport;
+  InitLinker;
   CompilerInitedAfterArgs:=true;
 end;
 
@@ -243,7 +243,7 @@ begin
   Message1(general_t_exepath,exepath);
   Message1(general_t_unitpath,unitsearchpath);
   Message1(general_t_includepath,includesearchpath);
-  Message1(general_t_librarypath,Linker.librarysearchpath);
+  Message1(general_t_librarypath,librarysearchpath);
   Message1(general_t_objectpath,objectsearchpath);
 {$ifdef TP}
 {$ifndef Delphi}
@@ -300,7 +300,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.29  1999-08-09 22:13:43  peter
+  Revision 1.30  1999-08-11 17:26:31  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+  Revision 1.29  1999/08/09 22:13:43  peter
     * fixed writing of lost memory which should be after donecompiler
 
   Revision 1.28  1999/08/04 13:02:40  jonas

+ 157 - 0
compiler/dos_targ.pas

@@ -0,0 +1,157 @@
+{
+    $Id$
+    Copyright (c) 1999 by Peter Vreman
+
+    This unit implements some support routines for the Dos targets
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit dos_targ;
+
+  interface
+  uses
+    link;
+
+  type
+    plinkergo32v2=^tlinkergo32v2;
+    tlinkergo32v2=object(tlinker)
+      procedure postprocessexecutable(const n : string);virtual;
+    end;
+
+
+  implementation
+
+    uses
+       strings,globtype,globals,cobjects,systems,verbose;
+
+
+{****************************************************************************
+                            Postprocess Executable
+****************************************************************************}
+
+    procedure tlinkergo32v2.postprocessexecutable(const n : string);
+      begin
+      end;
+
+{$ifdef dummy}
+      type
+        tcoffheader=packed record
+          mach   : word;
+          nsects : word;
+          time   : longint;
+          sympos : longint;
+          syms   : longint;
+          opthdr : word;
+          flag   : word;
+        end;
+        tcoffsechdr=packed record
+          name     : array[0..7] of char;
+          vsize    : longint;
+          rvaofs   : longint;
+          datalen  : longint;
+          datapos  : longint;
+          relocpos : longint;
+          lineno1  : longint;
+          nrelocs  : word;
+          lineno2  : word;
+          flags    : longint;
+        end;
+        psecfill=^tsecfill;
+        tsecfill=record
+          fillpos,
+          fillsize : longint;
+          next : psecfill;
+        end;
+
+      var
+         f : file;
+         coffheader : tcoffheader;
+         firstsecpos,
+         maxfillsize,
+         l : longint;
+         coffsec : tcoffsechdr;
+         secroot,hsecroot : psecfill;
+         zerobuf : pointer;
+      begin
+         { when -s is used quit, because there is no .exe }
+         if cs_link_extern in aktglobalswitches then
+          exit;
+         { open file }
+         assign(f,n);
+         {$I-}
+          reset(f,1);
+         if ioresult<>0 then
+           Message1(execinfo_f_cant_open_executable,n);
+         { read headers }
+         seek(f,2048);
+         blockread(f,coffheader,sizeof(tcoffheader));
+         { read section info }
+         maxfillsize:=0;
+         firstsecpos:=0;
+         secroot:=nil;
+         for l:=1to coffheader.nSects do
+          begin
+            blockread(f,coffsec,sizeof(tcoffsechdr));
+            if coffsec.datapos>0 then
+             begin
+               if secroot=nil then
+                firstsecpos:=coffsec.datapos;
+               new(hsecroot);
+               hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
+               hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
+               hsecroot^.next:=secroot;
+               secroot:=hsecroot;
+               if secroot^.fillsize>maxfillsize then
+                maxfillsize:=secroot^.fillsize;
+             end;
+          end;
+         if firstsecpos>0 then
+          begin
+            l:=firstsecpos-filepos(f);
+            if l>maxfillsize then
+             maxfillsize:=l;
+          end
+         else
+          l:=0;
+         { get zero buffer }
+         getmem(zerobuf,maxfillsize);
+         fillchar(zerobuf^,maxfillsize,0);
+         { zero from sectioninfo until first section }
+         blockwrite(f,zerobuf^,l);
+         { zero section alignments }
+         while assigned(secroot) do
+          begin
+            seek(f,secroot^.fillpos);
+            blockwrite(f,zerobuf^,secroot^.fillsize);
+            hsecroot:=secroot;
+            secroot:=secroot^.next;
+            dispose(hsecroot);
+          end;
+         freemem(zerobuf,maxfillsize);
+         close(f);
+         {$I+}
+      end;
+{$endif}
+
+end.
+{
+  $Log$
+  Revision 1.1  1999-08-11 17:26:32  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+}

+ 10 - 12
compiler/globals.pas

@@ -84,6 +84,10 @@ unit globals;
        outputexedir   : dirstr;
        outputunitdir  : dirstr;
 
+       { things specified with parameters }
+       paralinkoptions,
+       paradynamiclinker : string;
+
        { directory where the utils can be found (options -FD) }
        utilsdirectory : dirstr;
 
@@ -93,6 +97,7 @@ unit globals;
        not_unit_proc : boolean;
        { path for searching units, different paths can be seperated by ; }
        exepath            : dirstr;  { Path to ppc }
+       librarysearchpath,
        unitsearchpath,
        objectsearchpath,
        includesearchpath  : string;
@@ -165,17 +170,6 @@ unit globals;
     const
        RelocSection : boolean = true;
        DLLsource : boolean = false;
-       { no binding needed for win32
-         .edata written directly !! PM
-         so use RelocSection here also
-       bind_win32_dll : boolean = false;}
-       {  WARNING !!!!!
-         without relocation a DLL cannot beloaded at any
-         address but the base address written into the
-         PE header !!!
-         So DLL's should allways be compiled with relocation (PM)
-         Thanks to Pavel Ozerski for explaining me that
-       }
 
        { should we allow non static members ? }
        allow_only_static : boolean = false;
@@ -1239,7 +1233,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.17  1999-08-10 12:51:14  pierre
+  Revision 1.18  1999-08-11 17:26:32  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+  Revision 1.17  1999/08/10 12:51:14  pierre
     * bind_win32_dll removed (Relocsection used instead)
     * now relocsection is true by default ! (needs dlltool
       for DLL generation)

+ 7 - 2
compiler/globtype.pas

@@ -103,7 +103,8 @@ interface
          cs_asm_leave,cs_asm_extern,cs_asm_pipe,cs_asm_source,
          cs_asm_regalloc,cs_asm_tempalloc,
          { linking }
-         cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile
+         cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
+         cs_link_strip,cs_link_toc
        );
        tglobalswitches = set of tglobalswitch;
 
@@ -176,7 +177,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.15  1999-08-04 13:02:42  jonas
+  Revision 1.16  1999-08-11 17:26:33  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+  Revision 1.15  1999/08/04 13:02:42  jonas
     * all tokens now start with an underscore
     * PowerPC compiles!!
 

+ 68 - 32
compiler/link.pas

@@ -41,7 +41,6 @@ Type
        ObjectFiles,
        SharedLibFiles,
        StaticLibFiles    : TStringContainer;
-       LibrarySearchPath,                 { Search path for libraries }
        LinkOptions       : string;        { Additional options to the linker }
        DynamicLinker     : String[80];    { What Dynamic linker ? }
        LinkResName       : String[32];    { Name of response file }
@@ -60,11 +59,15 @@ Type
        Function  MakeExecutable:boolean;
        Procedure MakeStaticLibrary(filescnt:longint);
        Procedure MakeSharedLibrary;
+       procedure postprocessexecutable(const n : string);virtual;
      end;
      PLinker=^TLinker;
 
 Var
-  Linker : TLinker;
+  Linker : PLinker;
+
+procedure InitLinker;
+procedure DoneLinker;
 
 
 Implementation
@@ -79,6 +82,7 @@ uses
   script,globals,verbose,ppu
 {$ifdef i386}
   ,win_targ
+  ,dos_targ
 {$endif}
 {$ifdef linux}
   ,linux
@@ -105,31 +109,33 @@ begin
   ObjectFiles.Init_no_double;
   SharedLibFiles.Init_no_double;
   StaticLibFiles.Init_no_double;
-  LinkToC:=False;
+  LinkToC:=(cs_link_toc in aktglobalswitches);
+  Strip:=(cs_link_strip in aktglobalswitches);
+  LinkOptions:=ParaLinkOptions;
+  DynamicLinker:=ParaDynamicLinker;
+  LinkResName:='link.res';
   Glibc2:=false;
   Glibc21:=false;
-  Strip:=false;
-  LinkOptions:='';
-{$ifdef linux}
-  { first try glibc2 }
-  DynamicLinker:='/lib/ld-linux.so.2';
-  if FileExists(DynamicLinker) then
+  if target_info.target=target_i386_linux then
    begin
-     Glibc2:=true;
-     { also glibc 2.1 / 2.1.1 / 2.1.2 ? }
-     if FileExists('/lib/ld-2.1.so') or
-        FileExists('/lib/ld-2.1.1.so') or
-        FileExists('/lib/ld-2.1.2.so') then
-      Glibc21:=true;
-   end
-  else
-   DynamicLinker:='/lib/ld-linux.so.1';
-  LibrarySearchPath:='/lib;/usr/lib;/usr/X11R6/lib';
-{$else}
-  DynamicLinker:='';
-  LibrarySearchPath:='';
-{$endif}
-  LinkResName:='link.res';
+     if DynamicLinker='' then
+      begin
+        { first try glibc2 }
+        DynamicLinker:='/lib/ld-linux.so.2';
+        if FileExists(DynamicLinker) then
+         begin
+           Glibc2:=true;
+           { also glibc 2.1 / 2.1.1 / 2.1.2 ? }
+           if FileExists('/lib/ld-2.1.so') or
+              FileExists('/lib/ld-2.1.1.so') or
+              FileExists('/lib/ld-2.1.2.so') then
+            Glibc21:=true;
+         end
+        else
+         DynamicLinker:='/lib/ld-linux.so.1';
+      end;
+     AddPathToList(LibrarySearchPath,'/lib;/usr/lib;/usr/X11R6/lib',true);
+   end;
 end;
 
 
@@ -644,14 +650,14 @@ begin
    end;
 
 { Post processor executable }
-{$ifdef i386}
-  if (target_info.target=target_i386_Win32) and success and
+  if success and
      not(cs_link_extern in aktglobalswitches) then
-    if DLLsource then
-      win_targ.postprocessexecutable(current_module^.sharedlibfilename^)
-    else
-      win_targ.postprocessexecutable(current_module^.exefilename^);
-{$endif}
+   begin
+     if DLLsource then
+      postprocessexecutable(current_module^.sharedlibfilename^)
+     else
+      postprocessexecutable(current_module^.exefilename^);
+   end;
 
 {Remove ReponseFile}
   if (success) and not(cs_link_extern in aktglobalswitches) then
@@ -731,11 +737,41 @@ begin
    RemoveFile(current_module^.objfilename^);
 end;
 
+procedure tlinker.postprocessexecutable(const n:string);
+begin
+end;
+
+
+procedure InitLinker;
+begin
+  case target_info.target of
+{$ifdef i386}
+    target_i386_Win32 :
+      linker:=new(plinkerwin32,Init);
+    target_i386_Go32v2 :
+      linker:=new(plinkergo32v2,Init);
+{$endif i386}
+    else
+      linker:=new(plinker,Init);
+  end;
+end;
+
+
+procedure DoneLinker;
+begin
+  if assigned(linker) then
+   dispose(linker,done);
+end;
+
 
 end.
 {
   $Log$
-  Revision 1.65  1999-08-10 12:51:16  pierre
+  Revision 1.66  1999-08-11 17:26:34  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+  Revision 1.65  1999/08/10 12:51:16  pierre
     * bind_win32_dll removed (Relocsection used instead)
     * now relocsection is true by default ! (needs dlltool
       for DLL generation)

+ 12 - 8
compiler/options.pas

@@ -483,9 +483,9 @@ begin
                        'E' : OutputExeDir:=FixPath(More,true);
                        'i' : AddPathToList(includesearchpath,More,not firstpass);
                        'g' : Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
-                       'l' : AddPathToList(Linker.LibrarySearchPath,More,not firstpass);
+                       'l' : AddPathToList(LibrarySearchPath,More,not firstpass);
                        'L' : if More<>'' then
-                              Linker.DynamicLinker:=More
+                              ParaDynamicLinker:=More
                              else
                               IllegalPara(opt);
                        'o' : AddPathToList(objectsearchpath,More,not firstpass);
@@ -503,7 +503,7 @@ begin
                        begin
 {$ifdef GDB}
                          initmoduleswitches:=initmoduleswitches+[cs_debuginfo];
-                         Linker.Strip:=false;
+                         initglobalswitches:=initglobalswitches-[cs_link_strip];
                          for j:=1 to length(more) do
                           case more[j] of
                            'd' : initglobalswitches:=initglobalswitches+[cs_gdb_dbx];
@@ -556,7 +556,7 @@ begin
                      end;
               'I' : AddPathToList(includesearchpath,More,not firstpass);
               'k' : if more<>'' then
-                     Linker.LinkOptions:=Linker.LinkOptions+' '+More
+                     ParaLinkOptions:=ParaLinkOptions+' '+More
                     else
                      IllegalPara(opt);
               'l' : if more='' then
@@ -677,8 +677,8 @@ begin
               'X' : begin
                       for j:=1 to length(More) do
                        case More[j] of
-                        'c' : Linker.LinkToC:=true;
-                        's' : Linker.Strip:=true;
+                        'c' : initglobalswitches:=initglobalswitches+[cs_link_toc];
+                        's' : initglobalswitches:=initglobalswitches+[cs_link_strip];
                         'D' : begin
                                 def_symbol('FPC_LINK_DYNAMIC');
                                 undef_symbol('FPC_LINK_SMART');
@@ -1143,7 +1143,7 @@ begin
   AddPathToList(UnitSearchPath,ExePath,false);
   { Add unit dir to the object and library path }
   AddPathToList(objectsearchpath,unitsearchpath,false);
-  AddPathToList(Linker.librarysearchpath,unitsearchpath,false);
+  AddPathToList(librarysearchpath,unitsearchpath,false);
 
 { switch assembler if it's binary and we got -a on the cmdline }
   if (cs_asm_leave in initglobalswitches) and
@@ -1163,7 +1163,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.12  1999-08-10 12:51:17  pierre
+  Revision 1.13  1999-08-11 17:26:35  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+  Revision 1.12  1999/08/10 12:51:17  pierre
     * bind_win32_dll removed (Relocsection used instead)
     * now relocsection is true by default ! (needs dlltool
       for DLL generation)

+ 25 - 26
compiler/pmodules.pas

@@ -51,7 +51,7 @@ unit pmodules;
          begin
            GenerateAsm(true);
            if target_asm.needar then
-             Linker.MakeStaticLibrary(SmartLinkFilesCnt);
+             Linker^.MakeStaticLibrary(SmartLinkFilesCnt);
          end;
 
         { resource files }
@@ -222,28 +222,23 @@ unit pmodules;
             end;
           target_i386_WIN32 :
             begin
-              { Generate an external entry to be sure that _mainCRTStarup will be
-                linked, can't use concat_external because those aren't written for
-                asw (PFV) }
-             target_link.bindcmd[1]:=target_link.bindcmd[1]+' -d '+deffile.fname;
-             if DLLsource then
-              target_link.binders:=2;
-             if RelocSection then
-              begin
-               target_link.linkcmd:=target_link.linkcmd+' --base-file base.$$$';
-               target_link.bindcmd[1]:=target_link.bindcmd[1]+' --base-file base.$$$';
-               target_link.binders:=2;
-              end;
-             if apptype=at_gui then
-              begin
-               target_link.linkcmd:='--subsystem windows '+target_link.linkcmd;
-               target_link.bindcmd[2]:='--subsystem windows '+target_link.bindcmd[2];
-              end;
-             if DLLsource then
-              begin
-               target_link.linkcmd:='--dll '+target_link.linkcmd;
-               target_link.bindcmd[2]:='--dll '+target_link.bindcmd[2];
-              end;
+              target_link.bindcmd[1]:=target_link.bindcmd[1]+' -d '+deffile.fname;
+              if DLLsource then
+               begin
+                 target_link.binders:=2;
+                 target_link.linkcmd:='--dll '+target_link.linkcmd;
+                 target_link.bindcmd[2]:='--dll '+target_link.bindcmd[2];
+                 if RelocSection then
+                  begin
+                    target_link.linkcmd:=target_link.linkcmd+' --base-file base.$$$';
+                    target_link.bindcmd[1]:=target_link.bindcmd[1]+' --base-file base.$$$';
+                  end;
+               end;
+              if apptype=at_gui then
+               begin
+                target_link.linkcmd:='--subsystem windows '+target_link.linkcmd;
+                target_link.bindcmd[2]:='--subsystem windows '+target_link.bindcmd[2];
+               end;
             end;
 {$endif i386}
 {$ifdef m68k}
@@ -1346,7 +1341,7 @@ unit pmodules;
             hp:=pmodule(loaded_units.first);
             while assigned(hp) do
              begin
-               Linker.AddModuleFiles(hp);
+               Linker^.AddModuleFiles(hp);
                hp:=pmodule(hp^.next);
              end;
             { write .def file }
@@ -1354,14 +1349,18 @@ unit pmodules;
              deffile.writefile;
             { finally we can create a executable }
             if (not current_module^.is_unit) then
-             Linker.MakeExecutable;
+             Linker^.MakeExecutable;
           end;
       end;
 
 end.
 {
   $Log$
-  Revision 1.140  1999-08-04 13:02:57  jonas
+  Revision 1.141  1999-08-11 17:26:36  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+  Revision 1.140  1999/08/04 13:02:57  jonas
     * all tokens now start with an underscore
     * PowerPC compiles!!
 

+ 149 - 72
compiler/win_targ.pas

@@ -25,7 +25,7 @@ unit win_targ;
 
   interface
 
-  uses import,export;
+  uses import,export,link;
 
   const
      winstackpagesize = 4096;
@@ -50,8 +50,11 @@ unit win_targ;
       procedure generatelib;virtual;
     end;
 
-    { sets some flags of the executable }
-    procedure postprocessexecutable(n : string);
+    plinkerwin32=^tlinkerwin32;
+    tlinkerwin32=object(tlinker)
+      procedure postprocessexecutable(const n : string);virtual;
+    end;
+
 
   implementation
 
@@ -63,71 +66,6 @@ unit win_targ;
 {$endif}
        ;
 
-    type
-       tdosheader = packed record
-          e_magic : word;
-          e_cblp : word;
-          e_cp : word;
-          e_crlc : word;
-          e_cparhdr : word;
-          e_minalloc : word;
-          e_maxalloc : word;
-          e_ss : word;
-          e_sp : word;
-          e_csum : word;
-          e_ip : word;
-          e_cs : word;
-          e_lfarlc : word;
-          e_ovno : word;
-          e_res : array[0..3] of word;
-          e_oemid : word;
-          e_oeminfo : word;
-          e_res2 : array[0..9] of word;
-          e_lfanew : longint;
-       end;
-
-       tpeheader = packed record
-          PEMagic : array[0..3] of char;
-          Machine : word;
-          NumberOfSections : word;
-          TimeDateStamp : longint;
-          PointerToSymbolTable : longint;
-          NumberOfSymbols : longint;
-          SizeOfOptionalHeader : word;
-          Characteristics : word;
-          Magic : word;
-          MajorLinkerVersion : byte;
-          MinorLinkerVersion : byte;
-          SizeOfCode : longint;
-          SizeOfInitializedData : longint;
-          SizeOfUninitializedData : longint;
-          AddressOfEntryPoint : longint;
-          BaseOfCode : longint;
-          BaseOfData : longint;
-          ImageBase : longint;
-          SectionAlignment : longint;
-          FileAlignment : longint;
-          MajorOperatingSystemVersion : word;
-          MinorOperatingSystemVersion : word;
-          MajorImageVersion : word;
-          MinorImageVersion : word;
-          MajorSubsystemVersion : word;
-          MinorSubsystemVersion : word;
-          Reserved1 : longint;
-          SizeOfImage : longint;
-          SizeOfHeaders : longint;
-          CheckSum : longint;
-          Subsystem : word;
-          DllCharacteristics : word;
-          SizeOfStackReserve : longint;
-          SizeOfStackCommit : longint;
-          SizeOfHeapReserve : longint;
-          SizeOfHeapCommit : longint;
-          LoaderFlags : longint;
-          NumberOfRvaAndSizes : longint;
-          { DataDirectory : array[0..(IMAGE_NUMBEROF_DIRECTORY_ENTRIES)-1] of IMAGE_DATA_DIRECTORY; }
-       end;
-
     function DllName(Const Name : string) : string;
       var n : string;
       begin
@@ -670,14 +608,105 @@ unit win_targ;
          dispose(tempexport,done);
       end;
 
-    procedure postprocessexecutable(n : string);
+
+{****************************************************************************
+                            Postprocess Executable
+****************************************************************************}
+
+    procedure tlinkerwin32.postprocessexecutable(const n : string);
+      type
+         tdosheader = packed record
+            e_magic : word;
+            e_cblp : word;
+            e_cp : word;
+            e_crlc : word;
+            e_cparhdr : word;
+            e_minalloc : word;
+            e_maxalloc : word;
+            e_ss : word;
+            e_sp : word;
+            e_csum : word;
+            e_ip : word;
+            e_cs : word;
+            e_lfarlc : word;
+            e_ovno : word;
+            e_res : array[0..3] of word;
+            e_oemid : word;
+            e_oeminfo : word;
+            e_res2 : array[0..9] of word;
+            e_lfanew : longint;
+         end;
+
+         tpeheader = packed record
+            PEMagic : array[0..3] of char;
+            Machine : word;
+            NumberOfSections : word;
+            TimeDateStamp : longint;
+            PointerToSymbolTable : longint;
+            NumberOfSymbols : longint;
+            SizeOfOptionalHeader : word;
+            Characteristics : word;
+            Magic : word;
+            MajorLinkerVersion : byte;
+            MinorLinkerVersion : byte;
+            SizeOfCode : longint;
+            SizeOfInitializedData : longint;
+            SizeOfUninitializedData : longint;
+            AddressOfEntryPoint : longint;
+            BaseOfCode : longint;
+            BaseOfData : longint;
+            ImageBase : longint;
+            SectionAlignment : longint;
+            FileAlignment : longint;
+            MajorOperatingSystemVersion : word;
+            MinorOperatingSystemVersion : word;
+            MajorImageVersion : word;
+            MinorImageVersion : word;
+            MajorSubsystemVersion : word;
+            MinorSubsystemVersion : word;
+            Reserved1 : longint;
+            SizeOfImage : longint;
+            SizeOfHeaders : longint;
+            CheckSum : longint;
+            Subsystem : word;
+            DllCharacteristics : word;
+            SizeOfStackReserve : longint;
+            SizeOfStackCommit : longint;
+            SizeOfHeapReserve : longint;
+            SizeOfHeapCommit : longint;
+            LoaderFlags : longint;
+            NumberOfRvaAndSizes : longint;
+            DataDirectory : array[1..$80] of byte;
+         end;
+        tcoffsechdr=packed record
+          name     : array[0..7] of char;
+          vsize    : longint;
+          rvaofs   : longint;
+          datalen  : longint;
+          datapos  : longint;
+          relocpos : longint;
+          lineno1  : longint;
+          nrelocs  : word;
+          lineno2  : word;
+          flags    : longint;
+        end;
+        psecfill=^tsecfill;
+        tsecfill=record
+          fillpos,
+          fillsize : longint;
+          next : psecfill;
+        end;
 
       var
          f : file;
          dosheader : tdosheader;
          peheader : tpeheader;
-         peheaderpos : longint;
-
+         firstsecpos,
+         maxfillsize,
+         l,peheaderpos : longint;
+         coffsec : tcoffsechdr;
+         secroot,hsecroot : psecfill;
+         zerobuf : pointer;
       begin
          { when -s is used quit, because there is no .exe }
          if cs_link_extern in aktglobalswitches then
@@ -719,6 +748,50 @@ unit win_targ;
 
          Message1(execinfo_x_stackreserve,tostr(peheader.SizeOfStackReserve));
          Message1(execinfo_x_stackcommit,tostr(peheader.SizeOfStackCommit));
+
+         { read section info }
+         maxfillsize:=0;
+         firstsecpos:=0;
+         secroot:=nil;
+         for l:=1to peheader.NumberOfSections do
+          begin
+            blockread(f,coffsec,sizeof(tcoffsechdr));
+            if coffsec.datapos>0 then
+             begin
+               if secroot=nil then
+                firstsecpos:=coffsec.datapos;
+               new(hsecroot);
+               hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
+               hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
+               hsecroot^.next:=secroot;
+               secroot:=hsecroot;
+               if secroot^.fillsize>maxfillsize then
+                maxfillsize:=secroot^.fillsize;
+             end;
+          end;
+         if firstsecpos>0 then
+          begin
+            l:=firstsecpos-filepos(f);
+            if l>maxfillsize then
+             maxfillsize:=l;
+          end
+         else
+          l:=0;
+         { get zero buffer }
+         getmem(zerobuf,maxfillsize);
+         fillchar(zerobuf^,maxfillsize,0);
+         { zero from sectioninfo until first section }
+         blockwrite(f,zerobuf^,l);
+         { zero section alignments }
+         while assigned(secroot) do
+          begin
+            seek(f,secroot^.fillpos);
+            blockwrite(f,zerobuf^,secroot^.fillsize);
+            hsecroot:=secroot;
+            secroot:=secroot^.next;
+            dispose(hsecroot);
+          end;
+         freemem(zerobuf,maxfillsize);
          close(f);
          {$I+}
       end;
@@ -726,7 +799,11 @@ unit win_targ;
 end.
 {
   $Log$
-  Revision 1.31  1999-08-04 00:23:50  florian
+  Revision 1.32  1999-08-11 17:26:38  peter
+    * tlinker object is now inherited for win32 and dos
+    * postprocessexecutable is now a method of tlinker
+
+  Revision 1.31  1999/08/04 00:23:50  florian
     * renamed i386asm and i386base to cpuasm and cpubase
 
   Revision 1.30  1999/07/29 20:54:11  peter