Index: COFF/InputFiles.h =================================================================== --- COFF/InputFiles.h +++ COFF/InputFiles.h @@ -170,6 +170,9 @@ 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 @@ std::vector SymbolBodies; llvm::BumpPtrAllocator Alloc; std::unique_ptr M; + std::string Directives; }; } // namespace coff Index: COFF/InputFiles.cpp =================================================================== --- COFF/InputFiles.cpp +++ COFF/InputFiles.cpp @@ -263,6 +263,23 @@ 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 Flags; + M->getModule().getModuleFlagsMetadata(Flags); + for (auto &&Flag : Flags) { + if (Flag.Key->getString() != "Linker Options") + continue; + + for (llvm::Metadata *Op : cast(Flag.Val)->operands()) { + for (llvm::Metadata *InnerOp : cast(Op)->operands()) { + Directives += " "; + Directives += cast(InnerOp)->getString(); + } + } + } + return std::error_code(); } Index: COFF/SymbolTable.h =================================================================== --- COFF/SymbolTable.h +++ COFF/SymbolTable.h @@ -77,6 +77,8 @@ 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); Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -40,6 +40,17 @@ return addImport(cast(FileP)); } +std::error_code SymbolTable::addDirectives(StringRef Dir) { + if (Dir.empty()) + return std::error_code(); + std::vector> Libs; + if (auto EC = Driver->parseDirectives(Dir, &Libs)) + return EC; + for (std::unique_ptr &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 @@ // 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> Libs; - if (auto EC = Driver->parseDirectives(Dir, &Libs)) - return EC; - for (std::unique_ptr &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 @@ 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: test/COFF/lto-linker-opts.ll =================================================================== --- /dev/null +++ test/COFF/lto-linker-opts.ll @@ -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"}