aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-03-07 19:45:53 +0000
committerRui Ueyama <ruiu@google.com>2017-03-07 19:45:53 +0000
commite0341db179d7ee24405afb6ba500a0cead5c3860 (patch)
tree0c0cdbc8556d6ba421fe335a89fde040f9024ab9
parent285208812698ca19e99267b9659af3e8bc5fd682 (diff)
downloadllvm-e0341db179d7ee24405afb6ba500a0cead5c3860.zip
llvm-e0341db179d7ee24405afb6ba500a0cead5c3860.tar.gz
llvm-e0341db179d7ee24405afb6ba500a0cead5c3860.tar.bz2
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. llvm-svn: 297191
-rw-r--r--lld/COFF/Driver.cpp27
-rw-r--r--lld/test/COFF/msvclto-archive.ll21
2 files changed, 46 insertions, 2 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 369a329..0d14ca4 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -417,11 +417,34 @@ static std::string getMapFile(const opt::InputArgList &Args) {
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.
diff --git a/lld/test/COFF/msvclto-archive.ll b/lld/test/COFF/msvclto-archive.ll
new file mode 100644
index 0000000..b525fad
--- /dev/null
+++ b/lld/test/COFF/msvclto-archive.ll
@@ -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
+}