On Tue, Jan 17, 2012 at 9:23 AM, Carmelo AMOROSO <[email protected]> wrote: > Defer removal of the local scope of a dl-opened library after > all the destructors (of itself and related dependencies) are actually > get unloaded, otherwise any function registered via atexit() > won't be resolved.
this patch works nicely. I so far tried it on x86 but I will test other arches soon but the patch is good to go in with testcase added as Mike pointed > > Signed-off-by: Khem Raj <[email protected]> > Signed-off-by: Filippo Arcidiacono <[email protected]> > Signed-off-by: Carmelo Amoroso <[email protected]> > --- > ldso/libdl/libdl.c | 33 +++++++++++++++++++++------------ > 1 files changed, 21 insertions(+), 12 deletions(-) > > diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c > index bc3ef8a..da3c405 100644 > --- a/ldso/libdl/libdl.c > +++ b/ldso/libdl/libdl.c > @@ -780,7 +780,9 @@ static int do_dlclose(void *vhandle, int need_fini) > struct dyn_elf *handle; > unsigned int end = 0, start = 0xffffffff; > unsigned int i, j; > - struct r_scope_elem *ls; > + struct r_scope_elem *ls, *ls_next = NULL; > + struct elf_resolve **handle_rlist; > + > #if defined(USE_TLS) && USE_TLS > bool any_tls = false; > size_t tls_free_start = NO_TLS_OFFSET; > @@ -813,6 +815,19 @@ static int do_dlclose(void *vhandle, int need_fini) > free(handle); > return 0; > } > + > + /* Store the handle's local scope array for later removal */ > + handle_rlist = handle->dyn->symbol_scope.r_list; > + > + /* Store references to the local scope entries for later removal */ > + for (ls = &_dl_loaded_modules->symbol_scope; ls && ls->next; ls = > ls->next) > + if (ls->next->r_list[0] == handle->dyn) { > + break; > + } > + /* ls points to the previous local symbol scope */ > + if(ls && ls->next) > + ls_next = ls->next->next; > + > /* OK, this is a valid handle - now close out the file */ > for (j = 0; j < handle->init_fini.nlist; ++j) { > tpnt = handle->init_fini.init_fini[j]; > @@ -974,16 +989,6 @@ static int do_dlclose(void *vhandle, int need_fini) > } > } > > - if (handle->dyn == tpnt) { > - /* Unlink the local scope from global one */ > - for (ls = &_dl_loaded_modules->symbol_scope; > ls; ls = ls->next) > - if (ls->next->r_list[0] == tpnt) { > - _dl_if_debug_print("removing > symbol_scope: %s\n", tpnt->libname); > - break; > - } > - ls->next = ls->next->next; > - } > - > /* Next, remove tpnt from the global symbol table list > */ > if (_dl_symbol_tables) { > if (_dl_symbol_tables->dyn == tpnt) { > @@ -1005,10 +1010,14 @@ static int do_dlclose(void *vhandle, int need_fini) > } > } > free(tpnt->libname); > - free(tpnt->symbol_scope.r_list); > free(tpnt); > } > } > + /* Unlink and release the handle's local scope from global one */ > + if(ls) > + ls->next = ls_next; > + free(handle_rlist); > + > for (rpnt1 = handle->next; rpnt1; rpnt1 = rpnt1_tmp) { > rpnt1_tmp = rpnt1->next; > free(rpnt1); > -- > 1.7.4.4 > _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
