patch for ldd to support dynamic libraries

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

patch for ldd to support dynamic libraries

Matt Provost
An earlier version of this was posted before, but I think this latest
one actually works. It adds support for listing shared library
dependencies, so for example:

% ldd /usr/local/lib/libgtk.so.1.2
/usr/local/lib/libgtk.so.1.2:
        Start    End      Type Open Ref GrpRef Name
        0d312000 2d349000 rlib 0    1   0      /usr/lib/libc.so.34.2
        0965d000 0965d000 rtld 0    1   0      /usr/libexec/ld.so
        0fb9b000 2fb9f000 rlib 0    1   0      /usr/local/lib/libgmodule.so.1.2
        0344c000 23453000 rlib 0    1   0      /usr/local/lib/libglib.so.1.2
        0a958000 2a95c000 rlib 0    1   0      /usr/X11R6/lib/libXi.so.8.0
        00f02000 20f06000 rlib 0    2   0      /usr/X11R6/lib/libXext.so.8.0
        0a553000 2a59e000 rlib 0    3   0      /usr/X11R6/lib/libX11.so.8.1
        09ae4000 29aeb000 rlib 0    1   0      /usr/lib/libm.so.2.0
        0c07d000 2c159000 rlib 0    1   0      /usr/local/lib/libiconv.so.4.0
        05d0c000 25d10000 rlib 0    1   0      /usr/local/lib/libintl.so.2.0

It doesn't execute constructors and destructors as well. I tested it
with this library but maybe there's a better way:
#include <stdio.h>
void __attribute__ ((constructor)) dl_init(void) {
        printf("constructor!\n");
}
void __attribute__ ((destructor)) dl_fini(void) {
        printf("destructor!\n");
}

Anyone else want to test this or poke holes in it?

Thanks,
Matt

Index: include/dlfcn.h
===================================================================
RCS file: /cvs/src/include/dlfcn.h,v
retrieving revision 1.9
diff -u -r1.9 dlfcn.h
--- include/dlfcn.h 11 Aug 2004 19:14:56 -0000 1.9
+++ include/dlfcn.h 24 Aug 2006 22:56:47 -0000
@@ -64,6 +64,7 @@
 #define RTLD_GLOBAL 0x100
 #define RTLD_LOCAL 0x000
 #define DL_LAZY RTLD_LAZY /* Compat */
+#define RTLD_TRACE 0x200
 
 /*
  * Special handle arguments for dlsym().
Index: libexec/ld.so/dlfcn.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/dlfcn.c,v
retrieving revision 1.73
diff -u -r1.73 dlfcn.c
--- libexec/ld.so/dlfcn.c 8 May 2006 20:34:36 -0000 1.73
+++ libexec/ld.so/dlfcn.c 24 Aug 2006 22:56:59 -0000
@@ -53,6 +53,9 @@
  if (libname == NULL)
  return RTLD_DEFAULT;
 
+ if ((flags & RTLD_TRACE) == RTLD_TRACE)
+ _dl_traceld = "true";
+
  DL_DEB(("dlopen: loading: %s\n", libname));
 
  _dl_thread_kern_stop();
@@ -95,6 +98,11 @@
  } else {
  int err;
  DL_DEB(("tail %s\n", object->load_name ));
+ if (_dl_traceld) {
+ _dl_show_objects();
+ _dl_unload_shlib(object);
+ _dl_exit(0);
+ }
  err = _dl_rtld(object);
  if (err != 0) {
  _dl_real_close(object);
@@ -365,13 +373,23 @@
  objtypename = "rtld";
  break;
  case OBJTYPE_EXE:
- objtypename = "exe ";
+ if (_dl_debug)
+ objtypename = "exe ";
+ else {
+ object = object->next;
+ continue;
+ }
  break;
  case OBJTYPE_LIB:
  objtypename = "rlib";
  break;
  case OBJTYPE_DLO:
- objtypename = "dlib";
+ if (_dl_debug)
+ objtypename = "dlib";
+ else {
+ object = object->next;
+ continue;
+ }
  break;
  default:
  objtypename = "????";
Index: libexec/ld.so/ldd/ldd.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/ldd/ldd.c,v
retrieving revision 1.11
diff -u -r1.11 ldd.c
--- libexec/ld.so/ldd/ldd.c 10 Jul 2003 00:04:28 -0000 1.11
+++ libexec/ld.so/ldd/ldd.c 24 Aug 2006 22:56:59 -0000
@@ -31,10 +31,12 @@
 #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>
 
 int usage(void);
 int doit(char *);
@@ -93,8 +95,9 @@
  Elf_Ehdr ehdr;
  Elf_Phdr *phdr;
  int fd, i, size, status;
+ char buf[MAXPATHLEN];
+ void * dlhandle;
 
- printf("%s:\n", name);
 
  if ((fd = open(name, O_RDONLY)) < 0) {
  warn("%s", name);
@@ -114,6 +117,21 @@
  return 1;
  }
 
+ if (ehdr.e_type == ET_DYN) {
+ 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);
+ return 0;
+ }
+
  size = ehdr.e_phnum * sizeof(Elf_Phdr);
  if ((phdr = malloc(size)) == NULL)
  err(1, "malloc");
@@ -135,6 +153,7 @@
  return 1;
  }
 
+ printf("%s:\n", name);
  fflush(stdout);
  switch (fork()) {
  case -1:

Reply | Threaded
Open this post in threaded view
|

Re: patch for ldd to support dynamic libraries

Han Boetes
Uhah, grand!

Much better than:

% which ldd_forlibs                        
ldd_forlibs () {
        readelf -ds $1 | fgrep NEEDED
}

=)



# Han