ntdll: Improve the error reporting for invalid PE file architectures.
authorAlexandre Julliard <julliard@winehq.org>
Sat, 19 Feb 2011 13:10:58 +0000 (14:10 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Sat, 19 Feb 2011 13:11:05 +0000 (14:11 +0100)
dlls/ntdll/virtual.c

index c22455de4855a5eeab3e3bb9acacc4d574c8cb17..0913b714bed3e2f766c7e4f056335224316d52c3 100644 (file)
@@ -1029,6 +1029,60 @@ static NTSTATUS allocate_dos_memory( struct file_view **view, unsigned int vprot
 }
 
 
+/***********************************************************************
+ *           check_architecture
+ *
+ * Check the architecture of a PE binary.
+ */
+static NTSTATUS check_architecture( const IMAGE_NT_HEADERS *nt )
+{
+    static const char *arch;
+
+#ifdef __i386__
+    if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) return STATUS_SUCCESS;
+    if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
+    {
+        if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)  /* don't warn for a 64-bit exe */
+            WARN( "loading amd64 dll in 32-bit mode will fail\n" );
+        return STATUS_INVALID_IMAGE_FORMAT;
+    }
+#elif defined(__x86_64__)
+    if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) return STATUS_SUCCESS;
+    if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
+    {
+        if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)  /* don't warn for a 32-bit exe */
+            WARN( "loading 32-bit dll in 64-bit mode will fail\n" );
+        return STATUS_INVALID_IMAGE_FORMAT;
+    }
+#elif defined(__ARMEL__)
+    if (nt->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM ||
+        nt->FileHeader.Machine == IMAGE_FILE_MACHINE_THUMB)
+        return STATUS_SUCCESS;
+#endif
+
+    switch (nt->FileHeader.Machine)
+    {
+        case IMAGE_FILE_MACHINE_UNKNOWN: arch = "Unknown"; break;
+        case IMAGE_FILE_MACHINE_I860:    arch = "I860"; break;
+        case IMAGE_FILE_MACHINE_I386:    arch = "I386"; break;
+        case IMAGE_FILE_MACHINE_R3000:   arch = "R3000"; break;
+        case IMAGE_FILE_MACHINE_R4000:   arch = "R4000"; break;
+        case IMAGE_FILE_MACHINE_R10000:  arch = "R10000"; break;
+        case IMAGE_FILE_MACHINE_ALPHA:   arch = "Alpha"; break;
+        case IMAGE_FILE_MACHINE_POWERPC: arch = "PowerPC"; break;
+        case IMAGE_FILE_MACHINE_IA64:    arch = "IA-64"; break;
+        case IMAGE_FILE_MACHINE_ALPHA64: arch = "Alpha-64"; break;
+        case IMAGE_FILE_MACHINE_AMD64:   arch = "AMD-64"; break;
+        case IMAGE_FILE_MACHINE_ARM:     arch = "ARM"; break;
+        case IMAGE_FILE_MACHINE_THUMB:   arch = "ARM Thumb"; break;
+        case IMAGE_FILE_MACHINE_SPARC:   arch = "SPARC"; break;
+        default: arch = wine_dbg_sprintf( "Unknown-%04x", nt->FileHeader.Machine ); break;
+    }
+    ERR( "Trying to load PE image for unsupported architecture %s\n", arch );
+    return STATUS_INVALID_IMAGE_FORMAT;
+}
+
+
 /***********************************************************************
  *           stat_mapping_file
  *
@@ -1110,39 +1164,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
     imports = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_IMPORT;
     if (!imports->Size || !imports->VirtualAddress) imports = NULL;
 
-    /* check the architecture */
-
-#ifdef __x86_64__
-    if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
-#elif defined(__ARMEL__)
-    if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_ARM &&
-        nt->FileHeader.Machine != IMAGE_FILE_MACHINE_THUMB)
-#else
-    if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
-#endif
-    {
-        MESSAGE("Trying to load PE image for unsupported architecture (");
-        switch (nt->FileHeader.Machine)
-        {
-        case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break;
-        case IMAGE_FILE_MACHINE_I860:    MESSAGE("I860"); break;
-        case IMAGE_FILE_MACHINE_I386:    MESSAGE("I386"); break;
-        case IMAGE_FILE_MACHINE_R3000:   MESSAGE("R3000"); break;
-        case IMAGE_FILE_MACHINE_R4000:   MESSAGE("R4000"); break;
-        case IMAGE_FILE_MACHINE_R10000:  MESSAGE("R10000"); break;
-        case IMAGE_FILE_MACHINE_ALPHA:   MESSAGE("Alpha"); break;
-        case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break;
-        case IMAGE_FILE_MACHINE_IA64:    MESSAGE("IA-64"); break;
-        case IMAGE_FILE_MACHINE_ALPHA64: MESSAGE("Alpha-64"); break;
-        case IMAGE_FILE_MACHINE_AMD64:   MESSAGE("AMD-64"); break;
-        case IMAGE_FILE_MACHINE_ARM:     MESSAGE("ARM"); break;
-        case IMAGE_FILE_MACHINE_THUMB:   MESSAGE("ARM Thumb"); break;
-        case IMAGE_FILE_MACHINE_SPARC:   MESSAGE("SPARC"); break;
-        default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break;
-        }
-        MESSAGE(")\n");
-        goto error;
-    }
+    if (check_architecture( nt )) goto error;
 
     /* check for non page-aligned binary */