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
die(const char * fmt,...)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
warn(const char * fmt,...)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 *
safe_malloc(size_t size)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 *
dis_demangle(const char * name)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