Fri May 12 11:03:55 1995 Steve Chamberlain <sac@slash.cygnus.com>
authorSteve Chamberlain <sac@cygnus>
Fri, 12 May 1995 18:55:06 +0000 (18:55 +0000)
committerSteve Chamberlain <sac@cygnus>
Fri, 12 May 1995 18:55:06 +0000 (18:55 +0000)
  Tom Griest <griest@cs.yale.edu>

Initial support for PE executables (eg NT, win32)

* Makefile.in (configure.in, ei386pe): Add support.
* ldmain.c (main): Initialize PE argument info.
* ldwrite.c (print_file_stuff): Don't print out .drectve
and .debug section info.
* lexsup.c (set_subsystem, set_stack_heap, OPTION_HEAP,
 OPTION_SUBSYSTEM, parse_argsm set_subsystem, set_stack_heap):
 Handle new arguments.
* config/i386-pe.mt, emultempl/i386pe.em, scripttempl/i386pe.sc:
New files

ld/config/.Sanitize
ld/config/i386-pe.mt [new file with mode: 0644]
ld/emulparams/.Sanitize
ld/emulparams/i386pe.sh [new file with mode: 0644]
ld/emultempl/.Sanitize
ld/emultempl/i386pe.em [new file with mode: 0644]
ld/ldlang.c
ld/scripttempl/.Sanitize
ld/scripttempl/i386pe.sc [new file with mode: 0644]

index b83a01e9b3c7012d7b89c8796615edb70d0de887..d0e688cc06e1c6353311cf5853cf3fcde350aac5 100644 (file)
@@ -41,17 +41,18 @@ Things-to-keep:
 
 alpha.mt
 alphaosf.mh
+cf-h8300h.mt
 coff-a29k.mt
 coff-h8300.mt
-cf-h8300h.mt
 coff-h8500.mt
 coff-sh.mt
 coff-sparc.mt
+coff-w65.mt
 delta88.mh
 dgux.mh
 ebmon29k.mt
-go32.mt
 go32.mh
+go32.mt
 hp300.mh
 hp300bsd.mt
 hp300hpux.mt
@@ -70,6 +71,7 @@ i386-lynx.mt
 i386-mach.mt
 i386-nbsd.mt
 i386-nw.mt
+i386-pe.mt
 i386bsd.mh
 i386linux.mh
 i386lynx.mh
@@ -82,21 +84,21 @@ i960coff.mt
 ieee-h8300.mt
 irix4.mh
 m68k-coff.mt
-m68k.mt
 m68k-elf.mt
 m68k-lynx.mt
 m68k-nbsd.mt
+m68k.mt
 m68klynx.mh
 m68kv.mt
 m88k-bcs.mt
-mipsbsd.mh
-mipsbsd.mt
 mips-big.mt
 mips-idt.mt
+mips-lit.mt
 mipsb-elf32.mt
+mipsbsd.mh
+mipsbsd.mt
 mipsl-elf32.mt
 mipsl-idt.mt
-mips-lit.mt
 news.mt
 ns32k-nbsd.mt
 ose68.mt
@@ -108,10 +110,10 @@ riscix.mt
 rtbsd.mh
 sa29200.mt
 solaris2.mh
-sparc64-elf.mt
 sparc-ll.mh
 sparc-lynx.mt
 sparc-nbsd.mt
+sparc64-elf.mt
 st2000.mt
 sun3.mh
 sun3.mt
@@ -121,7 +123,6 @@ vax.mt
 vsta.mt
 vxworks68.mt
 z8ksim.mt
-coff-w65.mt
 
 Things-to-lose:
 
diff --git a/ld/config/i386-pe.mt b/ld/config/i386-pe.mt
new file mode 100644 (file)
index 0000000..10d7f83
--- /dev/null
@@ -0,0 +1 @@
+EMUL=i386pe
index b17b1afda59d6680cb2caa953e353c7f1735f8fe..326cd9f5d4652206e002bb399853ce256dd35c1c 100644 (file)
@@ -45,10 +45,10 @@ alpha.sh
 coff_sparc.sh
 ebmon29k.sh
 elf32_sparc.sh
-elf64_sparc.sh
 elf32bmip.sh
 elf32lmip.sh
 elf32ppc.sh
+elf64_sparc.sh
 elf32ppcle.sh
 elf_i386.sh
 gld960.sh
@@ -59,8 +59,8 @@ h8300h.sh
 h8500.sh
 h8500b.sh
 h8500c.sh
-h8500s.sh
 h8500m.sh
+h8500s.sh
 hp300bsd.sh
 hp3hpux.sh
 hppaelf.sh
@@ -73,6 +73,7 @@ i386lynx.sh
 i386mach.sh
 i386nbsd.sh
 i386nw.sh
+i386pe.sh
 lnk960.sh
 m68kaout.sh
 m68kcoff.sh
diff --git a/ld/emulparams/i386pe.sh b/ld/emulparams/i386pe.sh
new file mode 100644 (file)
index 0000000..df2e9d8
--- /dev/null
@@ -0,0 +1,3 @@
+ARCH=i386
+SCRIPT_NAME=i386pe
+OUTPUT_FORMAT="pe-i386"
index 8080c6896b840ae83f1d0a86238419957e77cfa6..e86e2044937849e048b9cf4adc6ef2bb713bdd46 100644 (file)
@@ -25,16 +25,17 @@ Do-first:
 Things-to-keep:
 
 README
-stringify.sed
 elf32.em
 generic.em
 gld960.em
 gld960c.em
 hppaelf.em
+i386pe.em
 linux.em
 lnk960.em
 m88kbcs.em
 mipsecoff.em
+stringify.sed
 sunos.em
 vanilla.em
 
diff --git a/ld/emultempl/i386pe.em b/ld/emultempl/i386pe.em
new file mode 100644 (file)
index 0000000..a27ed40
--- /dev/null
@@ -0,0 +1,230 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* For WINDOWS_NT */
+/* This file is a copy of ei385coff which was originally generated on a Linux
+   system.  It has been modified to provide a decent default script file
+   for the NT PE format. */
+
+/* The original file generated returned different default scripts depending
+   on whether certain switches were set, but these switches pertain to the
+   Linux system and that particular version of coff.  In the NT case, we
+   only determine if the subsystem is console or windows in order to select
+   the correct entry point by default. */ 
+  
+
+/* emulate the original gld for the given i386pe
+   Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+   Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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.  */
+
+#define TARGET_IS_i386pe
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "config.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+static void gldi386pe_before_parse PARAMS ((void));
+static char *gldi386pe_get_script PARAMS ((int *isfile));
+
+static void
+gldi386pe_before_parse()
+{
+#ifndef TARGET_                        /* I.e., if not generic.  */
+  ldfile_output_architecture = bfd_arch_i386;
+#endif /* not TARGET_ */
+}
+
+static char *
+gldi386pe_get_script(isfile)
+     int *isfile;
+{                           
+  *isfile = 0;
+
+  if (link_info.subsystem == windows)
+    return
+"OUTPUT_FORMAT(\"coff-i386\")\n\
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/i386-coff/lib);\n\
+ENTRY(_WinMainCRTStartup)\n\
+SECTIONS\n\
+{\n\
+  .text 0x401000 : {\n\
+    *(.text)\n\
+    ;\n\
+  }\n\
+  .bss BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.bss)\n\
+    *(COMMON)\n\
+    ;\n\
+  }\n\
+  .rdata BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.rdata)\n\
+    ;\n\
+  }\n\
+  .data BLOCK(0x1000) : {\n\
+    *(.data)\n\
+    *(.data2)\n\
+    ;\n\
+  }\n\
+  .idata BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.idata$2)\n\
+    *(.idata$3)\n\
+    *(.idata$4)\n\
+    *(.idata$5)\n\
+    *(.idata$6)\n\
+    *(.idata$7)\n\
+    ;\n\
+  }\n\
+  .CRT BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.CRT$XCA)\n\
+    *(.CRT$XCC)\n\
+    *(.CRT$XCZ)\n\
+    *(.CRT$XIA)\n\
+    *(.CRT$XIC)\n\
+    *(.CRT$XIZ)\n\
+    *(.CRT$XLA)\n\
+    *(.CRT$XLZ)\n\
+    *(.CRT$XPA)\n\
+    *(.CRT$XPX)\n\
+    *(.CRT$XPZ)\n\
+    *(.CRT$XTA)\n\
+    *(.CRT$XTZ)\n\
+    ;\n\
+  }\n\
+  .rsrc BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.rsrc$01)\n\
+    *(.rsrc$02)\n\
+    ;\n\
+  }\n\
+  .reloc BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.reloc)\n\
+    ;\n\
+  }\n\
+  .junk BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.debug$S)\n\
+    *(.debug$T)\n\
+    *(.debug$F)\n\
+    *(.drectve)\n\
+    ;\n\
+  }\n\
+}\n\n"
+  ; else return
+"OUTPUT_FORMAT(\"coff-i386\")\n\
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/i386-coff/lib);\n\
+ENTRY(_mainCRTStartup)\n\
+SECTIONS\n\
+{\n\
+  .text 0x401000 : {\n\
+    *(.text)\n\
+    ;\n\
+  }\n\
+  .bss BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.bss)\n\
+    *(COMMON)\n\
+    ;\n\
+  }\n\
+  .rdata BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.rdata)\n\
+    ;\n\
+  }\n\
+  .data BLOCK(0x1000) : {\n\
+    *(.data)\n\
+    *(.data2)\n\
+    ;\n\
+  }\n\
+  .idata BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.idata$2)\n\
+    *(.idata$3)\n\
+    *(.idata$4)\n\
+    *(.idata$5)\n\
+    *(.idata$6)\n\
+    *(.idata$7)\n\
+    ;\n\
+  }\n\
+  .CRT BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.CRT$XCA)\n\
+    *(.CRT$XCC)\n\
+    *(.CRT$XCZ)\n\
+    *(.CRT$XIA)\n\
+    *(.CRT$XIC)\n\
+    *(.CRT$XIZ)\n\
+    *(.CRT$XLA)\n\
+    *(.CRT$XLZ)\n\
+    *(.CRT$XPA)\n\
+    *(.CRT$XPX)\n\
+    *(.CRT$XPZ)\n\
+    *(.CRT$XTA)\n\
+    *(.CRT$XTZ)\n\
+    ;\n\
+  }\n\
+  .rsrc BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.rsrc$01)\n\
+    *(.rsrc$02)\n\
+    ;\n\
+  }\n\
+  .reloc BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.reloc)\n\
+    ;\n\
+  }\n\
+  .junk BLOCK(0x1000) :\n\
+  {                                    \n\
+    *(.debug$S)\n\
+    *(.debug$T)\n\
+    *(.debug$F)\n\
+    *(.drectve)\n\
+    ;\n\
+  }\n\
+}\n\n"
+  ; 
+}
+
+struct ld_emulation_xfer_struct ld_i386pe_emulation = 
+{
+  gldi386pe_before_parse,
+  syslib_default,
+  hll_default,
+  after_parse_default,
+  after_allocation_default,
+  set_output_arch_default,
+  ldemul_default_target,
+  before_allocation_default,
+  gldi386pe_get_script,
+  "i386pe",
+  "pe-i386"
+};
+EOF
\ No newline at end of file
index f7847d38ad584d123b22da4d00da656037a58c86..3c9350ddaada6462060e4ff04d9216be91e3d420 100644 (file)
@@ -2752,6 +2752,21 @@ lang_section_start (name, address)
    called by ENTRY in a linker script.  Command line arguments take
    precedence.  */
 
+/* WINDOWS_NT.  When an entry point has been specified, we will also force
+   this symbol to be defined by calling ldlang_add_undef (equivalent to 
+   having switch -u entry_name on the command line).  The reason we do
+   this is so that the user doesn't have to because they would have to use
+   the -u switch if they were specifying an entry point other than 
+   _mainCRTStartup.  Specifically, if creating a windows application, entry
+   point _WinMainCRTStartup must be specified.
+     What I have found for non console applications (entry not _mainCRTStartup)
+   is that the .obj that contains mainCRTStartup is brought in since it is
+   the first encountered in libc.lib and it has other symbols in it which will
+   be pulled in by the link process.  To avoid this, adding -u with the entry
+   point name specified forces the correct .obj to be used.  We can avoid
+   making the user do this by always adding the entry point name as an
+   undefined symbol.  */
+
 void
 lang_add_entry (name, cmdline)
      CONST char *name;
@@ -2766,6 +2781,14 @@ lang_add_entry (name, cmdline)
       entry_symbol = name;
       from_cmdline = cmdline;
     }
+#ifdef 0 /* WINDOWS_NT */
+  /* don't do this yet.  It seems to work (the executables run), but the 
+     image created is very different from what I was getting before indicating
+     that something else is being pulled in.  When everything else is working,
+     then try to put this back in to see if it will do the right thing for
+     other more complicated applications */
+  ldlang_add_undef (name);
+#endif
 }
 
 void
index bf8a171ec5e78ebd9b3f071bbb3ddfc2e7cc8d3e..46c22427e3c17c78a85b3a076dfc46d72a7f373f 100644 (file)
@@ -48,6 +48,7 @@ h8500m.sc
 h8500s.sc
 hppaelf.sc
 i386coff.sc
+i386pe.sc
 i386go32.sc
 i386lynx.sc
 i960.sc
diff --git a/ld/scripttempl/i386pe.sc b/ld/scripttempl/i386pe.sc
new file mode 100644 (file)
index 0000000..d23506d
--- /dev/null
@@ -0,0 +1,95 @@
+# Linker script for 386 PE.
+# These are substituted in as variables in order to get '}' in a shell
+# conditional expansion.
+INIT='.init : { *(.init) }'
+FINI='.fini : { *(.fini) }'
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(_mainCRTStartup)
+
+SECTIONS
+{
+
+  .text ${RELOCATING+ 0x401000} : 
+       {
+           ${RELOCATING+ *(.init);}
+           *(.text)
+           ${RELOCATING+ *(.fini);}
+           ${RELOCATING+ etext  =  .};
+         }
+
+  .bss BLOCK(0x1000)  :
+       {
+       *(.bss)
+       *(COMMON);
+       }
+
+  .rdata BLOCK(0x1000) :
+  {                                    
+    *(.rdata)
+    ;
+  }
+  .data BLOCK(0x1000) : {
+    *(.data)
+    *(.data2)
+    ;
+  }
+  .idata BLOCK(0x1000) :
+  {                                    
+    *(.idata$2)
+    *(.idata$3)
+    *(.idata$4)
+    *(.idata$5)
+    *(.idata$6)
+    *(.idata$7)
+    ;
+  }
+  .CRT BLOCK(0x1000) :
+  {                                    
+    *(.CRT$XCA)
+    *(.CRT$XCC)
+    *(.CRT$XCZ)
+    *(.CRT$XIA)
+    *(.CRT$XIC)
+    *(.CRT$XIZ)
+    *(.CRT$XLA)
+    *(.CRT$XLZ)
+    *(.CRT$XPA)
+    *(.CRT$XPX)
+    *(.CRT$XPZ)
+    *(.CRT$XTA)
+    *(.CRT$XTZ)
+    ;
+  }
+  .rsrc BLOCK(0x1000) :
+  {                                    
+    *(.rsrc$01)
+    *(.rsrc$02)
+    ;
+  }
+  .reloc BLOCK(0x1000) :
+  {                                    
+    *(.reloc)
+    ;
+  }
+  .junk BLOCK(0x1000) :
+  {                                    
+    *(.debug$S)
+    *(.debug$T)
+    *(.debug$F)
+    *(.drectve)
+    ;
+  }
+  .stab  0 ${RELOCATING+(NOLOAD)} : 
+  {
+    [ .stab ]
+  }
+
+  .stabstr  0 ${RELOCATING+(NOLOAD)} :
+  {
+    [ .stabstr ]
+  }
+}
+EOF