Fix /msvclto.

Previously, bitcode files in library paths were passed to the MSVC linker.
This patch strips them.

llvm-svn: 295913
This commit is contained in:
Rui Ueyama 2017-02-23 00:26:42 +00:00
parent a9e16e6597
commit 85d54b050e
4 changed files with 51 additions and 42 deletions

View File

@ -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<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;
}
// 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<StringRef> Path = doFindFile(Arg->getValue()))
if (isBitcodeFile(*Path))
break;
Rsp += quote(Arg->getValue()) + " ";
break;
default:
Rsp += toString(Arg) + " ";
}
}
std::vector<StringRef> ObjectFiles = Symtab.compileBitcodeFiles();
runMSVCLinker(Rsp, ObjectFiles);
}
void LinkerDriver::enqueueTask(std::function<void()> Task) {
TaskQueue.push_back(std::move(Task));
}
@ -820,8 +860,7 @@ void LinkerDriver::link(ArrayRef<const char *> 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<StringRef> ObjectFiles = Symtab.compileBitcodeFiles();
runMSVCLinker(Args, ObjectFiles);
invokeMSVC(Args);
exit(0);
}

View File

@ -107,6 +107,8 @@ private:
StringRef findDefaultEntry();
WindowsSubsystem inferSubsystem();
void invokeMSVC(llvm::opt::InputArgList &Args);
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
void addBuffer(std::unique_ptr<MemoryBuffer> MB);
void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
@ -178,7 +180,7 @@ void checkFailIfMismatch(StringRef Arg);
std::unique_ptr<MemoryBuffer>
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs);
void runMSVCLinker(llvm::opt::InputArgList &Args, ArrayRef<StringRef> Objects);
void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
// Create enum with OPT_xxx values for each option in Options.td
enum {

View File

@ -626,48 +626,15 @@ convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
return File.getMemoryBuffer();
}
static bool isBitcodeFile(StringRef Path) {
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;
}
// 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<StringRef> Objects) {
void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
// Write the in-memory object files to disk.
std::vector<TemporaryFile> 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);

View File

@ -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