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