On Thu, Apr 28, 2011 at 05:26:35PM -0500, Amit Kulkarni wrote: > > Diff below fixes "ldd /usr/lib/*.so.*" so that it outputs more than > > just the first shared object's dependencies, like the behavior from > > "ldd /usr/bin/*". > > > > The issue is that dlopen(f, RTLD_TRACE) calls exit() after it's done. > > I looked into changing this to properly cleanup and return, but > > figured it was easier to just fork first like we already do for > > exec()-based tracing. > > > I was checking this diff after the libc.so and libm.so change today, to > verify what's on the machine. > > ldd -x is unused, so I removed it from manpage and ldd.c, diff attached at > the very end of this email. >
hi. i have commented out the -x stuff for now, and removed it from usage(). the rest of your diff is for other people though, so i'll leave it there. jmc > when you do ldd /usr/lib/*.so.* you get a funny output > > /usr/lib/libasn1.so.18.0: > Start End Type Open Ref GrpRef Name > 0000000207297000 0000000207735000 dlib 1 0 0 > /usr/lib/libasn1.so.18.0 > /usr/lib/libc.so.58.0: > Start End Type Open Ref GrpRef Name > 000000020151d000 0000000201a03000 dlib 1 0 0 > /usr/lib/libc.so.58.2 > /usr/lib/libc.so.58.1: > Start End Type Open Ref GrpRef Name > 0000000203abe000 0000000203fa4000 dlib 1 0 0 > /usr/lib/libc.so.58.2 > /usr/lib/libc.so.58.2: > Start End Type Open Ref GrpRef Name > 0000000208fc4000 00000002094aa000 dlib 1 0 0 > /usr/lib/libc.so.58.2 > /usr/lib/libc.so.59.1: > /usr/lib/libcom_err.so.18.0: > Start End Type Open Ref GrpRef Name > 0000000203b10000 0000000203fae000 dlib 1 0 0 > /usr/lib/libcom_err.so.18.0 > > .... > .... > .... > /usr/lib/libkvm.so.10.0: > Start End Type Open Ref GrpRef Name > 0000000206891000 0000000206c9a000 dlib 1 0 0 > /usr/lib/libkvm.so.10.0 > /usr/lib/libm.so.5.2: > Start End Type Open Ref GrpRef Name > 000000020d6b1000 000000020dacf000 dlib 1 0 0 > /usr/lib/libm.so.5.3 > /usr/lib/libm.so.5.3: > Start End Type Open Ref GrpRef Name > 00000002042ef000 000000020470d000 dlib 1 0 0 > /usr/lib/libm.so.5.3 > /usr/lib/libmenu.so.5.0: > > > > Notice that ldd now prints the correct file and the Start + End > sections are different but it prints the wrong filename for the Start + > End sections. > > ldd now prints libc.so.58.2 for all Start + End sections and is silent > about current libc.so.59.1 > ldd now prints libm.so.5.3 for both libm.so.5.2 & libm.so.5.3 > > I checked freebsd changelog and saw they mention that ldd has problem > handling libc.so because ldd itself is linked with libc.so > http://svnweb.freebsd.org/base/head/usr.bin/ldd/ldd.c?view=log > > Anyway, matthew's diff doesn't bail with exit 1 but bails out silently. > > The modified diff which removes -x from manpage and code now follows... > I also deleted some unused headers. > > thanks, > amit > > Index: ldd.1 > =================================================================== > RCS file: /cvs/src/libexec/ld.so/ldd/ldd.1,v > retrieving revision 1.8 > diff -u ldd.1 > --- ldd.1 2 Mar 2009 09:27:34 -0000 1.8 > +++ ldd.1 28 Apr 2011 22:20:04 -0000 > @@ -32,7 +32,6 @@ > .Nd list dynamic object dependencies > .Sh SYNOPSIS > .Nm ldd > -.Op Fl x > .Ar program ... > .Sh DESCRIPTION > .Nm > @@ -49,13 +48,6 @@ > and then execs > .Ar program . > .Pp > -If > -.Nm > -is invoked with the > -.Fl x > -flag, the tags from > -.Ar program > -are listed without using current ldconfig configuration. > .Sh DIAGNOSTICS > Exit status 0 if no error. > Exit status 1 if arg error. > Index: ldd.c > =================================================================== > RCS file: /cvs/src/libexec/ld.so/ldd/ldd.c,v > retrieving revision 1.14 > diff -u ldd.c > --- ldd.c 2 Mar 2009 09:27:34 -0000 1.14 > +++ ldd.c 28 Apr 2011 22:20:04 -0000 > @@ -27,14 +27,10 @@ > #include <stdio.h> > #include <stdlib.h> > #include <elf_abi.h> > -#include <err.h> > #include <fcntl.h> > -#include <string.h> > #include <unistd.h> > #include <dlfcn.h> > > -#include <sys/stat.h> > -#include <sys/mman.h> > #include <sys/wait.h> > #include <sys/param.h> > > @@ -44,23 +40,11 @@ > int > main(int argc, char **argv) > { > - int c, xflag, ret; > + int c, ret; > > - xflag = 0; > - while ((c = getopt(argc, argv, "x")) != -1) { > - switch (c) { > - case 'x': > - xflag = 1; > - break; > - default: > - usage(); > - /*NOTREACHED*/ > - } > - } > + while ((c = getopt(argc, argv, "")) != -1) > + ; /* EMPTY */ > > - if (xflag) > - errx(1, "-x not yet implemented"); > - > argc -= optind; > argv += optind; > > @@ -84,7 +68,7 @@ > { > extern char *__progname; > > - fprintf(stderr, "usage: %s [-x] program ...\n", __progname); > + fprintf(stderr, "usage: %s program ...\n", __progname); > exit(1); > } > > @@ -94,9 +78,9 @@ > { > Elf_Ehdr ehdr; > Elf_Phdr *phdr; > - int fd, i, size, status, interp=0; > + int fd, i, size, status, interp = 0; > char buf[MAXPATHLEN]; > - void * dlhandle; > + void *dlhandle; > > if ((fd = open(name, O_RDONLY)) < 0) { > warn("%s", name); > @@ -110,8 +94,9 @@ > } > > if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) || > - ehdr.e_machine != ELF_TARG_MACH) { > - warnx("%s: not an ELF executable", name); > + ehdr.e_machine != ELF_TARG_MACH || > + (ehdr.e_type != ET_EXEC && ehdr.e_type != ET_DYN)) { > + warnx("%s: not an ELF executable or shared object", name); > close(fd); > return 1; > } > @@ -133,26 +118,10 @@ > break; > } > > - if (ehdr.e_type == ET_DYN && !interp) { > - printf("%s:\n", name); > - if (realpath(name, buf) == NULL) { > - warn("realpath(%s)", name); > - return 1; > - } > - dlhandle = dlopen(buf, RTLD_TRACE); > - if (dlhandle == NULL) { > - printf("%s\n", dlerror()); > - return 1; > - } > - close(fd); > - free(phdr); > - return 0; > - } > - > close(fd); > free(phdr); > > - if (i == ehdr.e_phnum) { > + if (ehdr.e_type == ET_EXEC && !interp) { > warnx("%s: not a dynamic executable", name); > return 1; > } > @@ -163,9 +132,16 @@ > case -1: > err(1, "fork"); > case 0: > - execl(name, name, (char *)NULL); > - perror(name); > - _exit(1); > + if (interp) { > + execl(name, name, NULL); > + err(1, "execl(%s)", name); > + } else { > + if (realpath(name, buf) == NULL) > + err(1, "realpath(%s)", name); > + if (dlopen(buf, RTLD_TRACE) == NULL) > + errx(1, "dlopen(%s): %s", buf, dlerror()); > + _exit(1); > + } > default: > if (wait(&status) < 0) { > warn("wait");