OSDN Git Service

Fix the library searching routine so it is way simpler, and so
authorEric Andersen <andersen@codepoet.org>
Sat, 11 Aug 2001 04:08:41 +0000 (04:08 -0000)
committerEric Andersen <andersen@codepoet.org>
Sat, 11 Aug 2001 04:08:41 +0000 (04:08 -0000)
it matches the routine in ldd.c

ldso/ldso/dl-elf.c
ldso/ldso/ld_string.h
ldso/ldso/readelflib1.c
ldso/ldso/string.h

index 75acde9..eed7432 100644 (file)
@@ -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 */
index fcdb876..b94b1c5 100644 (file)
@@ -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;
index 75acde9..eed7432 100644 (file)
@@ -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 */
index fcdb876..b94b1c5 100644 (file)
@@ -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;