]> code.delx.au - gnu-emacs/blobdiff - src/unexw32.c
(SET_RAW_SYNTAX_ENTRY, SYNTAX_ENTRY): Adjusted for the change of
[gnu-emacs] / src / unexw32.c
index cf89f031bb956d2d0fb75a27f56831eddac5df13..d449a79eaa0be89e31e71671c84620d0d81c106d 100644 (file)
@@ -1,23 +1,22 @@
-/*
-   unexec for GNU Emacs on Windows NT.
-
+/* unexec for GNU Emacs on Windows NT.
    Copyright (C) 1994 Free Software Foundation, Inc.
 
-   This file is part of GNU Emacs.
+This file is part of GNU Emacs.
 
-   GNU Emacs 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, or (at your option) any later
-   version.
+GNU Emacs 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, or (at your option)
+any later version.
 
-   GNU Emacs 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.
+GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to the Free Software
-   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
 
    Geoff Voelker (voelker@cs.washington.edu)                         8-12-94
 */
@@ -29,7 +28,7 @@
 
 extern BOOL ctrl_c_handler (unsigned long type);
 
-#include "ntheap.h"
+#include "w32heap.h"
 
 /* A convenient type for keeping all the info about a mapped file together.  */
 typedef struct file_data {
@@ -63,6 +62,13 @@ DWORD  data_size = 0;
 PUCHAR bss_start = 0;
 DWORD  bss_size = 0;
 
+#ifdef HAVE_NTGUI
+HINSTANCE hinst = NULL;
+HINSTANCE hprevinst = NULL;
+LPSTR lpCmdLine = "";
+int nCmdShow = 0;
+#endif /* HAVE_NTGUI */
+
 /* Startup code for running on NT.  When we are running as the dumped
    version, we need to bootstrap our heap and .bss section into our
    address space before we can actually hand off control to the startup
@@ -103,10 +109,16 @@ _start (void)
 
   /* Invoke the NT CRT startup routine now that our housecleaning
      is finished.  */
+#ifdef HAVE_NTGUI
+  /* determine WinMain args like crt0.c does */
+  hinst = GetModuleHandle(NULL);
+  lpCmdLine = GetCommandLine();
+  nCmdShow = SW_SHOWDEFAULT;
+#endif
   mainCRTStartup ();
 }
 
-/* Dump out .data and .bss sections into a new exectubale.  */
+/* Dump out .data and .bss sections into a new executable.  */
 void
 unexec (char *new_name, char *old_name, void *start_data, void *start_bss,
        void *entry_address)
@@ -209,13 +221,15 @@ open_output_file (file_data *p_file, char *filename, unsigned long size)
   HANDLE file;
   HANDLE file_mapping;
   void  *file_base;
-  
+  int    i;
+
   file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                     CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
   if (file == INVALID_HANDLE_VALUE) 
     {
+      i = GetLastError ();
       printf ("open_output_file: Failed to open %s (%d).\n", 
-            filename, GetLastError ());
+            filename, i);
       exit (1);
     }
   
@@ -223,16 +237,18 @@ open_output_file (file_data *p_file, char *filename, unsigned long size)
                                    0, size, NULL);
   if (!file_mapping) 
     {
+      i = GetLastError ();
       printf ("open_output_file: Failed to create file mapping of %s (%d).\n",
-            filename, GetLastError ());
+            filename, i);
       exit (1);
     }
   
   file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
   if (file_base == 0) 
     {
+      i = GetLastError ();
       printf ("open_output_file: Failed to map view of file of %s (%d).\n",
-            filename, GetLastError ());
+            filename, i);
       exit (1);
     }
   
@@ -255,12 +271,50 @@ close_file_data (file_data *p_file)
 
 /* Routines to manipulate NT executable file sections.  */
 
+static void
+get_bss_info_from_map_file (file_data *p_infile, PUCHAR *p_bss_start, 
+                           DWORD *p_bss_size)
+{
+  int n, start, len;
+  char map_filename[MAX_PATH];
+  char buffer[256];
+  FILE *map;
+
+  /* Overwrite the .exe extension on the executable file name with
+     the .map extension.  */
+  strcpy (map_filename, p_infile->name);
+  n = strlen (map_filename) - 3;
+  strcpy (&map_filename[n], "map");
+
+  map = fopen (map_filename, "r");
+  if (!map)
+    {
+      printf ("Failed to open map file %s, error %d...bailing out.\n",
+             map_filename, GetLastError ());
+      exit (-1);
+    }
+
+  while (fgets (buffer, sizeof (buffer), map))
+    {
+      if (!(strstr (buffer, ".bss") && strstr (buffer, "DATA")))
+       continue;
+      n = sscanf (buffer, " %*d:%x %x", &start, &len);
+      if (n != 2)
+       {
+         printf ("Failed to scan the .bss section line:\n%s", buffer);
+         exit (-1);
+       }
+      break;
+    }
+  *p_bss_start = (PUCHAR) start;
+  *p_bss_size = (DWORD) len;
+}
 
 static unsigned long
 get_section_size (PIMAGE_SECTION_HEADER p_section)
 {
   /* The section size is in different locations in the different versions.  */
-  switch (get_nt_minor_version ()) 
+  switch (get_w32_minor_version ()) 
     {
     case 10:
       return p_section->SizeOfRawData;
@@ -275,7 +329,7 @@ get_section_info (file_data *p_infile)
 {
   PIMAGE_DOS_HEADER dos_header;
   PIMAGE_NT_HEADERS nt_header;
-  PIMAGE_SECTION_HEADER section;
+  PIMAGE_SECTION_HEADER section, data_section;
   unsigned char *ptr;
   int i;
   
@@ -319,7 +373,8 @@ get_section_info (file_data *p_infile)
          extern char my_edata[];
 
          /* The .data section.  */
-         ptr  = (char *) nt_header->OptionalHeader.ImageBase +
+         data_section = section;
+         ptr = (char *) nt_header->OptionalHeader.ImageBase +
            section->VirtualAddress;
          data_start_va = ptr;
          data_start_file = section->PointerToRawData;
@@ -332,6 +387,21 @@ get_section_info (file_data *p_infile)
        }
       section++;
     }
+
+  if (!bss_start && !bss_size)
+    {
+      /* Starting with MSVC 4.0, the .bss section has been eliminated
+        and appended virtually to the end of the .data section.  Our
+        only hint about where the .bss section starts in the address
+        comes from the SizeOfRawData field in the .data section
+        header.  Unfortunately, this field is only approximate, as it
+        is a rounded number and is typically rounded just beyond the
+        start of the .bss section.  To find the start and size of the
+        .bss section exactly, we have to peek into the map file.  */
+      get_bss_info_from_map_file (p_infile, &ptr, &bss_size);
+      bss_start = ptr + nt_header->OptionalHeader.ImageBase
+       + data_section->VirtualAddress;
+    }
 }