$OpenBSD: patch-nspr_pr_src_linking_prlink_c,v 1.6 2020/09/21 13:50:18 landry Exp $
If dlopen() fails, retry with everything stripped after .so
https://bugzilla.mozilla.org/show_bug.cgi?id=650772
Index: nspr/pr/src/linking/prlink.c
--- nspr/pr/src/linking/prlink.c.orig
+++ nspr/pr/src/linking/prlink.c
@@ -7,6 +7,10 @@
 
 #include <string.h>
 
+#if defined(OPENBSD)
+#include <limits.h> /* for PATH_MAX */
+#endif
+
 #ifdef XP_UNIX
 #ifdef USE_DLFCN
 #include <dlfcn.h>
@@ -531,6 +535,10 @@ pr_LoadLibraryByPathname(const char *name, PRIntn flag
 #else
         int dl_flags = 0;
 #endif
+#if defined(OPENBSD)
+    char sname[PATH_MAX];
+    char *c;
+#endif
         void *h = NULL;
 #if defined(DARWIN)
         PRBool okToLoad = PR_FALSE;
@@ -582,7 +590,18 @@ pr_LoadLibraryByPathname(const char *name, PRIntn flag
         }
 #else
         h = dlopen(name, dl_flags);
+#if defined(OPENBSD)
+    /* On OpenBSD, we don't know what can be major.minor in libfoo.so.major.minor */
+    /* but ld.so is smart enough to open the correct lib when asked for libfoo.so */
+    /* so if the previous dlopen() failed, let's strip what's after .so and retry */
+    strncpy(sname, name, PATH_MAX);
+    if (!h) {
+        if ((c = strstr(sname,".so")) != NULL)
+            c[3] = '\0';
+        h = dlopen(sname, dl_flags);
+    }
 #endif
+#endif
 #elif defined(USE_HPSHL)
         int shl_flags = 0;
         shl_t h;
@@ -611,7 +630,11 @@ pr_LoadLibraryByPathname(const char *name, PRIntn flag
             PR_DELETE(lm);
             goto unlock;
         }
+#if defined(OPENBSD)
+        lm->name = strdup(sname);
+#else
         lm->name = strdup(name);
+#endif
         lm->dlh = h;
         lm->next = pr_loadmap;
         pr_loadmap = lm;
