Index: lld/ELF/InputFiles.cpp
--- lld/ELF/InputFiles.cpp.orig
+++ lld/ELF/InputFiles.cpp
@@ -47,6 +47,8 @@ extern template void ObjFile<ELF32BE>::importCmseSymbo
 extern template void ObjFile<ELF64LE>::importCmseSymbols();
 extern template void ObjFile<ELF64BE>::importCmseSymbols();
 
+DenseMap<StringRef, StringRef> elf::gnuWarnings;
+
 // Returns "<internal>", "foo.a(bar.o)" or "baz.o".
 std::string elf::toStr(Ctx &ctx, const InputFile *f) {
   static std::mutex mu;
@@ -70,6 +72,19 @@ const ELFSyncStream &elf::operator<<(const ELFSyncStre
   return s << toStr(s.ctx, f);
 }
 
+// .gnu.warning.SYMBOL are treated as warning symbols for the given symbol
+void InputFile::parseGNUWarning(Ctx &ctx, StringRef name, ArrayRef<char> data, size_t size) {
+  static std::mutex mu;
+  if (!name.empty() && name.starts_with(".gnu.warning.")) {
+    std::lock_guard<std::mutex> lock(mu);
+    StringRef wsym = name.substr(13);
+    StringRef s(data.begin());
+    StringRef wng(s.substr(0, size));
+    ctx.symtab->insert(wsym)->gwarn = true;
+    gnuWarnings.insert({wsym, wng});
+  }
+}
+
 static ELFKind getELFKind(Ctx &ctx, MemoryBufferRef mb, StringRef archiveName) {
   unsigned char size;
   unsigned char endian;
@@ -859,6 +874,12 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComd
     case SHT_PREINIT_ARRAY:
       this->sections[i] =
           createInputSection(i, sec, check(obj.getSectionName(sec, shstrtab)));
+      if (type == SHT_PROGBITS) {
+        StringRef name = check(obj.getSectionName(sec, shstrtab));
+        ArrayRef<char> data =
+            CHECK2(obj.template getSectionContentsAsArray<char>(sec), this);
+	parseGNUWarning(ctx, name, data, sec.sh_size);
+      }
       break;
     case SHT_LLVM_LTO:
       // Discard .llvm.lto in a relocatable link that does not use the bitcode.
@@ -1192,7 +1213,20 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(ui
 
 // Initialize symbols. symbols is a parallel array to the corresponding ELF
 // symbol table.
+//
+// LLVM's SPARC assembler and OpenBSD ld.so do not implement application
+// register metadata. Accept GCC scratch declarations, but keep them out of
+// ordinary symbol resolution.
 template <class ELFT>
+static bool isSparcRegister(const Ctx &ctx, const typename ELFT::Sym &sym) {
+  return ctx.arg.emachine == EM_SPARCV9 && sym.getType() == STT_SPARC_REGISTER;
+}
+
+static bool isSparcScratchRegister(uint64_t value) {
+  return value == 2 || value == 3 || value == 6 || value == 7;
+}
+
+template <class ELFT>
 void ObjFile<ELFT>::initializeSymbols(const object::ELFFile<ELFT> &obj) {
   ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();
   if (!symbols)
@@ -1200,14 +1234,25 @@ void ObjFile<ELFT>::initializeSymbols(const object::EL
 
   // Some entries have been filled by LazyObjFile.
   auto *symtab = ctx.symtab.get();
-  for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i)
-    if (!symbols[i])
-      symbols[i] = symtab->insert(CHECK2(eSyms[i].getName(stringTable), this));
+  for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {
+    const Elf_Sym &eSym = eSyms[i];
+    if (isSparcRegister<ELFT>(ctx, eSym)) {
+      StringRef name = CHECK2(eSym.getName(stringTable), this);
+      if (eSym.getBinding() != STB_GLOBAL || eSym.st_shndx != SHN_UNDEF ||
+          !name.empty() || !isSparcScratchRegister(eSym.st_value))
+        Err(ctx) << this << ": unsupported SPARC register declaration";
+      symbols[i] = ctx.dummySym;
+    } else if (!symbols[i]) {
+      symbols[i] = symtab->insert(CHECK2(eSym.getName(stringTable), this));
+    }
+  }
 
   // Perform symbol resolution on non-local symbols.
   SmallVector<unsigned, 32> undefineds;
   for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {
     const Elf_Sym &eSym = eSyms[i];
+    if (isSparcRegister<ELFT>(ctx, eSym))
+      continue;
     uint32_t secIdx = eSym.st_shndx;
     if (secIdx == SHN_UNDEF) {
       undefineds.push_back(i);
@@ -1307,6 +1352,8 @@ template <class ELFT> void ObjFile<ELFT>::postParse() 
   ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();
   for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {
     const Elf_Sym &eSym = eSyms[i];
+    if (isSparcRegister<ELFT>(ctx, eSym))
+      continue;
     Symbol &sym = *symbols[i];
     uint32_t secIdx = eSym.st_shndx;
     uint8_t binding = eSym.getBinding();
@@ -1565,6 +1612,9 @@ template <class ELFT> void SharedFile::parse() {
   const ELFFile<ELFT> obj = this->getObj<ELFT>();
   ArrayRef<Elf_Shdr> sections = getELFShdrs<ELFT>();
 
+  StringRef sectionStringTable =
+      CHECK2(obj.getSectionStringTable(sections), this);
+
   const Elf_Shdr *versymSec = nullptr;
   const Elf_Shdr *verdefSec = nullptr;
   const Elf_Shdr *verneedSec = nullptr;
@@ -1588,7 +1638,14 @@ template <class ELFT> void SharedFile::parse() {
     case SHT_GNU_verneed:
       verneedSec = &sec;
       break;
+    case SHT_PROGBITS: {
+      StringRef name = CHECK2(obj.getSectionName(sec, sectionStringTable), this);
+      ArrayRef<char> data =
+          CHECK2(obj.template getSectionContentsAsArray<char>(sec), this);
+      parseGNUWarning(ctx, name, data, sec.sh_size);
+      break;
     }
+    }
   }
 
   if (versymSec && numSymbols == 0) {
@@ -1659,6 +1716,9 @@ template <class ELFT> void SharedFile::parse() {
   ArrayRef<Elf_Sym> syms = this->getGlobalELFSyms<ELFT>();
   for (size_t i = 0, e = syms.size(); i != e; ++i) {
     const Elf_Sym &sym = syms[i];
+    // A SPARC register declaration is DSO metadata, not a symbol dependency.
+    if (isSparcRegister<ELFT>(ctx, sym))
+      continue;
 
     // ELF spec requires that all local symbols precede weak or global
     // symbols in each symbol table, and the index of first non-local symbol
