summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/ldso.c43
-rw-r--r--ldso/util/Makefile8
-rw-r--r--ldso/util/ldd.c92
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);