diff options
-rw-r--r-- | ldso/ldso/ldso.c | 43 | ||||
-rw-r--r-- | ldso/util/Makefile | 8 | ||||
-rw-r--r-- | ldso/util/ldd.c | 92 |
3 files changed, 106 insertions, 37 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index d365a38c3..7340f4ead 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -931,21 +931,18 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a #ifdef __LDSO_LDD_SUPPORT__ if (_dl_trace_loaded_objects) _dl_dprintf(1, "\t%s => not found\n", str); - else { + else #endif - _dl_dprintf(2, "%s: can't load " - "library '%s'\n", _dl_progname, str); + { + _dl_dprintf(2, "%s: can't load " "library '%s'\n", _dl_progname, str); _dl_exit(15); -#ifdef __LDSO_LDD_SUPPORT__ } -#endif } else { #ifdef __SUPPORT_LD_DEBUG_EARLY__ _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname); #endif #ifdef __LDSO_LDD_SUPPORT__ - if (_dl_trace_loaded_objects - && tpnt1->usage_count==1) { + if (_dl_trace_loaded_objects && tpnt1->usage_count==1) { /* this is a real hack to make ldd not print * the library itself when run on a library. */ if (_dl_strcmp(_dl_progname, str) != 0) @@ -1010,21 +1007,18 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a #ifdef __LDSO_LDD_SUPPORT__ if (_dl_trace_loaded_objects) _dl_dprintf(1, "\t%s => not found\n", cp2); - else { + else #endif - _dl_dprintf(2, "%s: can't load library '%s'\n", - _dl_progname, cp2); + { + _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2); _dl_exit(15); -#ifdef __LDSO_LDD_SUPPORT__ } -#endif } else { #ifdef __SUPPORT_LD_DEBUG_EARLY__ _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname); #endif #ifdef __LDSO_LDD_SUPPORT__ - if (_dl_trace_loaded_objects - && tpnt1->usage_count==1) { + if (_dl_trace_loaded_objects && tpnt1->usage_count==1) { _dl_dprintf(1, "\t%s => %s (0x%x)\n", cp2, tpnt1->libname, (unsigned) tpnt1->loadaddr); } @@ -1086,13 +1080,12 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a #ifdef __LDSO_LDD_SUPPORT__ if (_dl_trace_loaded_objects) _dl_dprintf(1, "\t%s => not found\n", lpntstr); - else { + else #endif + { _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr); _dl_exit(16); -#ifdef __LDSO_LDD_SUPPORT__ } -#endif } else { #ifdef __SUPPORT_LD_DEBUG_EARLY__ _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname); @@ -1111,15 +1104,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a #ifdef USE_CACHE _dl_unmap_cache(); #endif - /* ldd uses uses this. I am not sure how you pick up the other flags */ -#ifdef __LDSO_LDD_SUPPORT__ - if (_dl_trace_loaded_objects) { - char *_dl_warn = 0; - _dl_warn = _dl_getenv("LD_WARN", envp); - if (!_dl_warn) - _dl_exit(0); - } -#endif /* * If the program interpreter is not in the module chain, add it. This will @@ -1154,7 +1138,9 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a rpnt->dyn = tpnt; tpnt = NULL; } + #ifdef __LDSO_LDD_SUPPORT__ + /* End of the line for ldd.... */ if (_dl_trace_loaded_objects) { _dl_dprintf(1, "\t%s => %s (0x%x)\n", rpnt->dyn->libname + (_dl_strlen(_dl_ldsopath)) + 1, rpnt->dyn->libname, rpnt->dyn->loadaddr); @@ -1162,6 +1148,7 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a } #endif + #ifdef __mips__ /* * Relocation of the GOT entries for MIPS have to be done @@ -1190,10 +1177,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a #endif if (_dl_symbol_tables) goof += _dl_copy_fixups(_dl_symbol_tables); -#ifdef __LDSO_LDD_SUPPORT__ - if (goof || _dl_trace_loaded_objects) - _dl_exit(0); -#endif /* OK, at this point things are pretty much ready to run. Now we need to touch up a few items that are required, and then diff --git a/ldso/util/Makefile b/ldso/util/Makefile index 0f36bd31e..7d49ee523 100644 --- a/ldso/util/Makefile +++ b/ldso/util/Makefile @@ -33,6 +33,10 @@ TARGETS += ldconfig endif all: $(TARGETS) +ifeq ($(strip $(LDSO_LDD_SUPPORT)),y) +XXFLAGS=-D__LDSO_LDD_SUPPORT +endif + elf_header: ln -fs $(TOPDIR)include/elf.h @@ -58,7 +62,7 @@ ldconfig: ldconfig.o readsoname.o strip -x -R .note -R .comment $@ ldd: ldd.c - $(HOSTCC) $(HOSTCFLAGS) -DUCLIBC_TARGET_PREFIX=\"$(TARGET_PREFIX)\" \ + $(HOSTCC) $(HOSTCFLAGS) $(XXFLAGS) -DUCLIBC_TARGET_PREFIX=\"$(TARGET_PREFIX)\" \ -DUCLIBC_DEVEL_PREFIX=\"$(DEVEL_PREFIX)\" \ -DUCLIBC_BUILD_DIR=\"$(shell cd $(TOPDIR) && pwd)\" \ -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" -I . \ @@ -66,7 +70,7 @@ ldd: ldd.c strip -x -R .note -R .comment $@ ldd.target: ldd.c - $(TARGET_CC) $(CFLAGS) -Wl,-s -DUCLIBC_TARGET_PREFIX=\"$(TARGET_PREFIX)\" \ + $(TARGET_CC) $(CFLAGS) $(XXFLAGS) -Wl,-s -DUCLIBC_TARGET_PREFIX=\"$(TARGET_PREFIX)\" \ -DUCLIBC_DEVEL_PREFIX=\"$(DEVEL_PREFIX)\" \ -DUCLIBC_BUILD_DIR=\"$(shell cd $(TOPDIR) && pwd)\" \ -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" \ diff --git a/ldso/util/ldd.c b/ldso/util/ldd.c index 7fdeaf5b0..664f55a4f 100644 --- a/ldso/util/ldd.c +++ b/ldso/util/ldd.c @@ -49,6 +49,59 @@ #include <dmalloc.h> #endif +#if defined(__arm__) +#define MATCH_MACHINE(x) (x == EM_ARM) +#define ELFCLASSM ELFCLASS32 +#endif + +#if defined(__s390__) +#define MATCH_MACHINE(x) (x == EM_S390) +#define ELFCLASSM ELFCLASS32 +#endif + +#if defined(__i386__) +#ifndef EM_486 +#define MATCH_MACHINE(x) (x == EM_386) +#else +#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486) +#endif +#define ELFCLASSM ELFCLASS32 +#endif + +#if defined(__mc68000__) +#define MATCH_MACHINE(x) (x == EM_68K) +#define ELFCLASSM ELFCLASS32 +#endif + +#if defined(__mips__) +#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE) +#define ELFCLASSM ELFCLASS32 +#endif + +#if defined(__powerpc__) +#define MATCH_MACHINE(x) (x == EM_PPC) +#define ELFCLASSM ELFCLASS32 +#endif + +#if defined(__sh__) +#define MATCH_MACHINE(x) (x == EM_SH) +#endif + +#if defined (__v850e__) +#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850) +#define ELFCLASSM ELFCLASS32 +#endif + +#ifndef MATCH_MACHINE +#warning "You really should add a MATCH_MACHINE() macro for your architecture" +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define ELFDATAM ELFDATA2LSB +#elif __BYTE_ORDER == __BIG_ENDIAN +#define ELFDATAM ELFDATA2MSB +#endif + struct library { char *name; int resolved; @@ -132,6 +185,7 @@ int check_elf_header(Elf32_Ehdr *const ehdr) } #elif __BYTE_ORDER == __BIG_ENDIAN if (ehdr->e_ident[5] == ELFDATA2LSB) { + /* Ick -- we will have to byte-swap everything */ byteswap = 1; } #else @@ -347,13 +401,14 @@ static void find_needed_libraries(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, char *st } } -static void find_elf_interpreter(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, char *strtab, int is_setuid) +static struct library * +find_elf_interpreter(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, char *strtab, int is_setuid) { static int been_there_done_that=0; Elf32_Phdr *phdr; if (been_there_done_that==1) - return; + return NULL; been_there_done_that=1; phdr = elf_find_phdr_type(PT_INTERP, ehdr); if (phdr) { @@ -383,13 +438,13 @@ static void find_elf_interpreter(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, char *str newlib = cur; free(newlib->name); free(newlib->path); - return; + return NULL; } } if (newlib == NULL) newlib = malloc(sizeof(struct library)); if (!newlib) - return; + return NULL; newlib->name = malloc(strlen(s)+1); strcpy(newlib->name, s); newlib->path = newlib->name; @@ -405,7 +460,9 @@ static void find_elf_interpreter(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, char *str cur->next = newlib; } #endif + return newlib; } + return NULL; } /* map the .so, and locate interesting pieces */ @@ -418,6 +475,7 @@ int find_dependancies(char* filename) Elf32_Ehdr *ehdr = NULL; Elf32_Shdr *dynsec = NULL; Elf32_Dyn *dynamic = NULL; + struct library *interp; if (filename == not_found) return 0; @@ -464,7 +522,31 @@ foo: } dynsec = elf_find_section_type(SHT_DYNAMIC, ehdr); - find_elf_interpreter(ehdr, dynamic, dynstr, is_suid); + interp = find_elf_interpreter(ehdr, dynamic, dynstr, is_suid); + +#ifdef __LDSO_LDD_SUPPORT + if (interp && ehdr->e_ident[EI_CLASS] == ELFCLASSM && ehdr->e_ident[EI_DATA] == ELFDATAM + && ehdr->e_ident[EI_VERSION] == EV_CURRENT && MATCH_MACHINE(ehdr->e_machine)) + { + struct stat statbuf; + if (stat(interp->path, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) { + static const char * const environment[] = { + "PATH=/usr/bin:/bin:/usr/sbin:/sbin", + "SHELL=/bin/sh", + "LD_TRACE_LOADED_OBJECTS=1", + NULL + }; + /* Cool, it looks like we should be able to actually + * run this puppy. Do so now... */ + execle(filename, filename, NULL, environment); + + /* If the exec failed, we fall through to trying to find + * all the needed libraries ourselves by rummaging about + * in the ELF headers... */ + } + } +#endif + if (dynsec) { dynamic = (Elf32_Dyn*)(byteswap32_to_host(dynsec->sh_offset) + (intptr_t)ehdr); dynstr = (char *)elf_find_dynamic(DT_STRTAB, dynamic, ehdr, 0); |