Hello John, I had to closer look into shared objects wrt self-containedness. Here is a patch for ldd(1), that extends it to be used w/ shared libraries, too. The patch probably needs some cleanup, but it works. ldd-stub should be in /usr/libexec. Is /usr/libexec/elf preferable?
Do you have an idea how to generate an ldd-stub without a DT_NEEDED for libc.so (and still working with ldd, of course)? -Björn
--- ldd.c 2002/02/06 02:17:46 1.1 +++ ldd.c 2002/02/06 02:39:49 @@ -42,6 +42,8 @@ #include <stdlib.h> #include <unistd.h> +#define LDD_STUB "/usr/libexec/ldd-stub" + extern void dump_file __P((const char *)); extern int error_count; @@ -116,6 +118,9 @@ int n; int status; int file_ok; + int shared_object; + + shared_object = 0; if ((fd = open(*argv, O_RDONLY, 0)) < 0) { warn("%s", *argv); @@ -152,6 +157,10 @@ warnx("%s: can't read program header", *argv); file_ok = 0; } else { + if (ehdr.e_type == ET_DYN) { + shared_object = 1; + dynamic = 1; + } else { /* need to fix white spaces */ for (i = 0; i < ehdr.e_phnum; i++) { if (read(fd, &phdr, ehdr.e_phentsize) != sizeof phdr) { @@ -163,6 +172,7 @@ if (phdr.p_type == PT_DYNAMIC) dynamic = 1; } + } } if (!dynamic) { warnx("%s: not a dynamic executable", *argv); @@ -204,7 +214,11 @@ } break; case 0: - rval |= execl(*argv, *argv, NULL) != 0; + if (shared_object) { + setenv("LD_PRELOAD", *argv, 1); + rval |= execl(LDD_STUB, LDD_STUB, NULL) != 0; + } else + rval |= execl(*argv, *argv, NULL) != 0; warn("%s", *argv); _exit(1); }
int main(int argc, char *argv[]) { }