diff options
author | John Baldwin <jhb@FreeBSD.org> | 2007-01-09 17:50:05 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2007-01-09 17:50:05 +0000 |
commit | 1f4b63f8240ef2f9ed4827e7ebc1851328e178ff (patch) | |
tree | 0fa5cd70b668b21da1aad4c6450b427ed7c2d58d /usr.bin/kdump | |
parent | 50928713c79c4071a34a0f0790cd7530e4ced373 (diff) | |
download | src-1f4b63f8240ef2f9ed4827e7ebc1851328e178ff.tar.gz src-1f4b63f8240ef2f9ed4827e7ebc1851328e178ff.zip |
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
Notes
Notes:
svn path=/head/; revision=165916
Diffstat (limited to 'usr.bin/kdump')
-rw-r--r-- | usr.bin/kdump/kdump.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 5854ba8e3cab..24979d9c299d 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; |