[lld] r297191 - Do not pass archive files containing bitcode files to the MSVC Linker.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 7 11:45:53 PST 2017


Author: ruiu
Date: Tue Mar  7 13:45:53 2017
New Revision: 297191

URL: http://llvm.org/viewvc/llvm-project?rev=297191&view=rev
Log:
Do not pass archive files containing bitcode files to the MSVC Linker.

If /msvclto is specified, we compile bitcode files and pass it to the
MSVC linker, stripping all bitcode files. We haven't stripped archive
files, because I was thinking that the MSVC linker wouldn't touch files
in archive files. When we pass an object file to link.exe, all symbols
have been resolved already, so link.exe shoulnd't need any of the files
in archives.

It turns out that even though link.exe doesn't need to do that, it
seems to try to read each file in all archives. And if there's a non-
COFF file in an archive, it exists with an error message. So we need
to remove archives from the command line too.

Added:
    lld/trunk/test/COFF/msvclto-archive.ll
Modified:
    lld/trunk/COFF/Driver.cpp

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=297191&r1=297190&r2=297191&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Tue Mar  7 13:45:53 2017
@@ -417,11 +417,34 @@ static std::string getMapFile(const opt:
   return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
 }
 
+// Returns true if a given file is a LLVM bitcode file. If it is a
+// static library, this function look at the first file in the archive
+// to determine if it's a bitcode file.
 static bool isBitcodeFile(StringRef Path) {
+  using namespace sys::fs;
+
   std::unique_ptr<MemoryBuffer> MB = check(
       MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
-  StringRef Buf = MB->getBuffer();
-  return sys::fs::identify_magic(Buf) == sys::fs::file_magic::bitcode;
+  file_magic Magic = identify_magic(MB->getBuffer());
+
+  if (Magic == file_magic::bitcode)
+    return true;
+
+  if (Magic == file_magic::archive) {
+    std::unique_ptr<Archive> File =
+        check(Archive::create(MB->getMemBufferRef()));
+    Error Err = Error::success();
+    for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
+      if (Err)
+        return true;
+      Archive::Child C = check(COrErr);
+      MemoryBufferRef MBRef = check(C.getMemoryBufferRef());
+      return identify_magic(MBRef.getBuffer()) == file_magic::bitcode;
+    }
+    return true;
+  }
+
+  return false;
 }
 
 // Create response file contents and invoke the MSVC linker.

Added: lld/trunk/test/COFF/msvclto-archive.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/msvclto-archive.ll?rev=297191&view=auto
==============================================================================
--- lld/trunk/test/COFF/msvclto-archive.ll (added)
+++ lld/trunk/test/COFF/msvclto-archive.ll Tue Mar  7 13:45:53 2017
@@ -0,0 +1,21 @@
+;; Make sure we do not pass archive files containing bitcode files.
+
+; RUN: llvm-as -o %t.obj %s
+; RUN: llvm-ar cru %t-main.a %t.obj
+; RUN: mkdir -p %t.dir
+; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s
+; RUN: lld-link %t-main.a %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
+; RUN:   /entry:main /verbose > %t.log || true
+; RUN: FileCheck %s < %t.log
+
+; CHECK-NOT: link.exe {{.*}}t-main.a
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+declare void @foo()
+
+define i32 @main() {
+  call void @foo()
+  ret i32 0
+}




More information about the llvm-commits mailing list