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 by Delphix. All rights reserved. 27 * Copyright (c) 2015, Joyent, Inc. All rights reserved. 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 916 /*ARGSUSED*/ 917 static int 918 num_members_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data) 919 { 920 int *count = data; 921 *count = *count + 1; 922 return (0); 923 } 924 925 int 926 mdb_ctf_num_members(mdb_ctf_id_t id) 927 { 928 int count = 0; 929 930 if (mdb_ctf_member_iter(id, num_members_cb, &count) != 0) 931 return (-1); /* errno is set for us */ 932 933 return (count); 934 } 935 936 typedef struct mbr_contains { 937 char **mbc_bufp; 938 size_t *mbc_lenp; 939 ulong_t *mbc_offp; 940 mdb_ctf_id_t *mbc_idp; 941 ssize_t mbc_total; 942 } mbr_contains_t; 943 944 static int 945 offset_to_name_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data) 946 { 947 mbr_contains_t *mbc = data; 948 ulong_t size; 949 ctf_encoding_t e; 950 size_t n; 951 952 if (*mbc->mbc_offp < off) 953 return (0); 954 955 if (mdb_ctf_type_encoding(id, &e) == -1) 956 size = mdb_ctf_type_size(id) * NBBY; 957 else 958 size = e.cte_bits; 959 960 if (off + size <= *mbc->mbc_offp) 961 return (0); 962 963 n = mdb_snprintf(*mbc->mbc_bufp, *mbc->mbc_lenp, "%s", name); 964 mbc->mbc_total += n; 965 if (n > *mbc->mbc_lenp) 966 n = *mbc->mbc_lenp; 967 968 *mbc->mbc_lenp -= n; 969 *mbc->mbc_bufp += n; 970 971 *mbc->mbc_offp -= off; 972 *mbc->mbc_idp = id; 973 974 return (1); 975 } 976 977 ssize_t 978 mdb_ctf_offset_to_name(mdb_ctf_id_t id, ulong_t off, char *buf, size_t len, 979 int dot, mdb_ctf_id_t *midp, ulong_t *moffp) 980 { 981 size_t size; 982 size_t n; 983 mbr_contains_t mbc; 984 985 if (!mdb_ctf_type_valid(id)) 986 return (set_errno(EINVAL)); 987 988 /* 989 * Quick sanity check to make sure the given offset is within 990 * this scope of this type. 991 */ 992 if (mdb_ctf_type_size(id) * NBBY <= off) 993 return (set_errno(EINVAL)); 994 995 mbc.mbc_bufp = &buf; 996 mbc.mbc_lenp = &len; 997 mbc.mbc_offp = &off; 998 mbc.mbc_idp = &id; 999 mbc.mbc_total = 0; 1000 1001 *buf = '\0'; 1002 1003 for (;;) { 1004 /* 1005 * Check for an exact match. 1006 */ 1007 if (off == 0) 1008 break; 1009 1010 (void) mdb_ctf_type_resolve(id, &id); 1011 1012 /* 1013 * Find the member that contains this offset. 1014 */ 1015 switch (mdb_ctf_type_kind(id)) { 1016 case CTF_K_ARRAY: { 1017 mdb_ctf_arinfo_t ar; 1018 uint_t index; 1019 1020 (void) mdb_ctf_array_info(id, &ar); 1021 size = mdb_ctf_type_size(ar.mta_contents) * NBBY; 1022 index = off / size; 1023 1024 id = ar.mta_contents; 1025 off %= size; 1026 1027 n = mdb_snprintf(buf, len, "[%u]", index); 1028 mbc.mbc_total += n; 1029 if (n > len) 1030 n = len; 1031 1032 buf += n; 1033 len -= n; 1034 break; 1035 } 1036 1037 case CTF_K_STRUCT: { 1038 int ret; 1039 1040 /* 1041 * Find the member that contains this offset 1042 * and continue. 1043 */ 1044 1045 if (dot) { 1046 mbc.mbc_total++; 1047 if (len != 0) { 1048 *buf++ = '.'; 1049 *buf = '\0'; 1050 len--; 1051 } 1052 } 1053 1054 ret = mdb_ctf_member_iter(id, offset_to_name_cb, &mbc); 1055 if (ret == -1) 1056 return (-1); /* errno is set for us */ 1057 1058 /* 1059 * If we did not find a member containing this offset 1060 * (due to holes in the structure), return EINVAL. 1061 */ 1062 if (ret == 0) 1063 return (set_errno(EINVAL)); 1064 1065 break; 1066 } 1067 1068 case CTF_K_UNION: 1069 /* 1070 * Treat unions like atomic entities since we can't 1071 * do more than guess which member of the union 1072 * might be the intended one. 1073 */ 1074 goto done; 1075 1076 case CTF_K_INTEGER: 1077 case CTF_K_FLOAT: 1078 case CTF_K_POINTER: 1079 case CTF_K_ENUM: 1080 goto done; 1081 1082 default: 1083 return (set_errno(EINVAL)); 1084 } 1085 1086 dot = 1; 1087 } 1088 done: 1089 if (midp != NULL) 1090 *midp = id; 1091 if (moffp != NULL) 1092 *moffp = off; 1093 1094 return (mbc.mbc_total); 1095 } 1096 1097 static void 1098 mdb_ctf_warn(uint_t flags, const char *format, ...) 1099 { 1100 va_list alist; 1101 1102 if (flags & MDB_CTF_VREAD_QUIET) 1103 return; 1104 1105 va_start(alist, format); 1106 vwarn(format, alist); 1107 va_end(alist); 1108 } 1109 1110 /* 1111 * Check if two types are structurally the same rather than logically 1112 * the same. That is to say that two types are equal if they have the 1113 * same logical structure rather than having the same ids in CTF-land. 1114 */ 1115 static int type_equals(mdb_ctf_id_t, mdb_ctf_id_t); 1116 1117 static int 1118 type_equals_cb(const char *name, mdb_ctf_id_t amem, ulong_t aoff, void *data) 1119 { 1120 mdb_ctf_id_t b = *(mdb_ctf_id_t *)data; 1121 ulong_t boff; 1122 mdb_ctf_id_t bmem; 1123 1124 /* 1125 * Look up the corresponding member in the other composite type. 1126 */ 1127 if (mdb_ctf_member_info(b, name, &boff, &bmem) != 0) 1128 return (1); 1129 1130 /* 1131 * We don't allow members to be shuffled around. 1132 */ 1133 if (aoff != boff) 1134 return (1); 1135 1136 return (type_equals(amem, bmem) ? 0 : 1); 1137 } 1138 1139 static int 1140 type_equals(mdb_ctf_id_t a, mdb_ctf_id_t b) 1141 { 1142 size_t asz, bsz; 1143 int akind, bkind; 1144 mdb_ctf_arinfo_t aar, bar; 1145 1146 /* 1147 * Resolve both types down to their fundamental types, and make 1148 * sure their sizes and kinds match. 1149 */ 1150 if (mdb_ctf_type_resolve(a, &a) != 0 || 1151 mdb_ctf_type_resolve(b, &b) != 0 || 1152 (asz = mdb_ctf_type_size(a)) == -1UL || 1153 (bsz = mdb_ctf_type_size(b)) == -1UL || 1154 (akind = mdb_ctf_type_kind(a)) == -1 || 1155 (bkind = mdb_ctf_type_kind(b)) == -1 || 1156 asz != bsz || akind != bkind) { 1157 return (0); 1158 } 1159 1160 switch (akind) { 1161 case CTF_K_INTEGER: 1162 case CTF_K_FLOAT: 1163 case CTF_K_POINTER: 1164 /* 1165 * For pointers we could be a little stricter and require 1166 * both pointers to reference types which look vaguely 1167 * similar (for example, we could insist that the two types 1168 * have the same name). However, all we really care about 1169 * here is that the structure of the two types are the same, 1170 * and, in that regard, one pointer is as good as another. 1171 */ 1172 return (1); 1173 1174 case CTF_K_UNION: 1175 case CTF_K_STRUCT: 1176 /* 1177 * The test for the number of members is only strictly 1178 * necessary for unions since we'll find other problems with 1179 * structs. However, the extra check will do no harm. 1180 */ 1181 return (mdb_ctf_num_members(a) == mdb_ctf_num_members(b) && 1182 mdb_ctf_member_iter(a, type_equals_cb, &b) == 0); 1183 1184 case CTF_K_ARRAY: 1185 return (mdb_ctf_array_info(a, &aar) == 0 && 1186 mdb_ctf_array_info(b, &bar) == 0 && 1187 aar.mta_nelems == bar.mta_nelems && 1188 type_equals(aar.mta_index, bar.mta_index) && 1189 type_equals(aar.mta_contents, bar.mta_contents)); 1190 } 1191 1192 return (0); 1193 } 1194 1195 1196 typedef struct member { 1197 char *m_modbuf; 1198 char *m_tgtbuf; 1199 const char *m_tgtname; 1200 mdb_ctf_id_t m_tgtid; 1201 uint_t m_flags; 1202 } member_t; 1203 1204 static int vread_helper(mdb_ctf_id_t, char *, mdb_ctf_id_t, char *, 1205 const char *, uint_t); 1206 1207 static int 1208 member_cb(const char *name, mdb_ctf_id_t modmid, ulong_t modoff, void *data) 1209 { 1210 member_t *mp = data; 1211 char *modbuf = mp->m_modbuf; 1212 mdb_ctf_id_t tgtmid; 1213 char *tgtbuf = mp->m_tgtbuf; 1214 ulong_t tgtoff; 1215 char tgtname[128]; 1216 1217 (void) mdb_snprintf(tgtname, sizeof (tgtname), 1218 "member %s of type %s", name, mp->m_tgtname); 1219 1220 if (mdb_ctf_member_info(mp->m_tgtid, name, &tgtoff, &tgtmid) != 0) { 1221 mdb_ctf_warn(mp->m_flags, 1222 "could not find %s\n", tgtname); 1223 return (set_errno(EMDB_CTFNOMEMB)); 1224 } 1225 1226 return (vread_helper(modmid, modbuf + modoff / NBBY, 1227 tgtmid, tgtbuf + tgtoff / NBBY, tgtname, mp->m_flags)); 1228 } 1229 1230 typedef struct enum_value { 1231 int *ev_modbuf; 1232 const char *ev_name; 1233 } enum_value_t; 1234 1235 static int 1236 enum_cb(const char *name, int value, void *data) 1237 { 1238 enum_value_t *ev = data; 1239 1240 if (strcmp(name, ev->ev_name) == 0) { 1241 *ev->ev_modbuf = value; 1242 return (1); 1243 } 1244 return (0); 1245 } 1246 1247 static int 1248 vread_helper(mdb_ctf_id_t modid, char *modbuf, 1249 mdb_ctf_id_t tgtid, char *tgtbuf, const char *tgtname, uint_t flags) 1250 { 1251 size_t modsz, tgtsz; 1252 int modkind, tgtkind; 1253 member_t mbr; 1254 enum_value_t ev; 1255 int ret; 1256 mdb_ctf_arinfo_t tar, mar; 1257 int i; 1258 char typename[128]; 1259 char mdbtypename[128]; 1260 ctf_encoding_t tgt_encoding, mod_encoding; 1261 boolean_t signed_int = B_FALSE; 1262 1263 if (mdb_ctf_type_name(tgtid, typename, sizeof (typename)) == NULL) { 1264 (void) mdb_snprintf(typename, sizeof (typename), 1265 "#%ul", mdb_ctf_type_id(tgtid)); 1266 } 1267 if (mdb_ctf_type_name(modid, 1268 mdbtypename, sizeof (mdbtypename)) == NULL) { 1269 (void) mdb_snprintf(mdbtypename, sizeof (mdbtypename), 1270 "#%ul", mdb_ctf_type_id(modid)); 1271 } 1272 1273 if (tgtname == NULL) 1274 tgtname = ""; 1275 1276 /* 1277 * Resolve the types to their canonical form. 1278 */ 1279 (void) mdb_ctf_type_resolve(modid, &modid); 1280 (void) mdb_ctf_type_resolve(tgtid, &tgtid); 1281 1282 if ((modkind = mdb_ctf_type_kind(modid)) == -1) { 1283 mdb_ctf_warn(flags, 1284 "couldn't determine type kind of mdb module type %s\n", 1285 mdbtypename); 1286 return (-1); /* errno is set for us */ 1287 } 1288 if ((tgtkind = mdb_ctf_type_kind(tgtid)) == -1) { 1289 mdb_ctf_warn(flags, 1290 "couldn't determine type kind of %s\n", typename); 1291 return (-1); /* errno is set for us */ 1292 } 1293 1294 if ((modsz = mdb_ctf_type_size(modid)) == -1UL) { 1295 mdb_ctf_warn(flags, "couldn't determine type size of " 1296 "mdb module type %s\n", mdbtypename); 1297 return (-1); /* errno is set for us */ 1298 } 1299 if ((tgtsz = mdb_ctf_type_size(tgtid)) == -1UL) { 1300 mdb_ctf_warn(flags, "couldn't determine size of %s (%s)\n", 1301 typename, tgtname); 1302 return (-1); /* errno is set for us */ 1303 } 1304 1305 if (tgtkind == CTF_K_POINTER && modkind == CTF_K_INTEGER && 1306 strcmp(mdbtypename, "uintptr_t") == 0) { 1307 /* allow them to convert a pointer to a uintptr_t */ 1308 ASSERT(modsz == tgtsz); 1309 } else if (tgtkind != modkind) { 1310 mdb_ctf_warn(flags, "unexpected kind for type %s (%s)\n", 1311 typename, tgtname); 1312 return (set_errno(EMDB_INCOMPAT)); 1313 } 1314 1315 switch (tgtkind) { 1316 case CTF_K_INTEGER: 1317 case CTF_K_FLOAT: 1318 /* 1319 * Must determine if the target and module types have the same 1320 * encoding before we can copy them. 1321 */ 1322 if (mdb_ctf_type_encoding(tgtid, &tgt_encoding) != 0) { 1323 mdb_ctf_warn(flags, 1324 "couldn't determine encoding of type %s (%s)\n", 1325 typename, tgtname); 1326 return (-1); /* errno is set for us */ 1327 } 1328 if (mdb_ctf_type_encoding(modid, &mod_encoding) != 0) { 1329 mdb_ctf_warn(flags, "couldn't determine encoding of " 1330 "mdb module type %s\n", mdbtypename); 1331 return (-1); /* errno is set for us */ 1332 } 1333 1334 if (modkind == CTF_K_INTEGER) { 1335 if ((tgt_encoding.cte_format & CTF_INT_SIGNED) != 1336 (mod_encoding.cte_format & CTF_INT_SIGNED)) { 1337 mdb_ctf_warn(flags, 1338 "signedness mismatch between type " 1339 "%s (%s) and mdb module type %s\n", 1340 typename, tgtname, mdbtypename); 1341 return (set_errno(EMDB_INCOMPAT)); 1342 } 1343 signed_int = 1344 ((tgt_encoding.cte_format & CTF_INT_SIGNED) != 0); 1345 } else if (tgt_encoding.cte_format != mod_encoding.cte_format) { 1346 mdb_ctf_warn(flags, 1347 "encoding mismatch (%#x != %#x) between type " 1348 "%s (%s) and mdb module type %s\n", 1349 tgt_encoding.cte_format, mod_encoding.cte_format, 1350 typename, tgtname, mdbtypename); 1351 return (set_errno(EMDB_INCOMPAT)); 1352 } 1353 /* FALLTHROUGH */ 1354 case CTF_K_POINTER: 1355 /* 1356 * If the sizes don't match we need to be tricky to make 1357 * sure that the caller gets the correct data. 1358 */ 1359 if (modsz < tgtsz) { 1360 mdb_ctf_warn(flags, "size of type %s (%s) is too " 1361 "large for mdb module type %s\n", 1362 typename, tgtname, mdbtypename); 1363 return (set_errno(EMDB_INCOMPAT)); 1364 } else if (modsz > tgtsz) { 1365 /* BEGIN CSTYLED */ 1366 /* 1367 * Fill modbuf with 1's for sign extension if target 1368 * buf is a signed integer and its value is negative. 1369 * 1370 * S = sign bit (in most-significant byte) 1371 * 1372 * BIG ENDIAN DATA 1373 * +--------+--------+--------+--------+ 1374 * |S | | | | 1375 * +--------+--------+--------+--------+ 1376 * 0 1 ... sz-1 sz 1377 * 1378 * LITTLE ENDIAN DATA 1379 * +--------+--------+--------+--------+ 1380 * | | | |S | 1381 * +--------+--------+--------+--------+ 1382 * 0 1 ... sz-1 sz 1383 */ 1384 /* END CSTYLED */ 1385 #ifdef _BIG_ENDIAN 1386 if (signed_int && (tgtbuf[0] & 0x80) != 0) 1387 #else 1388 if (signed_int && (tgtbuf[tgtsz - 1] & 0x80) != 0) 1389 #endif 1390 (void) memset(modbuf, 0xFF, modsz); 1391 else 1392 bzero(modbuf, modsz); 1393 #ifdef _BIG_ENDIAN 1394 bcopy(tgtbuf, modbuf + modsz - tgtsz, tgtsz); 1395 #else 1396 bcopy(tgtbuf, modbuf, tgtsz); 1397 #endif 1398 } else { 1399 bcopy(tgtbuf, modbuf, modsz); 1400 } 1401 1402 return (0); 1403 1404 case CTF_K_ENUM: 1405 if (modsz != tgtsz || modsz != sizeof (int)) { 1406 mdb_ctf_warn(flags, "unexpected size of type %s (%s)\n", 1407 typename, tgtname); 1408 return (set_errno(EMDB_INCOMPAT)); 1409 } 1410 1411 /* 1412 * Default to the same value as in the target. 1413 */ 1414 bcopy(tgtbuf, modbuf, sizeof (int)); 1415 1416 /* LINTED */ 1417 i = *(int *)tgtbuf; 1418 1419 /* LINTED */ 1420 ev.ev_modbuf = (int *)modbuf; 1421 ev.ev_name = mdb_ctf_enum_name(tgtid, i); 1422 if (ev.ev_name == NULL) { 1423 mdb_ctf_warn(flags, 1424 "unexpected value %u of enum type %s (%s)\n", 1425 i, typename, tgtname); 1426 return (set_errno(EMDB_INCOMPAT)); 1427 } 1428 1429 ret = mdb_ctf_enum_iter(modid, enum_cb, &ev); 1430 if (ret == 0) { 1431 /* value not found */ 1432 mdb_ctf_warn(flags, 1433 "unexpected value %s (%u) of enum type %s (%s)\n", 1434 ev.ev_name, i, typename, tgtname); 1435 return (set_errno(EMDB_INCOMPAT)); 1436 } else if (ret == 1) { 1437 /* value found */ 1438 return (0); 1439 } else if (ret == -1) { 1440 mdb_ctf_warn(flags, "could not iterate enum %s (%s)\n", 1441 typename, tgtname); 1442 } 1443 return (ret); 1444 1445 case CTF_K_STRUCT: 1446 mbr.m_modbuf = modbuf; 1447 mbr.m_tgtbuf = tgtbuf; 1448 mbr.m_tgtid = tgtid; 1449 mbr.m_flags = flags; 1450 mbr.m_tgtname = typename; 1451 1452 return (mdb_ctf_member_iter(modid, member_cb, &mbr)); 1453 1454 case CTF_K_UNION: 1455 1456 /* 1457 * Unions are a little tricky. The only time it's truly 1458 * safe to read in a union is if no part of the union or 1459 * any of its component types have changed. The correct 1460 * use of this feature is to read the containing structure, 1461 * figure out which component of the union is valid, compute 1462 * the location of that in the target and then read in 1463 * that part of the structure. 1464 */ 1465 1466 if (!type_equals(modid, tgtid)) { 1467 mdb_ctf_warn(flags, "inexact match for union %s (%s)\n", 1468 typename, tgtname); 1469 return (set_errno(EMDB_INCOMPAT)); 1470 } 1471 1472 ASSERT(modsz == tgtsz); 1473 1474 bcopy(tgtbuf, modbuf, modsz); 1475 1476 return (0); 1477 1478 case CTF_K_ARRAY: 1479 if (mdb_ctf_array_info(tgtid, &tar) != 0) { 1480 mdb_ctf_warn(flags, 1481 "couldn't get array info for %s (%s)\n", 1482 typename, tgtname); 1483 return (-1); /* errno is set for us */ 1484 } 1485 if (mdb_ctf_array_info(modid, &mar) != 0) { 1486 mdb_ctf_warn(flags, 1487 "couldn't get array info for mdb module type %s\n", 1488 mdbtypename); 1489 return (-1); /* errno is set for us */ 1490 } 1491 1492 if (tar.mta_nelems != mar.mta_nelems) { 1493 mdb_ctf_warn(flags, 1494 "unexpected array size (%u) for type %s (%s)\n", 1495 tar.mta_nelems, typename, tgtname); 1496 return (set_errno(EMDB_INCOMPAT)); 1497 } 1498 1499 if ((modsz = mdb_ctf_type_size(mar.mta_contents)) == -1UL) { 1500 mdb_ctf_warn(flags, "couldn't determine type size of " 1501 "mdb module type %s\n", mdbtypename); 1502 return (-1); /* errno is set for us */ 1503 } 1504 if ((tgtsz = mdb_ctf_type_size(tar.mta_contents)) == -1UL) { 1505 mdb_ctf_warn(flags, 1506 "couldn't determine size of %s (%s)\n", 1507 typename, tgtname); 1508 return (-1); /* errno is set for us */ 1509 } 1510 1511 for (i = 0; i < tar.mta_nelems; i++) { 1512 ret = vread_helper(mar.mta_contents, modbuf + i * modsz, 1513 tar.mta_contents, tgtbuf + i * tgtsz, 1514 tgtname, flags); 1515 1516 if (ret != 0) 1517 return (ret); 1518 } 1519 1520 return (0); 1521 } 1522 1523 mdb_ctf_warn(flags, "unsupported kind %d for type %s (%s)\n", 1524 modkind, typename, tgtname); 1525 return (set_errno(EMDB_INCOMPAT)); 1526 } 1527 1528 /* 1529 * Like mdb_vread(), mdb_ctf_vread() is used to read from the target's 1530 * virtual address space. However, mdb_ctf_vread() can be used to safely 1531 * read a complex type (e.g. a struct) from the target, even if MDB was compiled 1532 * against a different definition of that type (e.g. when debugging a crash 1533 * dump from an older release). 1534 * 1535 * Callers can achieve this by defining their own type which corresponds to the 1536 * type in the target, but contains only the members that the caller requires. 1537 * Using the CTF type information embedded in the target, mdb_ctf_vread will 1538 * find the required members in the target and fill in the caller's structure. 1539 * The members are located by name, and their types are verified to be 1540 * compatible. 1541 * 1542 * By convention, the caller will declare a type with the name "mdb_<type>", 1543 * where <type> is the name of the type in the target (e.g. mdb_zio_t). This 1544 * type will contain the members that the caller is interested in. For example: 1545 * 1546 * typedef struct mdb_zio { 1547 * enum zio_type io_type; 1548 * uintptr_t io_waiter; 1549 * struct { 1550 * struct { 1551 * uintptr_t list_next; 1552 * } list_head; 1553 * } io_parent_list; 1554 * int io_error; 1555 * } mdb_zio_t; 1556 * 1557 * mdb_zio_t zio; 1558 * error = mdb_ctf_vread(&zio, "zio_t", "mdb_zio_t", zio_target_addr, 0); 1559 * 1560 * If a given MDB module has different dcmds or walkers that need to read 1561 * different members from the same struct, then different "mdb_" types 1562 * should be declared for each caller. By convention, these types should 1563 * be named "mdb_<dcmd or walker>_<type>", e.g. mdb_findstack_kthread_t 1564 * for ::findstack. If the MDB module is compiled from several source files, 1565 * one must be especially careful to not define different types with the 1566 * same name in different source files, because the compiler can not detect 1567 * this error. 1568 * 1569 * Enums will also be translated by name, so the mdb module will receive 1570 * the enum value it expects even if the target has renumbered the enum. 1571 * Warning: it will therefore only work with enums are only used to store 1572 * legitimate enum values (not several values or-ed together). 1573 * 1574 * By default, if mdb_ctf_vread() can not find any members or enum values, 1575 * it will print a descriptive message (with mdb_warn()) and fail. 1576 * Passing MDB_CTF_VREAD_QUIET in 'flags' will suppress the warning message. 1577 * Additional flags can be used to ignore specific types of translation 1578 * failure, but should be used with caution, because they will silently leave 1579 * the caller's buffer uninitialized. 1580 */ 1581 int 1582 mdb_ctf_vread(void *modbuf, const char *target_typename, 1583 const char *mdb_typename, uintptr_t addr, uint_t flags) 1584 { 1585 ctf_file_t *mfp; 1586 ctf_id_t mid; 1587 void *tgtbuf; 1588 size_t size; 1589 mdb_ctf_id_t tgtid; 1590 mdb_ctf_id_t modid; 1591 mdb_module_t *mod; 1592 1593 if ((mod = mdb_get_module()) == NULL || (mfp = mod->mod_ctfp) == NULL) { 1594 mdb_ctf_warn(flags, "no ctf data found for mdb module %s\n", 1595 mod->mod_name); 1596 return (set_errno(EMDB_NOCTF)); 1597 } 1598 1599 if ((mid = ctf_lookup_by_name(mfp, mdb_typename)) == CTF_ERR) { 1600 mdb_ctf_warn(flags, "couldn't find ctf data for " 1601 "type %s in mdb module %s\n", 1602 mdb_typename, mod->mod_name); 1603 return (set_errno(ctf_to_errno(ctf_errno(mfp)))); 1604 } 1605 1606 set_ctf_id(&modid, mfp, mid); 1607 1608 if (mdb_ctf_lookup_by_name(target_typename, &tgtid) != 0) { 1609 mdb_ctf_warn(flags, 1610 "couldn't find type %s in target's ctf data\n", 1611 target_typename); 1612 return (set_errno(EMDB_NOCTF)); 1613 } 1614 1615 /* 1616 * Read the data out of the target's address space. 1617 */ 1618 if ((size = mdb_ctf_type_size(tgtid)) == -1UL) { 1619 mdb_ctf_warn(flags, "couldn't determine size of type %s\n", 1620 target_typename); 1621 return (-1); /* errno is set for us */ 1622 } 1623 1624 tgtbuf = mdb_alloc(size, UM_SLEEP | UM_GC); 1625 1626 if (mdb_vread(tgtbuf, size, addr) < 0) { 1627 mdb_ctf_warn(flags, "couldn't read %s from %p\n", 1628 target_typename, addr); 1629 return (-1); /* errno is set for us */ 1630 } 1631 1632 return (vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags)); 1633 } 1634 1635 /* 1636 * Note: mdb_ctf_readsym() doesn't take separate parameters for the name 1637 * of the target's type vs the mdb module's type. Use with complicated 1638 * types (e.g. structs) may result in unnecessary failure if a member of 1639 * the struct has been changed in the target, but is not actually needed 1640 * by the mdb module. Use mdb_lookup_by_name() + mdb_ctf_vread() to 1641 * avoid this problem. 1642 */ 1643 int 1644 mdb_ctf_readsym(void *buf, const char *typename, const char *name, uint_t flags) 1645 { 1646 GElf_Sym sym; 1647 1648 if (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY, name, &sym) != 0) { 1649 mdb_ctf_warn(flags, "couldn't find symbol %s\n", name); 1650 return (-1); /* errno is set for us */ 1651 } 1652 1653 return (mdb_ctf_vread(buf, typename, typename, sym.st_value, flags)); 1654 } 1655 1656 ctf_file_t * 1657 mdb_ctf_bufopen(const void *ctf_va, size_t ctf_size, const void *sym_va, 1658 Shdr *symhdr, const void *str_va, Shdr *strhdr, int *errp) 1659 { 1660 ctf_sect_t ctdata, symtab, strtab; 1661 1662 ctdata.cts_name = ".SUNW_ctf"; 1663 ctdata.cts_type = SHT_PROGBITS; 1664 ctdata.cts_flags = 0; 1665 ctdata.cts_data = ctf_va; 1666 ctdata.cts_size = ctf_size; 1667 ctdata.cts_entsize = 1; 1668 ctdata.cts_offset = 0; 1669 1670 symtab.cts_name = ".symtab"; 1671 symtab.cts_type = symhdr->sh_type; 1672 symtab.cts_flags = symhdr->sh_flags; 1673 symtab.cts_data = sym_va; 1674 symtab.cts_size = symhdr->sh_size; 1675 symtab.cts_entsize = symhdr->sh_entsize; 1676 symtab.cts_offset = symhdr->sh_offset; 1677 1678 strtab.cts_name = ".strtab"; 1679 strtab.cts_type = strhdr->sh_type; 1680 strtab.cts_flags = strhdr->sh_flags; 1681 strtab.cts_data = str_va; 1682 strtab.cts_size = strhdr->sh_size; 1683 strtab.cts_entsize = strhdr->sh_entsize; 1684 strtab.cts_offset = strhdr->sh_offset; 1685 1686 return (ctf_bufopen(&ctdata, &symtab, &strtab, errp)); 1687 } 1688 1689 int 1690 mdb_ctf_synthetics_init(void) 1691 { 1692 int err; 1693 1694 if ((mdb.m_synth = ctf_create(&err)) == NULL) 1695 return (set_errno(ctf_to_errno(err))); 1696 1697 return (0); 1698 } 1699 1700 void 1701 mdb_ctf_synthetics_fini(void) 1702 { 1703 if (mdb.m_synth == NULL) 1704 return; 1705 1706 ctf_close(mdb.m_synth); 1707 mdb.m_synth = NULL; 1708 } 1709 1710 int 1711 mdb_ctf_synthetics_create_base(int kind) 1712 { 1713 const synth_intrinsic_t *synp; 1714 const synth_typedef_t *sytp; 1715 int err; 1716 ctf_id_t id; 1717 ctf_file_t *cp = mdb.m_synth; 1718 1719 if (mdb.m_synth == NULL) { 1720 mdb_printf("synthetic types disabled: ctf create failed\n"); 1721 return (1); 1722 } 1723 1724 switch (kind) { 1725 case SYNTHETIC_ILP32: 1726 synp = synth_builtins32; 1727 sytp = synth_typedefs32; 1728 break; 1729 case SYNTHETIC_LP64: 1730 synp = synth_builtins64; 1731 sytp = synth_typedefs64; 1732 break; 1733 default: 1734 mdb_dprintf(MDB_DBG_CTF, "invalid type of intrinsic: %d\n", 1735 kind); 1736 return (1); 1737 } 1738 1739 err = 0; 1740 for (; synp->syn_name != NULL; synp++) { 1741 if (synp->syn_kind == CTF_K_INTEGER) { 1742 err = ctf_add_integer(cp, CTF_ADD_ROOT, synp->syn_name, 1743 &synp->syn_enc); 1744 } else { 1745 err = ctf_add_float(cp, CTF_ADD_ROOT, synp->syn_name, 1746 &synp->syn_enc); 1747 } 1748 1749 if (err == CTF_ERR) { 1750 mdb_dprintf(MDB_DBG_CTF, "couldn't add synthetic " 1751 "type: %s\n", synp->syn_name); 1752 goto discard; 1753 } 1754 } 1755 1756 if (ctf_update(cp) == CTF_ERR) { 1757 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n"); 1758 goto discard; 1759 } 1760 1761 for (; sytp->syt_src != NULL; sytp++) { 1762 id = ctf_lookup_by_name(cp, sytp->syt_src); 1763 if (id == CTF_ERR) { 1764 mdb_dprintf(MDB_DBG_CTF, "cailed to lookup %s: %s\n", 1765 sytp->syt_src, ctf_errmsg(ctf_errno(cp))); 1766 goto discard; 1767 } 1768 if (ctf_add_typedef(cp, CTF_ADD_ROOT, sytp->syt_targ, id) == 1769 CTF_ERR) { 1770 mdb_dprintf(MDB_DBG_CTF, "couldn't add typedef %s " 1771 "%s: %s\n", sytp->syt_targ, sytp->syt_src, 1772 ctf_errmsg(ctf_errno(cp))); 1773 goto discard; 1774 } 1775 } 1776 1777 if (ctf_update(cp) == CTF_ERR) { 1778 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n"); 1779 goto discard; 1780 } 1781 1782 return (0); 1783 1784 discard: 1785 err = set_errno(ctf_to_errno(ctf_errno(cp))); 1786 (void) ctf_discard(cp); 1787 return (err); 1788 } 1789 1790 int 1791 mdb_ctf_synthetics_reset(void) 1792 { 1793 mdb_ctf_synthetics_fini(); 1794 return (mdb_ctf_synthetics_init()); 1795 } 1796 1797 int 1798 mdb_ctf_add_typedef(const char *name, const mdb_ctf_id_t *p, mdb_ctf_id_t *new) 1799 { 1800 ctf_id_t rid; 1801 mdb_ctf_id_t tid; 1802 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p; 1803 1804 if (mdb.m_synth == NULL) { 1805 mdb_printf("synthetic types disabled: ctf create failed\n"); 1806 return (1); 1807 } 1808 1809 if (mdb_ctf_lookup_by_name(name, &tid) == 0) { 1810 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type " 1811 "with that name already exists\n", name); 1812 return (set_errno(EEXIST)); 1813 } 1814 1815 rid = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id); 1816 if (rid == CTF_ERR) { 1817 mdb_dprintf(MDB_DBG_CTF, "failed to add reference type: %s\n", 1818 ctf_errmsg(ctf_errno(mdb.m_synth))); 1819 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1820 } 1821 rid = ctf_add_typedef(mdb.m_synth, CTF_ADD_ROOT, name, rid); 1822 if (rid == CTF_ERR) { 1823 mdb_dprintf(MDB_DBG_CTF, "failed to add typedef: %s", 1824 ctf_errmsg(ctf_errno(mdb.m_synth))); 1825 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1826 } 1827 1828 if (ctf_update(mdb.m_synth) == CTF_ERR) { 1829 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 1830 ctf_errmsg(ctf_errno(mdb.m_synth))); 1831 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1832 } 1833 1834 if (new != NULL) 1835 set_ctf_id(new, mdb.m_synth, rid); 1836 1837 return (0); 1838 } 1839 1840 int 1841 mdb_ctf_add_struct(const char *name, mdb_ctf_id_t *rid) 1842 { 1843 mdb_ctf_id_t tid; 1844 ctf_id_t id; 1845 1846 if (mdb.m_synth == NULL) { 1847 mdb_printf("synthetic types disabled: ctf create failed\n"); 1848 return (1); 1849 } 1850 1851 if (name != NULL && mdb_ctf_lookup_by_name(name, &tid) == 0) { 1852 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type " 1853 "with that name already exists\n", name); 1854 return (set_errno(EEXIST)); 1855 } 1856 1857 if ((id = ctf_add_struct(mdb.m_synth, CTF_ADD_ROOT, name)) == 1858 CTF_ERR) { 1859 mdb_dprintf(MDB_DBG_CTF, "failed to add struct: %s\n", 1860 ctf_errmsg(ctf_errno(mdb.m_synth))); 1861 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1862 } 1863 1864 if (ctf_update(mdb.m_synth) == CTF_ERR) { 1865 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 1866 ctf_errmsg(ctf_errno(mdb.m_synth))); 1867 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1868 } 1869 1870 if (rid != NULL) 1871 set_ctf_id(rid, mdb.m_synth, id); 1872 1873 return (0); 1874 } 1875 1876 int 1877 mdb_ctf_add_union(const char *name, mdb_ctf_id_t *rid) 1878 { 1879 mdb_ctf_id_t tid; 1880 ctf_id_t id; 1881 1882 if (mdb.m_synth == NULL) { 1883 mdb_printf("synthetic types disabled: ctf create failed\n"); 1884 return (1); 1885 } 1886 1887 if (name != NULL && mdb_ctf_lookup_by_name(name, &tid) == 0) { 1888 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type " 1889 "with that name already exists\n", name); 1890 return (set_errno(EEXIST)); 1891 } 1892 1893 if ((id = ctf_add_union(mdb.m_synth, CTF_ADD_ROOT, name)) == 1894 CTF_ERR) { 1895 mdb_dprintf(MDB_DBG_CTF, "failed to add union: %s\n", 1896 ctf_errmsg(ctf_errno(mdb.m_synth))); 1897 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1898 } 1899 1900 if (ctf_update(mdb.m_synth) == CTF_ERR) { 1901 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 1902 ctf_errmsg(ctf_errno(mdb.m_synth))); 1903 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1904 } 1905 1906 if (rid != NULL) 1907 set_ctf_id(rid, mdb.m_synth, id); 1908 1909 return (0); 1910 } 1911 1912 int 1913 mdb_ctf_add_member(const mdb_ctf_id_t *p, const char *name, 1914 const mdb_ctf_id_t *mtype, mdb_ctf_id_t *rid) 1915 { 1916 ctf_id_t id, mtid; 1917 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p; 1918 mdb_ctf_impl_t *mcim = (mdb_ctf_impl_t *)mtype; 1919 1920 if (mdb.m_synth == NULL) { 1921 mdb_printf("synthetic types disabled: ctf create failed\n"); 1922 return (DCMD_ERR); 1923 } 1924 1925 if (mcip->mci_fp != mdb.m_synth) { 1926 mdb_dprintf(MDB_DBG_CTF, "requested to add member to a type " 1927 "that wasn't created from a synthetic\n"); 1928 return (set_errno(EINVAL)); 1929 } 1930 1931 mtid = ctf_add_type(mdb.m_synth, mcim->mci_fp, mcim->mci_id); 1932 if (mtid == CTF_ERR) { 1933 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n", 1934 ctf_errmsg(ctf_errno(mdb.m_synth))); 1935 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1936 } 1937 1938 if (ctf_update(mdb.m_synth) == CTF_ERR) { 1939 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 1940 ctf_errmsg(ctf_errno(mdb.m_synth))); 1941 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1942 } 1943 1944 id = ctf_add_member(mdb.m_synth, mcip->mci_id, name, mtid, ULONG_MAX); 1945 if (id == CTF_ERR) { 1946 mdb_dprintf(MDB_DBG_CTF, "failed to add member %s: %s\n", 1947 name, ctf_errmsg(ctf_errno(mdb.m_synth))); 1948 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1949 } 1950 1951 if (ctf_update(mdb.m_synth) == CTF_ERR) { 1952 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 1953 ctf_errmsg(ctf_errno(mdb.m_synth))); 1954 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1955 } 1956 1957 if (rid != NULL) 1958 set_ctf_id(rid, mdb.m_synth, id); 1959 1960 return (0); 1961 } 1962 1963 int 1964 mdb_ctf_add_array(const mdb_ctf_arinfo_t *marp, mdb_ctf_id_t *rid) 1965 { 1966 mdb_ctf_impl_t *mcip; 1967 ctf_arinfo_t car; 1968 ctf_id_t id; 1969 1970 if (mdb.m_synth == NULL) { 1971 mdb_printf("synthetic types disabled: ctf create failed\n"); 1972 return (1); 1973 } 1974 1975 car.ctr_nelems = marp->mta_nelems; 1976 1977 mcip = (mdb_ctf_impl_t *)&marp->mta_contents; 1978 id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id); 1979 if (id == 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 car.ctr_contents = id; 1985 1986 mcip = (mdb_ctf_impl_t *)&marp->mta_index; 1987 id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id); 1988 if (id == CTF_ERR) { 1989 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n", 1990 ctf_errmsg(ctf_errno(mdb.m_synth))); 1991 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1992 } 1993 car.ctr_index = id; 1994 1995 if (ctf_update(mdb.m_synth) == CTF_ERR) { 1996 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 1997 ctf_errmsg(ctf_errno(mdb.m_synth))); 1998 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 1999 } 2000 2001 id = ctf_add_array(mdb.m_synth, CTF_ADD_ROOT, &car); 2002 if (id == CTF_ERR) { 2003 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 2004 ctf_errmsg(ctf_errno(mdb.m_synth))); 2005 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2006 } 2007 2008 if (ctf_update(mdb.m_synth) == CTF_ERR) { 2009 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 2010 ctf_errmsg(ctf_errno(mdb.m_synth))); 2011 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2012 } 2013 2014 if (rid != NULL) 2015 set_ctf_id(rid, mdb.m_synth, id); 2016 2017 return (0); 2018 } 2019 2020 int 2021 mdb_ctf_add_pointer(const mdb_ctf_id_t *p, mdb_ctf_id_t *rid) 2022 { 2023 ctf_id_t id; 2024 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p; 2025 2026 if (mdb.m_synth == NULL) { 2027 mdb_printf("synthetic types disabled: ctf create failed\n"); 2028 return (1); 2029 } 2030 2031 id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id); 2032 if (id == CTF_ERR) { 2033 mdb_dprintf(MDB_DBG_CTF, "failed to add pointer type: %s\n", 2034 ctf_errmsg(ctf_errno(mdb.m_synth))); 2035 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2036 } 2037 2038 if (ctf_update(mdb.m_synth) == CTF_ERR) { 2039 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 2040 ctf_errmsg(ctf_errno(mdb.m_synth))); 2041 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2042 } 2043 2044 2045 id = ctf_add_pointer(mdb.m_synth, CTF_ADD_ROOT, NULL, id); 2046 if (id == CTF_ERR) { 2047 mdb_dprintf(MDB_DBG_CTF, "failed to add pointer: %s\n", 2048 ctf_errmsg(ctf_errno(mdb.m_synth))); 2049 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2050 } 2051 2052 if (ctf_update(mdb.m_synth) == CTF_ERR) { 2053 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 2054 ctf_errmsg(ctf_errno(mdb.m_synth))); 2055 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2056 } 2057 2058 2059 if (rid != NULL) 2060 set_ctf_id(rid, mdb.m_synth, id); 2061 2062 return (0); 2063 } 2064 2065 int 2066 mdb_ctf_type_delete(const mdb_ctf_id_t *id) 2067 { 2068 int ret; 2069 2070 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)id; 2071 2072 if (mcip->mci_fp != mdb.m_synth) { 2073 mdb_warn("bad ctf_file_t, expected synth container\n"); 2074 return (1); 2075 } 2076 2077 ret = ctf_delete_type(mcip->mci_fp, mcip->mci_id); 2078 if (ret != 0) { 2079 mdb_dprintf(MDB_DBG_CTF, "failed to delete synthetic type: %s", 2080 ctf_errmsg(ctf_errno(mdb.m_synth))); 2081 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2082 } 2083 2084 if (ctf_update(mdb.m_synth) == CTF_ERR) { 2085 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s", 2086 ctf_errmsg(ctf_errno(mdb.m_synth))); 2087 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth)))); 2088 } 2089 2090 return (0); 2091 } 2092 2093 /* ARGSUSED */ 2094 static int 2095 mdb_ctf_synthetics_file_cb(mdb_ctf_id_t id, void *arg) 2096 { 2097 ctf_file_t *targ = arg; 2098 mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)&id; 2099 2100 if (ctf_add_type(targ, mcip->mci_fp, mcip->mci_id) == CTF_ERR) { 2101 mdb_dprintf(MDB_DBG_CTF, "failed to add type %d: %s\n", 2102 mcip->mci_id, ctf_errmsg(ctf_errno(mcip->mci_fp))); 2103 return (set_errno(ctf_to_errno(ctf_errno(mcip->mci_fp)))); 2104 } 2105 2106 return (0); 2107 } 2108 2109 int 2110 mdb_ctf_synthetics_from_file(const char *file) 2111 { 2112 ctf_file_t *fp, *syn = mdb.m_synth; 2113 int ret; 2114 type_iter_t ti; 2115 2116 if (syn == NULL) { 2117 mdb_warn("synthetic types disabled: ctf create failed\n"); 2118 return (1); 2119 } 2120 2121 if ((fp = mdb_ctf_open(file, &ret)) == NULL) { 2122 mdb_warn("failed to parse ctf data in %s: %s\n", file, 2123 ctf_errmsg(ret)); 2124 return (1); 2125 } 2126 2127 ret = DCMD_OK; 2128 ti.ti_fp = fp; 2129 ti.ti_arg = syn; 2130 ti.ti_cb = mdb_ctf_synthetics_file_cb; 2131 if (ctf_type_iter(fp, B_FALSE, type_iter_cb, &ti) == CTF_ERR) { 2132 ret = set_errno(ctf_to_errno(ctf_errno(fp))); 2133 mdb_warn("failed to add types"); 2134 goto cleanup; 2135 } 2136 2137 if (ctf_update(syn) == CTF_ERR) { 2138 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n"); 2139 ret = set_errno(ctf_to_errno(ctf_errno(fp))); 2140 } 2141 2142 cleanup: 2143 ctf_close(fp); 2144 if (ret != 0) 2145 (void) ctf_discard(syn); 2146 return (ret); 2147 } 2148 2149 int 2150 mdb_ctf_synthetics_to_file(const char *file) 2151 { 2152 int err; 2153 ctf_file_t *fp = mdb.m_synth; 2154 2155 if (fp == NULL) { 2156 mdb_warn("synthetic types are disabled, not writing " 2157 "anything\n"); 2158 return (DCMD_ERR); 2159 } 2160 2161 err = mdb_ctf_write(file, fp); 2162 if (err != 0) { 2163 if (err == CTF_ERR) 2164 (void) set_errno(ctf_to_errno(ctf_errno(fp))); 2165 else 2166 (void) set_errno(err); 2167 err = DCMD_ERR; 2168 } else { 2169 err = DCMD_OK; 2170 } 2171 2172 return (err); 2173 } 2174