1*d6fb4894SJohn Baldwin /*- 2*d6fb4894SJohn Baldwin * Copyright (c) 1988, 1993 3*d6fb4894SJohn Baldwin * The Regents of the University of California. All rights reserved. 4*d6fb4894SJohn Baldwin * 5*d6fb4894SJohn Baldwin * Redistribution and use in source and binary forms, with or without 6*d6fb4894SJohn Baldwin * modification, are permitted provided that the following conditions 7*d6fb4894SJohn Baldwin * are met: 8*d6fb4894SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 9*d6fb4894SJohn Baldwin * notice, this list of conditions and the following disclaimer. 10*d6fb4894SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 11*d6fb4894SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 12*d6fb4894SJohn Baldwin * documentation and/or other materials provided with the distribution. 13*d6fb4894SJohn Baldwin * 4. Neither the name of the University nor the names of its contributors 14*d6fb4894SJohn Baldwin * may be used to endorse or promote products derived from this software 15*d6fb4894SJohn Baldwin * without specific prior written permission. 16*d6fb4894SJohn Baldwin * 17*d6fb4894SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18*d6fb4894SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*d6fb4894SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*d6fb4894SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21*d6fb4894SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*d6fb4894SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*d6fb4894SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*d6fb4894SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*d6fb4894SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*d6fb4894SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*d6fb4894SJohn Baldwin * SUCH DAMAGE. 28*d6fb4894SJohn Baldwin */ 29*d6fb4894SJohn Baldwin 30*d6fb4894SJohn Baldwin #include <sys/cdefs.h> 31*d6fb4894SJohn Baldwin __FBSDID("$FreeBSD$"); 32*d6fb4894SJohn Baldwin 33*d6fb4894SJohn Baldwin #include <sys/param.h> 34*d6fb4894SJohn Baldwin #include <dlfcn.h> 35*d6fb4894SJohn Baldwin #include <stdio.h> 36*d6fb4894SJohn Baldwin #include <strings.h> 37*d6fb4894SJohn Baldwin #include <sysdecode.h> 38*d6fb4894SJohn Baldwin 39*d6fb4894SJohn Baldwin #define UTRACE_DLOPEN_START 1 40*d6fb4894SJohn Baldwin #define UTRACE_DLOPEN_STOP 2 41*d6fb4894SJohn Baldwin #define UTRACE_DLCLOSE_START 3 42*d6fb4894SJohn Baldwin #define UTRACE_DLCLOSE_STOP 4 43*d6fb4894SJohn Baldwin #define UTRACE_LOAD_OBJECT 5 44*d6fb4894SJohn Baldwin #define UTRACE_UNLOAD_OBJECT 6 45*d6fb4894SJohn Baldwin #define UTRACE_ADD_RUNDEP 7 46*d6fb4894SJohn Baldwin #define UTRACE_PRELOAD_FINISHED 8 47*d6fb4894SJohn Baldwin #define UTRACE_INIT_CALL 9 48*d6fb4894SJohn Baldwin #define UTRACE_FINI_CALL 10 49*d6fb4894SJohn Baldwin #define UTRACE_DLSYM_START 11 50*d6fb4894SJohn Baldwin #define UTRACE_DLSYM_STOP 12 51*d6fb4894SJohn Baldwin 52*d6fb4894SJohn Baldwin struct utrace_rtld { 53*d6fb4894SJohn Baldwin char sig[4]; /* 'RTLD' */ 54*d6fb4894SJohn Baldwin int event; 55*d6fb4894SJohn Baldwin void *handle; 56*d6fb4894SJohn Baldwin void *mapbase; 57*d6fb4894SJohn Baldwin size_t mapsize; 58*d6fb4894SJohn Baldwin int refcnt; 59*d6fb4894SJohn Baldwin char name[MAXPATHLEN]; 60*d6fb4894SJohn Baldwin }; 61*d6fb4894SJohn Baldwin 62*d6fb4894SJohn Baldwin static int 63*d6fb4894SJohn Baldwin print_utrace_rtld(FILE *fp, void *p) 64*d6fb4894SJohn Baldwin { 65*d6fb4894SJohn Baldwin struct utrace_rtld *ut = p; 66*d6fb4894SJohn Baldwin void *parent; 67*d6fb4894SJohn Baldwin int mode; 68*d6fb4894SJohn Baldwin 69*d6fb4894SJohn Baldwin switch (ut->event) { 70*d6fb4894SJohn Baldwin case UTRACE_DLOPEN_START: 71*d6fb4894SJohn Baldwin mode = ut->refcnt; 72*d6fb4894SJohn Baldwin fprintf(fp, "dlopen(%s, ", ut->name); 73*d6fb4894SJohn Baldwin switch (mode & RTLD_MODEMASK) { 74*d6fb4894SJohn Baldwin case RTLD_NOW: 75*d6fb4894SJohn Baldwin fprintf(fp, "RTLD_NOW"); 76*d6fb4894SJohn Baldwin break; 77*d6fb4894SJohn Baldwin case RTLD_LAZY: 78*d6fb4894SJohn Baldwin fprintf(fp, "RTLD_LAZY"); 79*d6fb4894SJohn Baldwin break; 80*d6fb4894SJohn Baldwin default: 81*d6fb4894SJohn Baldwin fprintf(fp, "%#x", mode & RTLD_MODEMASK); 82*d6fb4894SJohn Baldwin } 83*d6fb4894SJohn Baldwin if (mode & RTLD_GLOBAL) 84*d6fb4894SJohn Baldwin fprintf(fp, " | RTLD_GLOBAL"); 85*d6fb4894SJohn Baldwin if (mode & RTLD_TRACE) 86*d6fb4894SJohn Baldwin fprintf(fp, " | RTLD_TRACE"); 87*d6fb4894SJohn Baldwin if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 88*d6fb4894SJohn Baldwin fprintf(fp, " | %#x", mode & 89*d6fb4894SJohn Baldwin ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 90*d6fb4894SJohn Baldwin fprintf(fp, ")"); 91*d6fb4894SJohn Baldwin break; 92*d6fb4894SJohn Baldwin case UTRACE_DLOPEN_STOP: 93*d6fb4894SJohn Baldwin fprintf(fp, "%p = dlopen(%s) ref %d", ut->handle, ut->name, 94*d6fb4894SJohn Baldwin ut->refcnt); 95*d6fb4894SJohn Baldwin break; 96*d6fb4894SJohn Baldwin case UTRACE_DLCLOSE_START: 97*d6fb4894SJohn Baldwin fprintf(fp, "dlclose(%p) (%s, %d)", ut->handle, ut->name, 98*d6fb4894SJohn Baldwin ut->refcnt); 99*d6fb4894SJohn Baldwin break; 100*d6fb4894SJohn Baldwin case UTRACE_DLCLOSE_STOP: 101*d6fb4894SJohn Baldwin fprintf(fp, "dlclose(%p) finished", ut->handle); 102*d6fb4894SJohn Baldwin break; 103*d6fb4894SJohn Baldwin case UTRACE_LOAD_OBJECT: 104*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: loaded %p @ %p - %p (%s)", ut->handle, 105*d6fb4894SJohn Baldwin ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 106*d6fb4894SJohn Baldwin ut->name); 107*d6fb4894SJohn Baldwin break; 108*d6fb4894SJohn Baldwin case UTRACE_UNLOAD_OBJECT: 109*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: unloaded %p @ %p - %p (%s)", ut->handle, 110*d6fb4894SJohn Baldwin ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 111*d6fb4894SJohn Baldwin ut->name); 112*d6fb4894SJohn Baldwin break; 113*d6fb4894SJohn Baldwin case UTRACE_ADD_RUNDEP: 114*d6fb4894SJohn Baldwin parent = ut->mapbase; 115*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: %p now depends on %p (%s, %d)", parent, 116*d6fb4894SJohn Baldwin ut->handle, ut->name, ut->refcnt); 117*d6fb4894SJohn Baldwin break; 118*d6fb4894SJohn Baldwin case UTRACE_PRELOAD_FINISHED: 119*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: LD_PRELOAD finished"); 120*d6fb4894SJohn Baldwin break; 121*d6fb4894SJohn Baldwin case UTRACE_INIT_CALL: 122*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: init %p for %p (%s)", ut->mapbase, ut->handle, 123*d6fb4894SJohn Baldwin ut->name); 124*d6fb4894SJohn Baldwin break; 125*d6fb4894SJohn Baldwin case UTRACE_FINI_CALL: 126*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: fini %p for %p (%s)", ut->mapbase, ut->handle, 127*d6fb4894SJohn Baldwin ut->name); 128*d6fb4894SJohn Baldwin break; 129*d6fb4894SJohn Baldwin case UTRACE_DLSYM_START: 130*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: dlsym(%p, %s)", ut->handle, ut->name); 131*d6fb4894SJohn Baldwin break; 132*d6fb4894SJohn Baldwin case UTRACE_DLSYM_STOP: 133*d6fb4894SJohn Baldwin fprintf(fp, "RTLD: %p = dlsym(%p, %s)", ut->mapbase, ut->handle, 134*d6fb4894SJohn Baldwin ut->name); 135*d6fb4894SJohn Baldwin break; 136*d6fb4894SJohn Baldwin default: 137*d6fb4894SJohn Baldwin return (0); 138*d6fb4894SJohn Baldwin } 139*d6fb4894SJohn Baldwin return (1); 140*d6fb4894SJohn Baldwin } 141*d6fb4894SJohn Baldwin 142*d6fb4894SJohn Baldwin struct utrace_malloc { 143*d6fb4894SJohn Baldwin void *p; 144*d6fb4894SJohn Baldwin size_t s; 145*d6fb4894SJohn Baldwin void *r; 146*d6fb4894SJohn Baldwin }; 147*d6fb4894SJohn Baldwin 148*d6fb4894SJohn Baldwin static void 149*d6fb4894SJohn Baldwin print_utrace_malloc(FILE *fp, void *p) 150*d6fb4894SJohn Baldwin { 151*d6fb4894SJohn Baldwin struct utrace_malloc *ut = p; 152*d6fb4894SJohn Baldwin 153*d6fb4894SJohn Baldwin if (ut->p == (void *)(intptr_t)(-1)) 154*d6fb4894SJohn Baldwin fprintf(fp, "malloc_init()"); 155*d6fb4894SJohn Baldwin else if (ut->s == 0) 156*d6fb4894SJohn Baldwin fprintf(fp, "free(%p)", ut->p); 157*d6fb4894SJohn Baldwin else if (ut->p == NULL) 158*d6fb4894SJohn Baldwin fprintf(fp, "%p = malloc(%zu)", ut->r, ut->s); 159*d6fb4894SJohn Baldwin else 160*d6fb4894SJohn Baldwin fprintf(fp, "%p = realloc(%p, %zu)", ut->r, ut->p, ut->s); 161*d6fb4894SJohn Baldwin } 162*d6fb4894SJohn Baldwin 163*d6fb4894SJohn Baldwin int 164*d6fb4894SJohn Baldwin sysdecode_utrace(FILE *fp, void *p, size_t len) 165*d6fb4894SJohn Baldwin { 166*d6fb4894SJohn Baldwin 167*d6fb4894SJohn Baldwin if (len == sizeof(struct utrace_rtld) && bcmp(p, "RTLD", 4) == 0) { 168*d6fb4894SJohn Baldwin return (print_utrace_rtld(fp, p)); 169*d6fb4894SJohn Baldwin } 170*d6fb4894SJohn Baldwin 171*d6fb4894SJohn Baldwin if (len == sizeof(struct utrace_malloc)) { 172*d6fb4894SJohn Baldwin print_utrace_malloc(fp, p); 173*d6fb4894SJohn Baldwin return (1); 174*d6fb4894SJohn Baldwin } 175*d6fb4894SJohn Baldwin 176*d6fb4894SJohn Baldwin return (0); 177*d6fb4894SJohn Baldwin } 178