summaryrefslogtreecommitdiffstats
path: root/package/uclibc/0.9.33.2/0028-dl-fix-dlsym-lookups-with-RTLD_NEXT.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/uclibc/0.9.33.2/0028-dl-fix-dlsym-lookups-with-RTLD_NEXT.patch')
-rw-r--r--package/uclibc/0.9.33.2/0028-dl-fix-dlsym-lookups-with-RTLD_NEXT.patch57
1 files changed, 57 insertions, 0 deletions
diff --git a/package/uclibc/0.9.33.2/0028-dl-fix-dlsym-lookups-with-RTLD_NEXT.patch b/package/uclibc/0.9.33.2/0028-dl-fix-dlsym-lookups-with-RTLD_NEXT.patch
new file mode 100644
index 0000000000..374136757c
--- /dev/null
+++ b/package/uclibc/0.9.33.2/0028-dl-fix-dlsym-lookups-with-RTLD_NEXT.patch
@@ -0,0 +1,57 @@
+From f5108ce0c0f72a285e4cb198426e477295c84517 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Tue, 8 Jan 2013 11:55:26 +0200
+Subject: [PATCH] dl: fix dlsym lookups with RTLD_NEXT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The current code for dlsym() when invoked with RTLD_NEXT lookup
+searches for the module where it's being called from, and executes the
+_dl_find_hash only for the next module in the chain. However, if the
+looked symbol is not there, the rest of the modules are not checked.
+
+Generally this is not a problem as symbols are merged for the parent
+modules; so this affects only RTLD_NEXT.
+
+This patch adds a loop iterating through all the following modules.
+
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+Reviewed-by: Filippo ARCIDIACONO <filippo.arcidiacono@st.com>
+Tested-by: Florian Fainelli <florian@openwrt.org>
+Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
+---
+ ldso/libdl/libdl.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
+index 51bcf7d..71ade1f 100644
+--- a/ldso/libdl/libdl.c
++++ b/ldso/libdl/libdl.c
+@@ -671,7 +671,7 @@ static void *do_dlsym(void *vhandle, const char *name, void *caller_address)
+ {
+ struct elf_resolve *tpnt, *tfrom;
+ struct dyn_elf *handle;
+- ElfW(Addr) from;
++ ElfW(Addr) from = 0;
+ struct dyn_elf *rpnt;
+ void *ret;
+ struct symbol_ref sym_ref = { NULL, NULL };
+@@ -729,7 +729,13 @@ static void *do_dlsym(void *vhandle, const char *name, void *caller_address)
+ tpnt = NULL;
+ if (handle == _dl_symbol_tables)
+ tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */
+- ret = _dl_find_hash(name2, &handle->dyn->symbol_scope, tpnt, ELF_RTYPE_CLASS_DLSYM, &sym_ref);
++
++ do {
++ ret = _dl_find_hash(name2, &handle->dyn->symbol_scope, tpnt, ELF_RTYPE_CLASS_DLSYM, &sym_ref);
++ if (ret != NULL)
++ break;
++ handle = handle->next;
++ } while (from && handle);
+
+ #if defined(USE_TLS) && USE_TLS && defined SHARED
+ if (sym_ref.sym && (ELF_ST_TYPE(sym_ref.sym->st_info) == STT_TLS) && (sym_ref.tpnt)) {
+--
+1.7.10.4
+
OpenPOWER on IntegriCloud