COFF: Read linker directives from bitcode files.
authorPeter Collingbourne <peter@pcc.me.uk>
Sat, 6 Jun 2015 02:00:45 +0000 (02:00 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Sat, 6 Jun 2015 02:00:45 +0000 (02:00 +0000)
Differential Revision: http://reviews.llvm.org/D10285

llvm-svn: 239212

lld/COFF/InputFiles.cpp
lld/COFF/InputFiles.h
lld/COFF/SymbolTable.cpp
lld/COFF/SymbolTable.h
lld/test/COFF/lto-linker-opts.ll [new file with mode: 0644]

index ec8e9f5..62bb144 100644 (file)
@@ -263,6 +263,23 @@ std::error_code BitcodeFile::parse() {
       SymbolBodies.push_back(new (Alloc) DefinedBitcode(SymName));
     }
   }
+
+  // Extract any linker directives from the bitcode file, which are represented
+  // as module flags with the key "Linker Options".
+  llvm::SmallVector<llvm::Module::ModuleFlagEntry, 8> Flags;
+  M->getModule().getModuleFlagsMetadata(Flags);
+  for (auto &&Flag : Flags) {
+    if (Flag.Key->getString() != "Linker Options")
+      continue;
+
+    for (llvm::Metadata *Op : cast<llvm::MDNode>(Flag.Val)->operands()) {
+      for (llvm::Metadata *InnerOp : cast<llvm::MDNode>(Op)->operands()) {
+        Directives += " ";
+        Directives += cast<llvm::MDString>(InnerOp)->getString();
+      }
+    }
+  }
+
   return std::error_code();
 }
 
index 9d7b0ef..e4c75d4 100644 (file)
@@ -170,6 +170,9 @@ public:
   LTOModule *getModule() const { return M.get(); }
   LTOModule *releaseModule() { return M.release(); }
 
+  // Returns linker directives from module flags metadata if present.
+  StringRef getDirectives() { return Directives; }
+
 private:
   std::error_code parse() override;
 
@@ -177,6 +180,7 @@ private:
   std::vector<SymbolBody *> SymbolBodies;
   llvm::BumpPtrAllocator Alloc;
   std::unique_ptr<LTOModule> M;
+  std::string Directives;
 };
 
 } // namespace coff
index 35042e5..a90e208 100644 (file)
@@ -40,6 +40,17 @@ std::error_code SymbolTable::addFile(std::unique_ptr<InputFile> File) {
   return addImport(cast<ImportFile>(FileP));
 }
 
+std::error_code SymbolTable::addDirectives(StringRef Dir) {
+  if (Dir.empty())
+    return std::error_code();
+  std::vector<std::unique_ptr<InputFile>> Libs;
+  if (auto EC = Driver->parseDirectives(Dir, &Libs))
+    return EC;
+  for (std::unique_ptr<InputFile> &Lib : Libs)
+    addFile(std::move(Lib));
+  return std::error_code();
+}
+
 std::error_code SymbolTable::addObject(ObjectFile *File) {
   ObjectFiles.emplace_back(File);
   for (SymbolBody *Body : File->getSymbols())
@@ -49,15 +60,7 @@ std::error_code SymbolTable::addObject(ObjectFile *File) {
 
   // If an object file contains .drectve section, read it and add
   // files listed in the section.
-  StringRef Dir = File->getDirectives();
-  if (!Dir.empty()) {
-    std::vector<std::unique_ptr<InputFile>> Libs;
-    if (auto EC = Driver->parseDirectives(Dir, &Libs))
-      return EC;
-    for (std::unique_ptr<InputFile> &Lib : Libs)
-      addFile(std::move(Lib));
-  }
-  return std::error_code();
+  return addDirectives(File->getDirectives());
 }
 
 std::error_code SymbolTable::addArchive(ArchiveFile *File) {
@@ -75,8 +78,8 @@ std::error_code SymbolTable::addBitcode(BitcodeFile *File) {
       if (auto EC = resolve(Body))
         return EC;
 
-  // TODO: Handle linker directives.
-  return std::error_code();
+  // Add any linker directives from the module flags metadata.
+  return addDirectives(File->getDirectives());
 }
 
 std::error_code SymbolTable::addImport(ImportFile *File) {
index 0c5e795..99a794d 100644 (file)
@@ -77,6 +77,8 @@ public:
   std::error_code rename(StringRef From, StringRef To);
 
 private:
+  std::error_code addDirectives(StringRef Dir);
+
   std::error_code addObject(ObjectFile *File);
   std::error_code addArchive(ArchiveFile *File);
   std::error_code addImport(ImportFile *File);
diff --git a/lld/test/COFF/lto-linker-opts.ll b/lld/test/COFF/lto-linker-opts.ll
new file mode 100644 (file)
index 0000000..baa9085
--- /dev/null
@@ -0,0 +1,11 @@
+; RUN: llvm-as -o %T/lto-linker-opts.obj %s
+; RUN: env LIB=%S/Inputs lld -flavor link2 /out:%T/lto-linker-opts.exe /entry:main /subsystem:console %T/lto-linker-opts.obj
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 6, !"Linker Options", !1}
+!1 = !{!2}
+!2 = !{!"/DEFAULTLIB:ret42.lib"}