|  | @@ -45,6 +45,7 @@
 | 
											
												
													
														|  |  #else
 |  |  #else
 | 
											
												
													
														|  |  #include "elf.h"
 |  |  #include "elf.h"
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  | 
 |  | +#include "dl-cache.h"
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  #ifdef DMALLOC
 |  |  #ifdef DMALLOC
 | 
											
												
													
														|  |  #include <dmalloc.h>
 |  |  #include <dmalloc.h>
 | 
											
										
											
												
													
														|  | @@ -229,6 +230,89 @@ int check_elf_header(Elf32_Ehdr *const ehdr)
 | 
											
												
													
														|  |  	return 0;
 |  |  	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
 |  |  /* This function's behavior must exactly match that
 | 
											
												
													
														|  |   * in uClibc/ldso/ldso/dl-elf.c */
 |  |   * in uClibc/ldso/ldso/dl-elf.c */
 | 
											
												
													
														|  |  static void search_for_named_library(char *name, char *result, const char *path_list)
 |  |  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
 |  |  #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.
 |  |  	/* Lastly, search the standard list of paths for the library.
 | 
											
												
													
														|  |  	   This list must exactly match the list in uClibc/ldso/ldso/dl-elf.c */
 |  |  	   This list must exactly match the list in uClibc/ldso/ldso/dl-elf.c */
 | 
											
												
													
														|  |  	path =	UCLIBC_RUNTIME_PREFIX "lib:"
 |  |  	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);
 |  |  	search_for_named_library(lib->name, buf, path);
 | 
											
												
													
														|  |  	if (*buf != '\0') {
 |  |  	if (*buf != '\0') {
 | 
											
												
													
														|  |  		lib->path = buf;
 |  |  		lib->path = buf;
 | 
											
										
											
												
													
														|  | @@ -644,6 +747,8 @@ int main( int argc, char** argv)
 | 
											
												
													
														|  |  			printf("%s:\n", *argv);
 |  |  			printf("%s:\n", *argv);
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +		map_cache();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  		if (find_dependancies(filename)!=0)
 |  |  		if (find_dependancies(filename)!=0)
 | 
											
												
													
														|  |  			continue;
 |  |  			continue;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -660,6 +765,7 @@ int main( int argc, char** argv)
 | 
											
												
													
														|  |  			}
 |  |  			}
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +		unmap_cache();
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		/* Print the list */
 |  |  		/* Print the list */
 | 
											
												
													
														|  |  		got_em_all=0;
 |  |  		got_em_all=0;
 |