summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'ldso')
-rw-r--r--ldso/ldso/dl-elf.c201
-rw-r--r--ldso/ldso/ld_string.h17
-rw-r--r--ldso/ldso/readelflib1.c201
-rw-r--r--ldso/ldso/string.h17
4 files changed, 170 insertions, 266 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 75acde927..eed74321d 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -118,6 +118,49 @@ int _dl_unmap_cache(void)
#endif
+/* This function's behavior must exactly match that
+ * in uClibc/ldso/util/ldd.c */
+static struct elf_resolve *
+search_for_named_library(char *name, int secure, const char *path_list)
+{
+ int i, count = 0;
+ char *path, *path_n;
+ char mylibname[2050];
+ struct elf_resolve *tpnt1;
+
+
+ /* We need a writable copy of this string */
+ path = _dl_strdup(path_list);
+ if (!path) {
+ _dl_dprintf(2, "Out of memory!\n");
+ _dl_exit(0);
+ }
+
+
+ /* Unlike ldd.c, don't bother to eliminate double //s */
+
+
+ /* Replace colons with zeros in path_list and count them */
+ for(i=_dl_strlen(path); i > 0; i--) {
+ if (path[i]==':') {
+ path[i]=0;
+ count++;
+ }
+ }
+
+ path_n = path;
+ for (i = 0; i < count; i++) {
+ _dl_strcpy(mylibname, path_n);
+ _dl_strcat(mylibname, "/");
+ _dl_strcat(mylibname, name);
+ if ((tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0)) != NULL)
+ return tpnt1;
+ path_n += (_dl_strlen(path_n) + 1);
+ }
+ return NULL;
+}
+
+
/*
* Used to return error codes back to dlopen et. al.
*/
@@ -128,9 +171,8 @@ unsigned long _dl_internal_error_number;
struct elf_resolve *_dl_load_shared_library(int secure,
struct elf_resolve *tpnt, char *full_libname)
{
- char *pnt, *pnt1, *pnt2;
- struct elf_resolve *tpnt1 = NULL;
- char mylibname[2050];
+ char *pnt;
+ struct elf_resolve *tpnt1;
char *libname;
_dl_internal_error_number = 0;
@@ -160,71 +202,30 @@ struct elf_resolve *_dl_load_shared_library(int secure,
/*
* The ABI specifies that RPATH is searched before LD_*_PATH or
- * the default path of /usr/lib.
- * Check in rpath directories
+ * the default path of /usr/lib. Check in rpath directories.
*/
for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
if (tpnt->libtype == elf_executable) {
- pnt1 = (char *) tpnt->dynamic_info[DT_RPATH];
- if (pnt1) {
- pnt1 += (unsigned long) tpnt->loadaddr +
+ pnt = (char *) tpnt->dynamic_info[DT_RPATH];
+ if (pnt) {
+ pnt += (unsigned long) tpnt->loadaddr +
tpnt->dynamic_info[DT_STRTAB];
- while (*pnt1) {
- pnt2 = mylibname;
- while (*pnt1 && *pnt1 != ':') {
- if (pnt2 - mylibname < 1024)
- *pnt2++ = *pnt1++;
- else
- pnt1++;
- }
- if (pnt2 - mylibname >= 1024)
- break;
- if (pnt2[-1] != '/')
- *pnt2++ = '/';
- pnt = libname;
- while (*pnt)
- *pnt2++ = *pnt++;
- *pnt2++ = 0;
- tpnt1 =
- _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
- if (*pnt1 == ':')
- pnt1++;
+ if ((tpnt1 = search_for_named_library(libname, secure, pnt)) != NULL)
+ {
+ return tpnt1;
}
}
}
}
-
/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
- pnt1 = _dl_library_path;
- if (pnt1 && *pnt1) {
- while (*pnt1) {
- pnt2 = mylibname;
- while (*pnt1 && *pnt1 != ':' && *pnt1 != ';') {
- if (pnt2 - mylibname < 1024)
- *pnt2++ = *pnt1++;
- else
- pnt1++;
- }
- if (pnt2 - mylibname >= 1024)
- break;
- if (pnt2[-1] != '/')
- *pnt2++ = '/';
- pnt = libname;
- while (*pnt)
- *pnt2++ = *pnt++;
- *pnt2++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
- if (*pnt1 == ':' || *pnt1 == ';')
- pnt1++;
- }
+ if (_dl_library_path) {
+ if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path)) != NULL)
+ {
+ return tpnt1;
+ }
}
-
/*
* Where should the cache be searched? There is no such concept in the
* ABI, so we have some flexibility here. For now, search it before
@@ -248,83 +249,19 @@ struct elf_resolve *_dl_load_shared_library(int secure,
}
#endif
- /* Check in <prefix>/usr/lib */
- pnt1 = UCLIBC_TARGET_PREFIX "/usr/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Check in <prefix>/lib */
- pnt1 = UCLIBC_TARGET_PREFIX "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Bummer. Nothing so far. Try <devel-dir>/lib */
- pnt1 = UCLIBC_DEVEL_PREFIX "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Still nothing... Ok, try <builddir>/lib */
- pnt1 = UCLIBC_BUILD_DIR "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Wow. Still nothing. Try /usr/lib */
- pnt1 = "/usr/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* This is our last hope before giving up -- Try /lib */
- pnt1 = "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
+ /* Lastly, search the standard list of paths for the library.
+ This list must exactly match the list in uClibc/ldso/util/ldd.c */
+ if ((tpnt1 = search_for_named_library(libname, secure,
+ UCLIBC_TARGET_PREFIX "/usr/lib:"
+ UCLIBC_TARGET_PREFIX "/lib:"
+ UCLIBC_DEVEL_PREFIX "/lib:"
+ UCLIBC_BUILD_DIR "/lib:"
+ "/usr/lib:"
+ "/lib")
+ ) != NULL)
+ {
return tpnt1;
+ }
goof:
/* Well, we shot our wad on that one. All we can do now is punt */
diff --git a/ldso/ldso/ld_string.h b/ldso/ldso/ld_string.h
index fcdb8768b..b94b1c5f9 100644
--- a/ldso/ldso/ld_string.h
+++ b/ldso/ldso/ld_string.h
@@ -11,6 +11,7 @@ extern void _dl_dprintf(int, const char *, ...);
static size_t _dl_strlen(const char * str);
+static char *_dl_strcat(char *dst, const char *src);
static char * _dl_strcpy(char * dst,const char *src);
static int _dl_strcmp(const char * s1,const char * s2);
static int _dl_strncmp(const char * s1,const char * s2,size_t len);
@@ -18,7 +19,7 @@ static char * _dl_strchr(const char * str,int c);
static char *_dl_strrchr(const char *str, int c);
static void * _dl_memcpy(void * dst, const void * src, size_t len);
static int _dl_memcmp(const void * s1,const void * s2,size_t len);
-static void * _dl_memset(void * str,int c,size_t len);
+static void *_dl_memset(void * str,int c,size_t len);
static char *_dl_get_last_path_component(char *path);
static char *_dl_simple_ltoa(char * local, unsigned long i);
static char *_dl_simple_ltoahex(char * local, unsigned long i);
@@ -36,6 +37,20 @@ static inline size_t _dl_strlen(const char * str)
return (ptr - str);
}
+static inline char *_dl_strcat(char *dst, const char *src)
+{
+ register char *ptr = dst;
+
+ while (*ptr)
+ ptr++;
+
+ while (*src)
+ *ptr++ = *src++;
+ *ptr = '\0';
+
+ return dst;
+}
+
static inline char * _dl_strcpy(char * dst,const char *src)
{
register char *ptr = dst;
diff --git a/ldso/ldso/readelflib1.c b/ldso/ldso/readelflib1.c
index 75acde927..eed74321d 100644
--- a/ldso/ldso/readelflib1.c
+++ b/ldso/ldso/readelflib1.c
@@ -118,6 +118,49 @@ int _dl_unmap_cache(void)
#endif
+/* This function's behavior must exactly match that
+ * in uClibc/ldso/util/ldd.c */
+static struct elf_resolve *
+search_for_named_library(char *name, int secure, const char *path_list)
+{
+ int i, count = 0;
+ char *path, *path_n;
+ char mylibname[2050];
+ struct elf_resolve *tpnt1;
+
+
+ /* We need a writable copy of this string */
+ path = _dl_strdup(path_list);
+ if (!path) {
+ _dl_dprintf(2, "Out of memory!\n");
+ _dl_exit(0);
+ }
+
+
+ /* Unlike ldd.c, don't bother to eliminate double //s */
+
+
+ /* Replace colons with zeros in path_list and count them */
+ for(i=_dl_strlen(path); i > 0; i--) {
+ if (path[i]==':') {
+ path[i]=0;
+ count++;
+ }
+ }
+
+ path_n = path;
+ for (i = 0; i < count; i++) {
+ _dl_strcpy(mylibname, path_n);
+ _dl_strcat(mylibname, "/");
+ _dl_strcat(mylibname, name);
+ if ((tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0)) != NULL)
+ return tpnt1;
+ path_n += (_dl_strlen(path_n) + 1);
+ }
+ return NULL;
+}
+
+
/*
* Used to return error codes back to dlopen et. al.
*/
@@ -128,9 +171,8 @@ unsigned long _dl_internal_error_number;
struct elf_resolve *_dl_load_shared_library(int secure,
struct elf_resolve *tpnt, char *full_libname)
{
- char *pnt, *pnt1, *pnt2;
- struct elf_resolve *tpnt1 = NULL;
- char mylibname[2050];
+ char *pnt;
+ struct elf_resolve *tpnt1;
char *libname;
_dl_internal_error_number = 0;
@@ -160,71 +202,30 @@ struct elf_resolve *_dl_load_shared_library(int secure,
/*
* The ABI specifies that RPATH is searched before LD_*_PATH or
- * the default path of /usr/lib.
- * Check in rpath directories
+ * the default path of /usr/lib. Check in rpath directories.
*/
for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
if (tpnt->libtype == elf_executable) {
- pnt1 = (char *) tpnt->dynamic_info[DT_RPATH];
- if (pnt1) {
- pnt1 += (unsigned long) tpnt->loadaddr +
+ pnt = (char *) tpnt->dynamic_info[DT_RPATH];
+ if (pnt) {
+ pnt += (unsigned long) tpnt->loadaddr +
tpnt->dynamic_info[DT_STRTAB];
- while (*pnt1) {
- pnt2 = mylibname;
- while (*pnt1 && *pnt1 != ':') {
- if (pnt2 - mylibname < 1024)
- *pnt2++ = *pnt1++;
- else
- pnt1++;
- }
- if (pnt2 - mylibname >= 1024)
- break;
- if (pnt2[-1] != '/')
- *pnt2++ = '/';
- pnt = libname;
- while (*pnt)
- *pnt2++ = *pnt++;
- *pnt2++ = 0;
- tpnt1 =
- _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
- if (*pnt1 == ':')
- pnt1++;
+ if ((tpnt1 = search_for_named_library(libname, secure, pnt)) != NULL)
+ {
+ return tpnt1;
}
}
}
}
-
/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
- pnt1 = _dl_library_path;
- if (pnt1 && *pnt1) {
- while (*pnt1) {
- pnt2 = mylibname;
- while (*pnt1 && *pnt1 != ':' && *pnt1 != ';') {
- if (pnt2 - mylibname < 1024)
- *pnt2++ = *pnt1++;
- else
- pnt1++;
- }
- if (pnt2 - mylibname >= 1024)
- break;
- if (pnt2[-1] != '/')
- *pnt2++ = '/';
- pnt = libname;
- while (*pnt)
- *pnt2++ = *pnt++;
- *pnt2++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
- if (*pnt1 == ':' || *pnt1 == ';')
- pnt1++;
- }
+ if (_dl_library_path) {
+ if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path)) != NULL)
+ {
+ return tpnt1;
+ }
}
-
/*
* Where should the cache be searched? There is no such concept in the
* ABI, so we have some flexibility here. For now, search it before
@@ -248,83 +249,19 @@ struct elf_resolve *_dl_load_shared_library(int secure,
}
#endif
- /* Check in <prefix>/usr/lib */
- pnt1 = UCLIBC_TARGET_PREFIX "/usr/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Check in <prefix>/lib */
- pnt1 = UCLIBC_TARGET_PREFIX "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Bummer. Nothing so far. Try <devel-dir>/lib */
- pnt1 = UCLIBC_DEVEL_PREFIX "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Still nothing... Ok, try <builddir>/lib */
- pnt1 = UCLIBC_BUILD_DIR "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* Wow. Still nothing. Try /usr/lib */
- pnt1 = "/usr/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
- return tpnt1;
-
- /* This is our last hope before giving up -- Try /lib */
- pnt1 = "/lib/";
- pnt = mylibname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- pnt1 = libname;
- while (*pnt1)
- *pnt++ = *pnt1++;
- *pnt++ = 0;
- tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
- if (tpnt1)
+ /* Lastly, search the standard list of paths for the library.
+ This list must exactly match the list in uClibc/ldso/util/ldd.c */
+ if ((tpnt1 = search_for_named_library(libname, secure,
+ UCLIBC_TARGET_PREFIX "/usr/lib:"
+ UCLIBC_TARGET_PREFIX "/lib:"
+ UCLIBC_DEVEL_PREFIX "/lib:"
+ UCLIBC_BUILD_DIR "/lib:"
+ "/usr/lib:"
+ "/lib")
+ ) != NULL)
+ {
return tpnt1;
+ }
goof:
/* Well, we shot our wad on that one. All we can do now is punt */
diff --git a/ldso/ldso/string.h b/ldso/ldso/string.h
index fcdb8768b..b94b1c5f9 100644
--- a/ldso/ldso/string.h
+++ b/ldso/ldso/string.h
@@ -11,6 +11,7 @@ extern void _dl_dprintf(int, const char *, ...);
static size_t _dl_strlen(const char * str);
+static char *_dl_strcat(char *dst, const char *src);
static char * _dl_strcpy(char * dst,const char *src);
static int _dl_strcmp(const char * s1,const char * s2);
static int _dl_strncmp(const char * s1,const char * s2,size_t len);
@@ -18,7 +19,7 @@ static char * _dl_strchr(const char * str,int c);
static char *_dl_strrchr(const char *str, int c);
static void * _dl_memcpy(void * dst, const void * src, size_t len);
static int _dl_memcmp(const void * s1,const void * s2,size_t len);
-static void * _dl_memset(void * str,int c,size_t len);
+static void *_dl_memset(void * str,int c,size_t len);
static char *_dl_get_last_path_component(char *path);
static char *_dl_simple_ltoa(char * local, unsigned long i);
static char *_dl_simple_ltoahex(char * local, unsigned long i);
@@ -36,6 +37,20 @@ static inline size_t _dl_strlen(const char * str)
return (ptr - str);
}
+static inline char *_dl_strcat(char *dst, const char *src)
+{
+ register char *ptr = dst;
+
+ while (*ptr)
+ ptr++;
+
+ while (*src)
+ *ptr++ = *src++;
+ *ptr = '\0';
+
+ return dst;
+}
+
static inline char * _dl_strcpy(char * dst,const char *src)
{
register char *ptr = dst;