summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-01-09 17:50:05 +0000
committerjhb <jhb@FreeBSD.org>2007-01-09 17:50:05 +0000
commit6952dd37724ec9f0f9e4375539e42b951f7ab934 (patch)
tree0fa5cd70b668b21da1aad4c6450b427ed7c2d58d /usr.bin
parent0f316bc65f504702265cc9bf8bea3ad73a18455e (diff)
downloadFreeBSD-src-6952dd37724ec9f0f9e4375539e42b951f7ab934.zip
FreeBSD-src-6952dd37724ec9f0f9e4375539e42b951f7ab934.tar.gz
Add various utrace's for use with ktrace to the ELF runtime linker. To
activate the traces, set the LD_UTRACE (or LD_32_UTRACE) environment variable. This also includes code in kdump(8) to parse the traces. Reviewed by: kan, jdp MFC after: 2 weeks
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/kdump/kdump.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 5854ba8..24979d9 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -59,6 +59,7 @@ extern int errno;
#include <sys/ioctl.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
+#include <dlfcn.h>
#include <err.h>
#include <locale.h>
#include <stdio.h>
@@ -975,6 +976,107 @@ ktrcsw(struct ktr_csw *cs)
cs->user ? "user" : "kernel");
}
+#define UTRACE_DLOPEN_START 1
+#define UTRACE_DLOPEN_STOP 2
+#define UTRACE_DLCLOSE_START 3
+#define UTRACE_DLCLOSE_STOP 4
+#define UTRACE_LOAD_OBJECT 5
+#define UTRACE_UNLOAD_OBJECT 6
+#define UTRACE_ADD_RUNDEP 7
+#define UTRACE_PRELOAD_FINISHED 8
+#define UTRACE_INIT_CALL 9
+#define UTRACE_FINI_CALL 10
+
+struct utrace_rtld {
+ char sig[4]; /* 'RTLD' */
+ int event;
+ void *handle;
+ void *mapbase;
+ size_t mapsize;
+ int refcnt;
+ char name[MAXPATHLEN];
+};
+
+void
+ktruser_rtld(int len, unsigned char *p)
+{
+ struct utrace_rtld *ut = (struct utrace_rtld *)p;
+ void *parent;
+ int mode;
+
+ switch (ut->event) {
+ case UTRACE_DLOPEN_START:
+ mode = ut->refcnt;
+ printf("dlopen(%s, ", ut->name);
+ switch (mode & RTLD_MODEMASK) {
+ case RTLD_NOW:
+ printf("RTLD_NOW");
+ break;
+ case RTLD_LAZY:
+ printf("RTLD_LAZY");
+ break;
+ default:
+ printf("%#x", mode & RTLD_MODEMASK);
+ }
+ if (mode & RTLD_GLOBAL)
+ printf(" | RTLD_GLOBAL");
+ if (mode & RTLD_TRACE)
+ printf(" | RTLD_TRACE");
+ if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
+ printf(" | %#x", mode &
+ ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
+ printf(")\n");
+ break;
+ case UTRACE_DLOPEN_STOP:
+ printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
+ ut->refcnt);
+ break;
+ case UTRACE_DLCLOSE_START:
+ printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
+ ut->refcnt);
+ break;
+ case UTRACE_DLCLOSE_STOP:
+ printf("dlclose(%p) finished\n", ut->handle);
+ break;
+ case UTRACE_LOAD_OBJECT:
+ printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle,
+ ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
+ ut->name);
+ break;
+ case UTRACE_UNLOAD_OBJECT:
+ printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
+ ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
+ ut->name);
+ break;
+ case UTRACE_ADD_RUNDEP:
+ parent = ut->mapbase;
+ printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
+ ut->handle, ut->name, ut->refcnt);
+ break;
+ case UTRACE_PRELOAD_FINISHED:
+ printf("RTLD: LD_PRELOAD finished\n");
+ break;
+ case UTRACE_INIT_CALL:
+ printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
+ ut->name);
+ break;
+ case UTRACE_FINI_CALL:
+ printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
+ ut->name);
+ break;
+ default:
+ p += 4;
+ len -= 4;
+ printf("RTLD: %d ", len);
+ while (len--)
+ if (decimal)
+ printf(" %d", *p++);
+ else
+ printf(" %02x", *p++);
+ printf("\n");
+ }
+}
+
struct utrace_malloc {
void *p;
size_t s;
@@ -1003,6 +1105,11 @@ void
ktruser(int len, unsigned char *p)
{
+ if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
+ ktruser_rtld(len, p);
+ return;
+ }
+
if (len == sizeof(struct utrace_malloc)) {
ktruser_malloc(len, p);
return;
OpenPOWER on IntegriCloud