Fix check whether PE file is a debug build for MinGW
authorKai Koehne <kai.koehne@digia.com>
Thu, 3 Apr 2014 13:55:16 +0000 (15:55 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 9 Apr 2014 19:58:00 +0000 (21:58 +0200)
Use code inspired by objdump / pfd library to decide
whether a MinGW PE file is a debug build, or not.

Task-number: QTBUG-38160
Change-Id: If6b6136238eb7962a948ea7168fb3a8f8f87e323
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
src/windeployqt/utils.cpp
src/windeployqt/utils.h

index f40c0d8..358601c 100644 (file)
@@ -131,7 +131,8 @@ QStringList findSharedLibraries(const QDir &directory, Platform platform, bool d
         bool matches = true;
         if (platform & WindowsBased) {
             bool debugDll;
-            if (readPeExecutable(dllPath, &errorMessage, 0, 0, &debugDll)) {
+            if (readPeExecutable(dllPath, &errorMessage, 0, 0, &debugDll,
+                                 (platform == WindowsMinGW))) {
                 matches = debugDll == debug;
             } else {
                 std::wcerr << "Warning: Unable to read " << QDir::toNativeSeparators(dllPath)
@@ -729,10 +730,10 @@ inline QStringList readImportSections(const ImageNtHeader *ntHeaders, const void
 }
 
 // Read a PE executable and determine dependent libraries, word size
-// and debug flags. Note that the debug flag cannot be relied on for MinGW.
+// and debug flags.
 bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage,
                       QStringList *dependentLibrariesIn, unsigned *wordSizeIn,
-                      bool *isDebugIn)
+                      bool *isDebugIn, bool isMinGW)
 {
     bool result = false;
     HANDLE hFile = NULL;
@@ -777,14 +778,29 @@ bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage
         bool debug = false;
         if (wordSize == 32) {
             const IMAGE_NT_HEADERS32 *ntHeaders32 = reinterpret_cast<const IMAGE_NT_HEADERS32 *>(ntHeaders);
-            debug = ntHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+
+            if (!isMinGW) {
+                debug = ntHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+            } else {
+                // Use logic that's used e.g. in objdump / pfd library
+                debug = !(ntHeaders32->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
+            }
+
             if (dependentLibrariesIn)
                 *dependentLibrariesIn = readImportSections(ntHeaders32, fileMemory, errorMessage);
+
         } else {
             const IMAGE_NT_HEADERS64 *ntHeaders64 = reinterpret_cast<const IMAGE_NT_HEADERS64 *>(ntHeaders);
             debug = ntHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
             if (dependentLibrariesIn)
                 *dependentLibrariesIn = readImportSections(ntHeaders64, fileMemory, errorMessage);
+
+            if (!isMinGW) {
+                debug = !(ntHeaders64->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
+            } else {
+                // Use logic that's used e.g. in objdump / pfd library
+                debug = !(ntHeaders64->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
+            }
         }
 
         if (isDebugIn)
index ff86ca5..a690361 100644 (file)
@@ -169,7 +169,7 @@ bool runProcess(const QString &binary, const QStringList &args,
 
 bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage,
                       QStringList *dependentLibraries = 0, unsigned *wordSize = 0,
-                      bool *isDebug = 0);
+                      bool *isDebug = 0, bool isMinGW = false);
 bool readElfExecutable(const QString &elfExecutableFileName, QString *errorMessage,
                       QStringList *dependentLibraries = 0, unsigned *wordSize = 0,
                       bool *isDebug = 0);
@@ -180,7 +180,8 @@ inline bool readExecutable(const QString &executableFileName, Platform platform,
 {
     return platform == Unix ?
         readElfExecutable(executableFileName, errorMessage, dependentLibraries, wordSize, isDebug) :
-        readPeExecutable(executableFileName, errorMessage, dependentLibraries, wordSize, isDebug);
+        readPeExecutable(executableFileName, errorMessage, dependentLibraries, wordSize, isDebug,
+                         (platform == WindowsMinGW));
 }
 
 // Return dependent modules of executable files.