From ace2f091fd4e2123794fc534da284e7cda39f314 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Sat, 6 Jun 2015 02:00:45 +0000 Subject: [PATCH] COFF: Read linker directives from bitcode files. Differential Revision: http://reviews.llvm.org/D10285 llvm-svn: 239212 --- lld/COFF/InputFiles.cpp | 17 +++++++++++++++++ lld/COFF/InputFiles.h | 4 ++++ lld/COFF/SymbolTable.cpp | 25 ++++++++++++++----------- lld/COFF/SymbolTable.h | 2 ++ lld/test/COFF/lto-linker-opts.ll | 11 +++++++++++ 5 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 lld/test/COFF/lto-linker-opts.ll diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index ec8e9f5..62bb144 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -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 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(); } diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index 9d7b0ef..e4c75d4 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -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 SymbolBodies; llvm::BumpPtrAllocator Alloc; std::unique_ptr M; + std::string Directives; }; } // namespace coff diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 35042e5..a90e208 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -40,6 +40,17 @@ std::error_code SymbolTable::addFile(std::unique_ptr File) { 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 @@ 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> 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 @@ 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) { diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 0c5e795..99a794d 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -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 index 0000000..baa9085 --- /dev/null +++ b/lld/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"} -- 2.7.4