xref: /titanic_52/usr/src/cmd/dis/dis_util.c (revision dc0093f44ee4fac928e006850f8ed53f68277af5)
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