summaryrefslogtreecommitdiffstats
path: root/utils/ldd.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-10-03 07:53:52 +0000
committerEric Andersen <andersen@codepoet.org>2004-10-03 07:53:52 +0000
commit3b8039fd51c6b2e292d44794ba273aca2c88b321 (patch)
treeee2868495a5f93fa093887d6e39e8da4768c330c /utils/ldd.c
parent31cfe2300d8b9aee110ba0a7213f6befdd3ffce0 (diff)
downloaduClibc-alpine-3b8039fd51c6b2e292d44794ba273aca2c88b321.tar.bz2
uClibc-alpine-3b8039fd51c6b2e292d44794ba273aca2c88b321.tar.xz
This patch from Mike Frysinger, extended from an earlier patch from Peter S.
Mazinger implements the changes suggested by me on the uclibc list. On Tuesday 28 September 2004 02:24 pm, Erik Andersen wrote: > What I think should be done is > > *) Someone that cares about USE_CACHE should fix that option > up to be sure it works, and give it a proper config entry > in extra/Configs/Config.in, and rename it to something > more appropriate such as LDSO_CACHE_SUPPORT. > > *) When LDSO_CACHE_SUPPORT=n, UCLIBC_RUNTIME_PREFIX /usr/X11R6/lib > should be included in the default library search path in > dl-elf.c, ldd, and ldconfig. > > *) When LDSO_CACHE_SUPPORT=y, UCLIBC_RUNTIME_PREFIX /usr/X11R6/lib > should be excluded from the default library search path in > dl-elf.c, ldd, and ldconfig, and those wishing to include > X11 stuff should add that into /etc/ld.so.conf and re-run > ldconfig. > > *) At present, LDSO_CONF and LDSO_CACHE use the same names > and same structure as glibc. This precludes > LDSO_CACHE_SUPPORT being uses in any sane fashion on a > dial glibc and uClibc system. Just as it was necessary > for use to use a different name for 'libuClibc' rather > than 'libc', and 'ld-uClibc.so.0' rather than > 'ld-linux.so.2' it seems that these configuration files > really ought to be given different names. >
Diffstat (limited to 'utils/ldd.c')
-rw-r--r--utils/ldd.c112
1 files changed, 109 insertions, 3 deletions
diff --git a/utils/ldd.c b/utils/ldd.c
index 48022cd8b..55433b601 100644
--- a/utils/ldd.c
+++ b/utils/ldd.c
@@ -45,6 +45,7 @@
#else
#include "elf.h"
#endif
+#include "dl-cache.h"
#ifdef DMALLOC
#include <dmalloc.h>
@@ -229,6 +230,89 @@ int check_elf_header(Elf32_Ehdr *const ehdr)
return 0;
}
+#ifdef __LDSO_CACHE_SUPPORT__
+static caddr_t cache_addr = NULL;
+static size_t cache_size = 0;
+
+int map_cache(void)
+{
+ int fd;
+ struct stat st;
+ header_t *header;
+ libentry_t *libent;
+ int i, strtabsize;
+
+ if (cache_addr == (caddr_t) - 1)
+ return -1;
+ else if (cache_addr != NULL)
+ return 0;
+
+ if (stat(LDSO_CACHE, &st)
+ || (fd = open(LDSO_CACHE, O_RDONLY, 0)) < 0) {
+ dprintf(2, "ldd: can't open cache '%s'\n", LDSO_CACHE);
+ cache_addr = (caddr_t) - 1; /* so we won't try again */
+ return -1;
+ }
+
+ cache_size = st.st_size;
+ cache_addr = (caddr_t) mmap(0, cache_size, PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+ if (cache_addr == MAP_FAILED) {
+ dprintf(2, "ldd: can't map cache '%s'\n", LDSO_CACHE);
+ return -1;
+ }
+
+ header = (header_t *) cache_addr;
+
+ if (cache_size < sizeof(header_t) ||
+ memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)
+ || memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)
+ || cache_size <
+ (sizeof(header_t) + header->nlibs * sizeof(libentry_t))
+ || cache_addr[cache_size - 1] != '\0')
+ {
+ dprintf(2, "ldd: cache '%s' is corrupt\n", LDSO_CACHE);
+ goto fail;
+ }
+
+ strtabsize = cache_size - sizeof(header_t) -
+ header->nlibs * sizeof(libentry_t);
+ libent = (libentry_t *) & header[1];
+
+ for (i = 0; i < header->nlibs; i++) {
+ if (libent[i].sooffset >= strtabsize ||
+ libent[i].liboffset >= strtabsize)
+ {
+ dprintf(2, "ldd: cache '%s' is corrupt\n", LDSO_CACHE);
+ goto fail;
+ }
+ }
+
+ return 0;
+
+fail:
+ munmap(cache_addr, cache_size);
+ cache_addr = (caddr_t) - 1;
+ return -1;
+}
+
+int unmap_cache(void)
+{
+ if (cache_addr == NULL || cache_addr == (caddr_t) - 1)
+ return -1;
+
+#if 1
+ munmap(cache_addr, cache_size);
+ cache_addr = NULL;
+#endif
+
+ return 0;
+}
+#else
+static inline void map_cache(void) { }
+static inline void unmap_cache(void) { }
+#endif
+
/* This function's behavior must exactly match that
* in uClibc/ldso/ldso/dl-elf.c */
static void search_for_named_library(char *name, char *result, const char *path_list)
@@ -320,8 +404,23 @@ void locate_library_file(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_suid, stru
}
}
-#ifdef USE_CACHE
- /* FIXME -- add code to check the Cache here */
+#ifdef __LDSO_CACHE_SUPPORT__
+ if (cache_addr != NULL && cache_addr != (caddr_t) - 1) {
+ int i;
+ header_t *header = (header_t *) cache_addr;
+ libentry_t *libent = (libentry_t *) & header[1];
+ char *strs = (char *) &libent[header->nlibs];
+
+ for (i = 0; i < header->nlibs; i++) {
+ if ((libent[i].flags == LIB_ELF ||
+ libent[i].flags == LIB_ELF_LIBC0 ||
+ libent[i].flags == LIB_ELF_LIBC5) &&
+ strcmp(lib->name, strs + libent[i].sooffset) == 0) {
+ lib->path = strdup(strs + libent[i].liboffset);
+ return;
+ }
+ }
+ }
#endif
@@ -339,7 +438,11 @@ void locate_library_file(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_suid, stru
/* Lastly, search the standard list of paths for the library.
This list must exactly match the list in uClibc/ldso/ldso/dl-elf.c */
path = UCLIBC_RUNTIME_PREFIX "lib:"
- UCLIBC_RUNTIME_PREFIX "usr/lib";
+ UCLIBC_RUNTIME_PREFIX "usr/lib"
+#if !defined (__LDSO_CACHE_SUPPORT__)
+ ":" UCLIBC_RUNTIME_PREFIX "usr/X11R6/lib"
+#endif
+ ;
search_for_named_library(lib->name, buf, path);
if (*buf != '\0') {
lib->path = buf;
@@ -644,6 +747,8 @@ int main( int argc, char** argv)
printf("%s:\n", *argv);
}
+ map_cache();
+
if (find_dependancies(filename)!=0)
continue;
@@ -660,6 +765,7 @@ int main( int argc, char** argv)
}
}
+ unmap_cache();
/* Print the list */
got_em_all=0;