diff options
Diffstat (limited to 'main/libc0.9.32/libdl.patch')
-rw-r--r-- | main/libc0.9.32/libdl.patch | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/main/libc0.9.32/libdl.patch b/main/libc0.9.32/libdl.patch new file mode 100644 index 0000000000..f8a90ffa16 --- /dev/null +++ b/main/libc0.9.32/libdl.patch @@ -0,0 +1,26 @@ +diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c +index 95a0650..3cfcb85 100644 +--- a/ldso/libdl/libdl.c ++++ b/ldso/libdl/libdl.c +@@ -544,8 +544,18 @@ static void *do_dlopen(const char *libname, int flag) + * to the GOT tables. We need to do this in reverse order so that COPY + * directives work correctly */ + +- /* Get the tail of the list */ +- for (ls = &_dl_loaded_modules->symbol_scope; ls && ls->next; ls = ls->next); ++ /* Extend the global scope by adding the local scope of the dlopened DSO. ++ * But only if it's not there. It can happen under certain cases that the ++ * DSO had refcount = 0, but was already loaded. (NODELETE flag is set, or ++ * it is pulled in via both NEEDED dependency and explicit dlopen()). */ ++ for (ls = &_dl_loaded_modules->symbol_scope; ; ls = ls->next) { ++ if (ls == &dyn_chain->dyn->symbol_scope) ++ break; ++ if (ls->next == NULL) { ++ ls->next = &dyn_chain->dyn->symbol_scope; ++ break; ++ } ++ } + + /* Extend the global scope by adding the local scope of the dlopened DSO. */ + ls->next = &dyn_chain->dyn->symbol_scope; + |