summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2007-05-29 04:47:18 +0000
committerJason Wright <jason@cvs.openbsd.org>2007-05-29 04:47:18 +0000
commit1df4eb73f8d7f64831c30fee52d8bf3dac85b6b9 (patch)
treee66a776eee1f0e48cc63c464ad06bc0aa887684b
parentbd14efd9d6861a5decfa8d097146a56b794777d6 (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
-rw-r--r--include/dlfcn.h3
-rw-r--r--libexec/ld.so/dlfcn.c21
-rw-r--r--libexec/ld.so/ldd/ldd.c23
3 files changed, 43 insertions, 4 deletions
diff --git a/include/dlfcn.h b/include/dlfcn.h
index 992db0387d7..3cf5fd78422 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dlfcn.h,v 1.10 2007/05/05 15:21:21 drahn Exp $ */
+/* $OpenBSD: dlfcn.h,v 1.11 2007/05/29 04:47:17 jason Exp $ */
/* $NetBSD: dlfcn.h,v 1.2 1995/06/05 19:38:00 pk Exp $ */
/*
@@ -64,6 +64,7 @@ __END_DECLS
#define RTLD_GLOBAL 0x100
#define RTLD_LOCAL 0x000
#define DL_LAZY RTLD_LAZY /* Compat */
+#define RTLD_TRACE 0x200
/*
* Special handle arguments for dlsym().
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: