Hi,

There's an old bug in ld.so preventing sdl2 to be ported to openbsd.
Lately I had time to play with it and continued the work of Henri
Kemppainen.  I think I managed to fix the issue.  I tested the patch
with amd64 and i386 builds.  Could someone please have a look at it?

It introduces some more code duplication that I will deal with
providing my diff is ok.

You can use the following repo to reproduce the bug.
https://github.com/peterhajdu/ld_openbsd_bug

Thank you very much in advance,
Peter Hajdu

Index: dlfcn.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/dlfcn.c,v
retrieving revision 1.91
diff -u -p -r1.91 dlfcn.c
--- dlfcn.c     19 Sep 2015 20:56:47 -0000      1.91
+++ dlfcn.c     21 Oct 2015 13:52:46 -0000
@@ -302,7 +302,7 @@ _dl_real_close(void *handle)
        object->opencount--;
        _dl_notify_unload_shlib(object);
        _dl_run_all_dtors();
-       _dl_unload_shlib(object);
+       _dl_unload_unused();
        _dl_cleanup_objects();
        return (0);
 }
Index: library.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/library.c,v
retrieving revision 1.71
diff -u -p -r1.71 library.c
--- library.c   16 Jan 2015 16:18:07 -0000      1.71
+++ library.c   21 Oct 2015 13:52:46 -0000
@@ -74,6 +74,22 @@ _dl_unload_shlib(elf_object_t *object)
        }
 }
 
+void
+_dl_unload_unused(void)
+{
+       elf_object_t *obj, *next;
+
+       for (obj = _dl_objects->next; obj != NULL; obj = next) {
+               next = obj->next;
+               if (OBJECT_REF_CNT(obj) != 0 || obj->status & STAT_UNLOADED)
+                       continue;
+               obj->status |= STAT_UNLOADED;
+               _dl_load_list_free(obj->load_list);
+               _dl_munmap((void *)obj->load_base, obj->load_size);
+               _dl_remove_object(obj);
+       }
+}
+
 elf_object_t *
 _dl_tryload_shlib(const char *libname, int type, int flags)
 {
Index: library_mquery.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/library_mquery.c,v
retrieving revision 1.49
diff -u -p -r1.49 library_mquery.c
--- library_mquery.c    22 Jan 2015 05:48:17 -0000      1.49
+++ library_mquery.c    21 Oct 2015 13:52:46 -0000
@@ -79,6 +79,20 @@ _dl_unload_shlib(elf_object_t *object)
        }
 }
 
+void
+_dl_unload_unused(void)
+{
+       elf_object_t *obj, *next;
+
+       for (obj = _dl_objects->next; obj != NULL; obj = next) {
+               next = obj->next;
+               if (OBJECT_REF_CNT(obj) != 0 || obj->status & STAT_UNLOADED)
+                       continue;
+               obj->status |= STAT_UNLOADED;
+               _dl_load_list_free(obj->load_list);
+               _dl_remove_object(obj);
+       }
+}
 
 elf_object_t *
 _dl_tryload_shlib(const char *libname, int type, int flags)
Index: resolve.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/resolve.h,v
retrieving revision 1.73
diff -u -p -r1.73 resolve.h
--- resolve.h   19 Sep 2015 20:56:47 -0000      1.73
+++ resolve.h   21 Oct 2015 13:52:46 -0000
@@ -223,6 +223,7 @@ void _dl_unlink_dlopen(elf_object_t *dep
 void _dl_notify_unload_shlib(elf_object_t *object);
 void _dl_unload_shlib(elf_object_t *object);
 void _dl_unload_dlopen(void);
+void _dl_unload_unused(void);
 
 void _dl_run_all_dtors(void);
 

Reply via email to