Print this page
Rich's feedback
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/mdb/mdb_demangle.c
+++ new/usr/src/cmd/mdb/common/mdb/mdb_demangle.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 *
26 - * Copyright 2017 Jason King
26 + * Copyright 2018 Jason King
27 27 */
28 28
29 29 #include <mdb/mdb_modapi.h>
30 30 #include <mdb/mdb_demangle.h>
31 31 #include <mdb/mdb_err.h>
32 32 #include <mdb/mdb.h>
33 33
34 -#include <demangle.h>
35 34 #include <strings.h>
36 35 #include <unistd.h>
37 36 #include <dlfcn.h>
38 37 #include <link.h>
39 -#include <sysdemangle.h>
40 38
41 39 static void *
42 40 mdb_dem_alloc(size_t len)
43 41 {
44 42 return (mdb_alloc(len, UM_SLEEP));
45 43 }
46 44
47 45 static void
48 46 mdb_dem_free(void *p, size_t len)
49 47 {
50 48 mdb_free(p, len);
51 49 }
52 50
53 51 static sysdem_ops_t mdb_dem_demops = {
54 52 .alloc = mdb_dem_alloc,
55 53 .free = mdb_dem_free
56 54 };
57 55
58 56 mdb_demangler_t *
59 57 mdb_dem_load(void)
60 58 {
61 59 mdb_demangler_t *dmp;
62 60
63 61 dmp = mdb_alloc(sizeof (mdb_demangler_t), UM_SLEEP);
64 62 dmp->dm_len = 0;
65 63 dmp->dm_buf = NULL;
66 64 dmp->dm_flags = MDB_DM_SCOPE;
67 65 /* stick with C++ for now to match old behavior */
68 66 dmp->dm_lang = SYSDEM_LANG_CPP;
69 67
70 68 return (dmp);
71 69 }
72 70
73 71 void
74 72 mdb_dem_unload(mdb_demangler_t *dmp)
75 73 {
76 74 mdb_free(dmp->dm_buf, dmp->dm_len);
77 75 mdb_free(dmp, sizeof (mdb_demangler_t));
78 76 }
79 77
80 78 static const char *
81 79 mdb_dem_filter(mdb_demangler_t *dmp, const char *name)
82 80 {
83 81 static const char s_pref[] = "static ";
84 82 static const char c_suff[] = " const";
85 83 static const char v_suff[] = " volatile";
86 84
87 85 /*
88 86 * We process dm_dem, which skips the prefix in dm_buf (if any)
89 87 */
90 88 size_t len = strlen(dmp->dm_dem);
91 89 char *end = dmp->dm_dem + len;
92 90 size_t resid;
93 91
94 92 /*
95 93 * If static, const, and volatile qualifiers should not be displayed,
96 94 * rip all of them out of dmp->dm_dem.
97 95 */
98 96 if (!(dmp->dm_flags & MDB_DM_QUAL)) {
99 97 if (strncmp(dmp->dm_dem, s_pref, sizeof (s_pref) - 1) == 0) {
100 98 bcopy(dmp->dm_dem + sizeof (s_pref) - 1, dmp->dm_dem,
101 99 len - (sizeof (s_pref) - 1) + 1);
102 100 end -= sizeof (s_pref) - 1;
103 101 len -= sizeof (s_pref) - 1;
104 102 }
105 103
106 104 for (;;) {
107 105 if (len > sizeof (c_suff) - 1 &&
108 106 strcmp(end - (sizeof (c_suff) - 1), c_suff) == 0) {
109 107 end -= sizeof (c_suff) - 1;
110 108 len -= sizeof (c_suff) - 1;
111 109 *end = '\0';
112 110 continue;
113 111 }
114 112 if (len > sizeof (v_suff) - 1 &&
115 113 strcmp(end - (sizeof (v_suff) - 1), v_suff) == 0) {
116 114 end -= sizeof (v_suff) - 1;
117 115 len -= sizeof (v_suff) - 1;
118 116 *end = '\0';
119 117 continue;
120 118 }
121 119 break;
122 120 }
123 121 }
124 122
125 123 /*
126 124 * If function arguments should not be displayed, remove everything
127 125 * between the outermost set of parentheses in dmp->dm_dem.
128 126 */
129 127 if (!(dmp->dm_flags & MDB_DM_FUNCARG)) {
130 128 char *lp = strchr(dmp->dm_dem, '(');
131 129 char *rp = strrchr(dmp->dm_dem, ')');
132 130
133 131 if (lp != NULL && rp != NULL)
134 132 bcopy(rp + 1, lp, strlen(rp) + 1);
135 133 }
136 134
137 135 /*
138 136 * If function scope specifiers should not be displayed, remove text
139 137 * from the leftmost space to the rightmost colon prior to any paren.
140 138 */
141 139 if (!(dmp->dm_flags & MDB_DM_SCOPE)) {
142 140 char *c, *s, *lp = strchr(dmp->dm_dem, '(');
143 141
144 142 if (lp != NULL)
145 143 *lp = '\0';
146 144
147 145 c = strrchr(dmp->dm_dem, ':');
148 146 s = strchr(dmp->dm_dem, ' ');
149 147
150 148 if (lp != NULL)
151 149 *lp = '(';
152 150
153 151 if (c != NULL) {
154 152 if (s == NULL || s > c)
155 153 bcopy(c + 1, dmp->dm_dem, strlen(c + 1) + 1);
156 154 else
157 155 bcopy(c + 1, s + 1, strlen(c + 1) + 1);
158 156 }
159 157 }
160 158
161 159 len = strlen(dmp->dm_dem); /* recompute length of buffer */
162 160
163 161 /*
164 162 * Compute bytes remaining
165 163 */
166 164 resid = (dmp->dm_buf + dmp->dm_len) - (dmp->dm_dem + len);
167 165
168 166 /*
169 167 * If we want to append the mangled name as well and there is enough
170 168 * space for "[]\0" and at least one character, append "["+name+"]".
171 169 */
172 170 if ((dmp->dm_flags & MDB_DM_MANGLED) && resid > 3) {
173 171 char *p = dmp->dm_dem + len;
174 172
175 173 *p++ = '[';
176 174 (void) strncpy(p, name, resid - 3);
177 175 p[resid - 3] = '\0';
178 176 p += strlen(p);
179 177 (void) strcpy(p, "]");
180 178 }
181 179
182 180 /*
183 181 * We return the whole string
184 182 */
185 183 return (dmp->dm_buf);
186 184 }
187 185
188 186 /*
189 187 * Take a name: (the foo`bar` is optional)
190 188 * foo`bar`__mangled_
191 189 * and put:
192 190 * foo`bar`demangled
193 191 * into dmp->dm_buf. Point dmp->dm_dem to the beginning of the
194 192 * demangled section of the result.
195 193 */
196 194 static int
197 195 mdb_dem_process(mdb_demangler_t *dmp, const char *name)
198 196 {
199 197 char *res = NULL;
200 198 size_t reslen = 0;
↓ open down ↓ |
151 lines elided |
↑ open up ↑ |
201 199
202 200 char *prefix = strrchr(name, '`');
203 201 size_t prefixlen = 0;
204 202
205 203 if (prefix) {
206 204 prefix++; /* the ` is part of the prefix */
207 205 prefixlen = prefix - name;
208 206 }
209 207
210 208 res = sysdemangle(name + prefixlen, dmp->dm_lang, &mdb_dem_demops);
211 - if (res == NULL && errno != EINVAL)
212 - mdb_warn("Error while demangling");
209 + if (res == NULL) {
210 + if (errno != EINVAL)
211 + mdb_warn("Error while demangling");
212 + return (-1);
213 + }
213 214
214 215 reslen = (res != NULL) ? strlen(res) : 0;
215 216 reslen += prefixlen;
216 217 reslen += 1;
217 218
218 219 if (reslen > dmp->dm_len) {
219 220 mdb_free(dmp->dm_buf, dmp->dm_len);
220 221
221 222 dmp->dm_buf = mdb_zalloc(reslen, UM_SLEEP);
222 223 if (dmp->dm_buf == NULL) {
223 224 dmp->dm_len = 0;
224 225 mdb_warn("Unable to allocate memory for demangling");
225 226 return (-1);
226 227 }
227 228 dmp->dm_len = reslen;
228 229 }
229 230
230 231 if (prefixlen > 0)
231 232 (void) strlcpy(dmp->dm_buf, name, prefixlen);
232 - if (res != NULL)
233 +
234 + if (res != NULL) {
233 235 (void) strlcat(dmp->dm_buf, res, dmp->dm_len);
236 + mdb_dem_free(res, strlen(res) + 1);
237 + }
234 238
235 239 /*
236 240 * Save the position of the demangled string for mdb_dem_filter()
237 241 */
238 242 dmp->dm_dem = dmp->dm_buf + prefixlen;
239 243
240 244 return (0);
241 245 }
242 246
243 247 /* used by mdb_io.c:iob_addr2str */
244 248 const char *
245 249 mdb_dem_convert(mdb_demangler_t *dmp, const char *name)
246 250 {
247 251 if (mdb_dem_process(dmp, name) != 0 ||
248 252 strcmp(dmp->dm_buf, name) == 0)
249 253 return (name);
250 254
251 255 return (mdb_dem_filter(dmp, name));
252 256 }
253 257
254 258 /*ARGSUSED*/
255 259 int
256 260 cmd_demangle(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
257 261 {
258 262 mdb_demangler_t *dmp = mdb.m_demangler;
259 263
260 264 if (argc > 0)
261 265 return (DCMD_USAGE);
262 266
263 267 if (dmp != NULL && !(mdb.m_flags & MDB_FL_DEMANGLE)) {
264 268 mdb_printf("C++ symbol demangling enabled\n");
265 269 mdb.m_flags |= MDB_FL_DEMANGLE;
266 270
267 271 } else if (dmp == NULL) {
268 272 if ((mdb.m_demangler = mdb_dem_load()) != NULL) {
269 273 mdb_printf("C++ symbol demangling enabled\n");
270 274 mdb.m_flags |= MDB_FL_DEMANGLE;
271 275 } else {
272 276 mdb_warn("no memory to load C++ demangler");
273 277 mdb.m_flags &= ~MDB_FL_DEMANGLE;
274 278 }
275 279
276 280 } else {
277 281 mdb_dem_unload(mdb.m_demangler);
278 282 mdb.m_flags &= ~MDB_FL_DEMANGLE;
279 283 mdb.m_demangler = NULL;
280 284 mdb_printf("C++ symbol demangling disabled\n");
281 285 }
282 286
283 287 return (DCMD_OK);
284 288 }
285 289
286 290 /*ARGSUSED*/
287 291 int
288 292 cmd_demflags(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
289 293 {
290 294 static const char *const dm_desc[] = {
291 295 "static/const/volatile member func qualifiers displayed",
292 296 "scope resolution specifiers displayed",
293 297 "function arguments displayed",
294 298 "mangled name displayed"
295 299 };
296 300
297 301 mdb_demangler_t *dmp = mdb.m_demangler;
298 302 int i;
299 303
300 304 if (argc > 0)
301 305 return (DCMD_USAGE);
302 306
303 307 if (dmp == NULL || !(mdb.m_flags & MDB_FL_DEMANGLE)) {
304 308 mdb_warn("C++ demangling facility is currently disabled\n");
305 309 return (DCMD_ERR);
306 310 }
307 311
308 312 if (flags & DCMD_ADDRSPEC)
309 313 dmp->dm_flags = ((uint_t)addr & MDB_DM_ALL);
310 314
311 315 for (i = 0; i < sizeof (dm_desc) / sizeof (dm_desc[0]); i++) {
312 316 mdb_printf("0x%x\t%s\t%s\n", 1 << i,
313 317 (dmp->dm_flags & (1 << i)) ? "on" : "off", dm_desc[i]);
314 318 }
315 319
316 320 return (DCMD_OK);
317 321 }
318 322
319 323 /*ARGSUSED*/
320 324 int
321 325 cmd_demstr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
322 326 {
323 327 if ((flags & DCMD_ADDRSPEC) || argc == 0)
324 328 return (DCMD_USAGE);
325 329
326 330 for (; argc != 0; argc--, argv++) {
327 331 mdb_printf("%s == %s\n", argv->a_un.a_str,
328 332 mdb_dem_convert(mdb.m_demangler, argv->a_un.a_str));
329 333 }
330 334
331 335 return (DCMD_OK);
332 336 }
↓ open down ↓ |
89 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX