summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libdl/dlclose.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/libdl/dlclose.c')
-rw-r--r--mdk-stage1/dietlibc/libdl/dlclose.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/mdk-stage1/dietlibc/libdl/dlclose.c b/mdk-stage1/dietlibc/libdl/dlclose.c
index 384550c47..6fafedcf5 100644
--- a/mdk-stage1/dietlibc/libdl/dlclose.c
+++ b/mdk-stage1/dietlibc/libdl/dlclose.c
@@ -1,14 +1,38 @@
+#include <sys/mman.h>
+
#include "_dl_int.h"
-int dlclose (void *handle)
-{
- if (handle) {
- struct _dl_handle *h = handle;
- if (h->lnk_count) {
- --h->lnk_count;
- return -1;
+static void dec_referenced_libs(struct _dl_handle*dh) {
+ Elf_Dyn* dyn_tab=dh->dynamic;
+ int i;
+ for(i=0;dyn_tab[i].d_tag;i++) {
+ if (dyn_tab[i].d_tag==DT_NEEDED) {
+ char *lib_name=dh->dyn_str_tab+dyn_tab[i].d_un.d_val;
+#ifdef DEBUG
+ pf(__FUNCTION__); pf(": lib: "); pf(lib_name); pf("\n");
+#endif
+ dlclose(_dl_find_lib(lib_name));
}
- if (munmap(h->mem_base,h->mem_size)!=0) return -1;
+ }
+}
+
+int dlclose(void*handle) {
+ _dl_error_location="dlclose";
+ if (handle) {
+ struct _dl_handle*dh=handle;
+ if (--(dh->lnk_count)) return 0; /* not yet unreferenced */
+
+#ifdef DEBUG
+ pf(__FUNCTION__); pf(": "); pf(dh->name); pf("\n");
+#endif
+ if (dh->fini) dh->fini();
+ dec_referenced_libs(dh);
+#ifdef __DIET_LD_SO__
+ if (_dl_sys_munmap(dh->mem_base,dh->mem_size)<0) return -1;
+#else
+ if (munmap(dh->mem_base,dh->mem_size)==-1) return -1;
+#endif
+ _dl_free_handle(handle);
}
return 0;
}