$OpenBSD: patch-lld_ELF_DriverUtils_cpp,v 1.1.1.1 2021/02/28 15:32:17 semarie Exp $

Index: lld/ELF/DriverUtils.cpp
--- lld/ELF/DriverUtils.cpp.orig
+++ lld/ELF/DriverUtils.cpp
@@ -227,9 +227,36 @@ Optional<std::string> elf::findFromSearchPaths(StringR
 // search paths.
 Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
   for (StringRef dir : config->searchPaths) {
-    if (!config->isStatic)
-      if (Optional<std::string> s = findFile(dir, "lib" + name + ".so"))
-        return s;
+      if (!config->isStatic) {
+	  if (Optional<std::string> s = findFile(dir, "lib" + name + ".so"))
+	      return s;
+
+	  // Handle OpenBSD-style maj/min shlib scheme
+	  llvm::SmallString<128> Scratch;
+	  const StringRef LibName = ("lib" + name + ".so.").toStringRef(Scratch);
+	  int MaxMaj = -1, MaxMin = -1;
+	  std::error_code EC;
+	  for (fs::directory_iterator LI(dir, EC), LE;
+	       LI != LE; LI = LI.increment(EC)) {
+	      StringRef FilePath = LI->path();
+	      StringRef FileName = path::filename(FilePath);
+	      if (!(FileName.startswith(LibName)))
+		  continue;
+	      std::pair<StringRef, StringRef> MajMin =
+		  FileName.substr(LibName.size()).split('.');
+	              int Maj, Min;
+	              if (MajMin.first.getAsInteger(10, Maj) || Maj < 0)
+			  continue;
+		      if (MajMin.second.getAsInteger(10, Min) || Min < 0)
+			  continue;
+		      if (Maj > MaxMaj)
+			  MaxMaj = Maj, MaxMin = Min;
+		      if (MaxMaj == Maj && Min > MaxMin)
+			  MaxMin = Min;
+	  }
+	  if (MaxMaj >= 0)
+	      return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin));
+      }
     if (Optional<std::string> s = findFile(dir, "lib" + name + ".a"))
       return s;
   }
