1*dc0093f4Seschrock /* 2*dc0093f4Seschrock * CDDL HEADER START 3*dc0093f4Seschrock * 4*dc0093f4Seschrock * The contents of this file are subject to the terms of the 5*dc0093f4Seschrock * Common Development and Distribution License (the "License"). 6*dc0093f4Seschrock * You may not use this file except in compliance with the License. 7*dc0093f4Seschrock * 8*dc0093f4Seschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*dc0093f4Seschrock * or http://www.opensolaris.org/os/licensing. 10*dc0093f4Seschrock * See the License for the specific language governing permissions 11*dc0093f4Seschrock * and limitations under the License. 12*dc0093f4Seschrock * 13*dc0093f4Seschrock * When distributing Covered Code, include this CDDL HEADER in each 14*dc0093f4Seschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*dc0093f4Seschrock * If applicable, add the following below this CDDL HEADER, with the 16*dc0093f4Seschrock * fields enclosed by brackets "[]" replaced with your own identifying 17*dc0093f4Seschrock * information: Portions Copyright [yyyy] [name of copyright owner] 18*dc0093f4Seschrock * 19*dc0093f4Seschrock * CDDL HEADER END 20*dc0093f4Seschrock */ 21*dc0093f4Seschrock 22*dc0093f4Seschrock /* 23*dc0093f4Seschrock * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*dc0093f4Seschrock * Use is subject to license terms. 25*dc0093f4Seschrock */ 26*dc0093f4Seschrock 27*dc0093f4Seschrock #pragma ident "%Z%%M% %I% %E% SMI" 28*dc0093f4Seschrock 29*dc0093f4Seschrock #include <dlfcn.h> 30*dc0093f4Seschrock #include <stdarg.h> 31*dc0093f4Seschrock #include <stdio.h> 32*dc0093f4Seschrock #include <stdlib.h> 33*dc0093f4Seschrock #include <demangle.h> 34*dc0093f4Seschrock 35*dc0093f4Seschrock #include "dis_util.h" 36*dc0093f4Seschrock 37*dc0093f4Seschrock int g_error; /* global process exit status, set when warn() is called */ 38*dc0093f4Seschrock 39*dc0093f4Seschrock /* 40*dc0093f4Seschrock * Fatal error. Print out the error with a leading "dis: ", and then exit the 41*dc0093f4Seschrock * program. 42*dc0093f4Seschrock */ 43*dc0093f4Seschrock void 44*dc0093f4Seschrock die(const char *fmt, ...) 45*dc0093f4Seschrock { 46*dc0093f4Seschrock va_list ap; 47*dc0093f4Seschrock 48*dc0093f4Seschrock (void) fprintf(stderr, "dis: fatal: "); 49*dc0093f4Seschrock 50*dc0093f4Seschrock va_start(ap, fmt); 51*dc0093f4Seschrock (void) vfprintf(stderr, fmt, ap); 52*dc0093f4Seschrock va_end(ap); 53*dc0093f4Seschrock 54*dc0093f4Seschrock (void) fprintf(stderr, "\n"); 55*dc0093f4Seschrock 56*dc0093f4Seschrock exit(1); 57*dc0093f4Seschrock } 58*dc0093f4Seschrock 59*dc0093f4Seschrock /* 60*dc0093f4Seschrock * Non-fatal error. Print out the error with a leading "dis: ", set the global 61*dc0093f4Seschrock * error flag, and return. 62*dc0093f4Seschrock */ 63*dc0093f4Seschrock void 64*dc0093f4Seschrock warn(const char *fmt, ...) 65*dc0093f4Seschrock { 66*dc0093f4Seschrock va_list ap; 67*dc0093f4Seschrock 68*dc0093f4Seschrock (void) fprintf(stderr, "dis: warning: "); 69*dc0093f4Seschrock 70*dc0093f4Seschrock va_start(ap, fmt); 71*dc0093f4Seschrock (void) vfprintf(stderr, fmt, ap); 72*dc0093f4Seschrock va_end(ap); 73*dc0093f4Seschrock 74*dc0093f4Seschrock (void) fprintf(stderr, "\n"); 75*dc0093f4Seschrock 76*dc0093f4Seschrock g_error = 1; 77*dc0093f4Seschrock } 78*dc0093f4Seschrock 79*dc0093f4Seschrock /* 80*dc0093f4Seschrock * Convenience wrapper around malloc() to cleanly exit if any allocation fails. 81*dc0093f4Seschrock */ 82*dc0093f4Seschrock void * 83*dc0093f4Seschrock safe_malloc(size_t size) 84*dc0093f4Seschrock { 85*dc0093f4Seschrock void *ret; 86*dc0093f4Seschrock 87*dc0093f4Seschrock if ((ret = calloc(1, size)) == NULL) 88*dc0093f4Seschrock die("Out of memory"); 89*dc0093f4Seschrock 90*dc0093f4Seschrock return (ret); 91*dc0093f4Seschrock } 92*dc0093f4Seschrock 93*dc0093f4Seschrock 94*dc0093f4Seschrock /* 95*dc0093f4Seschrock * Generic interface to demangle C++ names. Calls cplus_demangle to do the 96*dc0093f4Seschrock * necessary translation. If the translation fails, the argument is returned 97*dc0093f4Seschrock * unchanged. The memory returned is only valid until the next call to 98*dc0093f4Seschrock * demangle(). 99*dc0093f4Seschrock * 100*dc0093f4Seschrock * We dlopen() libdemangle.so rather than linking directly against it in case it 101*dc0093f4Seschrock * is not installed on the system. 102*dc0093f4Seschrock */ 103*dc0093f4Seschrock const char * 104*dc0093f4Seschrock dis_demangle(const char *name) 105*dc0093f4Seschrock { 106*dc0093f4Seschrock static char *demangled_name; 107*dc0093f4Seschrock static int (*demangle_func)() = NULL; 108*dc0093f4Seschrock static int size = BUFSIZE; 109*dc0093f4Seschrock static int first_flag = 0; 110*dc0093f4Seschrock int ret; 111*dc0093f4Seschrock 112*dc0093f4Seschrock /* 113*dc0093f4Seschrock * If this is the first call, allocate storage 114*dc0093f4Seschrock * for the buffer. 115*dc0093f4Seschrock */ 116*dc0093f4Seschrock if (first_flag == 0) { 117*dc0093f4Seschrock void *demangle_hand; 118*dc0093f4Seschrock 119*dc0093f4Seschrock demangle_hand = dlopen("libdemangle.so.1", RTLD_LAZY); 120*dc0093f4Seschrock if (demangle_hand != NULL) 121*dc0093f4Seschrock demangle_func = (int (*)(int))dlsym( 122*dc0093f4Seschrock demangle_hand, "cplus_demangle"); 123*dc0093f4Seschrock 124*dc0093f4Seschrock demangled_name = safe_malloc(size); 125*dc0093f4Seschrock first_flag = 1; 126*dc0093f4Seschrock } 127*dc0093f4Seschrock 128*dc0093f4Seschrock /* 129*dc0093f4Seschrock * If libdemangle is not present, pass through unchanged. 130*dc0093f4Seschrock */ 131*dc0093f4Seschrock if (demangle_func == NULL) 132*dc0093f4Seschrock return (name); 133*dc0093f4Seschrock 134*dc0093f4Seschrock /* 135*dc0093f4Seschrock * The function returns -1 when the buffer size is not sufficient. 136*dc0093f4Seschrock */ 137*dc0093f4Seschrock while ((ret = (*demangle_func)(name, demangled_name, size)) == -1) { 138*dc0093f4Seschrock free(demangled_name); 139*dc0093f4Seschrock size = size + BUFSIZE; 140*dc0093f4Seschrock demangled_name = safe_malloc(size); 141*dc0093f4Seschrock } 142*dc0093f4Seschrock 143*dc0093f4Seschrock if (ret != 0) 144*dc0093f4Seschrock return (name); 145*dc0093f4Seschrock 146*dc0093f4Seschrock return (demangled_name); 147*dc0093f4Seschrock } 148