diff options
Diffstat (limited to 'meta/recipes-core/uclibc/uclibc-git/fix_libdl.patch')
-rw-r--r-- | meta/recipes-core/uclibc/uclibc-git/fix_libdl.patch | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/meta/recipes-core/uclibc/uclibc-git/fix_libdl.patch b/meta/recipes-core/uclibc/uclibc-git/fix_libdl.patch new file mode 100644 index 0000000000..16e48b1bca --- /dev/null +++ b/meta/recipes-core/uclibc/uclibc-git/fix_libdl.patch @@ -0,0 +1,83 @@ +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. + +Signed-off-by: Khem Raj <raj.khem at gmail.com> +Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono at st.com> +Signed-off-by: Carmelo Amoroso <carmelo.amoroso at st.com> +--- + ldso/libdl/libdl.c | 33 +++++++++++++++++++++------------ + 1 files changed, 21 insertions(+), 12 deletions(-) + + +Upstream-Status: Pending + +Index: git/ldso/libdl/libdl.c +=================================================================== +--- git.orig/ldso/libdl/libdl.c 2012-01-17 17:38:44.930821794 -0800 ++++ git/ldso/libdl/libdl.c 2012-01-17 17:39:02.754822656 -0800 +@@ -780,7 +780,9 @@ + 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 @@ + 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 @@ + } + } + +- 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 @@ + } + } + 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); |