Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
ld.so not calling destructor
To:
tech@openbsd.org
Cc:
Philip Guenther <guenther@openbsd.org>
Date:
Fri, 20 Dec 2024 16:36:19 +0100

Download raw body.

Thread
Hi,

The test suite of my new devel/llvm-openmp port fails as ld.so does
not call the destructor.  OpenMP registers it like this.

__attribute__((destructor)) void __kmp_internal_end_dtor(void) {
  __kmp_internal_end_atexit();
}

Debugging in ld.so shows that the library refcount is never decremented
and so the callback is never invoked.  Diff below fixes the issue.

I this approach correct?

bluhm

Index: libexec/ld.so/library_subr.c
===================================================================
RCS file: /mount/openbsd/cvs/src/libexec/ld.so/library_subr.c,v
diff -u -p -r1.55 library_subr.c
--- libexec/ld.so/library_subr.c	27 Apr 2023 12:27:56 -0000	1.55
+++ libexec/ld.so/library_subr.c	6 Dec 2024 20:28:11 -0000
@@ -533,6 +533,17 @@ _dl_link_child(elf_object_t *dep, elf_ob
 }
 
 void
+_dl_unlink_children(void)
+{
+	elf_object_t *node;
+
+	for (node = _dl_objects; node != NULL; node = node->next) {
+		if (node->refcount > 0)
+			_dl_child_refcnt_decrement(node);
+	}
+}
+
+void
 object_vec_grow(struct object_vector *vec, int more)
 {
 	vec->alloc += more;
Index: libexec/ld.so/loader.c
===================================================================
RCS file: /mount/openbsd/cvs/src/libexec/ld.so/loader.c,v
diff -u -p -r1.223 loader.c
--- libexec/ld.so/loader.c	22 Jan 2024 02:08:31 -0000	1.223
+++ libexec/ld.so/loader.c	6 Dec 2024 20:25:07 -0000
@@ -202,6 +202,7 @@ _dl_dtors(void)
 
 	/* ORDER? */
 	_dl_unload_dlopen();
+	_dl_unlink_children();
 
 	DL_DEB(("doing dtors\n"));
 
Index: libexec/ld.so/resolve.h
===================================================================
RCS file: /mount/openbsd/cvs/src/libexec/ld.so/resolve.h,v
diff -u -p -r1.108 resolve.h
--- libexec/ld.so/resolve.h	21 May 2024 05:00:47 -0000	1.108
+++ libexec/ld.so/resolve.h	6 Dec 2024 20:23:31 -0000
@@ -318,6 +318,7 @@ int _dl_load_dep_libs(elf_object_t *obje
 int _dl_rtld(elf_object_t *object);
 void _dl_call_init(elf_object_t *object);
 void _dl_link_child(elf_object_t *dep, elf_object_t *p);
+void _dl_unlink_children(void);
 void _dl_link_grpsym(elf_object_t *object);
 void _dl_cache_grpsym_list_setup(elf_object_t *_object);
 void _dl_link_grpref(elf_object_t *load_group, elf_object_t *load_object);