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