]> code.delx.au - gnu-emacs/blobdiff - src/unexw32.c
(Fmake_network_process): Only support server sockets
[gnu-emacs] / src / unexw32.c
index 4cdffac287d886f10d4e82e4c19df71b997b1745..7b907beda6e51166e4b66d88e0d54395763245a7 100644 (file)
@@ -67,17 +67,17 @@ void dump_bss_and_heap (file_data *p_infile, file_data *p_outfile);
 
 /* Cached info about the .data section in the executable.  */
 PIMAGE_SECTION_HEADER data_section;
-PUCHAR data_start = 0;
+PCHAR  data_start = 0;
 DWORD  data_size = 0;
 
 /* Cached info about the .bss section in the executable.  */
 PIMAGE_SECTION_HEADER bss_section;
-PUCHAR bss_start = 0;
+PCHAR  bss_start = 0;
 DWORD  bss_size = 0;
 DWORD  extra_bss_size = 0;
 /* bss data that is static might be discontiguous from non-static.  */
 PIMAGE_SECTION_HEADER bss_section_static;
-PUCHAR bss_start_static = 0;
+PCHAR  bss_start_static = 0;
 DWORD  bss_size_static = 0;
 DWORD  extra_bss_size_static = 0;
 
@@ -99,7 +99,7 @@ _start (void)
 {
   extern void mainCRTStartup (void);
 
-#if 0
+#if 1
   /* Give us a way to debug problems with crashes on startup when
      running under the MSVC profiler. */
   if (GetEnvironmentVariable ("EMACS_DEBUG", NULL, 0) > 0)
@@ -284,7 +284,7 @@ offset_to_section (DWORD offset, IMAGE_NT_HEADERS * nt_header)
 /* Return offset to an object in dst, given offset in src.  We assume
    there is at least one section in both src and dst images, and that
    the some sections may have been added to dst (after sections in src).  */
-static DWORD
+DWORD
 relocate_offset (DWORD offset,
                 IMAGE_NT_HEADERS * src_nt_header,
                 IMAGE_NT_HEADERS * dst_nt_header)
@@ -331,14 +331,14 @@ relocate_offset (DWORD offset,
 #define PTR_TO_RVA(ptr) ((DWORD)(ptr) - (DWORD) GetModuleHandle (NULL))
 
 #define PTR_TO_OFFSET(ptr, pfile_data) \
-          ((char *)(ptr) - (pfile_data)->file_base)
+          ((unsigned char *)(ptr) - (pfile_data)->file_base)
 
 #define OFFSET_TO_PTR(offset, pfile_data) \
           ((pfile_data)->file_base + (DWORD)(offset))
 
 
 /* Flip through the executable and cache the info necessary for dumping.  */
-static void
+void
 get_section_info (file_data *p_infile)
 {
   PIMAGE_DOS_HEADER dos_header;
@@ -380,13 +380,31 @@ get_section_info (file_data *p_infile)
      area for the bss section, so we can make the new image the correct
      size.  */
 
-  data_start = my_begdata;
-  data_size = my_edata - my_begdata;
-  data_section = rva_to_section (PTR_TO_RVA (my_begdata), nt_header);
-  if (data_section != rva_to_section (PTR_TO_RVA (my_edata), nt_header))
+  /* We arrange for the Emacs initialized data to be in a separate
+     section if possible, because we cannot rely on my_begdata and
+     my_edata marking out the full extent of the initialized data, at
+     least on the Alpha where the linker freely reorders variables
+     across libraries.  If we can arrange for this, all we need to do is
+     find the start and size of the EMDATA section.  */
+  data_section = find_section ("EMDATA", nt_header);
+  if (data_section)
     {
-      printf ("Initialized data is not in a single section...bailing\n");
-      exit (1);
+      data_start = (char *) nt_header->OptionalHeader.ImageBase +
+       data_section->VirtualAddress;
+      data_size = data_section->Misc.VirtualSize;
+    }
+  else
+    {
+      /* Fallback on the old method if compiler doesn't support the
+         data_set #pragma (or its equivalent).  */
+      data_start = my_begdata;
+      data_size = my_edata - my_begdata;
+      data_section = rva_to_section (PTR_TO_RVA (my_begdata), nt_header);
+      if (data_section != rva_to_section (PTR_TO_RVA (my_edata), nt_header))
+       {
+         printf ("Initialized data is not in a single section...bailing\n");
+         exit (1);
+       }
     }
 
   /* As noted in lastfile.c, the Alpha (but not the Intel) MSVC linker
@@ -429,7 +447,11 @@ get_section_info (file_data *p_infile)
     - bss_section_static->SizeOfRawData;
 
   /* Combine the bss sections into one if they overlap.  */
+#ifdef _ALPHA_
+  overlap = 1;                 /* force all bss data to be dumped */
+#else
   overlap = 0;
+#endif
   if (bss_start < bss_start_static)
     {
       if (bss_start_static < bss_start + bss_size)
@@ -459,7 +481,7 @@ get_section_info (file_data *p_infile)
 
 /* The dump routines.  */
 
-static void
+void
 copy_executable_and_dump_data (file_data *p_infile, 
                               file_data *p_outfile)
 {
@@ -499,6 +521,14 @@ copy_executable_and_dump_data (file_data *p_infile,
 #define DST_TO_OFFSET()  PTR_TO_OFFSET (dst, p_outfile)
 #define ROUND_UP_DST(align) \
   (dst = p_outfile->file_base + ROUND_UP (DST_TO_OFFSET (), (align)))
+#define ROUND_UP_DST_AND_ZERO(align)                                           \
+  do {                                                                         \
+    unsigned char *newdst = p_outfile->file_base                               \
+      + ROUND_UP (DST_TO_OFFSET (), (align));                                  \
+    /* Zero the alignment slop; it may actually initialize real data.  */      \
+    memset (dst, 0, newdst - dst);                                             \
+    dst = newdst;                                                              \
+  } while (0)
 
   /* Copy the source image sequentially, ie. section by section after
      copying the headers and section table, to simplify the process of
@@ -522,13 +552,16 @@ copy_executable_and_dump_data (file_data *p_infile,
   COPY_CHUNK ("Copying section table...", section,
              nt_header->FileHeader.NumberOfSections * sizeof (*section));
 
+  /* Align the first section's raw data area, and set the header size
+     field accordingly.  */
+  ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
+  dst_nt_header->OptionalHeader.SizeOfHeaders = DST_TO_OFFSET ();
+
   for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
     {
       char msg[100];
       sprintf (msg, "Copying raw data for %s...", section->Name);
 
-      /* Align the section's raw data area.  */
-      ROUND_UP_DST (dst_nt_header->OptionalHeader.FileAlignment);
       dst_save = dst;
 
       /* Update the file-relative offset for this section's raw data (if
@@ -541,6 +574,8 @@ copy_executable_and_dump_data (file_data *p_infile,
       COPY_CHUNK
        (msg, OFFSET_TO_PTR (section->PointerToRawData, p_infile),
         section->SizeOfRawData);
+      /* Ensure alignment slop is zeroed.  */
+      ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
 
       /* Note that various sections below may be aliases.  */
       if (section == data_section)
@@ -582,7 +617,7 @@ copy_executable_and_dump_data (file_data *p_infile,
        }
       if (section == heap_section)
        {
-         DWORD heap_start = get_heap_start ();
+         DWORD heap_start = (DWORD) get_heap_start ();
          DWORD heap_size = get_committed_heap_size ();
 
          /* Dump the used portion of the predump heap, adjusting the
@@ -608,13 +643,13 @@ copy_executable_and_dump_data (file_data *p_infile,
          dst_section->Characteristics |= IMAGE_SCN_CNT_INITIALIZED_DATA;
        }
 
+      /* Align the section's raw data area.  */
+      ROUND_UP_DST (dst_nt_header->OptionalHeader.FileAlignment);
+
       section++;
       dst_section++;
     }
 
-  /* Pad out the final section raw data area.  */
-  ROUND_UP_DST (dst_nt_header->OptionalHeader.FileAlignment);
-
   /* Copy remainder of source image.  */
   do
     section--;
@@ -684,18 +719,28 @@ unexec (char *new_name, char *old_name, void *start_data, void *start_bss,
   file_data in_file, out_file;
   char out_filename[MAX_PATH], in_filename[MAX_PATH];
   unsigned long size;
-  char *ptr;
+  char *p;
+  char *q;
+
+  /* Ignore old_name, and get our actual location from the OS.  */
+  if (!GetModuleFileName (NULL, in_filename, MAX_PATH))
+    abort ();
+  dostounix_filename (in_filename);
+  strcpy (out_filename, in_filename);
+
+  /* Change the base of the output filename to match the requested name.  */
+  if ((p = strrchr (out_filename, '/')) == NULL)
+    abort ();
+  /* The filenames have already been expanded, and will be in Unix
+     format, so it is safe to expect an absolute name.  */
+  if ((q = strrchr (new_name, '/')) == NULL)
+    abort ();
+  strcpy (p, q);
   
-  /* Make sure that the input and output filenames have the
-     ".exe" extension...patch them up if they don't.  */
-  strcpy (in_filename, old_name);
-  ptr = in_filename + strlen (in_filename) - 4;
-  if (strcmp (ptr, ".exe"))
-    strcat (in_filename, ".exe");
-
-  strcpy (out_filename, new_name);
-  ptr = out_filename + strlen (out_filename) - 4;
-  if (strcmp (ptr, ".exe"))
+  /* Make sure that the output filename has the ".exe" extension...patch
+     it up if not.  */
+  p = out_filename + strlen (out_filename) - 4;
+  if (strcmp (p, ".exe"))
     strcat (out_filename, ".exe");
 
   printf ("Dumping from %s\n", in_filename);