bd1976llvm updated this revision to Diff 195495.
bd1976llvm added a comment.

No longer shortening "dependent libraries" to "deplibs" except for the .deplibs 
section (as this takes up bytes on disk).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60274/new/

https://reviews.llvm.org/D60274

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/dependent-lib.c
  clang/test/CodeGen/elf-linker-options.c
  clang/test/CodeGen/pragma-comment.c
  clang/test/Modules/autolink.m
  lld/ELF/Config.h
  lld/ELF/Driver.cpp
  lld/ELF/Driver.h
  lld/ELF/DriverUtils.cpp
  lld/ELF/InputFiles.cpp
  lld/ELF/Options.td
  lld/test/ELF/Inputs/deplibs-lib_bar.s
  lld/test/ELF/Inputs/deplibs-lib_foo.s
  lld/test/ELF/deplibs-colon-prefix.s
  lld/test/ELF/deplibs-corrupt.s
  lld/test/ELF/deplibs.s
  lld/test/ELF/lto/deplibs.s
  llvm/docs/Extensions.rst
  llvm/docs/LangRef.rst
  llvm/include/llvm-c/lto.h
  llvm/include/llvm/BinaryFormat/ELF.h
  llvm/include/llvm/LTO/LTO.h
  llvm/include/llvm/LTO/legacy/LTOModule.h
  llvm/include/llvm/Object/IRSymtab.h
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/LTO/LTO.cpp
  llvm/lib/LTO/LTOModule.cpp
  llvm/lib/MC/MCParser/ELFAsmParser.cpp
  llvm/lib/MC/MCSectionELF.cpp
  llvm/lib/Object/ELF.cpp
  llvm/lib/Object/IRSymtab.cpp
  llvm/lib/ObjectYAML/ELFYAML.cpp
  llvm/test/Feature/elf-deplibs.ll
  llvm/test/LTO/Resolution/X86/symtab-elf.ll
  llvm/test/MC/ELF/section.s
  llvm/test/Object/X86/irsymtab.ll
  llvm/tools/llvm-lto2/llvm-lto2.cpp
  llvm/tools/llvm-readobj/ELFDumper.cpp
  llvm/tools/lto/lto.cpp

Index: llvm/tools/lto/lto.cpp
===================================================================
--- llvm/tools/lto/lto.cpp
+++ llvm/tools/lto/lto.cpp
@@ -325,6 +325,10 @@
   return unwrap(mod)->getLinkerOpts().data();
 }
 
+const char* lto_module_get_dependent_libraries(lto_module_t mod) {
+    return unwrap(mod)->getDependentLibraries().data();
+}
+
 void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
                                         lto_diagnostic_handler_t diag_handler,
                                         void *ctxt) {
Index: llvm/tools/llvm-readobj/ELFDumper.cpp
===================================================================
--- llvm/tools/llvm-readobj/ELFDumper.cpp
+++ llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -2830,6 +2830,8 @@
     return "LLVM_CALL_GRAPH_PROFILE";
   case SHT_LLVM_ADDRSIG:
     return "LLVM_ADDRSIG";
+  case SHT_LLVM_DEPENDENT_LIBRARIES:
+    return "LLVM_DEPENDENT_LIBRARIES";
   // FIXME: Parse processor specific GNU attributes
   case SHT_GNU_ATTRIBUTES:
     return "ATTRIBUTES";
Index: llvm/tools/llvm-lto2/llvm-lto2.cpp
===================================================================
--- llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -360,6 +360,13 @@
     if (TT.isOSBinFormatCOFF())
       outs() << "linker opts: " << Input->getCOFFLinkerOpts() << '\n';
 
+    if (TT.isOSBinFormatELF()) {
+      outs() << "dependent libraries:";
+      for (auto L : Input->getDependentLibraries())
+        outs() << " \"" << L << "\"";
+      outs() << '\n';
+    }
+
     std::vector<StringRef> ComdatTable = Input->getComdatTable();
     for (const InputFile::Symbol &Sym : Input->symbols()) {
       switch (Sym.getVisibility()) {
Index: llvm/test/Object/X86/irsymtab.ll
===================================================================
--- llvm/test/Object/X86/irsymtab.ll
+++ llvm/test/Object/X86/irsymtab.ll
@@ -9,16 +9,17 @@
 
 ; BCA:      <SYMTAB_BLOCK
 ; Version stored at offset 0.
-; BCA-NEXT:   <BLOB abbrevid=4/> blob data = '\x01\x00\x00\x00\x06\x00\x00\x00\x08\x00\x00\x00D\x00\x00\x00\x01\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x02\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x0E\x00\x00\x00\x18\x00\x00\x00&\x00\x00\x00\x0B\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\xFF\xFF\xFF\xFF\x00$\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\xFF\xFF\xFF\xFF\x08$\x00\x00'
+; BCA-NEXT:   <BLOB abbrevid=4/> blob data = '\x02\x00\x00\x00\x06\x00\x00\x00\x08\x00\x00\x00L\x00\x00\x00\x01\x00\x00\x00X\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x02\x00\x00\x00\x88\x00\x00\x00\x00\x00\x00\x00\x0E\x00\x00\x00\x18\x00\x00\x00&\x00\x00\x00\x0B\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\xFF\xFF\xFF\xFF\x00$\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\xFF\xFF\xFF\xFF\x08$\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00'
 ; BCA-NEXT: </SYMTAB_BLOCK>
 ; BCA-NEXT: <STRTAB_BLOCK
 ; BCA-NEXT:   <BLOB abbrevid=4/> blob data = 'foobarproducerx86_64-unknown-linux-gnuirsymtab.ll'
 ; BCA-NEXT: </STRTAB_BLOCK>
 
-; SYMTAB:      version: 1
+; SYMTAB:      version: 2
 ; SYMTAB-NEXT: producer: producer
 ; SYMTAB-NEXT: target triple: x86_64-unknown-linux-gnu
 ; SYMTAB-NEXT: source filename: irsymtab.ll
+; SYMTAB-NEXT: {{^dependent libraries: \"foo\" \"bar\"$}}
 ; SYMTAB-NEXT: D------X foo
 ; SYMTAB-NEXT: DU-----X bar
 
@@ -31,3 +32,8 @@
 }
 
 declare void @bar()
+
+!llvm.dependent-libraries = !{!0, !1}
+
+!0 = !{!"foo"}
+!1 = !{!"bar"}
Index: llvm/test/MC/ELF/section.s
===================================================================
--- llvm/test/MC/ELF/section.s
+++ llvm/test/MC/ELF/section.s
@@ -293,3 +293,17 @@
 // CHECK-NEXT:   ]
 // CHECK: }
 
+// Test SHT_LLVM_DEPENDENT_LIBRARIES
+
+.section .deplibs,"MS",@llvm_dependent_libaries,1
+// ASM: .section .deplibs,"MS",@llvm_dependent_libaries,1
+
+// CHECK: Section {
+// CHECK:   Name: .deplibs
+// CHECK-NEXT:   Type: SHT_LLVM_DEPENDENT_LIBRARIES
+// CHECK-NEXT:   Flags [
+// CHECK-NEXT:       SHF_MERGE
+// CHECK-NEXT:       SHF_STRINGS
+// CHECK-NEXT:   ]
+// CHECK: }
+
Index: llvm/test/LTO/Resolution/X86/symtab-elf.ll
===================================================================
--- llvm/test/LTO/Resolution/X86/symtab-elf.ll
+++ llvm/test/LTO/Resolution/X86/symtab-elf.ll
@@ -9,6 +9,12 @@
 !0 = !{!"/include:foo"}
 !llvm.linker.options = !{ !0 }
 
+; CHECK: {{^dependent libraries: \"foo\" \"b a r\" \"baz\"$}}
+!1 = !{!"foo"}
+!2 = !{!"b a r"}
+!3 = !{!"baz"}
+!llvm.dependent-libraries = !{!1, !2, !3}
+
 @g1 = global i32 0
 
 ; CHECK-NOT: fallback g1
Index: llvm/test/Feature/elf-deplibs.ll
===================================================================
--- /dev/null
+++ llvm/test/Feature/elf-deplibs.ll
@@ -0,0 +1,15 @@
+; RUN: llc -mtriple x86_64-elf -filetype asm -o - %s | FileCheck %s
+; REQUIRES: x86-registered-target
+
+!llvm.dependent-libraries = !{!0, !1, !0}
+
+!0 = !{!"foo"}
+!1 = !{!"b a r"}
+
+; CHECK: .section .deplibs,"MS",@llvm_dependent_libraries,1
+; CHECK-NEXT: .ascii  "foo"
+; CHECK-NEXT: .byte   0
+; CHECK-NEXT: .ascii  "b a r"
+; CHECK-NEXT: .byte   0
+; CHECK-NEXT: .ascii  "foo"
+; CHECK-NEXT: .byte   0
Index: llvm/lib/ObjectYAML/ELFYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/ELFYAML.cpp
+++ llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -454,6 +454,7 @@
   ECase(SHT_LLVM_LINKER_OPTIONS);
   ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
   ECase(SHT_LLVM_ADDRSIG);
+  ECase(SHT_LLVM_DEPENDENT_LIBRARIES);
   ECase(SHT_GNU_ATTRIBUTES);
   ECase(SHT_GNU_HASH);
   ECase(SHT_GNU_verdef);
Index: llvm/lib/Object/IRSymtab.cpp
===================================================================
--- llvm/lib/Object/IRSymtab.cpp
+++ llvm/lib/Object/IRSymtab.cpp
@@ -89,6 +89,8 @@
   std::string COFFLinkerOpts;
   raw_string_ostream COFFLinkerOptsOS{COFFLinkerOpts};
 
+  std::vector<storage::Str> DependentLibraries;
+
   void setStr(storage::Str &S, StringRef Value) {
     S.Offset = StrtabBuilder.add(Value);
     S.Size = Value.size();
@@ -140,6 +142,20 @@
     }
   }
 
+  if (TT.isOSBinFormatELF()) {
+    if (auto E = M->materializeMetadata())
+      return E;
+    if (NamedMDNode *N = M->getNamedMetadata("llvm.dependent-libraries")) {
+      for (MDNode *MDOptions : N->operands()) {
+        const auto OperandStr =
+            cast<MDString>(cast<MDNode>(MDOptions)->getOperand(0))->getString();
+        storage::Str Specifier;
+        setStr(Specifier, OperandStr);
+        DependentLibraries.emplace_back(Specifier);
+      }
+    }
+  }
+
   for (ModuleSymbolTable::Symbol Msym : Msymtab.symbols())
     if (Error Err = addSymbol(Msymtab, Used, Msym))
       return Err;
@@ -312,7 +328,7 @@
   writeRange(Hdr.Comdats, Comdats);
   writeRange(Hdr.Symbols, Syms);
   writeRange(Hdr.Uncommons, Uncommons);
-
+  writeRange(Hdr.DependentLibraries, DependentLibraries);
   *reinterpret_cast<storage::Header *>(Symtab.data()) = Hdr;
   return Error::success();
 }
Index: llvm/lib/Object/ELF.cpp
===================================================================
--- llvm/lib/Object/ELF.cpp
+++ llvm/lib/Object/ELF.cpp
@@ -253,6 +253,7 @@
     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG);
+    STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES);
     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
Index: llvm/lib/MC/MCSectionELF.cpp
===================================================================
--- llvm/lib/MC/MCSectionELF.cpp
+++ llvm/lib/MC/MCSectionELF.cpp
@@ -152,6 +152,8 @@
     OS << "llvm_linker_options";
   else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
     OS << "llvm_call_graph_profile";
+  else if (Type == ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
+    OS << "llvm_dependent_libraries";
   else
     report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
                        " for section " + getSectionName());
Index: llvm/lib/MC/MCParser/ELFAsmParser.cpp
===================================================================
--- llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -615,6 +615,8 @@
       Type = ELF::SHT_LLVM_LINKER_OPTIONS;
     else if (TypeName == "llvm_call_graph_profile")
       Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
+    else if (TypeName == "llvm_dependent_libraries")
+      Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES;
     else if (TypeName.getAsInteger(0, Type))
       return TokError("unknown section type");
   }
Index: llvm/lib/LTO/LTOModule.cpp
===================================================================
--- llvm/lib/LTO/LTOModule.cpp
+++ llvm/lib/LTO/LTOModule.cpp
@@ -646,5 +646,9 @@
     emitLinkerFlagsForGlobalCOFF(OS, Sym.symbol, TT, M);
   }
 
-  // Add other interesting metadata here.
+  // Dependent Libraries
+  raw_string_ostream OSD(DependentLibraries);
+  if (NamedMDNode *DependentLibraries = getModule().getNamedMetadata("llvm.dependent-libraries"))
+    for (MDNode *N : DependentLibraries->operands())
+      OSD << " " << cast<MDString>(N->getOperand(0))->getString();
 }
Index: llvm/lib/LTO/LTO.cpp
===================================================================
--- llvm/lib/LTO/LTO.cpp
+++ llvm/lib/LTO/LTO.cpp
@@ -398,6 +398,7 @@
   File->TargetTriple = FOrErr->TheReader.getTargetTriple();
   File->SourceFileName = FOrErr->TheReader.getSourceFileName();
   File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
+  File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
   File->ComdatTable = FOrErr->TheReader.getComdatTable();
 
   for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) {
Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
===================================================================
--- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -271,6 +271,19 @@
     }
   }
 
+  if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) {
+    auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES,
+                              ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
+
+    Streamer.SwitchSection(S);
+
+    for (const auto &Operand : DependentLibraries->operands()) {
+      Streamer.EmitBytes(
+          cast<MDString>(cast<MDNode>(Operand)->getOperand(0))->getString());
+      Streamer.EmitIntValue(0, 1);
+    }
+  }
+
   unsigned Version = 0;
   unsigned Flags = 0;
   StringRef Section;
Index: llvm/include/llvm/Object/IRSymtab.h
===================================================================
--- llvm/include/llvm/Object/IRSymtab.h
+++ llvm/include/llvm/Object/IRSymtab.h
@@ -125,12 +125,13 @@
   Str SectionName;
 };
 
+
 struct Header {
   /// Version number of the symtab format. This number should be incremented
   /// when the format changes, but it does not need to be incremented if a
   /// change to LLVM would cause it to create a different symbol table.
   Word Version;
-  enum { kCurrentVersion = 1 };
+  enum { kCurrentVersion = 2 };
 
   /// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION).
   /// Consumers should rebuild the symbol table from IR if the producer's
@@ -147,6 +148,9 @@
 
   /// COFF-specific: linker directives.
   Str COFFLinkerOpts;
+
+  /// Dependent Library Specifiers
+  Range<Str> DependentLibraries;
 };
 
 } // end namespace storage
@@ -231,6 +235,7 @@
   ArrayRef<storage::Comdat> Comdats;
   ArrayRef<storage::Symbol> Symbols;
   ArrayRef<storage::Uncommon> Uncommons;
+  ArrayRef<storage::Str> DependentLibraries;
 
   StringRef str(storage::Str S) const { return S.get(Strtab); }
 
@@ -251,6 +256,7 @@
     Comdats = range(header().Comdats);
     Symbols = range(header().Symbols);
     Uncommons = range(header().Uncommons);
+    DependentLibraries = range(header().DependentLibraries);
   }
 
   using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
@@ -283,6 +289,16 @@
 
   /// COFF-specific: returns linker options specified in the input file.
   StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
+
+  /// Returns dependent library specifiers
+  std::vector<StringRef> getDependentLibraries() const {
+    std::vector<StringRef> Specifiers;
+    Specifiers.reserve(DependentLibraries.size());
+    for (auto S : DependentLibraries) {
+      Specifiers.push_back(str(S));
+    }
+    return Specifiers;
+  }
 };
 
 /// Ephemeral symbols produced by Reader::symbols() and
Index: llvm/include/llvm/LTO/legacy/LTOModule.h
===================================================================
--- llvm/include/llvm/LTO/legacy/LTOModule.h
+++ llvm/include/llvm/LTO/legacy/LTOModule.h
@@ -47,6 +47,8 @@
 
   std::string LinkerOpts;
 
+  std::string DependentLibraries;
+
   std::unique_ptr<Module> Mod;
   MemoryBufferRef MBRef;
   ModuleSymbolTable SymTab;
@@ -153,6 +155,8 @@
 
   StringRef getLinkerOpts() { return LinkerOpts; }
 
+  StringRef getDependentLibraries() { return DependentLibraries; }
+
   const std::vector<StringRef> &getAsmUndefinedRefs() { return _asm_undefines; }
 
 private:
Index: llvm/include/llvm/LTO/LTO.h
===================================================================
--- llvm/include/llvm/LTO/LTO.h
+++ llvm/include/llvm/LTO/LTO.h
@@ -110,6 +110,7 @@
   std::vector<std::pair<size_t, size_t>> ModuleSymIndices;
 
   StringRef TargetTriple, SourceFileName, COFFLinkerOpts;
+  std::vector<StringRef> DependentLibraries;
   std::vector<StringRef> ComdatTable;
 
 public:
@@ -149,6 +150,9 @@
   /// Returns linker options specified in the input file.
   StringRef getCOFFLinkerOpts() const { return COFFLinkerOpts; }
 
+  /// Returns dependent library specifiers from the input file.
+  ArrayRef<StringRef> getDependentLibraries() const { return DependentLibraries; }
+
   /// Returns the path to the InputFile.
   StringRef getName() const;
 
Index: llvm/include/llvm/BinaryFormat/ELF.h
===================================================================
--- llvm/include/llvm/BinaryFormat/ELF.h
+++ llvm/include/llvm/BinaryFormat/ELF.h
@@ -838,6 +838,7 @@
   SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile.
   SHT_LLVM_ADDRSIG = 0x6fff4c03,        // List of address-significant symbols
                                         // for safe ICF.
+  SHT_LLVM_DEPENDENT_LIBRARIES = 0x6fff4c04, // LLVM Dependent Library Specifiers.
   // Android's experimental support for SHT_RELR sections.
   // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
   SHT_ANDROID_RELR = 0x6fffff00,        // Relocation entries; only offsets.
Index: llvm/include/llvm-c/lto.h
===================================================================
--- llvm/include/llvm-c/lto.h
+++ llvm/include/llvm-c/lto.h
@@ -44,7 +44,7 @@
  * @{
  */
 
-#define LTO_API_VERSION 23
+#define LTO_API_VERSION 24
 
 /**
  * \since prior to LTO_API_VERSION=3
@@ -297,6 +297,14 @@
 extern const char*
 lto_module_get_linkeropts(lto_module_t mod);
 
+/**
+* Returns the module's dependent library specifiers.
+*
+* \since LTO_API_VERSION=24
+*/
+extern const char*
+lto_module_get_dependent_libraries(lto_module_t mod);
+
 /**
  * Diagnostic severity.
  *
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -6081,10 +6081,10 @@
 Automatic Linker Flags Named Metadata
 =====================================
 
-Some targets support embedding flags to the linker inside individual object
+Some targets support embedding of flags to the linker inside individual object
 files. Typically this is used in conjunction with language extensions which
-allow source files to explicitly declare the libraries they depend on, and have
-these automatically be transmitted to the linker via object files.
+allow source files to contain linker command line options, and have these
+automatically be transmitted to the linker via object files.
 
 These flags are encoded in the IR using named metadata with the name
 ``!llvm.linker.options``. Each operand is expected to be a metadata node
@@ -6095,8 +6095,8 @@
 linker options, presumably to link against ``libz`` and the ``Cocoa``
 framework::
 
-    !0 = !{ !"-lz" },
-    !1 = !{ !"-framework", !"Cocoa" } } }
+    !0 = !{ !"-lz" }
+    !1 = !{ !"-framework", !"Cocoa" }
     !llvm.linker.options = !{ !0, !1 }
 
 The metadata encoding as lists of lists of options, as opposed to a collapsed
@@ -6109,6 +6109,28 @@
 linker, or an option that is reserved by the target specific assembly writer or
 object file emitter. No other aspect of these options is defined by the IR.
 
+Dependent Libs Named Metadata
+=============================
+
+Some targets support embedding of strings into object files to indicate
+a set of libraries to add to the link. Typically this is used in conjunction
+with language extensions which allow source files to explicitly declare the
+libraries they depend on, and have these automatically be transmitted to the
+linker via object files.
+
+The list is encoded in the IR using named metadata with the name
+``!llvm.dependent-libraries``. Each operand is expected to be a metadata node
+which should contain a single string operand.
+
+For example, the following metadata section contains two library specfiers::
+
+    !0 = !{!"a library specifier"}
+    !1 = !{!"another library specifier"}
+    !llvm.dependent-libraries = !{ !0, !1 }
+
+Each library specifier will be handled independently by the consuming linker.
+The effect of the library specifiers are defined by the consuming linker. 
+
 .. _summary:
 
 ThinLTO Summary
Index: llvm/docs/Extensions.rst
===================================================================
--- llvm/docs/Extensions.rst
+++ llvm/docs/Extensions.rst
@@ -285,6 +285,26 @@
     The paramter identifies an additional library search path to be considered
     when looking up libraries after the inclusion of this option.
 
+``SHT_LLVM_DEPENDENT_LIBRARIES`` Section (Dependent Libraries)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This section contains strings specifying libraries to be added to the link by
+the linker.
+
+The section should be consumed by the linker and not written to the output.
+
+The strings are encoded as standard null-terminated UTF-8 strings.
+
+For example:
+
+.. code-block:: gas
+
+  .section ".deplibs","MS",@llvm_dependent_libraries,1
+  .asciz "library specifier 1"
+  .asciz "library specifier 2"
+
+The interpretation of the library specifiers is defined by the consuming linker.
+
 ``SHT_LLVM_CALL_GRAPH_PROFILE`` Section (Call Graph Profile)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
Index: lld/test/ELF/lto/deplibs.s
===================================================================
--- /dev/null
+++ lld/test/ELF/lto/deplibs.s
@@ -0,0 +1,15 @@
+; REQUIRES: x86
+
+; RUN: llvm-as %s -o %t.o
+; RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s -DOBJ=%t.o
+
+; CHECK: error: [[OBJ]]: unable to find library from dependent library specifier: foo
+; CHECK: error: [[OBJ]]: unable to find library from dependent library specifier: bar
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+!llvm.dependent-libraries = !{!0, !1}
+
+!0 = !{!"foo"}
+!1 = !{!"bar"}
Index: lld/test/ELF/deplibs.s
===================================================================
--- /dev/null
+++ lld/test/ELF/deplibs.s
@@ -0,0 +1,57 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/deplibs-lib_foo.s -o %tfoo.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/deplibs-lib_bar.s -o %tbar.o
+# RUN: rm -rf %t.dir %t.cwd
+# RUN: mkdir -p %t.dir
+
+# error if dependent libraries cannot be found
+# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s -DOBJ=%t.o --check-prefix MISSING
+# MISSING: error: [[OBJ]]: unable to find library from dependent library specifier: foo.a
+# MISSING-NEXT: error: [[OBJ]]: unable to find library from dependent library specifier: bar
+
+# can ignore dependent libraries
+# RUN: not ld.lld %t.o -o /dev/null --no-dependent-libraries 2>&1 | FileCheck %s --check-prefix IGNORE
+# IGNORE: error: undefined symbol: foo
+# IGNORE: error: undefined symbol: bar
+
+# -r links preserve dependent libraries
+# RUN: ld.lld %t.o %t.o -r -o %t-r.o
+# RUN: not ld.lld %t-r.o -o /dev/null 2>&1 | sort | FileCheck %s -DOBJ=%t-r.o --check-prefixes MINUSR
+# MINUSR: error: [[OBJ]]: unable to find library from dependent library specifier: bar
+# MINUSR-NEXT: error: [[OBJ]]: unable to find library from dependent library specifier: foo.a
+# MINUSR-NOT: unable to find library from dependent library specifier
+
+# static archives located relative to library search paths
+# RUN: llvm-ar rc %t.dir/foo.a %tfoo.o
+# RUN: llvm-ar rc %t.dir/libbar.a %tbar.o
+# RUN: ld.lld %t.o -o /dev/null -L %t.dir
+
+# shared objects located relative to library search paths
+# RUN: rm %t.dir/libbar.a
+# RUN: ld.lld -shared -o %t.dir/libbar.so %tbar.o
+# RUN: ld.lld -Bdynamic %t.o -o /dev/null -L %t.dir
+
+# dependent libraries searched for symbols after libraries on the command line
+# RUN: mkdir -p %t.cwd
+# RUN: cd %t.cwd
+# RUN: cp %t.dir/foo.a %t.cwd/libcmdline.a
+# RUN: ld.lld %t.o libcmdline.a -o /dev/null -L %t.dir --trace 2>&1 | FileCheck %s -DOBJ=%t.o -DSO=%t.dir --check-prefix CMDLINE --implicit-check-not foo.a
+# CMDLINE: [[OBJ]]
+# CMDLINE-NEXT: {{^libcmdline\.a}}
+# CMDLINE-NEXT: [[SO]]{{[\\/]}}libbar.so
+
+# libraries can be found from specifiers as if the specifiers were listed on on the command-line.
+# RUN: cp %t.dir/foo.a %t.cwd/foo.a
+# RUN: ld.lld %t.o -o /dev/null -L %t.dir --trace 2>&1 | FileCheck %s -DOBJ=%t.o -DSO=%t.dir --check-prefix ASIFCMDLINE --implicit-check-not foo.a
+# ASIFCMDLINE: [[OBJ]]
+# ASIFCMDLINE-NEXT: {{^foo\.a}}
+# ASIFCMDLINE-NEXT: [[SO]]{{[\\/]}}libbar.so
+
+    call foo
+    call bar
+.section ".deplibs","MS",@llvm_dependent_libraries,1
+    .asciz  "foo.a"
+    .asciz  "bar"
+
Index: lld/test/ELF/deplibs-corrupt.s
===================================================================
--- /dev/null
+++ lld/test/ELF/deplibs-corrupt.s
@@ -0,0 +1,9 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o /dev/null -L %t.dir 2>&1 | FileCheck %s -DOBJ=%t.o
+# CHECK: error: [[OBJ]]: corrupted dependent libraries section (unterminated string): .deplibs
+
+.section ".deplibs","MS",@llvm_dependent_libraries,1
+    .ascii  ":foo.a"
+
Index: lld/test/ELF/deplibs-colon-prefix.s
===================================================================
--- /dev/null
+++ lld/test/ELF/deplibs-colon-prefix.s
@@ -0,0 +1,15 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/deplibs-lib_foo.s -o %tfoo.o
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir
+# RUN: llvm-ar rc %t.dir/foo.a %tfoo.o
+# RUN: not ld.lld %t.o -o /dev/null -L %t.dir 2>&1 | FileCheck %s -DOBJ=%t.o
+# CHECK: error: [[OBJ]]: unable to find library from dependent library specifier: :foo.a
+
+        .global _start
+_start:
+        call foo
+    .section ".deplibs","MS",@llvm_dependent_libraries,1
+        .asciz  ":foo.a"
Index: lld/test/ELF/Inputs/deplibs-lib_foo.s
===================================================================
--- /dev/null
+++ lld/test/ELF/Inputs/deplibs-lib_foo.s
@@ -0,0 +1,2 @@
+        .global foo
+foo:
Index: lld/test/ELF/Inputs/deplibs-lib_bar.s
===================================================================
--- /dev/null
+++ lld/test/ELF/Inputs/deplibs-lib_bar.s
@@ -0,0 +1,2 @@
+        .global bar
+bar:
Index: lld/ELF/Options.td
===================================================================
--- lld/ELF/Options.td
+++ lld/ELF/Options.td
@@ -71,6 +71,10 @@
     "Apply link-time values for dynamic relocations",
     "Do not apply link-time values for dynamic relocations (default)">;
 
+defm dependent_libraries: B<"dependent-libraries",
+    "Process dependent library specifiers from input files (default)",
+    "Ignore dependent library specifiers from input files">;
+
 defm as_needed: B<"as-needed",
     "Only set DT_NEEDED for shared libraries if used",
     "Always set DT_NEEDED for shared libraries (default)">;
Index: lld/ELF/InputFiles.cpp
===================================================================
--- lld/ELF/InputFiles.cpp
+++ lld/ELF/InputFiles.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "InputFiles.h"
+#include "Driver.h"
 #include "InputSection.h"
 #include "LinkerScript.h"
 #include "SymbolTable.h"
@@ -396,6 +397,27 @@
   }
 }
 
+// An ELF object file may contain a `.deplibs` section. If it exists, the
+// section contains a list of library specifiers such as `m` for libm. This
+// function resolves a given name by finding the first matching library checking
+// the various ways that a library can be specified to LLD. This ELF extension
+// is a form of autolinking and is called `dependent libraries`. It is currently
+// unique to LLVM and lld.
+static void addDependentLibrary(StringRef Specifier, const InputFile *F) {
+  if (!Config->DependentLibraries)
+    return;
+  if (fs::exists(Specifier))
+    Driver->addFile(Specifier, /*WithLOption=*/false);
+  else if (Optional<std::string> S = findFromSearchPaths(Specifier))
+    Driver->addFile(*S, /*WithLOption=*/true);
+  else if (Optional<std::string> S = searchLibraryBaseName(Specifier))
+    Driver->addFile(*S, /*WithLOption=*/true);
+  else
+    error(toString(F) +
+          ": unable to find library from dependent library specifier: " +
+          Specifier);
+}
+
 template <class ELFT>
 void ObjFile<ELFT>::initializeSections(
     DenseSet<CachedHashStringRef> &ComdatGroups) {
@@ -637,6 +659,24 @@
     }
     return &InputSection::Discarded;
   }
+  case SHT_LLVM_DEPENDENT_LIBRARIES: {
+    if (Config->Relocatable)
+      break;
+    ArrayRef<char> Data =
+        CHECK(this->getObj().template getSectionContentsAsArray<char>(&Sec), this);
+    if (!Data.empty() && Data.back() != '\0') {
+      error(toString(this) +
+            ": corrupted dependent libraries section (unterminated string): " +
+            Name);
+      return &InputSection::Discarded;
+    }
+    for (const char *D = Data.begin(), *E = Data.end(); D < E;) {
+      StringRef S(D);
+      addDependentLibrary(S, this);
+      D += S.size() + 1;
+    }
+    return &InputSection::Discarded;
+  }
   case SHT_RELA:
   case SHT_REL: {
     // Find a relocation target section and associate this section with that.
@@ -1186,6 +1226,9 @@
 
   for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
     Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, *this));
+
+  for (auto L : Obj->getDependentLibraries())
+    addDependentLibrary(L, this);
 }
 
 static ELFKind getELFKind(MemoryBufferRef MB, StringRef ArchiveName) {
Index: lld/ELF/DriverUtils.cpp
===================================================================
--- lld/ELF/DriverUtils.cpp
+++ lld/ELF/DriverUtils.cpp
@@ -217,12 +217,9 @@
   return None;
 }
 
-// This is for -lfoo. We'll look for libfoo.so or libfoo.a from
+// This is for -l<basename>. We'll look for lib<basename>.so or lib<basename>.a from
 // search paths.
-Optional<std::string> elf::searchLibrary(StringRef Name) {
-  if (Name.startswith(":"))
-    return findFromSearchPaths(Name.substr(1));
-
+Optional<std::string> elf::searchLibraryBaseName(StringRef Name) {
   for (StringRef Dir : Config->SearchPaths) {
     if (!Config->Static)
       if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".so"))
@@ -233,6 +230,13 @@
   return None;
 }
 
+// This is for -l<namespec>.
+Optional<std::string> elf::searchLibrary(StringRef Name) {
+    if (Name.startswith(":"))
+        return findFromSearchPaths(Name.substr(1));
+    return searchLibraryBaseName (Name);
+}
+
 // If a linker/version script doesn't exist in the current directory, we also
 // look for the script in the '-L' search paths. This matches the behaviour of
 // '-T', --version-script=, and linker script INPUT() command in ld.bfd.
Index: lld/ELF/Driver.h
===================================================================
--- lld/ELF/Driver.h
+++ lld/ELF/Driver.h
@@ -64,6 +64,7 @@
 
 llvm::Optional<std::string> findFromSearchPaths(StringRef Path);
 llvm::Optional<std::string> searchScript(StringRef Path);
+llvm::Optional<std::string> searchLibraryBaseName(StringRef Path);
 llvm::Optional<std::string> searchLibrary(StringRef Path);
 
 } // namespace elf
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -778,6 +778,7 @@
   Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common,
                                       !Args.hasArg(OPT_relocatable));
   Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
+  Config->DependentLibraries = Args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true);
   Config->DisableVerify = Args.hasArg(OPT_disable_verify);
   Config->Discard = getDiscard(Args);
   Config->DwoDir = Args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
@@ -1493,9 +1494,11 @@
     Symtab->trace(Arg->getValue());
 
   // Add all files to the symbol table. This will add almost all
-  // symbols that we need to the symbol table.
-  for (InputFile *F : Files)
-    Symtab->addFile<ELFT>(F);
+  // symbols that we need to the symbol table. This process might
+  // add files to the link, via autolinking, these files are always
+  // appended to the Files vector.
+  for (size_t I = 0; I < Files.size(); ++I)
+    Symtab->addFile<ELFT>(Files[I]);
 
   // Now that we have every file, we can decide if we will need a
   // dynamic symbol table.
Index: lld/ELF/Config.h
===================================================================
--- lld/ELF/Config.h
+++ lld/ELF/Config.h
@@ -136,6 +136,7 @@
   bool Cref;
   bool DefineCommon;
   bool Demangle = true;
+  bool DependentLibraries;
   bool DisableVerify;
   bool EhFrameHdr;
   bool EmitLLVM;
Index: clang/test/Modules/autolink.m
===================================================================
--- clang/test/Modules/autolink.m
+++ clang/test/Modules/autolink.m
@@ -37,9 +37,9 @@
 // NOTE: "autolink_sub" is intentionally not linked.
 
 // CHECK: !llvm.linker.options = !{![[AUTOLINK_PCH:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[AUTOLINK:[0-9]+]], ![[DEPENDSONMODULE:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]}
-// CHECK: ![[AUTOLINK_PCH]] = !{!"{{(\\01|-l|/DEFAULTLIB:|lib", !")}}autolink_from_pch{{(\.lib)?}}"}
+// CHECK: ![[AUTOLINK_PCH]] = !{!"{{(-l|/DEFAULTLIB:|lib", !")}}autolink_from_pch{{(\.lib)?}}"}
 // CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"autolink_framework"}
-// CHECK: ![[AUTOLINK]] = !{!"{{(\\01|-l|/DEFAULTLIB:|lib", !")}}autolink{{(\.lib)?}}"}
+// CHECK: ![[AUTOLINK]] = !{!"{{(-l|/DEFAULTLIB:|lib", !")}}autolink{{(\.lib)?}}"}
 // CHECK: ![[DEPENDSONMODULE]] = !{!"-framework", !"DependsOnModule"}
 // CHECK: ![[MODULE]] = !{!"-framework", !"Module"}
 // CHECK: ![[NOUMBRELLA]] = !{!"-framework", !"NoUmbrella"}
Index: clang/test/CodeGen/pragma-comment.c
===================================================================
--- clang/test/CodeGen/pragma-comment.c
+++ clang/test/CodeGen/pragma-comment.c
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s -triple thumbv7-windows -fms-extensions -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple thumbv7-linux-gnueabihf -fms-extensions -emit-llvm -o - | FileCheck -check-prefix LINUX %s
-// RUN: %clang_cc1 %s -triple i686-pc-linux -fms-extensions -emit-llvm -o - | FileCheck -check-prefix LINUX %s
-// RUN: %clang_cc1 %s -triple x86_64-scei-ps4 -fms-extensions -emit-llvm -o - | FileCheck -check-prefix PS4 %s
+// RUN: %clang_cc1 %s -triple thumbv7-linux-gnueabihf -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
+// RUN: %clang_cc1 %s -triple i686-pc-linux -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
+// RUN: %clang_cc1 %s -triple x86_64-scei-ps4 -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
 // RUN: %clang_cc1 %s -triple aarch64-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
 
 #pragma comment(lib, "msvcrt.lib")
@@ -23,11 +23,10 @@
 // CHECK: ![[bar]] = !{!" /bar=2"}
 // CHECK: ![[foo]] = !{!" /foo=\22foo bar\22"}
 
-// LINUX: !{!"lib", !"msvcrt.lib"}
-// LINUX: !{!"lib", !"kernel32"}
-// LINUX: !{!"lib", !"USER32.LIB"}
-
-// PS4: !{!"\01msvcrt.lib"}
-// PS4: !{!"\01kernel32"}
-// PS4: !{!"\01USER32.LIB"}
-// PS4: !{!"\01\22with space\22"}
+// ELF: !llvm.dependent-libraries = !{![[msvcrt:[0-9]+]], ![[kernel32:[0-9]+]], ![[USER32:[0-9]+]], ![[space:[0-9]+]]
+// ELF: ![[msvcrt]] = !{!"msvcrt.lib"}
+// ELF: ![[kernel32]] = !{!"kernel32"}
+// ELF: ![[USER32]] = !{!"USER32.LIB"}
+// ELF: ![[space]] = !{!"with space"}
+// ELF-NOT: bar
+// ELF-NOT: foo
Index: clang/test/CodeGen/elf-linker-options.c
===================================================================
--- clang/test/CodeGen/elf-linker-options.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang_cc1 -triple i686---elf -emit-llvm %s -o - | FileCheck %s
-
-#pragma comment(lib, "alpha")
-
-// CHECK: !llvm.linker.options = !{[[NODE:![0-9]+]]}
-// CHECK: [[NODE]] = !{!"lib", !"alpha"}
-
Index: clang/test/CodeGen/dependent-lib.c
===================================================================
--- clang/test/CodeGen/dependent-lib.c
+++ clang/test/CodeGen/dependent-lib.c
@@ -1,12 +1,12 @@
 // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple thumbv7-windows -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s
+// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s --implicit-check-not llvm.linker.options
 
 // CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]]}
 // CHECK: ![[msvcrt]] = !{!"/DEFAULTLIB:msvcrt.lib"}
 
-// LINUX: !llvm.linker.options = !{![[msvcrt:[0-9]+]]}
-// LINUX: ![[msvcrt]] = !{!"-lmsvcrt"}
+// LINUX: !llvm.dependent-libraries = !{![[msvcrt:[0-9]+]]}
+// LINUX: ![[msvcrt]] = !{!"msvcrt"}
 
 int f();
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -2348,22 +2348,6 @@
   }
 };
 
-class PS4TargetCodeGenInfo : public X86_64TargetCodeGenInfo {
-public:
-  PS4TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel)
-    : X86_64TargetCodeGenInfo(CGT, AVXLevel) {}
-
-  void getDependentLibraryOption(llvm::StringRef Lib,
-                                 llvm::SmallString<24> &Opt) const override {
-    Opt = "\01";
-    // If the argument contains a space, enclose it in quotes.
-    if (Lib.find(" ") != StringRef::npos)
-      Opt += "\"" + Lib.str() + "\"";
-    else
-      Opt += Lib;
-  }
-};
-
 static std::string qualifyWindowsLibrary(llvm::StringRef Lib) {
   // If the argument does not end in .lib, automatically add the suffix.
   // If the argument contains a space, enclose it in quotes.
@@ -9492,8 +9476,6 @@
     switch (Triple.getOS()) {
     case llvm::Triple::Win32:
       return SetCGInfo(new WinX86_64TargetCodeGenInfo(Types, AVXLevel));
-    case llvm::Triple::PS4:
-      return SetCGInfo(new PS4TargetCodeGenInfo(Types, AVXLevel));
     default:
       return SetCGInfo(new X86_64TargetCodeGenInfo(Types, AVXLevel));
     }
Index: clang/lib/CodeGen/CodeGenModule.h
===================================================================
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -465,9 +465,12 @@
   /// have been emitted.
   llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers;
 
-  /// A vector of metadata strings.
+  /// A vector of metadata strings for linker options.
   SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata;
 
+  /// A vector of metadata strings for dependent libraries for ELF.
+  SmallVector<llvm::MDNode *, 16> ELFDependentLibraries;
+
   /// @name Cache for Objective-C runtime types
   /// @{
 
@@ -1152,11 +1155,9 @@
   /// Appends a detect mismatch command to the linker options.
   void AddDetectMismatch(StringRef Name, StringRef Value);
 
-  /// Appends a dependent lib to the "llvm.linker.options" metadata
-  /// value.
+  /// Appends a dependent lib to the appropriate metadata value.
   void AddDependentLib(StringRef Lib);
 
-  void AddELFLibDirective(StringRef Lib);
 
   llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD);
 
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -445,6 +445,19 @@
     EmitModuleLinkOptions();
   }
 
+  // On ELF we pass the dependent library specifiers directly to the linker
+  // without manipulating them. This is in contrast to other platforms where
+  // they are mapped to a specific linker option by the compiler. This
+  // difference is a result of the greater variety of ELF linkers and the fact
+  // that ELF linkers tend to handle libraries in a more complicated fashion
+  // than on other platforms. This forces us to defer handling the dependent
+  // libs to the linker.
+  if (!ELFDependentLibraries.empty()) {
+    auto *NMD = getModule().getOrInsertNamedMetadata("llvm.dependent-libraries");
+    for (auto *MD : ELFDependentLibraries)
+      NMD->addOperand(MD);
+  }
+
   // Record mregparm value now so it is visible through rest of codegen.
   if (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
     getModule().addModuleFlag(llvm::Module::Error, "NumRegisterParameters",
@@ -1690,17 +1703,18 @@
   LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
 }
 
-void CodeGenModule::AddELFLibDirective(StringRef Lib) {
-  auto &C = getLLVMContext();
-  LinkerOptionsMetadata.push_back(llvm::MDNode::get(
-      C, {llvm::MDString::get(C, "lib"), llvm::MDString::get(C, Lib)}));
-}
-
 void CodeGenModule::AddDependentLib(StringRef Lib) {
+  auto &C = getLLVMContext();
+  if (getTarget().getTriple().isOSBinFormatELF()) {
+      ELFDependentLibraries.push_back(
+        llvm::MDNode::get(C, llvm::MDString::get(C, Lib)));
+    return;
+  }
+
   llvm::SmallString<24> Opt;
   getTargetCodeGenInfo().getDependentLibraryOption(Lib, Opt);
   auto *MDOpts = llvm::MDString::get(getLLVMContext(), Opt);
-  LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
+  LinkerOptionsMetadata.push_back(llvm::MDNode::get(C, MDOpts));
 }
 
 /// Add link options implied by the given module, including modules
@@ -1723,7 +1737,6 @@
   // described by this module.
   llvm::LLVMContext &Context = CGM.getLLVMContext();
   bool IsELF = CGM.getTarget().getTriple().isOSBinFormatELF();
-  bool IsPS4 = CGM.getTarget().getTriple().isPS4();
 
   // For modules that use export_as for linking, use that module
   // name instead.
@@ -1743,7 +1756,7 @@
     }
 
     // Link against a library.
-    if (IsELF && !IsPS4) {
+    if (IsELF) {
       llvm::Metadata *Args[2] = {
           llvm::MDString::get(Context, "lib"),
           llvm::MDString::get(Context, Mod->LinkLibraries[I - 1].Library),
@@ -4973,10 +4986,6 @@
       AppendLinkerOptions(PCD->getArg());
       break;
     case PCK_Lib:
-      if (getTarget().getTriple().isOSBinFormatELF() &&
-          !getTarget().getTriple().isPS4())
-        AddELFLibDirective(PCD->getArg());
-      else
         AddDependentLib(PCD->getArg());
       break;
     case PCK_Compiler:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to