Print this page
11584 ::xcall would be useful
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/mdb/mdb_ctf.c
+++ new/usr/src/cmd/mdb/common/mdb/mdb_ctf.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 (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25 /*
26 26 * Copyright (c) 2013, 2016 by Delphix. All rights reserved.
27 - * Copyright (c) 2015, Joyent, Inc. All rights reserved.
27 + * Copyright (c) 2018, Joyent, Inc.
28 28 */
29 29
30 30 #include <mdb/mdb_ctf.h>
31 31 #include <mdb/mdb_ctf_impl.h>
32 32 #include <mdb/mdb_err.h>
33 33 #include <mdb/mdb_modapi.h>
34 34 #include <mdb/mdb_string.h>
35 35 #include <mdb/mdb.h>
36 36 #include <mdb/mdb_debug.h>
37 37
38 38 #include <libctf.h>
39 39 #include <string.h>
40 40 #include <limits.h>
41 41
42 42 typedef struct tnarg {
43 43 mdb_tgt_t *tn_tgt; /* target to use for lookup */
44 44 const char *tn_name; /* query string to lookup */
45 45 ctf_file_t *tn_fp; /* CTF container from match */
46 46 ctf_id_t tn_id; /* CTF type ID from match */
47 47 } tnarg_t;
48 48
49 49 typedef struct type_iter {
50 50 mdb_ctf_type_f *ti_cb;
51 51 void *ti_arg;
52 52 ctf_file_t *ti_fp;
53 53 } type_iter_t;
54 54
55 55 typedef struct member_iter {
56 56 mdb_ctf_member_f *mi_cb;
57 57 void *mi_arg;
58 58 ctf_file_t *mi_fp;
59 59 } member_iter_t;
60 60
61 61 typedef struct type_visit {
62 62 mdb_ctf_visit_f *tv_cb;
63 63 void *tv_arg;
64 64 ctf_file_t *tv_fp;
65 65 ulong_t tv_base_offset; /* used when recursing from type_cb() */
66 66 int tv_base_depth; /* used when recursing from type_cb() */
67 67 int tv_min_depth;
68 68 } type_visit_t;
69 69
70 70 typedef struct mbr_info {
71 71 const char *mbr_member;
72 72 ulong_t *mbr_offp;
73 73 mdb_ctf_id_t *mbr_typep;
74 74 } mbr_info_t;
75 75
76 76 typedef struct synth_intrinsic {
77 77 const char *syn_name;
78 78 ctf_encoding_t syn_enc;
79 79 uint_t syn_kind;
80 80 } synth_intrinsic_t;
81 81
82 82 typedef struct synth_typedef {
83 83 const char *syt_src;
84 84 const char *syt_targ;
85 85 } synth_typedef_t;
86 86
87 87 /*
88 88 * As part of our support for synthetic types via ::typedef, we define a core
89 89 * set of types.
90 90 */
91 91 static const synth_intrinsic_t synth_builtins32[] = {
92 92 { "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
93 93 { "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
94 94 { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
95 95 { "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
96 96 { "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
97 97 { "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
98 98 { "long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
99 99 { "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
100 100 { "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
101 101 { "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
102 102 { "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
103 103 { "signed long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
104 104 { "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
105 105 { "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
106 106 { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
107 107 { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
108 108 { "unsigned long", { 0, 0, 32 }, CTF_K_INTEGER },
109 109 { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
110 110 { "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
111 111 { "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
112 112 { "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
113 113 { "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
114 114 { "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
115 115 { "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
116 116 { "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
117 117 { "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
118 118 { "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
119 119 { "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
120 120 { NULL, { 0, 0, 0}, 0 }
121 121 };
122 122
123 123 static const synth_intrinsic_t synth_builtins64[] = {
124 124 { "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
125 125 { "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
126 126 { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
127 127 { "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
128 128 { "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
129 129 { "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
130 130 { "long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
131 131 { "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
132 132 { "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
133 133 { "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
134 134 { "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
135 135 { "signed long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
136 136 { "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
137 137 { "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
138 138 { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
139 139 { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
140 140 { "unsigned long", { 0, 0, 64 }, CTF_K_INTEGER },
141 141 { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
142 142 { "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
143 143 { "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
144 144 { "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
145 145 { "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
146 146 { "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
147 147 { "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
148 148 { "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
149 149 { "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
150 150 { "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
151 151 { "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
152 152 { NULL, { 0, 0, 0 }, 0 }
153 153 };
154 154
155 155 static const synth_typedef_t synth_typedefs32[] = {
156 156 { "char", "int8_t" },
157 157 { "short", "int16_t" },
158 158 { "int", "int32_t" },
159 159 { "long long", "int64_t" },
160 160 { "int", "intptr_t" },
161 161 { "unsigned char", "uint8_t" },
162 162 { "unsigned short", "uint16_t" },
163 163 { "unsigned", "uint32_t" },
164 164 { "unsigned long long", "uint64_t" },
165 165 { "unsigned char", "uchar_t" },
166 166 { "unsigned short", "ushort_t" },
167 167 { "unsigned", "uint_t" },
168 168 { "unsigned long", "ulong_t" },
169 169 { "unsigned long long", "u_longlong_t" },
170 170 { "int", "ptrdiff_t" },
171 171 { "unsigned", "uintptr_t" },
172 172 { NULL, NULL }
173 173 };
174 174
175 175 static const synth_typedef_t synth_typedefs64[] = {
176 176 { "char", "int8_t" },
177 177 { "short", "int16_t" },
178 178 { "int", "int32_t" },
179 179 { "long", "int64_t" },
180 180 { "long", "intptr_t" },
181 181 { "unsigned char", "uint8_t" },
182 182 { "unsigned short", "uint16_t" },
183 183 { "unsigned", "uint32_t" },
184 184 { "unsigned long", "uint64_t" },
185 185 { "unsigned char", "uchar_t" },
186 186 { "unsigned short", "ushort_t" },
187 187 { "unsigned", "uint_t" },
188 188 { "unsigned long", "ulong_t" },
189 189 { "unsigned long long", "u_longlong_t" },
190 190 { "long", "ptrdiff_t" },
191 191 { "unsigned long", "uintptr_t" },
192 192 { NULL, NULL }
193 193 };
194 194
195 195 static void
196 196 set_ctf_id(mdb_ctf_id_t *p, ctf_file_t *fp, ctf_id_t id)
197 197 {
198 198 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
199 199
200 200 mcip->mci_fp = fp;
201 201 mcip->mci_id = id;
202 202 }
203 203
204 204 /*
205 205 * Callback function for mdb_tgt_object_iter used from name_to_type, below,
206 206 * to search the CTF namespace of each object file for a particular name.
207 207 */
208 208 /*ARGSUSED*/
209 209 static int
210 210 obj_lookup(void *data, const mdb_map_t *mp, const char *name)
211 211 {
212 212 tnarg_t *tnp = data;
213 213 ctf_file_t *fp;
214 214 ctf_id_t id;
215 215
216 216 if ((fp = mdb_tgt_name_to_ctf(tnp->tn_tgt, name)) != NULL &&
217 217 (id = ctf_lookup_by_name(fp, tnp->tn_name)) != CTF_ERR) {
218 218 tnp->tn_fp = fp;
219 219 tnp->tn_id = id;
220 220
221 221 /*
222 222 * We may have found a forward declaration. If we did, we'll
223 223 * note the ID and file pointer, but we'll keep searching in
224 224 * an attempt to find the real thing. If we found something
225 225 * real (i.e. not a forward), we stop the iteration.
226 226 */
227 227 return (ctf_type_kind(fp, id) == CTF_K_FORWARD ? 0 : -1);
228 228 }
229 229
230 230 return (0);
231 231 }
232 232
233 233 /*
234 234 * Convert a string type name with an optional leading object specifier into
235 235 * the corresponding CTF file container and type ID. If an error occurs, we
236 236 * print an appropriate message and return NULL.
237 237 */
238 238 static ctf_file_t *
239 239 name_to_type(mdb_tgt_t *t, const char *cname, ctf_id_t *idp)
240 240 {
241 241 const char *object = MDB_TGT_OBJ_EXEC;
242 242 ctf_file_t *fp = NULL;
243 243 ctf_id_t id;
244 244 tnarg_t arg;
245 245 char *p, *s;
246 246 char buf[MDB_SYM_NAMLEN];
247 247 char *name = &buf[0];
248 248
249 249 (void) mdb_snprintf(buf, sizeof (buf), "%s", cname);
250 250
251 251 if ((p = strrsplit(name, '`')) != NULL) {
252 252 /*
253 253 * We need to shuffle things around a little to support
254 254 * type names of the form "struct module`name".
255 255 */
256 256 if ((s = strsplit(name, ' ')) != NULL) {
257 257 bcopy(cname + (s - name), name, (p - s) - 1);
258 258 name[(p - s) - 1] = '\0';
259 259 bcopy(cname, name + (p - s), s - name);
260 260 p = name + (p - s);
261 261 }
262 262 if (*name != '\0')
263 263 object = name;
264 264 name = p;
265 265 }
266 266
267 267 /*
268 268 * Attempt to look up the name in the primary object file. If this
269 269 * fails and the name was unscoped, search all remaining object files.
270 270 * Finally, search the synthetic types.
271 271 */
272 272 if (((fp = mdb_tgt_name_to_ctf(t, object)) == NULL ||
273 273 (id = ctf_lookup_by_name(fp, name)) == CTF_ERR ||
274 274 ctf_type_kind(fp, id) == CTF_K_FORWARD) &&
275 275 object == MDB_TGT_OBJ_EXEC) {
276 276
277 277 arg.tn_tgt = t;
278 278 arg.tn_name = name;
279 279 arg.tn_fp = NULL;
280 280 arg.tn_id = CTF_ERR;
281 281
282 282 (void) mdb_tgt_object_iter(t, obj_lookup, &arg);
283 283
284 284 if (arg.tn_id != CTF_ERR) {
285 285 fp = arg.tn_fp;
286 286 id = arg.tn_id;
287 287 } else if (mdb.m_synth != NULL) {
288 288 if ((id = ctf_lookup_by_name(mdb.m_synth,
289 289 name)) != CTF_ERR)
290 290 fp = mdb.m_synth;
291 291 }
292 292 }
293 293
294 294 if (fp == NULL)
295 295 return (NULL); /* errno is set for us */
296 296
297 297 if (id == CTF_ERR) {
298 298 (void) set_errno(ctf_to_errno(ctf_errno(fp)));
299 299 return (NULL);
300 300 }
301 301
302 302 *idp = id;
303 303 return (fp);
304 304 }
305 305
306 306 /*
307 307 * Check to see if there is ctf data in the given object. This is useful
308 308 * so that we don't enter some loop where every call to lookup fails.
309 309 */
310 310 int
311 311 mdb_ctf_enabled_by_object(const char *object)
312 312 {
313 313 mdb_tgt_t *t = mdb.m_target;
314 314
315 315 return (mdb_tgt_name_to_ctf(t, object) != NULL);
316 316 }
317 317
318 318 int
319 319 mdb_ctf_lookup_by_name(const char *name, mdb_ctf_id_t *p)
320 320 {
321 321 ctf_file_t *fp = NULL;
322 322 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
323 323 mdb_tgt_t *t = mdb.m_target;
324 324
325 325 if (mcip == NULL)
326 326 return (set_errno(EINVAL));
327 327
328 328 if ((fp = name_to_type(t, name, &mcip->mci_id)) == NULL) {
329 329 mdb_ctf_type_invalidate(p);
330 330 return (-1); /* errno is set for us */
331 331 }
332 332
333 333 mcip->mci_fp = fp;
334 334
335 335 return (0);
336 336 }
337 337
338 338 int
339 339 mdb_ctf_lookup_by_symbol(const GElf_Sym *symp, const mdb_syminfo_t *sip,
340 340 mdb_ctf_id_t *p)
341 341 {
342 342 ctf_file_t *fp = NULL;
343 343 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
344 344 mdb_tgt_t *t = mdb.m_target;
345 345
346 346 if (mcip == NULL)
347 347 return (set_errno(EINVAL));
348 348
349 349 if (symp == NULL || sip == NULL) {
350 350 mdb_ctf_type_invalidate(p);
351 351 return (set_errno(EINVAL));
352 352 }
353 353
354 354 if ((fp = mdb_tgt_addr_to_ctf(t, symp->st_value)) == NULL) {
355 355 mdb_ctf_type_invalidate(p);
356 356 return (-1); /* errno is set for us */
357 357 }
358 358
359 359 if ((mcip->mci_id = ctf_lookup_by_symbol(fp, sip->sym_id)) == CTF_ERR) {
360 360 mdb_ctf_type_invalidate(p);
361 361 return (set_errno(ctf_to_errno(ctf_errno(fp))));
362 362 }
363 363
364 364 mcip->mci_fp = fp;
365 365
366 366 return (0);
367 367 }
368 368
369 369 int
370 370 mdb_ctf_lookup_by_addr(uintptr_t addr, mdb_ctf_id_t *p)
371 371 {
372 372 GElf_Sym sym;
373 373 mdb_syminfo_t si;
374 374 char name[MDB_SYM_NAMLEN];
375 375 const mdb_map_t *mp;
376 376 mdb_tgt_t *t = mdb.m_target;
377 377 const char *obj, *c;
378 378
379 379 if (p == NULL)
380 380 return (set_errno(EINVAL));
381 381
382 382 if (mdb_tgt_lookup_by_addr(t, addr, MDB_TGT_SYM_EXACT, name,
383 383 sizeof (name), NULL, NULL) == -1) {
384 384 mdb_ctf_type_invalidate(p);
385 385 return (-1); /* errno is set for us */
386 386 }
387 387
388 388 if ((c = strrsplit(name, '`')) != NULL) {
389 389 obj = name;
390 390 } else {
391 391 if ((mp = mdb_tgt_addr_to_map(t, addr)) == NULL) {
392 392 mdb_ctf_type_invalidate(p);
393 393 return (-1); /* errno is set for us */
394 394 }
395 395
396 396 obj = mp->map_name;
397 397 c = name;
398 398 }
399 399
400 400 if (mdb_tgt_lookup_by_name(t, obj, c, &sym, &si) == -1) {
401 401 mdb_ctf_type_invalidate(p);
402 402 return (-1); /* errno is set for us */
403 403 }
404 404
405 405 return (mdb_ctf_lookup_by_symbol(&sym, &si, p));
406 406 }
407 407
408 408 int
409 409 mdb_ctf_module_lookup(const char *name, mdb_ctf_id_t *p)
410 410 {
411 411 ctf_file_t *fp;
412 412 ctf_id_t id;
413 413 mdb_module_t *mod;
414 414
415 415 if ((mod = mdb_get_module()) == NULL)
416 416 return (set_errno(EMDB_CTX));
417 417
418 418 if ((fp = mod->mod_ctfp) == NULL)
419 419 return (set_errno(EMDB_NOCTF));
420 420
421 421 if ((id = ctf_lookup_by_name(fp, name)) == CTF_ERR)
422 422 return (set_errno(ctf_to_errno(ctf_errno(fp))));
423 423
424 424 set_ctf_id(p, fp, id);
425 425
426 426 return (0);
427 427 }
428 428
429 429 /*ARGSUSED*/
430 430 int
431 431 mdb_ctf_func_info(const GElf_Sym *symp, const mdb_syminfo_t *sip,
432 432 mdb_ctf_funcinfo_t *mfp)
433 433 {
434 434 ctf_file_t *fp = NULL;
435 435 ctf_funcinfo_t f;
436 436 mdb_tgt_t *t = mdb.m_target;
437 437 char name[MDB_SYM_NAMLEN];
438 438 const mdb_map_t *mp;
439 439 mdb_syminfo_t si;
440 440 int err;
441 441
442 442 if (symp == NULL || mfp == NULL)
443 443 return (set_errno(EINVAL));
444 444
445 445 /*
446 446 * In case the input symbol came from a merged or private symbol table,
447 447 * re-lookup the address as a symbol, and then perform a fully scoped
448 448 * lookup of that symbol name to get the mdb_syminfo_t for its CTF.
449 449 */
450 450 if ((fp = mdb_tgt_addr_to_ctf(t, symp->st_value)) == NULL ||
451 451 (mp = mdb_tgt_addr_to_map(t, symp->st_value)) == NULL ||
452 452 mdb_tgt_lookup_by_addr(t, symp->st_value, MDB_TGT_SYM_FUZZY,
453 453 name, sizeof (name), NULL, NULL) != 0)
454 454 return (-1); /* errno is set for us */
455 455
456 456 if (strchr(name, '`') != NULL)
457 457 err = mdb_tgt_lookup_by_scope(t, name, NULL, &si);
458 458 else
459 459 err = mdb_tgt_lookup_by_name(t, mp->map_name, name, NULL, &si);
460 460
461 461 if (err != 0)
462 462 return (-1); /* errno is set for us */
463 463
464 464 if (ctf_func_info(fp, si.sym_id, &f) == CTF_ERR)
465 465 return (set_errno(ctf_to_errno(ctf_errno(fp))));
466 466
467 467 set_ctf_id(&mfp->mtf_return, fp, f.ctc_return);
468 468 mfp->mtf_argc = f.ctc_argc;
469 469 mfp->mtf_flags = f.ctc_flags;
470 470 mfp->mtf_symidx = si.sym_id;
471 471
472 472 return (0);
473 473 }
474 474
475 475 int
476 476 mdb_ctf_func_args(const mdb_ctf_funcinfo_t *funcp, uint_t len,
477 477 mdb_ctf_id_t *argv)
478 478 {
479 479 ctf_file_t *fp;
480 480 ctf_id_t cargv[32];
481 481 int i;
482 482
483 483 if (len > (sizeof (cargv) / sizeof (cargv[0])))
484 484 return (set_errno(EINVAL));
485 485
486 486 if (funcp == NULL || argv == NULL)
487 487 return (set_errno(EINVAL));
488 488
489 489 fp = mdb_ctf_type_file(funcp->mtf_return);
490 490
491 491 if (ctf_func_args(fp, funcp->mtf_symidx, len, cargv) == CTF_ERR)
492 492 return (set_errno(ctf_to_errno(ctf_errno(fp))));
493 493
494 494 for (i = MIN(len, funcp->mtf_argc) - 1; i >= 0; i--) {
495 495 set_ctf_id(&argv[i], fp, cargv[i]);
496 496 }
497 497
498 498 return (0);
499 499 }
500 500
501 501 void
502 502 mdb_ctf_type_invalidate(mdb_ctf_id_t *idp)
503 503 {
504 504 set_ctf_id(idp, NULL, CTF_ERR);
505 505 }
506 506
507 507 int
508 508 mdb_ctf_type_valid(mdb_ctf_id_t id)
509 509 {
510 510 return (((mdb_ctf_impl_t *)&id)->mci_id != CTF_ERR);
511 511 }
512 512
513 513 int
514 514 mdb_ctf_type_cmp(mdb_ctf_id_t aid, mdb_ctf_id_t bid)
515 515 {
516 516 mdb_ctf_impl_t *aidp = (mdb_ctf_impl_t *)&aid;
517 517 mdb_ctf_impl_t *bidp = (mdb_ctf_impl_t *)&bid;
518 518
519 519 return (ctf_type_cmp(aidp->mci_fp, aidp->mci_id,
520 520 bidp->mci_fp, bidp->mci_id));
521 521 }
522 522
523 523 int
524 524 mdb_ctf_type_resolve(mdb_ctf_id_t mid, mdb_ctf_id_t *outp)
525 525 {
526 526 ctf_id_t id;
527 527 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)∣
528 528
529 529 if ((id = ctf_type_resolve(idp->mci_fp, idp->mci_id)) == CTF_ERR) {
530 530 if (outp)
531 531 mdb_ctf_type_invalidate(outp);
532 532 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
533 533 }
534 534
535 535 if (ctf_type_kind(idp->mci_fp, id) == CTF_K_FORWARD) {
536 536 char name[MDB_SYM_NAMLEN];
537 537 mdb_ctf_id_t lookup_id;
538 538
539 539 if (ctf_type_name(idp->mci_fp, id, name, sizeof (name)) !=
540 540 NULL &&
541 541 mdb_ctf_lookup_by_name(name, &lookup_id) == 0 &&
542 542 outp != NULL) {
543 543 *outp = lookup_id;
544 544 return (0);
545 545 }
546 546 }
547 547
548 548 if (outp != NULL)
549 549 set_ctf_id(outp, idp->mci_fp, id);
550 550
551 551 return (0);
552 552 }
553 553
554 554 char *
555 555 mdb_ctf_type_name(mdb_ctf_id_t id, char *buf, size_t len)
556 556 {
557 557 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
558 558 char *ret;
559 559
560 560 if (!mdb_ctf_type_valid(id)) {
561 561 (void) set_errno(EINVAL);
562 562 return (NULL);
563 563 }
564 564
565 565 ret = ctf_type_name(idp->mci_fp, idp->mci_id, buf, len);
566 566 if (ret == NULL)
567 567 (void) set_errno(ctf_to_errno(ctf_errno(idp->mci_fp)));
568 568
569 569 return (ret);
570 570 }
571 571
572 572 ssize_t
573 573 mdb_ctf_type_size(mdb_ctf_id_t id)
574 574 {
575 575 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
576 576 ssize_t ret;
577 577
578 578 /* resolve the type in case there's a forward declaration */
579 579 if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
580 580 return (ret);
581 581
582 582 if ((ret = ctf_type_size(idp->mci_fp, idp->mci_id)) == CTF_ERR)
583 583 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
584 584
585 585 return (ret);
586 586 }
587 587
588 588 int
589 589 mdb_ctf_type_kind(mdb_ctf_id_t id)
590 590 {
591 591 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
592 592 int ret;
593 593
594 594 if ((ret = ctf_type_kind(idp->mci_fp, idp->mci_id)) == CTF_ERR)
595 595 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
596 596
597 597 return (ret);
598 598 }
599 599
600 600 int
601 601 mdb_ctf_type_reference(mdb_ctf_id_t mid, mdb_ctf_id_t *outp)
602 602 {
603 603 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)∣
604 604 ctf_id_t id;
605 605
606 606 if ((id = ctf_type_reference(idp->mci_fp, idp->mci_id)) == CTF_ERR) {
607 607 if (outp)
608 608 mdb_ctf_type_invalidate(outp);
609 609 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
610 610 }
611 611
612 612 if (outp != NULL)
613 613 set_ctf_id(outp, idp->mci_fp, id);
614 614
615 615 return (0);
616 616 }
617 617
618 618
619 619 int
620 620 mdb_ctf_type_encoding(mdb_ctf_id_t id, ctf_encoding_t *ep)
621 621 {
622 622 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
623 623
624 624 if (ctf_type_encoding(idp->mci_fp, idp->mci_id, ep) == CTF_ERR)
625 625 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
626 626
627 627 return (0);
628 628 }
629 629
630 630 /*
631 631 * callback proxy for mdb_ctf_type_visit
632 632 */
633 633 static int
634 634 type_cb(const char *name, ctf_id_t type, ulong_t off, int depth, void *arg)
635 635 {
636 636 type_visit_t *tvp = arg;
637 637 mdb_ctf_id_t id;
638 638 mdb_ctf_id_t base;
639 639 mdb_ctf_impl_t *basep = (mdb_ctf_impl_t *)&base;
640 640
641 641 int ret;
642 642
643 643 if (depth < tvp->tv_min_depth)
644 644 return (0);
645 645
646 646 off += tvp->tv_base_offset;
647 647 depth += tvp->tv_base_depth;
648 648
649 649 set_ctf_id(&id, tvp->tv_fp, type);
650 650
651 651 (void) mdb_ctf_type_resolve(id, &base);
652 652 if ((ret = tvp->tv_cb(name, id, base, off, depth, tvp->tv_arg)) != 0)
653 653 return (ret);
654 654
655 655 /*
656 656 * If the type resolves to a type in a different file, we must have
657 657 * followed a forward declaration. We need to recurse into the
658 658 * new type.
659 659 */
660 660 if (basep->mci_fp != tvp->tv_fp && mdb_ctf_type_valid(base)) {
661 661 type_visit_t tv;
662 662
663 663 tv.tv_cb = tvp->tv_cb;
664 664 tv.tv_arg = tvp->tv_arg;
665 665 tv.tv_fp = basep->mci_fp;
666 666
667 667 tv.tv_base_offset = off;
668 668 tv.tv_base_depth = depth;
669 669 tv.tv_min_depth = 1; /* depth = 0 has already been done */
670 670
671 671 ret = ctf_type_visit(basep->mci_fp, basep->mci_id,
672 672 type_cb, &tv);
673 673 }
674 674 return (ret);
675 675 }
676 676
677 677 int
678 678 mdb_ctf_type_visit(mdb_ctf_id_t id, mdb_ctf_visit_f *func, void *arg)
679 679 {
680 680 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
681 681 type_visit_t tv;
682 682 int ret;
683 683
684 684 tv.tv_cb = func;
685 685 tv.tv_arg = arg;
686 686 tv.tv_fp = idp->mci_fp;
687 687 tv.tv_base_offset = 0;
688 688 tv.tv_base_depth = 0;
689 689 tv.tv_min_depth = 0;
690 690
691 691 ret = ctf_type_visit(idp->mci_fp, idp->mci_id, type_cb, &tv);
692 692
693 693 if (ret == CTF_ERR)
694 694 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
695 695
696 696 return (ret);
697 697 }
698 698
699 699 int
700 700 mdb_ctf_array_info(mdb_ctf_id_t id, mdb_ctf_arinfo_t *arp)
701 701 {
702 702 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
703 703 ctf_arinfo_t car;
704 704
705 705 if (ctf_array_info(idp->mci_fp, idp->mci_id, &car) == CTF_ERR)
706 706 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
707 707
708 708 set_ctf_id(&arp->mta_contents, idp->mci_fp, car.ctr_contents);
709 709 set_ctf_id(&arp->mta_index, idp->mci_fp, car.ctr_index);
710 710
711 711 arp->mta_nelems = car.ctr_nelems;
712 712
713 713 return (0);
714 714 }
715 715
716 716 const char *
717 717 mdb_ctf_enum_name(mdb_ctf_id_t id, int value)
718 718 {
719 719 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
720 720 const char *ret;
721 721
722 722 /* resolve the type in case there's a forward declaration */
723 723 if (mdb_ctf_type_resolve(id, &id) != 0)
724 724 return (NULL);
725 725
726 726 if ((ret = ctf_enum_name(idp->mci_fp, idp->mci_id, value)) == NULL)
727 727 (void) set_errno(ctf_to_errno(ctf_errno(idp->mci_fp)));
728 728
729 729 return (ret);
730 730 }
731 731
732 732 /*
733 733 * callback proxy for mdb_ctf_member_iter
734 734 */
735 735 static int
736 736 member_iter_cb(const char *name, ctf_id_t type, ulong_t off, void *data)
737 737 {
738 738 member_iter_t *mip = data;
739 739 mdb_ctf_id_t id;
740 740
741 741 set_ctf_id(&id, mip->mi_fp, type);
742 742
743 743 return (mip->mi_cb(name, id, off, mip->mi_arg));
744 744 }
745 745
746 746 int
747 747 mdb_ctf_member_iter(mdb_ctf_id_t id, mdb_ctf_member_f *cb, void *data)
748 748 {
749 749 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
750 750 member_iter_t mi;
751 751 int ret;
752 752
753 753 /* resolve the type in case there's a forward declaration */
754 754 if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
755 755 return (ret);
756 756
757 757 mi.mi_cb = cb;
758 758 mi.mi_arg = data;
759 759 mi.mi_fp = idp->mci_fp;
760 760
761 761 ret = ctf_member_iter(idp->mci_fp, idp->mci_id, member_iter_cb, &mi);
762 762
763 763 if (ret == CTF_ERR)
764 764 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
765 765
766 766 return (ret);
767 767 }
768 768
769 769 int
770 770 mdb_ctf_enum_iter(mdb_ctf_id_t id, mdb_ctf_enum_f *cb, void *data)
771 771 {
772 772 mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
773 773 int ret;
774 774
775 775 /* resolve the type in case there's a forward declaration */
776 776 if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
777 777 return (ret);
778 778
779 779 return (ctf_enum_iter(idp->mci_fp, idp->mci_id, cb, data));
780 780 }
781 781
782 782 /*
783 783 * callback proxy for mdb_ctf_type_iter
784 784 */
785 785 /* ARGSUSED */
786 786 static int
787 787 type_iter_cb(ctf_id_t type, boolean_t root, void *data)
788 788 {
789 789 type_iter_t *tip = data;
790 790 mdb_ctf_id_t id;
791 791
792 792 set_ctf_id(&id, tip->ti_fp, type);
793 793
794 794 return (tip->ti_cb(id, tip->ti_arg));
795 795 }
796 796
797 797 int
798 798 mdb_ctf_type_iter(const char *object, mdb_ctf_type_f *cb, void *data)
799 799 {
800 800 ctf_file_t *fp;
801 801 mdb_tgt_t *t = mdb.m_target;
802 802 int ret;
803 803 type_iter_t ti;
804 804
805 805 if (object == MDB_CTF_SYNTHETIC_ITER)
806 806 fp = mdb.m_synth;
807 807 else
808 808 fp = mdb_tgt_name_to_ctf(t, object);
809 809
810 810 if (fp == NULL)
811 811 return (-1);
812 812
813 813 ti.ti_cb = cb;
814 814 ti.ti_arg = data;
815 815 ti.ti_fp = fp;
816 816
817 817 if ((ret = ctf_type_iter(fp, B_FALSE, type_iter_cb, &ti)) == CTF_ERR)
818 818 return (set_errno(ctf_to_errno(ctf_errno(fp))));
819 819
820 820 return (ret);
821 821 }
822 822
823 823 /* utility functions */
824 824
825 825 ctf_id_t
826 826 mdb_ctf_type_id(mdb_ctf_id_t id)
827 827 {
828 828 return (((mdb_ctf_impl_t *)&id)->mci_id);
829 829 }
830 830
831 831 ctf_file_t *
832 832 mdb_ctf_type_file(mdb_ctf_id_t id)
833 833 {
834 834 return (((mdb_ctf_impl_t *)&id)->mci_fp);
835 835 }
836 836
837 837 static int
838 838 member_info_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data)
839 839 {
840 840 mbr_info_t *mbrp = data;
841 841
842 842 if (strcmp(name, mbrp->mbr_member) == 0) {
843 843 if (mbrp->mbr_offp != NULL)
844 844 *(mbrp->mbr_offp) = off;
845 845 if (mbrp->mbr_typep != NULL)
846 846 *(mbrp->mbr_typep) = id;
847 847
848 848 return (1);
849 849 }
850 850
851 851 return (0);
852 852 }
853 853
854 854 int
855 855 mdb_ctf_member_info(mdb_ctf_id_t id, const char *member, ulong_t *offp,
856 856 mdb_ctf_id_t *typep)
857 857 {
858 858 mbr_info_t mbr;
859 859 int rc;
860 860
861 861 mbr.mbr_member = member;
862 862 mbr.mbr_offp = offp;
863 863 mbr.mbr_typep = typep;
864 864
865 865 rc = mdb_ctf_member_iter(id, member_info_cb, &mbr);
866 866
867 867 /* couldn't get member list */
868 868 if (rc == -1)
869 869 return (-1); /* errno is set for us */
870 870
871 871 /* not a member */
872 872 if (rc == 0)
873 873 return (set_errno(EMDB_CTFNOMEMB));
874 874
875 875 return (0);
876 876 }
877 877
878 878 /*
879 879 * Returns offset in _bits_ in *retp.
880 880 */
881 881 int
882 882 mdb_ctf_offsetof(mdb_ctf_id_t id, const char *member, ulong_t *retp)
883 883 {
884 884 return (mdb_ctf_member_info(id, member, retp, NULL));
885 885 }
886 886
887 887 /*
888 888 * Returns offset in _bytes_, or -1 on failure.
889 889 */
890 890 int
891 891 mdb_ctf_offsetof_by_name(const char *type, const char *member)
892 892 {
893 893 mdb_ctf_id_t id;
894 894 ulong_t off;
895 895
896 896 if (mdb_ctf_lookup_by_name(type, &id) == -1) {
897 897 mdb_warn("couldn't find type %s", type);
898 898 return (-1);
899 899 }
900 900
901 901 if (mdb_ctf_offsetof(id, member, &off) == -1) {
902 902 mdb_warn("couldn't find member %s of type %s", member, type);
903 903 return (-1);
904 904 }
905 905 if (off % 8 != 0) {
906 906 mdb_warn("member %s of type %s is an unsupported bitfield\n",
907 907 member, type);
908 908 return (-1);
909 909 }
910 910 off /= 8;
911 911
912 912 return (off);
913 913 }
914 914
915 915 ssize_t
916 916 mdb_ctf_sizeof_by_name(const char *type)
917 917 {
918 918 mdb_ctf_id_t id;
919 919 ssize_t size;
920 920
921 921 if (mdb_ctf_lookup_by_name(type, &id) == -1) {
922 922 mdb_warn("couldn't find type %s", type);
923 923 return (-1);
924 924 }
925 925
926 926 if ((size = mdb_ctf_type_size(id)) == -1) {
927 927 mdb_warn("couldn't determine type size of %s", type);
928 928 return (-1);
929 929 }
930 930
931 931 return (size);
932 932 }
933 933
934 934 /*ARGSUSED*/
935 935 static int
936 936 num_members_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data)
937 937 {
938 938 int *count = data;
939 939 *count = *count + 1;
940 940 return (0);
941 941 }
942 942
943 943 int
944 944 mdb_ctf_num_members(mdb_ctf_id_t id)
945 945 {
946 946 int count = 0;
947 947
948 948 if (mdb_ctf_member_iter(id, num_members_cb, &count) != 0)
949 949 return (-1); /* errno is set for us */
950 950
951 951 return (count);
952 952 }
953 953
954 954 typedef struct mbr_contains {
955 955 char **mbc_bufp;
956 956 size_t *mbc_lenp;
957 957 ulong_t *mbc_offp;
958 958 mdb_ctf_id_t *mbc_idp;
959 959 ssize_t mbc_total;
960 960 } mbr_contains_t;
961 961
962 962 static int
963 963 offset_to_name_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data)
964 964 {
965 965 mbr_contains_t *mbc = data;
966 966 ulong_t size;
967 967 ctf_encoding_t e;
968 968 size_t n;
969 969
970 970 if (*mbc->mbc_offp < off)
971 971 return (0);
972 972
973 973 if (mdb_ctf_type_encoding(id, &e) == -1)
974 974 size = mdb_ctf_type_size(id) * NBBY;
975 975 else
976 976 size = e.cte_bits;
977 977
978 978 if (off + size <= *mbc->mbc_offp)
979 979 return (0);
980 980
981 981 n = mdb_snprintf(*mbc->mbc_bufp, *mbc->mbc_lenp, "%s", name);
982 982 mbc->mbc_total += n;
983 983 if (n > *mbc->mbc_lenp)
984 984 n = *mbc->mbc_lenp;
985 985
986 986 *mbc->mbc_lenp -= n;
987 987 *mbc->mbc_bufp += n;
988 988
989 989 *mbc->mbc_offp -= off;
990 990 *mbc->mbc_idp = id;
991 991
992 992 return (1);
993 993 }
994 994
995 995 ssize_t
996 996 mdb_ctf_offset_to_name(mdb_ctf_id_t id, ulong_t off, char *buf, size_t len,
997 997 int dot, mdb_ctf_id_t *midp, ulong_t *moffp)
998 998 {
999 999 size_t size;
1000 1000 size_t n;
1001 1001 mbr_contains_t mbc;
1002 1002
1003 1003 if (!mdb_ctf_type_valid(id))
1004 1004 return (set_errno(EINVAL));
1005 1005
1006 1006 /*
1007 1007 * Quick sanity check to make sure the given offset is within
1008 1008 * this scope of this type.
1009 1009 */
1010 1010 if (mdb_ctf_type_size(id) * NBBY <= off)
1011 1011 return (set_errno(EINVAL));
1012 1012
1013 1013 mbc.mbc_bufp = &buf;
1014 1014 mbc.mbc_lenp = &len;
1015 1015 mbc.mbc_offp = &off;
1016 1016 mbc.mbc_idp = &id;
1017 1017 mbc.mbc_total = 0;
1018 1018
1019 1019 *buf = '\0';
1020 1020
1021 1021 for (;;) {
1022 1022 /*
1023 1023 * Check for an exact match.
1024 1024 */
1025 1025 if (off == 0)
1026 1026 break;
1027 1027
1028 1028 (void) mdb_ctf_type_resolve(id, &id);
1029 1029
1030 1030 /*
1031 1031 * Find the member that contains this offset.
1032 1032 */
1033 1033 switch (mdb_ctf_type_kind(id)) {
1034 1034 case CTF_K_ARRAY: {
1035 1035 mdb_ctf_arinfo_t ar;
1036 1036 uint_t index;
1037 1037
1038 1038 (void) mdb_ctf_array_info(id, &ar);
1039 1039 size = mdb_ctf_type_size(ar.mta_contents) * NBBY;
1040 1040 index = off / size;
1041 1041
1042 1042 id = ar.mta_contents;
1043 1043 off %= size;
1044 1044
1045 1045 n = mdb_snprintf(buf, len, "[%u]", index);
1046 1046 mbc.mbc_total += n;
1047 1047 if (n > len)
1048 1048 n = len;
1049 1049
1050 1050 buf += n;
1051 1051 len -= n;
1052 1052 break;
1053 1053 }
1054 1054
1055 1055 case CTF_K_STRUCT: {
1056 1056 int ret;
1057 1057
1058 1058 /*
1059 1059 * Find the member that contains this offset
1060 1060 * and continue.
1061 1061 */
1062 1062
1063 1063 if (dot) {
1064 1064 mbc.mbc_total++;
1065 1065 if (len != 0) {
1066 1066 *buf++ = '.';
1067 1067 *buf = '\0';
1068 1068 len--;
1069 1069 }
1070 1070 }
1071 1071
1072 1072 ret = mdb_ctf_member_iter(id, offset_to_name_cb, &mbc);
1073 1073 if (ret == -1)
1074 1074 return (-1); /* errno is set for us */
1075 1075
1076 1076 /*
1077 1077 * If we did not find a member containing this offset
1078 1078 * (due to holes in the structure), return EINVAL.
1079 1079 */
1080 1080 if (ret == 0)
1081 1081 return (set_errno(EINVAL));
1082 1082
1083 1083 break;
1084 1084 }
1085 1085
1086 1086 case CTF_K_UNION:
1087 1087 /*
1088 1088 * Treat unions like atomic entities since we can't
1089 1089 * do more than guess which member of the union
1090 1090 * might be the intended one.
1091 1091 */
1092 1092 goto done;
1093 1093
1094 1094 case CTF_K_INTEGER:
1095 1095 case CTF_K_FLOAT:
1096 1096 case CTF_K_POINTER:
1097 1097 case CTF_K_ENUM:
1098 1098 goto done;
1099 1099
1100 1100 default:
1101 1101 return (set_errno(EINVAL));
1102 1102 }
1103 1103
1104 1104 dot = 1;
1105 1105 }
1106 1106 done:
1107 1107 if (midp != NULL)
1108 1108 *midp = id;
1109 1109 if (moffp != NULL)
1110 1110 *moffp = off;
1111 1111
1112 1112 return (mbc.mbc_total);
1113 1113 }
1114 1114
1115 1115 static void
1116 1116 mdb_ctf_warn(uint_t flags, const char *format, ...)
1117 1117 {
1118 1118 va_list alist;
1119 1119
1120 1120 if (flags & MDB_CTF_VREAD_QUIET)
1121 1121 return;
1122 1122
1123 1123 va_start(alist, format);
1124 1124 vwarn(format, alist);
1125 1125 va_end(alist);
1126 1126 }
1127 1127
1128 1128 /*
1129 1129 * Check if two types are structurally the same rather than logically
1130 1130 * the same. That is to say that two types are equal if they have the
1131 1131 * same logical structure rather than having the same ids in CTF-land.
1132 1132 */
1133 1133 static int type_equals(mdb_ctf_id_t, mdb_ctf_id_t);
1134 1134
1135 1135 static int
1136 1136 type_equals_cb(const char *name, mdb_ctf_id_t amem, ulong_t aoff, void *data)
1137 1137 {
1138 1138 mdb_ctf_id_t b = *(mdb_ctf_id_t *)data;
1139 1139 ulong_t boff;
1140 1140 mdb_ctf_id_t bmem;
1141 1141
1142 1142 /*
1143 1143 * Look up the corresponding member in the other composite type.
1144 1144 */
1145 1145 if (mdb_ctf_member_info(b, name, &boff, &bmem) != 0)
1146 1146 return (1);
1147 1147
1148 1148 /*
1149 1149 * We don't allow members to be shuffled around.
1150 1150 */
1151 1151 if (aoff != boff)
1152 1152 return (1);
1153 1153
1154 1154 return (type_equals(amem, bmem) ? 0 : 1);
1155 1155 }
1156 1156
1157 1157 static int
1158 1158 type_equals(mdb_ctf_id_t a, mdb_ctf_id_t b)
1159 1159 {
1160 1160 size_t asz, bsz;
1161 1161 int akind, bkind;
1162 1162 mdb_ctf_arinfo_t aar, bar;
1163 1163
1164 1164 /*
1165 1165 * Resolve both types down to their fundamental types, and make
1166 1166 * sure their sizes and kinds match.
1167 1167 */
1168 1168 if (mdb_ctf_type_resolve(a, &a) != 0 ||
1169 1169 mdb_ctf_type_resolve(b, &b) != 0 ||
1170 1170 (asz = mdb_ctf_type_size(a)) == -1UL ||
1171 1171 (bsz = mdb_ctf_type_size(b)) == -1UL ||
1172 1172 (akind = mdb_ctf_type_kind(a)) == -1 ||
1173 1173 (bkind = mdb_ctf_type_kind(b)) == -1 ||
1174 1174 asz != bsz || akind != bkind) {
1175 1175 return (0);
1176 1176 }
1177 1177
1178 1178 switch (akind) {
1179 1179 case CTF_K_INTEGER:
1180 1180 case CTF_K_FLOAT:
1181 1181 case CTF_K_POINTER:
1182 1182 /*
1183 1183 * For pointers we could be a little stricter and require
1184 1184 * both pointers to reference types which look vaguely
1185 1185 * similar (for example, we could insist that the two types
1186 1186 * have the same name). However, all we really care about
1187 1187 * here is that the structure of the two types are the same,
1188 1188 * and, in that regard, one pointer is as good as another.
1189 1189 */
1190 1190 return (1);
1191 1191
1192 1192 case CTF_K_UNION:
1193 1193 case CTF_K_STRUCT:
1194 1194 /*
1195 1195 * The test for the number of members is only strictly
1196 1196 * necessary for unions since we'll find other problems with
1197 1197 * structs. However, the extra check will do no harm.
1198 1198 */
1199 1199 return (mdb_ctf_num_members(a) == mdb_ctf_num_members(b) &&
1200 1200 mdb_ctf_member_iter(a, type_equals_cb, &b) == 0);
1201 1201
1202 1202 case CTF_K_ARRAY:
1203 1203 return (mdb_ctf_array_info(a, &aar) == 0 &&
1204 1204 mdb_ctf_array_info(b, &bar) == 0 &&
1205 1205 aar.mta_nelems == bar.mta_nelems &&
1206 1206 type_equals(aar.mta_index, bar.mta_index) &&
1207 1207 type_equals(aar.mta_contents, bar.mta_contents));
1208 1208 }
1209 1209
1210 1210 return (0);
1211 1211 }
1212 1212
1213 1213
1214 1214 typedef struct member {
1215 1215 char *m_modbuf;
1216 1216 char *m_tgtbuf;
1217 1217 const char *m_tgtname;
1218 1218 mdb_ctf_id_t m_tgtid;
1219 1219 uint_t m_flags;
1220 1220 } member_t;
1221 1221
1222 1222 static int vread_helper(mdb_ctf_id_t, char *, mdb_ctf_id_t, char *,
1223 1223 const char *, uint_t);
1224 1224
1225 1225 static int
1226 1226 member_cb(const char *name, mdb_ctf_id_t modmid, ulong_t modoff, void *data)
1227 1227 {
1228 1228 member_t *mp = data;
↓ open down ↓ |
1191 lines elided |
↑ open up ↑ |
1229 1229 char *modbuf = mp->m_modbuf;
1230 1230 mdb_ctf_id_t tgtmid;
1231 1231 char *tgtbuf = mp->m_tgtbuf;
1232 1232 ulong_t tgtoff;
1233 1233 char tgtname[128];
1234 1234
1235 1235 (void) mdb_snprintf(tgtname, sizeof (tgtname),
1236 1236 "member %s of type %s", name, mp->m_tgtname);
1237 1237
1238 1238 if (mdb_ctf_member_info(mp->m_tgtid, name, &tgtoff, &tgtmid) != 0) {
1239 - mdb_ctf_warn(mp->m_flags,
1240 - "could not find %s\n", tgtname);
1239 + if (mp->m_flags & MDB_CTF_VREAD_IGNORE_ABSENT)
1240 + return (0);
1241 + mdb_ctf_warn(mp->m_flags, "could not find %s\n", tgtname);
1241 1242 return (set_errno(EMDB_CTFNOMEMB));
1242 1243 }
1243 1244
1244 1245 return (vread_helper(modmid, modbuf + modoff / NBBY,
1245 1246 tgtmid, tgtbuf + tgtoff / NBBY, tgtname, mp->m_flags));
1246 1247 }
1247 1248
1248 1249 typedef struct enum_value {
1249 1250 int *ev_modbuf;
1250 1251 const char *ev_name;
1251 1252 } enum_value_t;
1252 1253
1253 1254 static int
1254 1255 enum_cb(const char *name, int value, void *data)
1255 1256 {
1256 1257 enum_value_t *ev = data;
1257 1258
1258 1259 if (strcmp(name, ev->ev_name) == 0) {
1259 1260 *ev->ev_modbuf = value;
1260 1261 return (1);
1261 1262 }
1262 1263 return (0);
1263 1264 }
1264 1265
1265 1266 static int
1266 1267 vread_helper(mdb_ctf_id_t modid, char *modbuf,
1267 1268 mdb_ctf_id_t tgtid, char *tgtbuf, const char *tgtname, uint_t flags)
1268 1269 {
1269 1270 size_t modsz, tgtsz;
1270 1271 int modkind, tgtkind, mod_members;
1271 1272 member_t mbr;
1272 1273 enum_value_t ev;
1273 1274 int ret;
1274 1275 mdb_ctf_arinfo_t tar, mar;
1275 1276 int i;
1276 1277 char typename[128];
1277 1278 char mdbtypename[128];
1278 1279 ctf_encoding_t tgt_encoding, mod_encoding;
1279 1280 boolean_t signed_int = B_FALSE;
1280 1281
1281 1282 if (mdb_ctf_type_name(tgtid, typename, sizeof (typename)) == NULL) {
1282 1283 (void) mdb_snprintf(typename, sizeof (typename),
1283 1284 "#%ul", mdb_ctf_type_id(tgtid));
1284 1285 }
1285 1286 if (mdb_ctf_type_name(modid,
1286 1287 mdbtypename, sizeof (mdbtypename)) == NULL) {
1287 1288 (void) mdb_snprintf(mdbtypename, sizeof (mdbtypename),
1288 1289 "#%ul", mdb_ctf_type_id(modid));
1289 1290 }
1290 1291
1291 1292 if (tgtname == NULL)
1292 1293 tgtname = "";
1293 1294
1294 1295 /*
1295 1296 * Resolve the types to their canonical form.
1296 1297 */
1297 1298 (void) mdb_ctf_type_resolve(modid, &modid);
1298 1299 (void) mdb_ctf_type_resolve(tgtid, &tgtid);
1299 1300
1300 1301 if ((modkind = mdb_ctf_type_kind(modid)) == -1) {
1301 1302 mdb_ctf_warn(flags,
1302 1303 "couldn't determine type kind of mdb module type %s\n",
1303 1304 mdbtypename);
1304 1305 return (-1); /* errno is set for us */
1305 1306 }
1306 1307 if ((tgtkind = mdb_ctf_type_kind(tgtid)) == -1) {
1307 1308 mdb_ctf_warn(flags,
1308 1309 "couldn't determine type kind of %s\n", typename);
1309 1310 return (-1); /* errno is set for us */
1310 1311 }
1311 1312
1312 1313 if ((modsz = mdb_ctf_type_size(modid)) == -1UL) {
1313 1314 mdb_ctf_warn(flags, "couldn't determine type size of "
1314 1315 "mdb module type %s\n", mdbtypename);
1315 1316 return (-1); /* errno is set for us */
1316 1317 }
1317 1318 if ((tgtsz = mdb_ctf_type_size(tgtid)) == -1UL) {
1318 1319 mdb_ctf_warn(flags, "couldn't determine size of %s (%s)\n",
1319 1320 typename, tgtname);
1320 1321 return (-1); /* errno is set for us */
1321 1322 }
1322 1323
1323 1324 if (tgtkind == CTF_K_POINTER && modkind == CTF_K_INTEGER &&
1324 1325 strcmp(mdbtypename, "uintptr_t") == 0) {
1325 1326 /* allow them to convert a pointer to a uintptr_t */
1326 1327 ASSERT(modsz == tgtsz);
1327 1328 } else if (tgtkind != modkind) {
1328 1329 mdb_ctf_warn(flags, "unexpected kind for type %s (%s)\n",
1329 1330 typename, tgtname);
1330 1331 return (set_errno(EMDB_INCOMPAT));
1331 1332 }
1332 1333
1333 1334 switch (tgtkind) {
1334 1335 case CTF_K_INTEGER:
1335 1336 case CTF_K_FLOAT:
1336 1337 /*
1337 1338 * Must determine if the target and module types have the same
1338 1339 * encoding before we can copy them.
1339 1340 */
1340 1341 if (mdb_ctf_type_encoding(tgtid, &tgt_encoding) != 0) {
1341 1342 mdb_ctf_warn(flags,
1342 1343 "couldn't determine encoding of type %s (%s)\n",
1343 1344 typename, tgtname);
1344 1345 return (-1); /* errno is set for us */
1345 1346 }
1346 1347 if (mdb_ctf_type_encoding(modid, &mod_encoding) != 0) {
1347 1348 mdb_ctf_warn(flags, "couldn't determine encoding of "
1348 1349 "mdb module type %s\n", mdbtypename);
1349 1350 return (-1); /* errno is set for us */
1350 1351 }
1351 1352
1352 1353 if (modkind == CTF_K_INTEGER) {
1353 1354 if ((tgt_encoding.cte_format & CTF_INT_SIGNED) !=
1354 1355 (mod_encoding.cte_format & CTF_INT_SIGNED)) {
1355 1356 mdb_ctf_warn(flags,
1356 1357 "signedness mismatch between type "
1357 1358 "%s (%s) and mdb module type %s\n",
1358 1359 typename, tgtname, mdbtypename);
1359 1360 return (set_errno(EMDB_INCOMPAT));
1360 1361 }
1361 1362 signed_int =
1362 1363 ((tgt_encoding.cte_format & CTF_INT_SIGNED) != 0);
1363 1364 } else if (tgt_encoding.cte_format != mod_encoding.cte_format) {
1364 1365 mdb_ctf_warn(flags,
1365 1366 "encoding mismatch (%#x != %#x) between type "
1366 1367 "%s (%s) and mdb module type %s\n",
1367 1368 tgt_encoding.cte_format, mod_encoding.cte_format,
1368 1369 typename, tgtname, mdbtypename);
1369 1370 return (set_errno(EMDB_INCOMPAT));
1370 1371 }
1371 1372 /* FALLTHROUGH */
1372 1373 case CTF_K_POINTER:
1373 1374 /*
1374 1375 * If the sizes don't match we need to be tricky to make
1375 1376 * sure that the caller gets the correct data.
1376 1377 */
1377 1378 if (modsz < tgtsz) {
1378 1379 mdb_ctf_warn(flags, "size of type %s (%s) is too "
1379 1380 "large for mdb module type %s\n",
1380 1381 typename, tgtname, mdbtypename);
1381 1382 return (set_errno(EMDB_INCOMPAT));
1382 1383 } else if (modsz > tgtsz) {
1383 1384 /* BEGIN CSTYLED */
1384 1385 /*
1385 1386 * Fill modbuf with 1's for sign extension if target
1386 1387 * buf is a signed integer and its value is negative.
1387 1388 *
1388 1389 * S = sign bit (in most-significant byte)
1389 1390 *
1390 1391 * BIG ENDIAN DATA
1391 1392 * +--------+--------+--------+--------+
1392 1393 * |S | | | |
1393 1394 * +--------+--------+--------+--------+
1394 1395 * 0 1 ... sz-1 sz
1395 1396 *
1396 1397 * LITTLE ENDIAN DATA
1397 1398 * +--------+--------+--------+--------+
1398 1399 * | | | |S |
1399 1400 * +--------+--------+--------+--------+
1400 1401 * 0 1 ... sz-1 sz
1401 1402 */
1402 1403 /* END CSTYLED */
1403 1404 #ifdef _BIG_ENDIAN
1404 1405 if (signed_int && (tgtbuf[0] & 0x80) != 0)
1405 1406 #else
1406 1407 if (signed_int && (tgtbuf[tgtsz - 1] & 0x80) != 0)
1407 1408 #endif
1408 1409 (void) memset(modbuf, 0xFF, modsz);
1409 1410 else
1410 1411 bzero(modbuf, modsz);
1411 1412 #ifdef _BIG_ENDIAN
1412 1413 bcopy(tgtbuf, modbuf + modsz - tgtsz, tgtsz);
1413 1414 #else
1414 1415 bcopy(tgtbuf, modbuf, tgtsz);
1415 1416 #endif
1416 1417 } else {
1417 1418 bcopy(tgtbuf, modbuf, modsz);
1418 1419 }
1419 1420
1420 1421 return (0);
1421 1422
1422 1423 case CTF_K_ENUM:
1423 1424 if (modsz != tgtsz || modsz != sizeof (int)) {
1424 1425 mdb_ctf_warn(flags, "unexpected size of type %s (%s)\n",
1425 1426 typename, tgtname);
1426 1427 return (set_errno(EMDB_INCOMPAT));
1427 1428 }
1428 1429
1429 1430 /*
1430 1431 * Default to the same value as in the target.
1431 1432 */
1432 1433 bcopy(tgtbuf, modbuf, sizeof (int));
1433 1434
1434 1435 /* LINTED */
1435 1436 i = *(int *)tgtbuf;
1436 1437
1437 1438 /* LINTED */
1438 1439 ev.ev_modbuf = (int *)modbuf;
1439 1440 ev.ev_name = mdb_ctf_enum_name(tgtid, i);
1440 1441 if (ev.ev_name == NULL) {
1441 1442 mdb_ctf_warn(flags,
1442 1443 "unexpected value %u of enum type %s (%s)\n",
1443 1444 i, typename, tgtname);
1444 1445 return (set_errno(EMDB_INCOMPAT));
1445 1446 }
1446 1447
1447 1448 ret = mdb_ctf_enum_iter(modid, enum_cb, &ev);
1448 1449 if (ret == 0) {
1449 1450 /* value not found */
1450 1451 mdb_ctf_warn(flags,
1451 1452 "unexpected value %s (%u) of enum type %s (%s)\n",
1452 1453 ev.ev_name, i, typename, tgtname);
1453 1454 return (set_errno(EMDB_INCOMPAT));
1454 1455 } else if (ret == 1) {
1455 1456 /* value found */
1456 1457 return (0);
1457 1458 } else if (ret == -1) {
1458 1459 mdb_ctf_warn(flags, "could not iterate enum %s (%s)\n",
1459 1460 typename, tgtname);
1460 1461 }
1461 1462 return (ret);
1462 1463
1463 1464 case CTF_K_STRUCT:
1464 1465 mbr.m_modbuf = modbuf;
1465 1466 mbr.m_tgtbuf = tgtbuf;
1466 1467 mbr.m_tgtid = tgtid;
1467 1468 mbr.m_flags = flags;
1468 1469 mbr.m_tgtname = typename;
1469 1470
1470 1471 return (mdb_ctf_member_iter(modid, member_cb, &mbr));
1471 1472
1472 1473 case CTF_K_UNION:
1473 1474 mbr.m_modbuf = modbuf;
1474 1475 mbr.m_tgtbuf = tgtbuf;
1475 1476 mbr.m_tgtid = tgtid;
1476 1477 mbr.m_flags = flags;
1477 1478 mbr.m_tgtname = typename;
1478 1479
1479 1480 /*
1480 1481 * Not all target union members need to be present in the
1481 1482 * mdb type. If there is only a single union member in the
1482 1483 * mdb type, its actual type does not need to match with
1483 1484 * its target's type. On the other hand, if more than one
1484 1485 * union members are specified in the mdb type, their types
1485 1486 * must match with the types of their relevant union members
1486 1487 * of the target union.
1487 1488 */
1488 1489 mod_members = mdb_ctf_num_members(modid);
1489 1490 if (mod_members == 1) {
1490 1491 return (mdb_ctf_member_iter(modid, member_cb, &mbr));
1491 1492 } else if (mod_members > 1) {
1492 1493 if (mdb_ctf_member_iter(modid, type_equals_cb,
1493 1494 &tgtid)) {
1494 1495 mdb_ctf_warn(flags,
1495 1496 "inexact match for union %s (%s)\n",
1496 1497 typename, tgtname);
1497 1498 return (set_errno(EMDB_INCOMPAT));
1498 1499 }
1499 1500
1500 1501 /*
1501 1502 * From the check above we know that the members
1502 1503 * which are present in the mdb type are equal to
1503 1504 * the types in the target. Thus, the member_cb
1504 1505 * callback below will not move anything around and
1505 1506 * it is equivalent to:
1506 1507 *
1507 1508 * bcopy(tgtbuf, modbuf, MAX(module member's sizes))
1508 1509 */
1509 1510 return (mdb_ctf_member_iter(modid, member_cb, &mbr));
1510 1511 } else {
1511 1512 /*
1512 1513 * We either got 0 or -1. In any case that number
1513 1514 * should be returned right away. For the error
1514 1515 * case of -1, errno has been set for us.
1515 1516 */
1516 1517 return (mod_members);
1517 1518 }
1518 1519
1519 1520 case CTF_K_ARRAY:
1520 1521 if (mdb_ctf_array_info(tgtid, &tar) != 0) {
1521 1522 mdb_ctf_warn(flags,
1522 1523 "couldn't get array info for %s (%s)\n",
1523 1524 typename, tgtname);
1524 1525 return (-1); /* errno is set for us */
1525 1526 }
1526 1527 if (mdb_ctf_array_info(modid, &mar) != 0) {
1527 1528 mdb_ctf_warn(flags,
1528 1529 "couldn't get array info for mdb module type %s\n",
1529 1530 mdbtypename);
1530 1531 return (-1); /* errno is set for us */
1531 1532 }
1532 1533
1533 1534 if (tar.mta_nelems != mar.mta_nelems) {
1534 1535 mdb_ctf_warn(flags,
1535 1536 "unexpected array size (%u) for type %s (%s)\n",
1536 1537 tar.mta_nelems, typename, tgtname);
1537 1538 return (set_errno(EMDB_INCOMPAT));
1538 1539 }
1539 1540
1540 1541 if ((modsz = mdb_ctf_type_size(mar.mta_contents)) == -1UL) {
1541 1542 mdb_ctf_warn(flags, "couldn't determine type size of "
1542 1543 "mdb module type %s\n", mdbtypename);
1543 1544 return (-1); /* errno is set for us */
1544 1545 }
1545 1546 if ((tgtsz = mdb_ctf_type_size(tar.mta_contents)) == -1UL) {
1546 1547 mdb_ctf_warn(flags,
1547 1548 "couldn't determine size of %s (%s)\n",
1548 1549 typename, tgtname);
1549 1550 return (-1); /* errno is set for us */
1550 1551 }
1551 1552
1552 1553 for (i = 0; i < tar.mta_nelems; i++) {
1553 1554 ret = vread_helper(mar.mta_contents, modbuf + i * modsz,
1554 1555 tar.mta_contents, tgtbuf + i * tgtsz,
1555 1556 tgtname, flags);
1556 1557
1557 1558 if (ret != 0)
1558 1559 return (ret);
1559 1560 }
1560 1561
1561 1562 return (0);
1562 1563 }
1563 1564
1564 1565 mdb_ctf_warn(flags, "unsupported kind %d for type %s (%s)\n",
1565 1566 modkind, typename, tgtname);
1566 1567 return (set_errno(EMDB_INCOMPAT));
1567 1568 }
1568 1569
1569 1570 /*
1570 1571 * Like mdb_vread(), mdb_ctf_vread() is used to read from the target's
1571 1572 * virtual address space. However, mdb_ctf_vread() can be used to safely
1572 1573 * read a complex type (e.g. a struct) from the target, even if MDB was compiled
1573 1574 * against a different definition of that type (e.g. when debugging a crash
1574 1575 * dump from an older release).
1575 1576 *
1576 1577 * Callers can achieve this by defining their own type which corresponds to the
1577 1578 * type in the target, but contains only the members that the caller requires.
1578 1579 * Using the CTF type information embedded in the target, mdb_ctf_vread will
1579 1580 * find the required members in the target and fill in the caller's structure.
1580 1581 * The members are located by name, and their types are verified to be
1581 1582 * compatible.
1582 1583 *
1583 1584 * By convention, the caller will declare a type with the name "mdb_<type>",
1584 1585 * where <type> is the name of the type in the target (e.g. mdb_zio_t). This
1585 1586 * type will contain the members that the caller is interested in. For example:
1586 1587 *
1587 1588 * typedef struct mdb_zio {
1588 1589 * enum zio_type io_type;
1589 1590 * uintptr_t io_waiter;
1590 1591 * struct {
1591 1592 * struct {
1592 1593 * uintptr_t list_next;
1593 1594 * } list_head;
1594 1595 * } io_parent_list;
1595 1596 * int io_error;
1596 1597 * } mdb_zio_t;
1597 1598 *
1598 1599 * mdb_zio_t zio;
1599 1600 * error = mdb_ctf_vread(&zio, "zio_t", "mdb_zio_t", zio_target_addr, 0);
1600 1601 *
1601 1602 * If a given MDB module has different dcmds or walkers that need to read
1602 1603 * different members from the same struct, then different "mdb_" types
1603 1604 * should be declared for each caller. By convention, these types should
1604 1605 * be named "mdb_<dcmd or walker>_<type>", e.g. mdb_findstack_kthread_t
↓ open down ↓ |
354 lines elided |
↑ open up ↑ |
1605 1606 * for ::findstack. If the MDB module is compiled from several source files,
1606 1607 * one must be especially careful to not define different types with the
1607 1608 * same name in different source files, because the compiler can not detect
1608 1609 * this error.
1609 1610 *
1610 1611 * Enums will also be translated by name, so the mdb module will receive
1611 1612 * the enum value it expects even if the target has renumbered the enum.
1612 1613 * Warning: it will therefore only work with enums are only used to store
1613 1614 * legitimate enum values (not several values or-ed together).
1614 1615 *
1615 - * By default, if mdb_ctf_vread() can not find any members or enum values,
1616 - * it will print a descriptive message (with mdb_warn()) and fail.
1617 - * Passing MDB_CTF_VREAD_QUIET in 'flags' will suppress the warning message.
1618 - * Additional flags can be used to ignore specific types of translation
1619 - * failure, but should be used with caution, because they will silently leave
1620 - * the caller's buffer uninitialized.
1616 + * Flags values:
1617 + *
1618 + * MDB_CTF_VREAD_QUIET: keep quiet about failures
1619 + * MDB_CTF_VREAD_IGNORE_ABSENT: ignore any member that couldn't be found in the
1620 + * target struct; be careful not to use an uninitialized result.
1621 1621 */
1622 1622 int
1623 1623 mdb_ctf_vread(void *modbuf, const char *target_typename,
1624 1624 const char *mdb_typename, uintptr_t addr, uint_t flags)
1625 1625 {
1626 1626 ctf_file_t *mfp;
1627 1627 ctf_id_t mid;
1628 1628 void *tgtbuf;
1629 1629 size_t size;
1630 1630 mdb_ctf_id_t tgtid;
1631 1631 mdb_ctf_id_t modid;
1632 1632 mdb_module_t *mod;
1633 + int ret;
1633 1634
1634 1635 if ((mod = mdb_get_module()) == NULL || (mfp = mod->mod_ctfp) == NULL) {
1635 1636 mdb_ctf_warn(flags, "no ctf data found for mdb module %s\n",
1636 1637 mod->mod_name);
1637 1638 return (set_errno(EMDB_NOCTF));
1638 1639 }
1639 1640
1640 1641 if ((mid = ctf_lookup_by_name(mfp, mdb_typename)) == CTF_ERR) {
1641 1642 mdb_ctf_warn(flags, "couldn't find ctf data for "
1642 1643 "type %s in mdb module %s\n",
1643 1644 mdb_typename, mod->mod_name);
1644 1645 return (set_errno(ctf_to_errno(ctf_errno(mfp))));
1645 1646 }
1646 1647
1647 1648 set_ctf_id(&modid, mfp, mid);
1648 1649
1649 1650 if (mdb_ctf_lookup_by_name(target_typename, &tgtid) != 0) {
1650 1651 mdb_ctf_warn(flags,
1651 1652 "couldn't find type %s in target's ctf data\n",
1652 1653 target_typename);
1653 1654 return (set_errno(EMDB_NOCTF));
1654 1655 }
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
1655 1656
1656 1657 /*
1657 1658 * Read the data out of the target's address space.
1658 1659 */
1659 1660 if ((size = mdb_ctf_type_size(tgtid)) == -1UL) {
1660 1661 mdb_ctf_warn(flags, "couldn't determine size of type %s\n",
1661 1662 target_typename);
1662 1663 return (-1); /* errno is set for us */
1663 1664 }
1664 1665
1665 - tgtbuf = mdb_alloc(size, UM_SLEEP | UM_GC);
1666 + tgtbuf = mdb_alloc(size, UM_SLEEP);
1666 1667
1667 1668 if (mdb_vread(tgtbuf, size, addr) < 0) {
1668 1669 mdb_ctf_warn(flags, "couldn't read %s from %p\n",
1669 1670 target_typename, addr);
1671 + mdb_free(tgtbuf, size);
1670 1672 return (-1); /* errno is set for us */
1671 1673 }
1672 1674
1673 - return (vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags));
1675 + ret = vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags);
1676 +
1677 + mdb_free(tgtbuf, size);
1678 +
1679 + return (ret);
1674 1680 }
1675 1681
1676 1682 /*
1677 1683 * Note: mdb_ctf_readsym() doesn't take separate parameters for the name
1678 1684 * of the target's type vs the mdb module's type. Use with complicated
1679 1685 * types (e.g. structs) may result in unnecessary failure if a member of
1680 1686 * the struct has been changed in the target, but is not actually needed
1681 1687 * by the mdb module. Use mdb_lookup_by_name() + mdb_ctf_vread() to
1682 1688 * avoid this problem.
1683 1689 */
1684 1690 int
1685 1691 mdb_ctf_readsym(void *buf, const char *typename, const char *name, uint_t flags)
1686 1692 {
1687 1693 GElf_Sym sym;
1688 1694
1689 1695 if (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY, name, &sym) != 0) {
1690 1696 mdb_ctf_warn(flags, "couldn't find symbol %s\n", name);
1691 1697 return (-1); /* errno is set for us */
1692 1698 }
1693 1699
1694 1700 return (mdb_ctf_vread(buf, typename, typename, sym.st_value, flags));
1695 1701 }
1696 1702
1697 1703 ctf_file_t *
1698 1704 mdb_ctf_bufopen(const void *ctf_va, size_t ctf_size, const void *sym_va,
1699 1705 Shdr *symhdr, const void *str_va, Shdr *strhdr, int *errp)
1700 1706 {
1701 1707 ctf_sect_t ctdata, symtab, strtab;
1702 1708
1703 1709 ctdata.cts_name = ".SUNW_ctf";
1704 1710 ctdata.cts_type = SHT_PROGBITS;
1705 1711 ctdata.cts_flags = 0;
1706 1712 ctdata.cts_data = ctf_va;
1707 1713 ctdata.cts_size = ctf_size;
1708 1714 ctdata.cts_entsize = 1;
1709 1715 ctdata.cts_offset = 0;
1710 1716
1711 1717 symtab.cts_name = ".symtab";
1712 1718 symtab.cts_type = symhdr->sh_type;
1713 1719 symtab.cts_flags = symhdr->sh_flags;
1714 1720 symtab.cts_data = sym_va;
1715 1721 symtab.cts_size = symhdr->sh_size;
1716 1722 symtab.cts_entsize = symhdr->sh_entsize;
1717 1723 symtab.cts_offset = symhdr->sh_offset;
1718 1724
1719 1725 strtab.cts_name = ".strtab";
1720 1726 strtab.cts_type = strhdr->sh_type;
1721 1727 strtab.cts_flags = strhdr->sh_flags;
1722 1728 strtab.cts_data = str_va;
1723 1729 strtab.cts_size = strhdr->sh_size;
1724 1730 strtab.cts_entsize = strhdr->sh_entsize;
1725 1731 strtab.cts_offset = strhdr->sh_offset;
1726 1732
1727 1733 return (ctf_bufopen(&ctdata, &symtab, &strtab, errp));
1728 1734 }
1729 1735
1730 1736 int
1731 1737 mdb_ctf_synthetics_init(void)
1732 1738 {
1733 1739 int err;
1734 1740
1735 1741 if ((mdb.m_synth = ctf_create(&err)) == NULL)
1736 1742 return (set_errno(ctf_to_errno(err)));
1737 1743
1738 1744 return (0);
1739 1745 }
1740 1746
1741 1747 void
1742 1748 mdb_ctf_synthetics_fini(void)
1743 1749 {
1744 1750 if (mdb.m_synth == NULL)
1745 1751 return;
1746 1752
1747 1753 ctf_close(mdb.m_synth);
1748 1754 mdb.m_synth = NULL;
1749 1755 }
1750 1756
1751 1757 int
1752 1758 mdb_ctf_synthetics_create_base(int kind)
1753 1759 {
1754 1760 const synth_intrinsic_t *synp;
1755 1761 const synth_typedef_t *sytp;
1756 1762 int err;
1757 1763 ctf_id_t id;
1758 1764 ctf_file_t *cp = mdb.m_synth;
1759 1765
1760 1766 if (mdb.m_synth == NULL) {
1761 1767 mdb_printf("synthetic types disabled: ctf create failed\n");
1762 1768 return (1);
1763 1769 }
1764 1770
1765 1771 switch (kind) {
1766 1772 case SYNTHETIC_ILP32:
1767 1773 synp = synth_builtins32;
1768 1774 sytp = synth_typedefs32;
1769 1775 break;
1770 1776 case SYNTHETIC_LP64:
1771 1777 synp = synth_builtins64;
1772 1778 sytp = synth_typedefs64;
1773 1779 break;
1774 1780 default:
1775 1781 mdb_dprintf(MDB_DBG_CTF, "invalid type of intrinsic: %d\n",
1776 1782 kind);
1777 1783 return (1);
1778 1784 }
1779 1785
1780 1786 err = 0;
1781 1787 for (; synp->syn_name != NULL; synp++) {
1782 1788 if (synp->syn_kind == CTF_K_INTEGER) {
1783 1789 err = ctf_add_integer(cp, CTF_ADD_ROOT, synp->syn_name,
1784 1790 &synp->syn_enc);
1785 1791 } else {
1786 1792 err = ctf_add_float(cp, CTF_ADD_ROOT, synp->syn_name,
1787 1793 &synp->syn_enc);
1788 1794 }
1789 1795
1790 1796 if (err == CTF_ERR) {
1791 1797 mdb_dprintf(MDB_DBG_CTF, "couldn't add synthetic "
1792 1798 "type: %s\n", synp->syn_name);
1793 1799 goto discard;
1794 1800 }
1795 1801 }
1796 1802
1797 1803 if (ctf_update(cp) == CTF_ERR) {
1798 1804 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n");
1799 1805 goto discard;
1800 1806 }
1801 1807
1802 1808 for (; sytp->syt_src != NULL; sytp++) {
1803 1809 id = ctf_lookup_by_name(cp, sytp->syt_src);
1804 1810 if (id == CTF_ERR) {
1805 1811 mdb_dprintf(MDB_DBG_CTF, "cailed to lookup %s: %s\n",
1806 1812 sytp->syt_src, ctf_errmsg(ctf_errno(cp)));
1807 1813 goto discard;
1808 1814 }
1809 1815 if (ctf_add_typedef(cp, CTF_ADD_ROOT, sytp->syt_targ, id) ==
1810 1816 CTF_ERR) {
1811 1817 mdb_dprintf(MDB_DBG_CTF, "couldn't add typedef %s "
1812 1818 "%s: %s\n", sytp->syt_targ, sytp->syt_src,
1813 1819 ctf_errmsg(ctf_errno(cp)));
1814 1820 goto discard;
1815 1821 }
1816 1822 }
1817 1823
1818 1824 if (ctf_update(cp) == CTF_ERR) {
1819 1825 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n");
1820 1826 goto discard;
1821 1827 }
1822 1828
1823 1829 return (0);
1824 1830
1825 1831 discard:
1826 1832 err = set_errno(ctf_to_errno(ctf_errno(cp)));
1827 1833 (void) ctf_discard(cp);
1828 1834 return (err);
1829 1835 }
1830 1836
1831 1837 int
1832 1838 mdb_ctf_synthetics_reset(void)
1833 1839 {
1834 1840 mdb_ctf_synthetics_fini();
1835 1841 return (mdb_ctf_synthetics_init());
1836 1842 }
1837 1843
1838 1844 int
1839 1845 mdb_ctf_add_typedef(const char *name, const mdb_ctf_id_t *p, mdb_ctf_id_t *new)
1840 1846 {
1841 1847 ctf_id_t rid;
1842 1848 mdb_ctf_id_t tid;
1843 1849 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
1844 1850
1845 1851 if (mdb.m_synth == NULL) {
1846 1852 mdb_printf("synthetic types disabled: ctf create failed\n");
1847 1853 return (1);
1848 1854 }
1849 1855
1850 1856 if (mdb_ctf_lookup_by_name(name, &tid) == 0) {
1851 1857 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type "
1852 1858 "with that name already exists\n", name);
1853 1859 return (set_errno(EEXIST));
1854 1860 }
1855 1861
1856 1862 rid = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
1857 1863 if (rid == CTF_ERR) {
1858 1864 mdb_dprintf(MDB_DBG_CTF, "failed to add reference type: %s\n",
1859 1865 ctf_errmsg(ctf_errno(mdb.m_synth)));
1860 1866 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1861 1867 }
1862 1868 rid = ctf_add_typedef(mdb.m_synth, CTF_ADD_ROOT, name, rid);
1863 1869 if (rid == CTF_ERR) {
1864 1870 mdb_dprintf(MDB_DBG_CTF, "failed to add typedef: %s",
1865 1871 ctf_errmsg(ctf_errno(mdb.m_synth)));
1866 1872 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1867 1873 }
1868 1874
1869 1875 if (ctf_update(mdb.m_synth) == CTF_ERR) {
1870 1876 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1871 1877 ctf_errmsg(ctf_errno(mdb.m_synth)));
1872 1878 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1873 1879 }
1874 1880
1875 1881 if (new != NULL)
1876 1882 set_ctf_id(new, mdb.m_synth, rid);
1877 1883
1878 1884 return (0);
1879 1885 }
1880 1886
1881 1887 int
1882 1888 mdb_ctf_add_struct(const char *name, mdb_ctf_id_t *rid)
1883 1889 {
1884 1890 mdb_ctf_id_t tid;
1885 1891 ctf_id_t id;
1886 1892
1887 1893 if (mdb.m_synth == NULL) {
1888 1894 mdb_printf("synthetic types disabled: ctf create failed\n");
1889 1895 return (1);
1890 1896 }
1891 1897
1892 1898 if (name != NULL && mdb_ctf_lookup_by_name(name, &tid) == 0) {
1893 1899 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type "
1894 1900 "with that name already exists\n", name);
1895 1901 return (set_errno(EEXIST));
1896 1902 }
1897 1903
1898 1904 if ((id = ctf_add_struct(mdb.m_synth, CTF_ADD_ROOT, name)) ==
1899 1905 CTF_ERR) {
1900 1906 mdb_dprintf(MDB_DBG_CTF, "failed to add struct: %s\n",
1901 1907 ctf_errmsg(ctf_errno(mdb.m_synth)));
1902 1908 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1903 1909 }
1904 1910
1905 1911 if (ctf_update(mdb.m_synth) == CTF_ERR) {
1906 1912 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1907 1913 ctf_errmsg(ctf_errno(mdb.m_synth)));
1908 1914 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1909 1915 }
1910 1916
1911 1917 if (rid != NULL)
1912 1918 set_ctf_id(rid, mdb.m_synth, id);
1913 1919
1914 1920 return (0);
1915 1921 }
1916 1922
1917 1923 int
1918 1924 mdb_ctf_add_union(const char *name, mdb_ctf_id_t *rid)
1919 1925 {
1920 1926 mdb_ctf_id_t tid;
1921 1927 ctf_id_t id;
1922 1928
1923 1929 if (mdb.m_synth == NULL) {
1924 1930 mdb_printf("synthetic types disabled: ctf create failed\n");
1925 1931 return (1);
1926 1932 }
1927 1933
1928 1934 if (name != NULL && mdb_ctf_lookup_by_name(name, &tid) == 0) {
1929 1935 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type "
1930 1936 "with that name already exists\n", name);
1931 1937 return (set_errno(EEXIST));
1932 1938 }
1933 1939
1934 1940 if ((id = ctf_add_union(mdb.m_synth, CTF_ADD_ROOT, name)) ==
1935 1941 CTF_ERR) {
1936 1942 mdb_dprintf(MDB_DBG_CTF, "failed to add union: %s\n",
1937 1943 ctf_errmsg(ctf_errno(mdb.m_synth)));
1938 1944 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1939 1945 }
1940 1946
1941 1947 if (ctf_update(mdb.m_synth) == CTF_ERR) {
1942 1948 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1943 1949 ctf_errmsg(ctf_errno(mdb.m_synth)));
1944 1950 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1945 1951 }
1946 1952
1947 1953 if (rid != NULL)
1948 1954 set_ctf_id(rid, mdb.m_synth, id);
1949 1955
1950 1956 return (0);
1951 1957 }
1952 1958
1953 1959 int
1954 1960 mdb_ctf_add_member(const mdb_ctf_id_t *p, const char *name,
1955 1961 const mdb_ctf_id_t *mtype, mdb_ctf_id_t *rid)
1956 1962 {
1957 1963 ctf_id_t id, mtid;
1958 1964 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
1959 1965 mdb_ctf_impl_t *mcim = (mdb_ctf_impl_t *)mtype;
1960 1966
1961 1967 if (mdb.m_synth == NULL) {
1962 1968 mdb_printf("synthetic types disabled: ctf create failed\n");
1963 1969 return (DCMD_ERR);
1964 1970 }
1965 1971
1966 1972 if (mcip->mci_fp != mdb.m_synth) {
1967 1973 mdb_dprintf(MDB_DBG_CTF, "requested to add member to a type "
1968 1974 "that wasn't created from a synthetic\n");
1969 1975 return (set_errno(EINVAL));
1970 1976 }
1971 1977
1972 1978 mtid = ctf_add_type(mdb.m_synth, mcim->mci_fp, mcim->mci_id);
1973 1979 if (mtid == CTF_ERR) {
1974 1980 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n",
1975 1981 ctf_errmsg(ctf_errno(mdb.m_synth)));
1976 1982 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1977 1983 }
1978 1984
1979 1985 if (ctf_update(mdb.m_synth) == CTF_ERR) {
1980 1986 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1981 1987 ctf_errmsg(ctf_errno(mdb.m_synth)));
1982 1988 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1983 1989 }
1984 1990
1985 1991 id = ctf_add_member(mdb.m_synth, mcip->mci_id, name, mtid, ULONG_MAX);
1986 1992 if (id == CTF_ERR) {
1987 1993 mdb_dprintf(MDB_DBG_CTF, "failed to add member %s: %s\n",
1988 1994 name, ctf_errmsg(ctf_errno(mdb.m_synth)));
1989 1995 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1990 1996 }
1991 1997
1992 1998 if (ctf_update(mdb.m_synth) == CTF_ERR) {
1993 1999 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1994 2000 ctf_errmsg(ctf_errno(mdb.m_synth)));
1995 2001 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1996 2002 }
1997 2003
1998 2004 if (rid != NULL)
1999 2005 set_ctf_id(rid, mdb.m_synth, id);
2000 2006
2001 2007 return (0);
2002 2008 }
2003 2009
2004 2010 int
2005 2011 mdb_ctf_add_array(const mdb_ctf_arinfo_t *marp, mdb_ctf_id_t *rid)
2006 2012 {
2007 2013 mdb_ctf_impl_t *mcip;
2008 2014 ctf_arinfo_t car;
2009 2015 ctf_id_t id;
2010 2016
2011 2017 if (mdb.m_synth == NULL) {
2012 2018 mdb_printf("synthetic types disabled: ctf create failed\n");
2013 2019 return (1);
2014 2020 }
2015 2021
2016 2022 car.ctr_nelems = marp->mta_nelems;
2017 2023
2018 2024 mcip = (mdb_ctf_impl_t *)&marp->mta_contents;
2019 2025 id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
2020 2026 if (id == CTF_ERR) {
2021 2027 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n",
2022 2028 ctf_errmsg(ctf_errno(mdb.m_synth)));
2023 2029 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2024 2030 }
2025 2031 car.ctr_contents = id;
2026 2032
2027 2033 mcip = (mdb_ctf_impl_t *)&marp->mta_index;
2028 2034 id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
2029 2035 if (id == CTF_ERR) {
2030 2036 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n",
2031 2037 ctf_errmsg(ctf_errno(mdb.m_synth)));
2032 2038 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2033 2039 }
2034 2040 car.ctr_index = id;
2035 2041
2036 2042 if (ctf_update(mdb.m_synth) == CTF_ERR) {
2037 2043 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2038 2044 ctf_errmsg(ctf_errno(mdb.m_synth)));
2039 2045 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2040 2046 }
2041 2047
2042 2048 id = ctf_add_array(mdb.m_synth, CTF_ADD_ROOT, &car);
2043 2049 if (id == CTF_ERR) {
2044 2050 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2045 2051 ctf_errmsg(ctf_errno(mdb.m_synth)));
2046 2052 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2047 2053 }
2048 2054
2049 2055 if (ctf_update(mdb.m_synth) == CTF_ERR) {
2050 2056 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2051 2057 ctf_errmsg(ctf_errno(mdb.m_synth)));
2052 2058 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2053 2059 }
2054 2060
2055 2061 if (rid != NULL)
2056 2062 set_ctf_id(rid, mdb.m_synth, id);
2057 2063
2058 2064 return (0);
2059 2065 }
2060 2066
2061 2067 int
2062 2068 mdb_ctf_add_pointer(const mdb_ctf_id_t *p, mdb_ctf_id_t *rid)
2063 2069 {
2064 2070 ctf_id_t id;
2065 2071 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
2066 2072
2067 2073 if (mdb.m_synth == NULL) {
2068 2074 mdb_printf("synthetic types disabled: ctf create failed\n");
2069 2075 return (1);
2070 2076 }
2071 2077
2072 2078 id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
2073 2079 if (id == CTF_ERR) {
2074 2080 mdb_dprintf(MDB_DBG_CTF, "failed to add pointer type: %s\n",
2075 2081 ctf_errmsg(ctf_errno(mdb.m_synth)));
2076 2082 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2077 2083 }
2078 2084
2079 2085 if (ctf_update(mdb.m_synth) == CTF_ERR) {
2080 2086 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2081 2087 ctf_errmsg(ctf_errno(mdb.m_synth)));
2082 2088 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2083 2089 }
2084 2090
2085 2091
2086 2092 id = ctf_add_pointer(mdb.m_synth, CTF_ADD_ROOT, NULL, id);
2087 2093 if (id == CTF_ERR) {
2088 2094 mdb_dprintf(MDB_DBG_CTF, "failed to add pointer: %s\n",
2089 2095 ctf_errmsg(ctf_errno(mdb.m_synth)));
2090 2096 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2091 2097 }
2092 2098
2093 2099 if (ctf_update(mdb.m_synth) == CTF_ERR) {
2094 2100 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2095 2101 ctf_errmsg(ctf_errno(mdb.m_synth)));
2096 2102 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2097 2103 }
2098 2104
2099 2105
2100 2106 if (rid != NULL)
2101 2107 set_ctf_id(rid, mdb.m_synth, id);
2102 2108
2103 2109 return (0);
2104 2110 }
2105 2111
2106 2112 int
2107 2113 mdb_ctf_type_delete(const mdb_ctf_id_t *id)
2108 2114 {
2109 2115 int ret;
2110 2116
2111 2117 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)id;
2112 2118
2113 2119 if (mcip->mci_fp != mdb.m_synth) {
2114 2120 mdb_warn("bad ctf_file_t, expected synth container\n");
2115 2121 return (1);
2116 2122 }
2117 2123
2118 2124 ret = ctf_delete_type(mcip->mci_fp, mcip->mci_id);
2119 2125 if (ret != 0) {
2120 2126 mdb_dprintf(MDB_DBG_CTF, "failed to delete synthetic type: %s",
2121 2127 ctf_errmsg(ctf_errno(mdb.m_synth)));
2122 2128 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2123 2129 }
2124 2130
2125 2131 if (ctf_update(mdb.m_synth) == CTF_ERR) {
2126 2132 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2127 2133 ctf_errmsg(ctf_errno(mdb.m_synth)));
2128 2134 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2129 2135 }
2130 2136
2131 2137 return (0);
2132 2138 }
2133 2139
2134 2140 /* ARGSUSED */
2135 2141 static int
2136 2142 mdb_ctf_synthetics_file_cb(mdb_ctf_id_t id, void *arg)
2137 2143 {
2138 2144 ctf_file_t *targ = arg;
2139 2145 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)&id;
2140 2146
2141 2147 if (ctf_add_type(targ, mcip->mci_fp, mcip->mci_id) == CTF_ERR) {
2142 2148 mdb_dprintf(MDB_DBG_CTF, "failed to add type %d: %s\n",
2143 2149 mcip->mci_id, ctf_errmsg(ctf_errno(mcip->mci_fp)));
2144 2150 return (set_errno(ctf_to_errno(ctf_errno(mcip->mci_fp))));
2145 2151 }
2146 2152
2147 2153 return (0);
2148 2154 }
2149 2155
2150 2156 int
2151 2157 mdb_ctf_synthetics_from_file(const char *file)
2152 2158 {
2153 2159 ctf_file_t *fp, *syn = mdb.m_synth;
2154 2160 int ret;
2155 2161 type_iter_t ti;
2156 2162
2157 2163 if (syn == NULL) {
2158 2164 mdb_warn("synthetic types disabled: ctf create failed\n");
2159 2165 return (1);
2160 2166 }
2161 2167
2162 2168 if ((fp = mdb_ctf_open(file, &ret)) == NULL) {
2163 2169 mdb_warn("failed to parse ctf data in %s: %s\n", file,
2164 2170 ctf_errmsg(ret));
2165 2171 return (1);
2166 2172 }
2167 2173
2168 2174 ret = DCMD_OK;
2169 2175 ti.ti_fp = fp;
2170 2176 ti.ti_arg = syn;
2171 2177 ti.ti_cb = mdb_ctf_synthetics_file_cb;
2172 2178 if (ctf_type_iter(fp, B_FALSE, type_iter_cb, &ti) == CTF_ERR) {
2173 2179 ret = set_errno(ctf_to_errno(ctf_errno(fp)));
2174 2180 mdb_warn("failed to add types");
2175 2181 goto cleanup;
2176 2182 }
2177 2183
2178 2184 if (ctf_update(syn) == CTF_ERR) {
2179 2185 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n");
2180 2186 ret = set_errno(ctf_to_errno(ctf_errno(fp)));
2181 2187 }
2182 2188
2183 2189 cleanup:
2184 2190 ctf_close(fp);
2185 2191 if (ret != 0)
2186 2192 (void) ctf_discard(syn);
2187 2193 return (ret);
2188 2194 }
2189 2195
2190 2196 int
2191 2197 mdb_ctf_synthetics_to_file(const char *file)
2192 2198 {
2193 2199 int err;
2194 2200 ctf_file_t *fp = mdb.m_synth;
2195 2201
2196 2202 if (fp == NULL) {
2197 2203 mdb_warn("synthetic types are disabled, not writing "
2198 2204 "anything\n");
2199 2205 return (DCMD_ERR);
2200 2206 }
2201 2207
2202 2208 err = mdb_ctf_write(file, fp);
2203 2209 if (err != 0) {
2204 2210 if (err == CTF_ERR)
2205 2211 (void) set_errno(ctf_to_errno(ctf_errno(fp)));
2206 2212 else
2207 2213 (void) set_errno(err);
2208 2214 err = DCMD_ERR;
2209 2215 } else {
2210 2216 err = DCMD_OK;
2211 2217 }
2212 2218
2213 2219 return (err);
2214 2220 }
↓ open down ↓ |
531 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX