summaryrefslogtreecommitdiff
path: root/ldso/libdl/libdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/libdl/libdl.c')
-rw-r--r--ldso/libdl/libdl.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index f2303c52e..e4a49c83a 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -446,7 +446,22 @@ void *dlsym(void *vhandle, const char *name)
ElfW(Addr) from;
struct dyn_elf *rpnt;
void *ret;
-
+ /* Nastiness to support underscore prefixes. */
+ char tmp_buf[80];
+#ifndef __UCLIBC_NO_UNDERSCORES__
+ char *name2 = tmp_buf;
+ size_t nlen = strlen (name) + 1;
+ if (nlen + 1 > sizeof (tmp_buf))
+ name2 = malloc (nlen + 1);
+ if (name2 == 0) {
+ _dl_error_number = LD_ERROR_MMAP_FAILED;
+ return 0;
+ }
+ name2[0] = '_';
+ memcpy (name2 + 1, name, nlen);
+#else
+ const char *name2 = name;
+#endif
handle = (struct dyn_elf *) vhandle;
/* First of all verify that we have a real handle
@@ -460,7 +475,8 @@ void *dlsym(void *vhandle, const char *name)
break;
if (!rpnt) {
_dl_error_number = LD_BAD_HANDLE;
- return NULL;
+ ret = NULL;
+ goto out;
}
} else if (handle == RTLD_NEXT) {
/*
@@ -484,13 +500,18 @@ 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((char*)name, handle, tpnt, 0);
+ ret = _dl_find_hash(name2, handle, tpnt, 0);
/*
* Nothing found.
*/
if (!ret)
_dl_error_number = LD_NO_SYMBOL;
+out:
+#ifndef __UCLIBC_NO_UNDERSCORES__
+ if (name2 != tmp_buf)
+ free (name2);
+#endif
return ret;
}