From 6952dd37724ec9f0f9e4375539e42b951f7ab934 Mon Sep 17 00:00:00 2001 From: jhb Date: Tue, 9 Jan 2007 17:50:05 +0000 Subject: 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 --- usr.bin/kdump/kdump.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'usr.bin') 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 #include #include +#include #include #include #include @@ -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; -- cgit v1.1