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);