From 85d54b050e84819e01a996c9a9754d496e321d4e Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 23 Feb 2017 00:26:42 +0000 Subject: [PATCH] Fix /msvclto. Previously, bitcode files in library paths were passed to the MSVC linker. This patch strips them. llvm-svn: 295913 --- lld/COFF/Driver.cpp | 43 ++++++++++++++++++++++++++++++++++++++-- lld/COFF/Driver.h | 4 +++- lld/COFF/DriverUtils.cpp | 39 +++--------------------------------- lld/test/COFF/msvclto.ll | 7 ++++--- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index cdfefde52df6..07b5f8bea06d 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -422,6 +422,46 @@ static std::string getMapFile(const opt::InputArgList &Args) { return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str(); } +static bool isBitcodeFile(StringRef Path) { + std::unique_ptr 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; +} + +// Create response file contents and invoke the MSVC linker. +void LinkerDriver::invokeMSVC(opt::InputArgList &Args) { + std::string Rsp = "/nologo "; + + for (auto *Arg : Args) { + switch (Arg->getOption().getID()) { + case OPT_linkrepro: + case OPT_lldmap: + case OPT_lldmap_file: + case OPT_msvclto: + // LLD-specific options are stripped. + break; + case OPT_opt: + if (!StringRef(Arg->getValue()).startswith("lld")) + Rsp += toString(Arg) + " "; + break; + case OPT_INPUT: + // Bitcode files are stripped as they've been compiled to + // native object files. + if (Optional Path = doFindFile(Arg->getValue())) + if (isBitcodeFile(*Path)) + break; + Rsp += quote(Arg->getValue()) + " "; + break; + default: + Rsp += toString(Arg) + " "; + } + } + + std::vector ObjectFiles = Symtab.compileBitcodeFiles(); + runMSVCLinker(Rsp, ObjectFiles); +} + void LinkerDriver::enqueueTask(std::function Task) { TaskQueue.push_back(std::move(Task)); } @@ -820,8 +860,7 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // If /msvclto is given, we use the MSVC linker to link LTO output files. // This is useful because MSVC link.exe can generate complete PDBs. if (Args.hasArg(OPT_msvclto)) { - std::vector ObjectFiles = Symtab.compileBitcodeFiles(); - runMSVCLinker(Args, ObjectFiles); + invokeMSVC(Args); exit(0); } diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h index 075c69b71365..4566f73eef31 100644 --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -107,6 +107,8 @@ private: StringRef findDefaultEntry(); WindowsSubsystem inferSubsystem(); + void invokeMSVC(llvm::opt::InputArgList &Args); + MemoryBufferRef takeBuffer(std::unique_ptr MB); void addBuffer(std::unique_ptr MB); void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName, @@ -178,7 +180,7 @@ void checkFailIfMismatch(StringRef Arg); std::unique_ptr convertResToCOFF(const std::vector &MBs); -void runMSVCLinker(llvm::opt::InputArgList &Args, ArrayRef Objects); +void runMSVCLinker(std::string Rsp, ArrayRef Objects); // Create enum with OPT_xxx values for each option in Options.td enum { diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp index d08616ed5cb0..a9c1c9d5593e 100644 --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -626,48 +626,15 @@ convertResToCOFF(const std::vector &MBs) { return File.getMemoryBuffer(); } -static bool isBitcodeFile(StringRef Path) { - std::unique_ptr 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; -} - // Run MSVC link.exe for given in-memory object files. // Command line options are copied from those given to LLD. // This is for the /msvclto option. -void runMSVCLinker(opt::InputArgList &Args, ArrayRef Objects) { +void runMSVCLinker(std::string Rsp, ArrayRef Objects) { // Write the in-memory object files to disk. std::vector Temps; - for (StringRef S : Objects) + for (StringRef S : Objects) { Temps.emplace_back("lto", "obj", S); - - // Create a response file. - std::string Rsp = "/nologo "; - for (TemporaryFile &T : Temps) - Rsp += quote(T.Path) + " "; - - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { - case OPT_linkrepro: - case OPT_lldmap: - case OPT_lldmap_file: - case OPT_msvclto: - // LLD-specific options are stripped. - break; - case OPT_opt: - if (!StringRef(Arg->getValue()).startswith("lld")) - Rsp += toString(Arg) + " "; - break; - case OPT_INPUT: - // Bitcode files are stripped as they've been compiled to - // native object files. - if (!isBitcodeFile(Arg->getValue())) - Rsp += quote(Arg->getValue()) + " "; - break; - default: - Rsp += toString(Arg) + " "; - } + Rsp += quote(Temps.back().Path) + " "; } log("link.exe " + Rsp); diff --git a/lld/test/COFF/msvclto.ll b/lld/test/COFF/msvclto.ll index 2d51ceaffd48..e8a6b5c49ce9 100644 --- a/lld/test/COFF/msvclto.ll +++ b/lld/test/COFF/msvclto.ll @@ -1,6 +1,7 @@ -; RUN: llvm-as -o %t1.obj %s -; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t2.obj %p/Inputs/msvclto.s -; RUN: lld-link %t1.obj %t2.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ +; RUN: llvm-as -o %t.obj %s +; 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.obj %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