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