diff options
| author | Rui Ueyama <ruiu@google.com> | 2017-03-07 19:45:53 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2017-03-07 19:45:53 +0000 |
| commit | e0341db179d7ee24405afb6ba500a0cead5c3860 (patch) | |
| tree | 0c0cdbc8556d6ba421fe335a89fde040f9024ab9 | |
| parent | 285208812698ca19e99267b9659af3e8bc5fd682 (diff) | |
| download | llvm-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.cpp | 27 | ||||
| -rw-r--r-- | lld/test/COFF/msvclto-archive.ll | 21 |
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 +} |
