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