diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2007-05-29 04:47:18 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2007-05-29 04:47:18 +0000 |
commit | 1df4eb73f8d7f64831c30fee52d8bf3dac85b6b9 (patch) | |
tree | e66a776eee1f0e48cc63c464ad06bc0aa887684b /libexec/ld.so | |
parent | bd14efd9d6861a5decfa8d097146a56b794777d6 (diff) |
based on a diff from Matt Provost: allow printing of ldd information
on libraries themselves. Works by setting up the debugging flags then
calling dlopen() to do the heavy lifting. ok drahn
Diffstat (limited to 'libexec/ld.so')
-rw-r--r-- | libexec/ld.so/dlfcn.c | 21 | ||||
-rw-r--r-- | libexec/ld.so/ldd/ldd.c | 23 |
2 files changed, 41 insertions, 3 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c index 506d4110375..36c14ef5d9e 100644 --- a/libexec/ld.so/dlfcn.c +++ b/libexec/ld.so/dlfcn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dlfcn.c,v 1.75 2007/05/05 15:21:21 drahn Exp $ */ +/* $OpenBSD: dlfcn.c,v 1.76 2007/05/29 04:47:17 jason Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -40,6 +40,7 @@ #include "sod.h" int _dl_errno; +int _dl_tracelib; int _dl_real_close(void *handle); void (*_dl_thread_fnc)(int) = NULL; @@ -55,6 +56,11 @@ dlopen(const char *libname, int flags) if (libname == NULL) return RTLD_DEFAULT; + if ((flags & RTLD_TRACE) == RTLD_TRACE) { + _dl_traceld = "true"; + _dl_tracelib = 1; + } + DL_DEB(("dlopen: loading: %s\n", libname)); _dl_thread_kern_stop(); @@ -97,6 +103,11 @@ dlopen(const char *libname, int flags) } 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); @@ -468,6 +479,14 @@ _dl_show_objects(void) _dl_fdprintf(outputfd, "\tStart %s End %s Type Open Ref GrpRef Name\n", pad, pad); + if (_dl_tracelib) { + for (; object != NULL; object = object->next) + if (object->obj_type == OBJTYPE_LDR) { + object = object->next; + break; + } + } + for (; object != NULL; object = object->next) { switch (object->obj_type) { case OBJTYPE_LDR: diff --git a/libexec/ld.so/ldd/ldd.c b/libexec/ld.so/ldd/ldd.c index 5254134037a..eac4a7d0eba 100644 --- a/libexec/ld.so/ldd/ldd.c +++ b/libexec/ld.so/ldd/ldd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldd.c,v 1.11 2003/07/10 00:04:28 david Exp $ */ +/* $OpenBSD: ldd.c,v 1.12 2007/05/29 04:47:17 jason Exp $ */ /* * Copyright (c) 2001 Artur Grabowski <art@openbsd.org> * All rights reserved. @@ -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 @@ doit(char *name) 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 @@ doit(char *name) 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 @@ doit(char *name) return 1; } + printf("%s:\n", name); fflush(stdout); switch (fork()) { case -1: |