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:
		
							parent
							
								
									a9e16e6597
								
							
						
					
					
						commit
						85d54b050e
					
				| 
						 | 
					@ -422,6 +422,46 @@ static std::string getMapFile(const opt::InputArgList &Args) {
 | 
				
			||||||
  return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
 | 
					  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) {
 | 
					void LinkerDriver::enqueueTask(std::function<void()> Task) {
 | 
				
			||||||
  TaskQueue.push_back(std::move(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.
 | 
					  // 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.
 | 
					  // This is useful because MSVC link.exe can generate complete PDBs.
 | 
				
			||||||
  if (Args.hasArg(OPT_msvclto)) {
 | 
					  if (Args.hasArg(OPT_msvclto)) {
 | 
				
			||||||
    std::vector<StringRef> ObjectFiles = Symtab.compileBitcodeFiles();
 | 
					    invokeMSVC(Args);
 | 
				
			||||||
    runMSVCLinker(Args, ObjectFiles);
 | 
					 | 
				
			||||||
    exit(0);
 | 
					    exit(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,8 @@ private:
 | 
				
			||||||
  StringRef findDefaultEntry();
 | 
					  StringRef findDefaultEntry();
 | 
				
			||||||
  WindowsSubsystem inferSubsystem();
 | 
					  WindowsSubsystem inferSubsystem();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void invokeMSVC(llvm::opt::InputArgList &Args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
 | 
					  MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
 | 
				
			||||||
  void addBuffer(std::unique_ptr<MemoryBuffer> MB);
 | 
					  void addBuffer(std::unique_ptr<MemoryBuffer> MB);
 | 
				
			||||||
  void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
 | 
					  void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
 | 
				
			||||||
| 
						 | 
					@ -178,7 +180,7 @@ void checkFailIfMismatch(StringRef Arg);
 | 
				
			||||||
std::unique_ptr<MemoryBuffer>
 | 
					std::unique_ptr<MemoryBuffer>
 | 
				
			||||||
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs);
 | 
					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
 | 
					// Create enum with OPT_xxx values for each option in Options.td
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -626,48 +626,15 @@ convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
 | 
				
			||||||
  return File.getMemoryBuffer();
 | 
					  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.
 | 
					// Run MSVC link.exe for given in-memory object files.
 | 
				
			||||||
// Command line options are copied from those given to LLD.
 | 
					// Command line options are copied from those given to LLD.
 | 
				
			||||||
// This is for the /msvclto option.
 | 
					// 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.
 | 
					  // Write the in-memory object files to disk.
 | 
				
			||||||
  std::vector<TemporaryFile> Temps;
 | 
					  std::vector<TemporaryFile> Temps;
 | 
				
			||||||
  for (StringRef S : Objects)
 | 
					  for (StringRef S : Objects) {
 | 
				
			||||||
    Temps.emplace_back("lto", "obj", S);
 | 
					    Temps.emplace_back("lto", "obj", S);
 | 
				
			||||||
 | 
					    Rsp += quote(Temps.back().Path) + " ";
 | 
				
			||||||
  // 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) + " ";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  log("link.exe " + Rsp);
 | 
					  log("link.exe " + Rsp);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
; RUN: llvm-as -o %t1.obj %s
 | 
					; RUN: llvm-as -o %t.obj %s
 | 
				
			||||||
; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t2.obj %p/Inputs/msvclto.s
 | 
					; RUN: mkdir -p %t.dir
 | 
				
			||||||
; RUN: lld-link %t1.obj %t2.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
 | 
					; 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:   /entry:main /verbose > %t.log || true
 | 
				
			||||||
; RUN: FileCheck %s < %t.log
 | 
					; RUN: FileCheck %s < %t.log
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue