dlsym call fails
Kevin Cernekee
cernekee at gmail.com
Fri Jul 22 01:36:57 UTC 2011
On Thu, Jul 21, 2011 at 2:52 AM, manish kumar <deliver2manish at gmail.com> wrote:
> if(!libc_malloc)
> libc_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc"); dlerror();
You probably want braces here, but that is not a likely cause of the
reported problem.
I have seen cases where uClibc dlsym(RTLD_NEXT, ...) will find an
undefined symbol and return an unusable pointer. I suspect that this
is not the behavior intended by the authors. For example, on an
application linked with these libraries:
$ readelf -s libuClibc-0.9.32.so | grep -E "\<malloc\>"
1225: 00036c90 2488 FUNC GLOBAL DEFAULT 7 malloc
$ readelf -s libfoo.so | grep malloc
74: 00003140 0 FUNC GLOBAL DEFAULT UND malloc
dlsym(RTLD_NEXT, ...) might find the libfoo entry instead of the
libuClibc entry. The returned pointer will not really reach malloc().
I noticed that when dlsym() calls _dl_find_hash(), it uses type_class
0. If it used type_class ELF_RTYPE_CLASS_DLSYM that would make more
sense to me (although it would not fix this problem), because nobody
else seems to pass in ELF_RTYPE_CLASS_DLSYM. If it used type_class
ELF_RTYPE_CLASS_PLT I do suspect it would fix your problem, but it
might break other things like data references. check_match() will not
match an undefined symbol, as long as (type_class & 1) == 1.
Would it be safe to pass in a bitmask of the desired types? ala:
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 52c77b0..e256f86 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -667,7 +667,7 @@ void *dlsym(void *vhandle, const char *name)
tpnt = NULL;
if (handle == _dl_symbol_tables)
tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if
global object */
- ret = _dl_find_hash(name2, handle, tpnt, 0, &sym_ref);
+ ret = _dl_find_hash(name2, handle, tpnt, ELF_RTYPE_CLASS_PLT |
ELF_RTYPE_CLASS_COPY, &sym_ref);
#if defined(USE_TLS) && USE_TLS && defined SHARED
if (sym_ref.tpnt) {
More information about the uClibc
mailing list