From 2d02166b430737a7ca910bfe72946b4119673da2 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 15 Nov 2016 00:54:54 +0000 Subject: [PATCH] Add a file magic for CL.exe's object file created with /GL. This patch makes it possible to identify object files created by CL.exe with /GL option. Such file contains Microsoft proprietary intermediate code instead of target machine code to do LTO. I need this to print out user-friendly error message from LLD. Differential Revision: https://reviews.llvm.org/D26645 llvm-svn: 286919 --- llvm/include/llvm/Support/COFF.h | 5 +++++ llvm/include/llvm/Support/FileSystem.h | 1 + llvm/lib/Object/ObjectFile.cpp | 1 + llvm/lib/Support/Path.cpp | 18 +++++++----------- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/llvm/include/llvm/Support/COFF.h b/llvm/include/llvm/Support/COFF.h index 1ca781b9..1922330 100644 --- a/llvm/include/llvm/Support/COFF.h +++ b/llvm/include/llvm/Support/COFF.h @@ -41,6 +41,11 @@ namespace COFF { '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8', }; + static const char ClGlObjMagic[] = { + '\x38', '\xfe', '\xb3', '\x0c', '\xa5', '\xd9', '\xab', '\x4d', + '\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2', + }; + // Sizes in bytes of various things in the COFF format. enum { Header16Size = 20, diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h index 04838e0..8503aa3 100644 --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/include/llvm/Support/FileSystem.h @@ -258,6 +258,7 @@ struct file_magic { macho_dsym_companion, ///< Mach-O dSYM companion file macho_kext_bundle, ///< Mach-O kext bundle file macho_universal_binary, ///< Mach-O universal binary + coff_cl_gl_object, ///< Microsoft cl.exe's intermediate code file coff_object, ///< COFF object file coff_import_library, ///< COFF import library pecoff_executable, ///< PECOFF executable file diff --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp index bd50773..996463d 100644 --- a/llvm/lib/Object/ObjectFile.cpp +++ b/llvm/lib/Object/ObjectFile.cpp @@ -78,6 +78,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) { switch (Type) { case sys::fs::file_magic::unknown: case sys::fs::file_magic::bitcode: + case sys::fs::file_magic::coff_cl_gl_object: case sys::fs::file_magic::archive: case sys::fs::file_magic::macho_universal_binary: case sys::fs::file_magic::windows_resource: diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp index b2d6457..49279d0 100644 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -986,22 +986,18 @@ file_magic identify_magic(StringRef Magic) { return file_magic::unknown; switch ((unsigned char)Magic[0]) { case 0x00: { - // COFF bigobj or short import library file - if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff && - Magic[3] == (char)0xff) { + // COFF bigobj, CL.exe's LTO object file, or short import library file + if (memcmp(Magic.data() + 1, "\0\xFF\xFF", 3) == 0) { size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic); if (Magic.size() < MinSize) return file_magic::coff_import_library; - int BigObjVersion = read16le( - Magic.data() + offsetof(COFF::BigObjHeader, Version)); - if (BigObjVersion < COFF::BigObjHeader::MinBigObjectVersion) - return file_magic::coff_import_library; - const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID); - if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) != 0) - return file_magic::coff_import_library; - return file_magic::coff_object; + if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) == 0) + return file_magic::coff_object; + if (memcmp(Start, COFF::ClGlObjMagic, sizeof(COFF::BigObjMagic)) == 0) + return file_magic::coff_cl_gl_object; + return file_magic::coff_import_library; } // Windows resource file const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' }; -- 2.7.4