bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug in Win32 version of emacs on x64 machines


From: Eric Youngdale
Subject: Bug in Win32 version of emacs on x64 machines
Date: Tue, 17 Jul 2007 14:29:18 -0400

If you are running the 32-bit version of emacs on a 64-bit machine with
a 64-bit version of windows, and the SHELL environment variable points
to a 64-bit executable, then M-x shell will cause emacs to crash.

The reason for this is that in w32proc.c, it starts checking the
executable to be loaded to see if it is a cygwin executable, but it
doesn't bother to check to see if it is a 64-bit executable or a 32-bit
executable and it assumes that the it can dereference structures as if
it were a 32-bit executable.  This causes emacs to crash.   The
quick-and-dirty fix is enclosed - basically restrict the test and see if
the executable type is x86 before doing the cygwin check.

This fix does work with VC6 - don't know about anything older, nor do I
know if anyone cares in this age.

Anyways, this fix seems to fix the problem I described above.  I am also
playing with an x64 port of emacs - I just got it running - need to test
and resolve a few other potential problems before I worry about
submitting diffs....

*** w32proc.c.~1~ Sat Jan 20 23:18:15 2007
--- w32proc.c Tue Jul 17 13:46:42 2007
***************
*** 63,68 ****
--- 63,72 ----
  #include "syssignal.h"
  #include "w32term.h"
  
+ #ifndef IMAGE_FILE_MACHINE_AMD64
+ #define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
+ #endif
+ 
  #define RVA_TO_PTR(var,section,filedata) \
    ((void *)((section)->PointerToRawData
\
            + ((DWORD)(var) - (section)->VirtualAddress)
\
***************
*** 630,636 ****
         executables use the OS/2 1.x format. */
  
        IMAGE_DOS_HEADER * dos_header;
!       IMAGE_NT_HEADERS * nt_header;
  
        dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
        if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
--- 634,641 ----
         executables use the OS/2 1.x format. */
  
        IMAGE_DOS_HEADER * dos_header;
!       IMAGE_NT_HEADERS32 * nt_header;
!       IMAGE_NT_HEADERS64 * nt_header64;
  
        dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
        if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
***************
*** 637,642 ****
--- 642,648 ----
        goto unwind;
  
        nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header +
dos_header->e_lfanew);
+       nt_header64 = (PIMAGE_NT_HEADERS64) ((char *) dos_header +
dos_header->e_lfanew);
  
        if ((char *) nt_header > (char *) dos_header + executable.size)
        {
***************
*** 650,678 ****
        }
        else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
        {
!         /* Look for cygwin.dll in DLL import list. */
!         IMAGE_DATA_DIRECTORY import_dir =
!
nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
!         IMAGE_IMPORT_DESCRIPTOR * imports;
!         IMAGE_SECTION_HEADER * section;
! 
!         section = rva_to_section (import_dir.VirtualAddress,
nt_header);
!         imports = RVA_TO_PTR (import_dir.VirtualAddress, section,
executable);
! 
!         for ( ; imports->Name; imports++)
!           {
!             char * dllname = RVA_TO_PTR (imports->Name, section,
executable);
! 
!             /* The exact name of the cygwin dll has changed with
!                various releases, but hopefully this will be reasonably
!                future proof.  */
!             if (strncmp (dllname, "cygwin", 6) == 0)
                {
!                 *is_cygnus_app = TRUE;
!                 break;
                }
!           }
! 
          /* Check whether app is marked as a console or windowed (aka
               GUI) app.  Accept Posix and OS2 subsytem apps as console
               apps.  */
--- 656,694 ----
        }
        else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
        {
!         /* cygwin is 32-bit only right now.  The code to check a
64-bit binary
!          is slightly different. */
!         if( nt_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 )
!           {
!             /* Look for cygwin.dll in DLL import list. */
!             IMAGE_DATA_DIRECTORY import_dir =
!
nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
!             IMAGE_IMPORT_DESCRIPTOR * imports;
!             IMAGE_SECTION_HEADER * section;
!             
!             section = rva_to_section (import_dir.VirtualAddress,
nt_header);
!             imports = RVA_TO_PTR (import_dir.VirtualAddress, section,
executable);
!             
!             for ( ; imports->Name; imports++)
                {
!                 char * dllname = RVA_TO_PTR (imports->Name, section,
executable);
!                 
!                 /* The exact name of the cygwin dll has changed with
!                    various releases, but hopefully this will be
reasonably
!                    future proof.  */
!                 if (strncmp (dllname, "cygwin", 6) == 0)
!                   {
!                     *is_cygnus_app = TRUE;
!                     break;
!                   }
                }
!           }
!         else if( nt_header64->FileHeader.Machine ==
IMAGE_FILE_MACHINE_AMD64 )
!           {
!             /* Ultimately if 64-bit cygwin ever becomes a reality, a
different
!                set of checks need to be added here. For now, the stub
is present
!                to allow for that possibility. */
!           }
          /* Check whether app is marked as a console or windowed (aka
               GUI) app.  Accept Posix and OS2 subsytem apps as console
               apps.  */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]