$OpenBSD: patch-boehm-gc_dyn_load_c,v 1.1 2002/06/09 00:35:38 espie Exp $
--- boehm-gc/dyn_load.c.orig	Mon Jun  3 21:27:26 2002
+++ boehm-gc/dyn_load.c	Mon Jun  3 21:37:23 2002
@@ -57,7 +57,9 @@
     !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
     !defined(RS6000) && !defined(SCO_ELF) && \
     !(defined(FREEBSD) && defined(__ELF__)) && \
-    !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD)
+    !(defined(NETBSD) && defined(__ELF__)) && \
+    !(defined(OPENBSD)) && \
+    !defined(HURD)
  --> We only know how to find data segments of dynamic libraries for the
  --> above.  Additional SVR4 variants might not be too
  --> hard to add.
@@ -81,7 +83,9 @@
 
 #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
     (defined(FREEBSD) && defined(__ELF__)) || \
-    (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
+    (defined(NETBSD) && defined(__ELF__)) || \
+    (defined(OPENBSD) && defined(__ELF__) || \
+    defined(HURD)
 #   include <stddef.h>
 #   include <elf.h>
 #   include <link.h>
@@ -263,9 +267,86 @@ void GC_register_dynamic_libraries()
 # endif /* !USE_PROC ... */
 # endif /* SUNOS */
 
+#if defined(OPENBSD) && !defined(__ELF__)
+
+#include <link.h>
+
+#ifdef LINT
+    struct _dynamic _DYNAMIC;
+#endif
+
+static struct so_map *
+GC_FirstDLOpenedLinkMap()
+{
+    extern struct _dynamic _DYNAMIC;
+
+    if( &_DYNAMIC == 0) {
+        return(0);
+    }
+    return(_DYNAMIC.d_un.d_dst->sdt_loaded);
+}
+
+
+#if 0
+/* Return the address of the ld.so allocated common symbol	*/
+/* with the least address, or 0 if none.			*/
+static ptr_t GC_first_common()
+{
+    ptr_t result = 0;
+    extern struct _dynamic _DYNAMIC;
+    struct rtc_symb * curr_symbol;
+    
+    if( &_DYNAMIC == 0) {
+        return(0);
+    }
+    curr_symbol = _DYNAMIC.ldd -> ldd_cp;
+    for (; curr_symbol != 0; curr_symbol = curr_symbol -> rtc_next) {
+        if (result == 0
+            || (ptr_t)(curr_symbol -> rtc_sp -> n_value) < result) {
+            result = (ptr_t)(curr_symbol -> rtc_sp -> n_value);
+        }
+    }
+    return(result);
+}
+#endif
+
+void GC_register_dynamic_libraries()
+{
+  struct so_map *lm = GC_FirstDLOpenedLinkMap();
+  
+
+  for (lm = GC_FirstDLOpenedLinkMap();
+       lm != (struct so_map *) 0;  lm = lm->som_next)
+    {
+	struct exec *e;
+	 
+        e = (struct exec *) lm->som_addr;
+        GC_add_roots_inner(
+      		    ((char *) (N_DATOFF(*e) + lm->som_addr)),
+		    ((char *) (N_BSSADDR(*e) + e->a_bss + lm->lm_addr)),
+		    TRUE);
+    }
+#if 0
+      {
+      	static ptr_t common_start = 0;
+      	ptr_t common_end;
+      	extern ptr_t GC_find_limit();
+      	
+      	if (common_start == 0) common_start = GC_first_common();
+      	if (common_start != 0) {
+      	    common_end = GC_find_limit(common_start, TRUE);
+      	    GC_add_roots_inner((char *)common_start, (char *)common_end, TRUE);
+      	}
+      }
+#endif
+}
+#endif
+
 #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
     (defined(FREEBSD) && defined(__ELF__)) || \
-    (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
+    (defined(NETBSD) && defined(__ELF__)) || \
+    (defined(OPENBSD) && defined(__ELF__)) || \
+    defined(HURD)
 
 
 #ifdef USE_PROC_FOR_LIBRARIES
