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 /* 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2013, Joyent, Inc. All rights reserved. 25 * Copyright 2025 Oxide Computer Company 26 */ 27 28 #include <sys/types.h> 29 #include <sys/modctl.h> 30 #include <sys/kobj.h> 31 #include <sys/kobj_impl.h> 32 #include <sys/sysmacros.h> 33 #include <sys/elf.h> 34 #include <sys/task.h> 35 36 #include <unistd.h> 37 #include <project.h> 38 #include <strings.h> 39 #include <stdlib.h> 40 #include <libelf.h> 41 #include <limits.h> 42 #include <assert.h> 43 #include <errno.h> 44 #include <dirent.h> 45 46 #include <dt_strtab.h> 47 #include <dt_module.h> 48 #include <dt_impl.h> 49 50 static const char *dt_module_strtab; /* active strtab for qsort callbacks */ 51 52 static void 53 dt_module_symhash_insert(dt_module_t *dmp, const char *name, uint_t id) 54 { 55 dt_sym_t *dsp = &dmp->dm_symchains[dmp->dm_symfree]; 56 uint_t h; 57 58 assert(dmp->dm_symfree < dmp->dm_nsymelems + 1); 59 60 dsp->ds_symid = id; 61 h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets; 62 dsp->ds_next = dmp->dm_symbuckets[h]; 63 dmp->dm_symbuckets[h] = dmp->dm_symfree++; 64 } 65 66 static uint_t 67 dt_module_syminit32(dt_module_t *dmp) 68 { 69 #if STT_NUM != (STT_TLS + 1) 70 #error "STT_NUM has grown. update dt_module_syminit32()" 71 #endif 72 73 const Elf32_Sym *sym = dmp->dm_symtab.cts_data; 74 const char *base = dmp->dm_strtab.cts_data; 75 size_t ss_size = dmp->dm_strtab.cts_size; 76 uint_t i, n = dmp->dm_nsymelems; 77 uint_t asrsv = 0; 78 79 for (i = 0; i < n; i++, sym++) { 80 const char *name = base + sym->st_name; 81 uchar_t type = ELF32_ST_TYPE(sym->st_info); 82 83 if (type >= STT_NUM || type == STT_SECTION) 84 continue; /* skip sections and unknown types */ 85 86 if (sym->st_name == 0 || sym->st_name >= ss_size) 87 continue; /* skip null or invalid names */ 88 89 if (sym->st_value != 0 && 90 (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) 91 asrsv++; /* reserve space in the address map */ 92 93 dt_module_symhash_insert(dmp, name, i); 94 } 95 96 return (asrsv); 97 } 98 99 static uint_t 100 dt_module_syminit64(dt_module_t *dmp) 101 { 102 #if STT_NUM != (STT_TLS + 1) 103 #error "STT_NUM has grown. update dt_module_syminit64()" 104 #endif 105 106 const Elf64_Sym *sym = dmp->dm_symtab.cts_data; 107 const char *base = dmp->dm_strtab.cts_data; 108 size_t ss_size = dmp->dm_strtab.cts_size; 109 uint_t i, n = dmp->dm_nsymelems; 110 uint_t asrsv = 0; 111 112 for (i = 0; i < n; i++, sym++) { 113 const char *name = base + sym->st_name; 114 uchar_t type = ELF64_ST_TYPE(sym->st_info); 115 116 if (type >= STT_NUM || type == STT_SECTION) 117 continue; /* skip sections and unknown types */ 118 119 if (sym->st_name == 0 || sym->st_name >= ss_size) 120 continue; /* skip null or invalid names */ 121 122 if (sym->st_value != 0 && 123 (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) 124 asrsv++; /* reserve space in the address map */ 125 126 dt_module_symhash_insert(dmp, name, i); 127 } 128 129 return (asrsv); 130 } 131 132 /* 133 * Sort comparison function for 32-bit symbol address-to-name lookups. We sort 134 * symbols by value. If values are equal, we prefer the symbol that is 135 * non-zero sized, typed, not weak, or lexically first, in that order. 136 */ 137 static int 138 dt_module_symcomp32(const void *lp, const void *rp) 139 { 140 Elf32_Sym *lhs = *((Elf32_Sym **)lp); 141 Elf32_Sym *rhs = *((Elf32_Sym **)rp); 142 143 if (lhs->st_value != rhs->st_value) 144 return (lhs->st_value > rhs->st_value ? 1 : -1); 145 146 if ((lhs->st_size == 0) != (rhs->st_size == 0)) 147 return (lhs->st_size == 0 ? 1 : -1); 148 149 if ((ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE) != 150 (ELF32_ST_TYPE(rhs->st_info) == STT_NOTYPE)) 151 return (ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1); 152 153 if ((ELF32_ST_BIND(lhs->st_info) == STB_WEAK) != 154 (ELF32_ST_BIND(rhs->st_info) == STB_WEAK)) 155 return (ELF32_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1); 156 157 return (strcmp(dt_module_strtab + lhs->st_name, 158 dt_module_strtab + rhs->st_name)); 159 } 160 161 /* 162 * Sort comparison function for 64-bit symbol address-to-name lookups. We sort 163 * symbols by value. If values are equal, we prefer the symbol that is 164 * non-zero sized, typed, not weak, or lexically first, in that order. 165 */ 166 static int 167 dt_module_symcomp64(const void *lp, const void *rp) 168 { 169 Elf64_Sym *lhs = *((Elf64_Sym **)lp); 170 Elf64_Sym *rhs = *((Elf64_Sym **)rp); 171 172 if (lhs->st_value != rhs->st_value) 173 return (lhs->st_value > rhs->st_value ? 1 : -1); 174 175 if ((lhs->st_size == 0) != (rhs->st_size == 0)) 176 return (lhs->st_size == 0 ? 1 : -1); 177 178 if ((ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE) != 179 (ELF64_ST_TYPE(rhs->st_info) == STT_NOTYPE)) 180 return (ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1); 181 182 if ((ELF64_ST_BIND(lhs->st_info) == STB_WEAK) != 183 (ELF64_ST_BIND(rhs->st_info) == STB_WEAK)) 184 return (ELF64_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1); 185 186 return (strcmp(dt_module_strtab + lhs->st_name, 187 dt_module_strtab + rhs->st_name)); 188 } 189 190 static void 191 dt_module_symsort32(dt_module_t *dmp) 192 { 193 Elf32_Sym *symtab = (Elf32_Sym *)dmp->dm_symtab.cts_data; 194 Elf32_Sym **sympp = (Elf32_Sym **)dmp->dm_asmap; 195 const dt_sym_t *dsp = dmp->dm_symchains + 1; 196 uint_t i, n = dmp->dm_symfree; 197 198 for (i = 1; i < n; i++, dsp++) { 199 Elf32_Sym *sym = symtab + dsp->ds_symid; 200 if (sym->st_value != 0 && 201 (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) 202 *sympp++ = sym; 203 } 204 205 dmp->dm_aslen = (uint_t)(sympp - (Elf32_Sym **)dmp->dm_asmap); 206 assert(dmp->dm_aslen <= dmp->dm_asrsv); 207 208 dt_module_strtab = dmp->dm_strtab.cts_data; 209 qsort(dmp->dm_asmap, dmp->dm_aslen, 210 sizeof (Elf32_Sym *), dt_module_symcomp32); 211 dt_module_strtab = NULL; 212 } 213 214 static void 215 dt_module_symsort64(dt_module_t *dmp) 216 { 217 Elf64_Sym *symtab = (Elf64_Sym *)dmp->dm_symtab.cts_data; 218 Elf64_Sym **sympp = (Elf64_Sym **)dmp->dm_asmap; 219 const dt_sym_t *dsp = dmp->dm_symchains + 1; 220 uint_t i, n = dmp->dm_symfree; 221 222 for (i = 1; i < n; i++, dsp++) { 223 Elf64_Sym *sym = symtab + dsp->ds_symid; 224 if (sym->st_value != 0 && 225 (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) 226 *sympp++ = sym; 227 } 228 229 dmp->dm_aslen = (uint_t)(sympp - (Elf64_Sym **)dmp->dm_asmap); 230 assert(dmp->dm_aslen <= dmp->dm_asrsv); 231 232 dt_module_strtab = dmp->dm_strtab.cts_data; 233 qsort(dmp->dm_asmap, dmp->dm_aslen, 234 sizeof (Elf64_Sym *), dt_module_symcomp64); 235 dt_module_strtab = NULL; 236 } 237 238 static GElf_Sym * 239 dt_module_symgelf32(const Elf32_Sym *src, GElf_Sym *dst) 240 { 241 if (dst != NULL) { 242 dst->st_name = src->st_name; 243 dst->st_info = src->st_info; 244 dst->st_other = src->st_other; 245 dst->st_shndx = src->st_shndx; 246 dst->st_value = src->st_value; 247 dst->st_size = src->st_size; 248 } 249 250 return (dst); 251 } 252 253 static GElf_Sym * 254 dt_module_symgelf64(const Elf64_Sym *src, GElf_Sym *dst) 255 { 256 if (dst != NULL) 257 bcopy(src, dst, sizeof (GElf_Sym)); 258 259 return (dst); 260 } 261 262 static GElf_Sym * 263 dt_module_symname32(dt_module_t *dmp, const char *name, 264 GElf_Sym *symp, uint_t *idp) 265 { 266 const Elf32_Sym *symtab = dmp->dm_symtab.cts_data; 267 const char *strtab = dmp->dm_strtab.cts_data; 268 269 const Elf32_Sym *sym; 270 const dt_sym_t *dsp; 271 uint_t i, h; 272 273 if (dmp->dm_nsymelems == 0) 274 return (NULL); 275 276 h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets; 277 278 for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) { 279 dsp = &dmp->dm_symchains[i]; 280 sym = symtab + dsp->ds_symid; 281 282 if (strcmp(name, strtab + sym->st_name) == 0) { 283 if (idp != NULL) 284 *idp = dsp->ds_symid; 285 return (dt_module_symgelf32(sym, symp)); 286 } 287 } 288 289 return (NULL); 290 } 291 292 static GElf_Sym * 293 dt_module_symname64(dt_module_t *dmp, const char *name, 294 GElf_Sym *symp, uint_t *idp) 295 { 296 const Elf64_Sym *symtab = dmp->dm_symtab.cts_data; 297 const char *strtab = dmp->dm_strtab.cts_data; 298 299 const Elf64_Sym *sym; 300 const dt_sym_t *dsp; 301 uint_t i, h; 302 303 if (dmp->dm_nsymelems == 0) 304 return (NULL); 305 306 h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets; 307 308 for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) { 309 dsp = &dmp->dm_symchains[i]; 310 sym = symtab + dsp->ds_symid; 311 312 if (strcmp(name, strtab + sym->st_name) == 0) { 313 if (idp != NULL) 314 *idp = dsp->ds_symid; 315 return (dt_module_symgelf64(sym, symp)); 316 } 317 } 318 319 return (NULL); 320 } 321 322 static GElf_Sym * 323 dt_module_symaddr32(dt_module_t *dmp, GElf_Addr addr, 324 GElf_Sym *symp, uint_t *idp) 325 { 326 const Elf32_Sym **asmap = (const Elf32_Sym **)dmp->dm_asmap; 327 const Elf32_Sym *symtab = dmp->dm_symtab.cts_data; 328 const Elf32_Sym *sym; 329 330 uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1; 331 Elf32_Addr v; 332 333 if (dmp->dm_aslen == 0) 334 return (NULL); 335 336 while (hi - lo > 1) { 337 mid = (lo + hi) / 2; 338 if (addr >= asmap[mid]->st_value) 339 lo = mid; 340 else 341 hi = mid; 342 } 343 344 i = addr < asmap[hi]->st_value ? lo : hi; 345 sym = asmap[i]; 346 v = sym->st_value; 347 348 /* 349 * If the previous entry has the same value, improve our choice. The 350 * order of equal-valued symbols is determined by the comparison func. 351 */ 352 while (i-- != 0 && asmap[i]->st_value == v) 353 sym = asmap[i]; 354 355 if (addr - sym->st_value < MAX(sym->st_size, 1)) { 356 if (idp != NULL) 357 *idp = (uint_t)(sym - symtab); 358 return (dt_module_symgelf32(sym, symp)); 359 } 360 361 return (NULL); 362 } 363 364 static GElf_Sym * 365 dt_module_symaddr64(dt_module_t *dmp, GElf_Addr addr, 366 GElf_Sym *symp, uint_t *idp) 367 { 368 const Elf64_Sym **asmap = (const Elf64_Sym **)dmp->dm_asmap; 369 const Elf64_Sym *symtab = dmp->dm_symtab.cts_data; 370 const Elf64_Sym *sym; 371 372 uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1; 373 Elf64_Addr v; 374 375 if (dmp->dm_aslen == 0) 376 return (NULL); 377 378 while (hi - lo > 1) { 379 mid = (lo + hi) / 2; 380 if (addr >= asmap[mid]->st_value) 381 lo = mid; 382 else 383 hi = mid; 384 } 385 386 i = addr < asmap[hi]->st_value ? lo : hi; 387 sym = asmap[i]; 388 v = sym->st_value; 389 390 /* 391 * If the previous entry has the same value, improve our choice. The 392 * order of equal-valued symbols is determined by the comparison func. 393 */ 394 while (i-- != 0 && asmap[i]->st_value == v) 395 sym = asmap[i]; 396 397 if (addr - sym->st_value < MAX(sym->st_size, 1)) { 398 if (idp != NULL) 399 *idp = (uint_t)(sym - symtab); 400 return (dt_module_symgelf64(sym, symp)); 401 } 402 403 return (NULL); 404 } 405 406 static const dt_modops_t dt_modops_32 = { 407 dt_module_syminit32, 408 dt_module_symsort32, 409 dt_module_symname32, 410 dt_module_symaddr32 411 }; 412 413 static const dt_modops_t dt_modops_64 = { 414 dt_module_syminit64, 415 dt_module_symsort64, 416 dt_module_symname64, 417 dt_module_symaddr64 418 }; 419 420 dt_module_t * 421 dt_module_create(dtrace_hdl_t *dtp, const char *name) 422 { 423 long pid; 424 char *eptr; 425 dt_ident_t *idp; 426 uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets; 427 dt_module_t *dmp; 428 429 for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) { 430 if (strcmp(dmp->dm_name, name) == 0) 431 return (dmp); 432 } 433 434 if ((dmp = malloc(sizeof (dt_module_t))) == NULL) 435 return (NULL); /* caller must handle allocation failure */ 436 437 bzero(dmp, sizeof (dt_module_t)); 438 (void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name)); 439 dt_list_append(&dtp->dt_modlist, dmp); 440 dmp->dm_next = dtp->dt_mods[h]; 441 dtp->dt_mods[h] = dmp; 442 dtp->dt_nmods++; 443 444 if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) 445 dmp->dm_ops = &dt_modops_64; 446 else 447 dmp->dm_ops = &dt_modops_32; 448 449 /* 450 * Modules for userland processes are special. They always refer to a 451 * specific process and have a copy of their CTF data from a specific 452 * instant in time. Any dt_module_t that begins with 'pid' is a module 453 * for a specific process, much like how any probe description that 454 * begins with 'pid' is special. pid123 refers to process 123. A module 455 * that is just 'pid' refers specifically to pid$target. This is 456 * generally done as D does not currently allow for macros to be 457 * evaluated when working with types. 458 */ 459 if (strncmp(dmp->dm_name, "pid", 3) == 0) { 460 errno = 0; 461 if (dmp->dm_name[3] == '\0') { 462 idp = dt_idhash_lookup(dtp->dt_macros, "target"); 463 if (idp != NULL && idp->di_id != 0) 464 dmp->dm_pid = idp->di_id; 465 } else { 466 pid = strtol(dmp->dm_name + 3, &eptr, 10); 467 if (errno == 0 && *eptr == '\0') 468 dmp->dm_pid = (pid_t)pid; 469 else 470 dt_dprintf("encountered malformed pid " 471 "module: %s\n", dmp->dm_name); 472 } 473 } 474 475 return (dmp); 476 } 477 478 dt_module_t * 479 dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name) 480 { 481 uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets; 482 dt_module_t *dmp; 483 484 for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) { 485 if (strcmp(dmp->dm_name, name) == 0) 486 return (dmp); 487 } 488 489 return (NULL); 490 } 491 492 /*ARGSUSED*/ 493 dt_module_t * 494 dt_module_lookup_by_ctf(dtrace_hdl_t *dtp, ctf_file_t *ctfp) 495 { 496 return (ctfp ? ctf_getspecific(ctfp) : NULL); 497 } 498 499 static int 500 dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp) 501 { 502 const char *s; 503 size_t shstrs; 504 GElf_Shdr sh; 505 Elf_Data *dp; 506 Elf_Scn *sp; 507 508 if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) 509 return (dt_set_errno(dtp, EDT_NOTLOADED)); 510 511 for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) { 512 if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL || 513 (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL) 514 continue; /* skip any malformed sections */ 515 516 if (sh.sh_type == ctsp->cts_type && 517 sh.sh_entsize == ctsp->cts_entsize && 518 strcmp(s, ctsp->cts_name) == 0) 519 break; /* section matches specification */ 520 } 521 522 /* 523 * If the section isn't found, return success but leave cts_data set 524 * to NULL and cts_size set to zero for our caller. 525 */ 526 if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL) 527 return (0); 528 529 ctsp->cts_data = dp->d_buf; 530 ctsp->cts_size = dp->d_size; 531 532 dt_dprintf("loaded %s [%s] (%lu bytes)\n", 533 dmp->dm_name, ctsp->cts_name, (ulong_t)ctsp->cts_size); 534 535 return (0); 536 } 537 538 typedef struct dt_module_cb_arg { 539 struct ps_prochandle *dpa_proc; 540 dtrace_hdl_t *dpa_dtp; 541 dt_module_t *dpa_dmp; 542 uint_t dpa_count; 543 } dt_module_cb_arg_t; 544 545 /* ARGSUSED */ 546 static int 547 dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj) 548 { 549 ctf_file_t *fp; 550 dt_module_cb_arg_t *dcp = arg; 551 552 /* Try to grab a ctf container if it exists */ 553 fp = Pname_to_ctf(dcp->dpa_proc, obj); 554 if (fp != NULL) 555 dcp->dpa_count++; 556 return (0); 557 } 558 559 /* ARGSUSED */ 560 static int 561 dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj) 562 { 563 ctf_file_t *fp; 564 char buf[MAXPATHLEN], *p; 565 dt_module_cb_arg_t *dcp = arg; 566 int count = dcp->dpa_count; 567 Lmid_t lmid; 568 569 fp = Pname_to_ctf(dcp->dpa_proc, obj); 570 if (fp == NULL) 571 return (0); 572 fp = ctf_dup(fp); 573 if (fp == NULL) 574 return (0); 575 dcp->dpa_dmp->dm_libctfp[count] = fp; 576 /* 577 * While it'd be nice to simply use objname here, because of our prior 578 * actions we'll always get a resolved object name to its on disk file. 579 * Like the pid provider, we need to tell a bit of a lie here. The type 580 * that the user thinks of is in terms of the libraries they requested, 581 * eg. libc.so.1, they don't care about the fact that it's 582 * libc_hwcap.so.1. 583 */ 584 (void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf)); 585 if ((p = strrchr(buf, '/')) == NULL) 586 p = buf; 587 else 588 p++; 589 590 /* 591 * If for some reason we can't find a link map id for this module, which 592 * would be really quite weird. We instead just say the link map id is 593 * zero. 594 */ 595 if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0) 596 lmid = 0; 597 598 if (lmid == 0) 599 dcp->dpa_dmp->dm_libctfn[count] = strdup(p); 600 else 601 (void) asprintf(&dcp->dpa_dmp->dm_libctfn[count], 602 "LM%lx`%s", lmid, p); 603 if (dcp->dpa_dmp->dm_libctfn[count] == NULL) 604 return (1); 605 ctf_setspecific(fp, dcp->dpa_dmp); 606 dcp->dpa_count++; 607 return (0); 608 } 609 610 /* 611 * We've been asked to load data that belongs to another process. As such we're 612 * going to pgrab it at this instant, load everything that we might ever care 613 * about, and then drive on. The reason for this is that the process that we're 614 * interested in might be changing. As long as we have grabbed it, then this 615 * can't be a problem for us. 616 * 617 * For now, we're actually going to punt on most things and just try to get CTF 618 * data, nothing else. Basically this is only useful as a source of type 619 * information, we can't go and do the stacktrace lookups, etc. 620 */ 621 static int 622 dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp) 623 { 624 struct ps_prochandle *p; 625 dt_module_cb_arg_t arg; 626 627 /* 628 * Note that on success we do not release this hold. We must hold this 629 * for our life time. 630 */ 631 p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE); 632 if (p == NULL) { 633 dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid); 634 return (dt_set_errno(dtp, EDT_CANTLOAD)); 635 } 636 dt_proc_lock(dtp, p); 637 638 arg.dpa_proc = p; 639 arg.dpa_dtp = dtp; 640 arg.dpa_dmp = dmp; 641 arg.dpa_count = 0; 642 if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) { 643 dt_dprintf("failed to iterate objects\n"); 644 dt_proc_release(dtp, p); 645 return (dt_set_errno(dtp, EDT_CANTLOAD)); 646 } 647 648 if (arg.dpa_count == 0) { 649 dt_dprintf("no ctf data present\n"); 650 dt_proc_unlock(dtp, p); 651 dt_proc_release(dtp, p); 652 return (dt_set_errno(dtp, EDT_CANTLOAD)); 653 } 654 655 dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count); 656 if (dmp->dm_libctfp == NULL) { 657 dt_proc_unlock(dtp, p); 658 dt_proc_release(dtp, p); 659 return (dt_set_errno(dtp, EDT_NOMEM)); 660 } 661 bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count); 662 663 dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count); 664 if (dmp->dm_libctfn == NULL) { 665 free(dmp->dm_libctfp); 666 dt_proc_unlock(dtp, p); 667 dt_proc_release(dtp, p); 668 return (dt_set_errno(dtp, EDT_NOMEM)); 669 } 670 bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count); 671 672 dmp->dm_nctflibs = arg.dpa_count; 673 674 arg.dpa_count = 0; 675 if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) { 676 dt_proc_unlock(dtp, p); 677 dt_module_unload(dtp, dmp); 678 dt_proc_release(dtp, p); 679 return (dt_set_errno(dtp, EDT_CANTLOAD)); 680 } 681 assert(arg.dpa_count == dmp->dm_nctflibs); 682 dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count, 683 (int)dmp->dm_pid); 684 685 dt_proc_unlock(dtp, p); 686 dt_proc_release(dtp, p); 687 dmp->dm_flags |= DT_DM_LOADED; 688 689 return (0); 690 } 691 692 int 693 dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp) 694 { 695 if (dmp->dm_flags & DT_DM_LOADED) 696 return (0); /* module is already loaded */ 697 698 if (dmp->dm_pid != 0) 699 return (dt_module_load_proc(dtp, dmp)); 700 701 dmp->dm_ctdata.cts_name = ".SUNW_ctf"; 702 dmp->dm_ctdata.cts_type = SHT_PROGBITS; 703 dmp->dm_ctdata.cts_flags = 0; 704 dmp->dm_ctdata.cts_data = NULL; 705 dmp->dm_ctdata.cts_size = 0; 706 dmp->dm_ctdata.cts_entsize = 0; 707 dmp->dm_ctdata.cts_offset = 0; 708 709 dmp->dm_symtab.cts_name = ".symtab"; 710 dmp->dm_symtab.cts_type = SHT_SYMTAB; 711 dmp->dm_symtab.cts_flags = 0; 712 dmp->dm_symtab.cts_data = NULL; 713 dmp->dm_symtab.cts_size = 0; 714 dmp->dm_symtab.cts_entsize = dmp->dm_ops == &dt_modops_64 ? 715 sizeof (Elf64_Sym) : sizeof (Elf32_Sym); 716 dmp->dm_symtab.cts_offset = 0; 717 718 dmp->dm_strtab.cts_name = ".strtab"; 719 dmp->dm_strtab.cts_type = SHT_STRTAB; 720 dmp->dm_strtab.cts_flags = 0; 721 dmp->dm_strtab.cts_data = NULL; 722 dmp->dm_strtab.cts_size = 0; 723 dmp->dm_strtab.cts_entsize = 0; 724 dmp->dm_strtab.cts_offset = 0; 725 726 /* 727 * Attempt to load the module's CTF section, symbol table section, and 728 * string table section. Note that modules may not contain CTF data: 729 * this will result in a successful load_sect but data of size zero. 730 * We will then fail if dt_module_getctf() is called, as shown below. 731 */ 732 if (dt_module_load_sect(dtp, dmp, &dmp->dm_ctdata) == -1 || 733 dt_module_load_sect(dtp, dmp, &dmp->dm_symtab) == -1 || 734 dt_module_load_sect(dtp, dmp, &dmp->dm_strtab) == -1) { 735 dt_module_unload(dtp, dmp); 736 return (-1); /* dt_errno is set for us */ 737 } 738 739 /* 740 * Allocate the hash chains and hash buckets for symbol name lookup. 741 * This is relatively simple since the symbol table is of fixed size 742 * and is known in advance. We allocate one extra element since we 743 * use element indices instead of pointers and zero is our sentinel. 744 */ 745 dmp->dm_nsymelems = 746 dmp->dm_symtab.cts_size / dmp->dm_symtab.cts_entsize; 747 748 dmp->dm_nsymbuckets = _dtrace_strbuckets; 749 dmp->dm_symfree = 1; /* first free element is index 1 */ 750 751 dmp->dm_symbuckets = malloc(sizeof (uint_t) * dmp->dm_nsymbuckets); 752 dmp->dm_symchains = malloc(sizeof (dt_sym_t) * dmp->dm_nsymelems + 1); 753 754 if (dmp->dm_symbuckets == NULL || dmp->dm_symchains == NULL) { 755 dt_module_unload(dtp, dmp); 756 return (dt_set_errno(dtp, EDT_NOMEM)); 757 } 758 759 bzero(dmp->dm_symbuckets, sizeof (uint_t) * dmp->dm_nsymbuckets); 760 bzero(dmp->dm_symchains, sizeof (dt_sym_t) * dmp->dm_nsymelems + 1); 761 762 /* 763 * Iterate over the symbol table data buffer and insert each symbol 764 * name into the name hash if the name and type are valid. Then 765 * allocate the address map, fill it in, and sort it. 766 */ 767 dmp->dm_asrsv = dmp->dm_ops->do_syminit(dmp); 768 769 dt_dprintf("hashed %s [%s] (%u symbols)\n", 770 dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_symfree - 1); 771 772 if ((dmp->dm_asmap = malloc(sizeof (void *) * dmp->dm_asrsv)) == NULL) { 773 dt_module_unload(dtp, dmp); 774 return (dt_set_errno(dtp, EDT_NOMEM)); 775 } 776 777 dmp->dm_ops->do_symsort(dmp); 778 779 dt_dprintf("sorted %s [%s] (%u symbols)\n", 780 dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_aslen); 781 782 dmp->dm_flags |= DT_DM_LOADED; 783 return (0); 784 } 785 786 int 787 dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp) 788 { 789 if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0) 790 return (1); 791 return (dt_module_getctf(dtp, dmp) != NULL); 792 } 793 794 ctf_file_t * 795 dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp) 796 { 797 const char *parent; 798 dt_module_t *pmp; 799 ctf_file_t *pfp; 800 int model; 801 802 if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0) 803 return (dmp->dm_ctfp); 804 805 if (dmp->dm_ops == &dt_modops_64) 806 model = CTF_MODEL_LP64; 807 else 808 model = CTF_MODEL_ILP32; 809 810 /* 811 * If the data model of the module does not match our program data 812 * model, then do not permit CTF from this module to be opened and 813 * returned to the compiler. If we support mixed data models in the 814 * future for combined kernel/user tracing, this can be removed. 815 */ 816 if (dtp->dt_conf.dtc_ctfmodel != model) { 817 (void) dt_set_errno(dtp, EDT_DATAMODEL); 818 return (NULL); 819 } 820 821 if (dmp->dm_ctdata.cts_size == 0) { 822 (void) dt_set_errno(dtp, EDT_NOCTF); 823 return (NULL); 824 } 825 826 dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata, 827 &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr); 828 829 if (dmp->dm_ctfp == NULL) { 830 (void) dt_set_errno(dtp, EDT_CTF); 831 return (NULL); 832 } 833 834 (void) ctf_setmodel(dmp->dm_ctfp, model); 835 ctf_setspecific(dmp->dm_ctfp, dmp); 836 837 if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) { 838 if ((pmp = dt_module_create(dtp, parent)) == NULL || 839 (pfp = dt_module_getctf(dtp, pmp)) == NULL) { 840 if (pmp == NULL) 841 (void) dt_set_errno(dtp, EDT_NOMEM); 842 goto err; 843 } 844 845 if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) { 846 dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp); 847 (void) dt_set_errno(dtp, EDT_CTF); 848 goto err; 849 } 850 } 851 852 dt_dprintf("loaded CTF container for %s (%p)\n", 853 dmp->dm_name, (void *)dmp->dm_ctfp); 854 855 return (dmp->dm_ctfp); 856 857 err: 858 ctf_close(dmp->dm_ctfp); 859 dmp->dm_ctfp = NULL; 860 return (NULL); 861 } 862 863 /*ARGSUSED*/ 864 void 865 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp) 866 { 867 int i; 868 869 ctf_close(dmp->dm_ctfp); 870 dmp->dm_ctfp = NULL; 871 872 if (dmp->dm_libctfp != NULL) { 873 for (i = 0; i < dmp->dm_nctflibs; i++) { 874 ctf_close(dmp->dm_libctfp[i]); 875 free(dmp->dm_libctfn[i]); 876 } 877 free(dmp->dm_libctfp); 878 free(dmp->dm_libctfn); 879 dmp->dm_libctfp = NULL; 880 dmp->dm_nctflibs = 0; 881 } 882 883 bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t)); 884 bzero(&dmp->dm_symtab, sizeof (ctf_sect_t)); 885 bzero(&dmp->dm_strtab, sizeof (ctf_sect_t)); 886 887 if (dmp->dm_symbuckets != NULL) { 888 free(dmp->dm_symbuckets); 889 dmp->dm_symbuckets = NULL; 890 } 891 892 if (dmp->dm_symchains != NULL) { 893 free(dmp->dm_symchains); 894 dmp->dm_symchains = NULL; 895 } 896 897 if (dmp->dm_asmap != NULL) { 898 free(dmp->dm_asmap); 899 dmp->dm_asmap = NULL; 900 } 901 902 dmp->dm_symfree = 0; 903 dmp->dm_nsymbuckets = 0; 904 dmp->dm_nsymelems = 0; 905 dmp->dm_asrsv = 0; 906 dmp->dm_aslen = 0; 907 908 dmp->dm_text_va = 0; 909 dmp->dm_text_size = 0; 910 dmp->dm_data_va = 0; 911 dmp->dm_data_size = 0; 912 dmp->dm_bss_va = 0; 913 dmp->dm_bss_size = 0; 914 915 if (dmp->dm_extern != NULL) { 916 dt_idhash_destroy(dmp->dm_extern); 917 dmp->dm_extern = NULL; 918 } 919 920 (void) elf_end(dmp->dm_elf); 921 dmp->dm_elf = NULL; 922 923 dmp->dm_pid = 0; 924 925 dmp->dm_flags &= ~DT_DM_LOADED; 926 } 927 928 void 929 dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp) 930 { 931 uint_t h = dt_strtab_hash(dmp->dm_name, NULL) % dtp->dt_modbuckets; 932 dt_module_t **dmpp = &dtp->dt_mods[h]; 933 934 dt_list_delete(&dtp->dt_modlist, dmp); 935 assert(dtp->dt_nmods != 0); 936 dtp->dt_nmods--; 937 938 /* 939 * Now remove this module from its hash chain. We expect to always 940 * find the module on its hash chain, so in this loop we assert that 941 * we don't run off the end of the list. 942 */ 943 while (*dmpp != dmp) { 944 dmpp = &((*dmpp)->dm_next); 945 assert(*dmpp != NULL); 946 } 947 948 *dmpp = dmp->dm_next; 949 950 dt_module_unload(dtp, dmp); 951 free(dmp); 952 } 953 954 /* 955 * Insert a new external symbol reference into the specified module. The new 956 * symbol will be marked as undefined and is assigned a symbol index beyond 957 * any existing cached symbols from this module. We use the ident's di_data 958 * field to store a pointer to a copy of the dtrace_syminfo_t for this symbol. 959 */ 960 dt_ident_t * 961 dt_module_extern(dtrace_hdl_t *dtp, dt_module_t *dmp, 962 const char *name, const dtrace_typeinfo_t *tip) 963 { 964 dtrace_syminfo_t *sip; 965 dt_ident_t *idp; 966 uint_t id; 967 968 if (dmp->dm_extern == NULL && (dmp->dm_extern = dt_idhash_create( 969 "extern", NULL, dmp->dm_nsymelems, UINT_MAX)) == NULL) { 970 (void) dt_set_errno(dtp, EDT_NOMEM); 971 return (NULL); 972 } 973 974 if (dt_idhash_nextid(dmp->dm_extern, &id) == -1) { 975 (void) dt_set_errno(dtp, EDT_SYMOFLOW); 976 return (NULL); 977 } 978 979 if ((sip = malloc(sizeof (dtrace_syminfo_t))) == NULL) { 980 (void) dt_set_errno(dtp, EDT_NOMEM); 981 return (NULL); 982 } 983 984 idp = dt_idhash_insert(dmp->dm_extern, name, DT_IDENT_SYMBOL, 0, id, 985 _dtrace_symattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen); 986 987 if (idp == NULL) { 988 (void) dt_set_errno(dtp, EDT_NOMEM); 989 free(sip); 990 return (NULL); 991 } 992 993 sip->dts_object = dmp->dm_name; 994 sip->dts_name = idp->di_name; 995 sip->dts_id = idp->di_id; 996 997 idp->di_data = sip; 998 idp->di_ctfp = tip->dtt_ctfp; 999 idp->di_type = tip->dtt_type; 1000 1001 return (idp); 1002 } 1003 1004 const char * 1005 dt_module_modelname(dt_module_t *dmp) 1006 { 1007 if (dmp->dm_ops == &dt_modops_64) 1008 return ("64-bit"); 1009 else 1010 return ("32-bit"); 1011 } 1012 1013 /* ARGSUSED */ 1014 int 1015 dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp) 1016 { 1017 int i; 1018 1019 for (i = 0; i < dmp->dm_nctflibs; i++) { 1020 if (dmp->dm_libctfp[i] == fp) 1021 return (i); 1022 } 1023 1024 return (-1); 1025 } 1026 1027 /* ARGSUSED */ 1028 ctf_file_t * 1029 dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name) 1030 { 1031 int i; 1032 1033 for (i = 0; i < dmp->dm_nctflibs; i++) { 1034 if (strcmp(dmp->dm_libctfn[i], name) == 0) 1035 return (dmp->dm_libctfp[i]); 1036 } 1037 1038 return (NULL); 1039 } 1040 1041 /* 1042 * Update our module cache by adding an entry for the specified module 'name'. 1043 * We create the dt_module_t and populate it using /system/object/<name>/. 1044 */ 1045 static void 1046 dt_module_update(dtrace_hdl_t *dtp, const char *name) 1047 { 1048 char fname[MAXPATHLEN]; 1049 struct stat64 st; 1050 int fd, err, bits; 1051 1052 dt_module_t *dmp; 1053 const char *s; 1054 size_t shstrs; 1055 GElf_Shdr sh; 1056 Elf_Data *dp; 1057 Elf_Scn *sp; 1058 1059 (void) snprintf(fname, sizeof (fname), 1060 "%s/%s/object", OBJFS_ROOT, name); 1061 1062 if ((fd = open(fname, O_RDONLY)) == -1 || fstat64(fd, &st) == -1 || 1063 (dmp = dt_module_create(dtp, name)) == NULL) { 1064 dt_dprintf("failed to open %s: %s\n", fname, strerror(errno)); 1065 (void) close(fd); 1066 return; 1067 } 1068 1069 /* 1070 * Since the module can unload out from under us (and /system/object 1071 * will return ENOENT), tell libelf to cook the entire file now and 1072 * then close the underlying file descriptor immediately. If this 1073 * succeeds, we know that we can continue safely using dmp->dm_elf. 1074 */ 1075 dmp->dm_elf = elf_begin(fd, ELF_C_READ, NULL); 1076 err = elf_cntl(dmp->dm_elf, ELF_C_FDREAD); 1077 (void) close(fd); 1078 1079 if (dmp->dm_elf == NULL || err == -1 || 1080 elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) { 1081 dt_dprintf("failed to load %s: %s\n", 1082 fname, elf_errmsg(elf_errno())); 1083 dt_module_destroy(dtp, dmp); 1084 return; 1085 } 1086 1087 switch (gelf_getclass(dmp->dm_elf)) { 1088 case ELFCLASS32: 1089 dmp->dm_ops = &dt_modops_32; 1090 bits = 32; 1091 break; 1092 case ELFCLASS64: 1093 dmp->dm_ops = &dt_modops_64; 1094 bits = 64; 1095 break; 1096 default: 1097 dt_dprintf("failed to load %s: unknown ELF class\n", fname); 1098 dt_module_destroy(dtp, dmp); 1099 return; 1100 } 1101 1102 /* 1103 * Iterate over the section headers locating various sections of 1104 * interest and use their attributes to flesh out the dt_module_t. 1105 */ 1106 for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) { 1107 if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL || 1108 (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL) 1109 continue; /* skip any malformed sections */ 1110 1111 if (strcmp(s, ".text") == 0) { 1112 dmp->dm_text_size = sh.sh_size; 1113 dmp->dm_text_va = sh.sh_addr; 1114 } else if (strcmp(s, ".data") == 0) { 1115 dmp->dm_data_size = sh.sh_size; 1116 dmp->dm_data_va = sh.sh_addr; 1117 } else if (strcmp(s, ".bss") == 0) { 1118 dmp->dm_bss_size = sh.sh_size; 1119 dmp->dm_bss_va = sh.sh_addr; 1120 } else if (strcmp(s, ".info") == 0 && 1121 (dp = elf_getdata(sp, NULL)) != NULL) { 1122 bcopy(dp->d_buf, &dmp->dm_info, 1123 MIN(sh.sh_size, sizeof (dmp->dm_info))); 1124 } else if (strcmp(s, ".filename") == 0 && 1125 (dp = elf_getdata(sp, NULL)) != NULL) { 1126 (void) strlcpy(dmp->dm_file, 1127 dp->d_buf, sizeof (dmp->dm_file)); 1128 } 1129 } 1130 1131 dmp->dm_flags |= DT_DM_KERNEL; 1132 dmp->dm_modid = (int)OBJFS_MODID(st.st_ino); 1133 1134 if (dmp->dm_info.objfs_info_primary) 1135 dmp->dm_flags |= DT_DM_PRIMARY; 1136 1137 dt_dprintf("opened %d-bit module %s (%s) [%d]\n", 1138 bits, dmp->dm_name, dmp->dm_file, dmp->dm_modid); 1139 } 1140 1141 /* 1142 * Unload all the loaded modules and then refresh the module cache with the 1143 * latest list of loaded modules and their address ranges. 1144 */ 1145 void 1146 dtrace_update(dtrace_hdl_t *dtp) 1147 { 1148 dt_module_t *dmp; 1149 DIR *dirp; 1150 1151 for (dmp = dt_list_next(&dtp->dt_modlist); 1152 dmp != NULL; dmp = dt_list_next(dmp)) 1153 dt_module_unload(dtp, dmp); 1154 1155 /* 1156 * Open /system/object and attempt to create a libdtrace module for 1157 * each kernel module that is loaded on the current system. 1158 */ 1159 if (!(dtp->dt_oflags & DTRACE_O_NOSYS) && 1160 (dirp = opendir(OBJFS_ROOT)) != NULL) { 1161 struct dirent *dp; 1162 1163 while ((dp = readdir(dirp)) != NULL) { 1164 if (dp->d_name[0] != '.') 1165 dt_module_update(dtp, dp->d_name); 1166 } 1167 1168 (void) closedir(dirp); 1169 } 1170 1171 /* 1172 * Look up all the macro identifiers and set di_id to the latest value. 1173 * This code collaborates with dt_lex.l on the use of di_id. We will 1174 * need to implement something fancier if we need to support non-ints. 1175 */ 1176 dt_idhash_lookup(dtp->dt_macros, "egid")->di_id = getegid(); 1177 dt_idhash_lookup(dtp->dt_macros, "euid")->di_id = geteuid(); 1178 dt_idhash_lookup(dtp->dt_macros, "gid")->di_id = getgid(); 1179 dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid(); 1180 dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0); 1181 dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid(); 1182 dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid(); 1183 dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0); 1184 dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid(); 1185 dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid(); 1186 1187 /* 1188 * Cache the pointers to the modules representing the base executable 1189 * and the run-time linker in the dtrace client handle. Note that on 1190 * x86 krtld is folded into unix, so if we don't find it, use unix 1191 * instead. 1192 */ 1193 dtp->dt_exec = dt_module_lookup_by_name(dtp, "genunix"); 1194 dtp->dt_rtld = dt_module_lookup_by_name(dtp, "krtld"); 1195 if (dtp->dt_rtld == NULL) 1196 dtp->dt_rtld = dt_module_lookup_by_name(dtp, "unix"); 1197 1198 /* 1199 * If this is the first time we are initializing the module list, 1200 * remove the module for genunix from the module list and then move it 1201 * to the front of the module list. We do this so that type and symbol 1202 * queries encounter genunix and thereby optimize for the common case 1203 * in dtrace_lookup_by_name() and dtrace_lookup_by_type(), below. 1204 */ 1205 if (dtp->dt_exec != NULL && 1206 dtp->dt_cdefs == NULL && dtp->dt_ddefs == NULL) { 1207 dt_list_delete(&dtp->dt_modlist, dtp->dt_exec); 1208 dt_list_prepend(&dtp->dt_modlist, dtp->dt_exec); 1209 } 1210 } 1211 1212 static dt_module_t * 1213 dt_module_from_object(dtrace_hdl_t *dtp, const char *object) 1214 { 1215 int err = EDT_NOMOD; 1216 dt_module_t *dmp; 1217 1218 switch ((uintptr_t)object) { 1219 case (uintptr_t)DTRACE_OBJ_EXEC: 1220 dmp = dtp->dt_exec; 1221 break; 1222 case (uintptr_t)DTRACE_OBJ_RTLD: 1223 dmp = dtp->dt_rtld; 1224 break; 1225 case (uintptr_t)DTRACE_OBJ_CDEFS: 1226 dmp = dtp->dt_cdefs; 1227 break; 1228 case (uintptr_t)DTRACE_OBJ_DDEFS: 1229 dmp = dtp->dt_ddefs; 1230 break; 1231 default: 1232 dmp = dt_module_create(dtp, object); 1233 err = EDT_NOMEM; 1234 } 1235 1236 if (dmp == NULL) 1237 (void) dt_set_errno(dtp, err); 1238 1239 return (dmp); 1240 } 1241 1242 /* 1243 * Exported interface to look up a symbol by name. We return the GElf_Sym and 1244 * complete symbol information for the matching symbol. 1245 */ 1246 int 1247 dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name, 1248 GElf_Sym *symp, dtrace_syminfo_t *sip) 1249 { 1250 dt_module_t *dmp; 1251 dt_ident_t *idp; 1252 uint_t n, id; 1253 GElf_Sym sym; 1254 1255 uint_t mask = 0; /* mask of dt_module flags to match */ 1256 uint_t bits = 0; /* flag bits that must be present */ 1257 1258 if (object != DTRACE_OBJ_EVERY && 1259 object != DTRACE_OBJ_KMODS && 1260 object != DTRACE_OBJ_UMODS) { 1261 if ((dmp = dt_module_from_object(dtp, object)) == NULL) 1262 return (-1); /* dt_errno is set for us */ 1263 1264 if (dt_module_load(dtp, dmp) == -1) 1265 return (-1); /* dt_errno is set for us */ 1266 n = 1; 1267 1268 } else { 1269 if (object == DTRACE_OBJ_KMODS) 1270 mask = bits = DT_DM_KERNEL; 1271 else if (object == DTRACE_OBJ_UMODS) 1272 mask = DT_DM_KERNEL; 1273 1274 dmp = dt_list_next(&dtp->dt_modlist); 1275 n = dtp->dt_nmods; 1276 } 1277 1278 if (symp == NULL) 1279 symp = &sym; 1280 1281 for (; n > 0; n--, dmp = dt_list_next(dmp)) { 1282 if ((dmp->dm_flags & mask) != bits) 1283 continue; /* failed to match required attributes */ 1284 1285 if (dt_module_load(dtp, dmp) == -1) 1286 continue; /* failed to load symbol table */ 1287 1288 if (dmp->dm_ops->do_symname(dmp, name, symp, &id) != NULL) { 1289 if (sip != NULL) { 1290 sip->dts_object = dmp->dm_name; 1291 sip->dts_name = (const char *) 1292 dmp->dm_strtab.cts_data + symp->st_name; 1293 sip->dts_id = id; 1294 } 1295 return (0); 1296 } 1297 1298 if (dmp->dm_extern != NULL && 1299 (idp = dt_idhash_lookup(dmp->dm_extern, name)) != NULL) { 1300 if (symp != &sym) { 1301 symp->st_name = (uintptr_t)idp->di_name; 1302 symp->st_info = 1303 GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); 1304 symp->st_other = 0; 1305 symp->st_shndx = SHN_UNDEF; 1306 symp->st_value = 0; 1307 symp->st_size = 1308 ctf_type_size(idp->di_ctfp, idp->di_type); 1309 } 1310 1311 if (sip != NULL) { 1312 sip->dts_object = dmp->dm_name; 1313 sip->dts_name = idp->di_name; 1314 sip->dts_id = idp->di_id; 1315 } 1316 1317 return (0); 1318 } 1319 } 1320 1321 return (dt_set_errno(dtp, EDT_NOSYM)); 1322 } 1323 1324 /* 1325 * Exported interface to look up a symbol by address. We return the GElf_Sym 1326 * and complete symbol information for the matching symbol. 1327 */ 1328 int 1329 dtrace_lookup_by_addr(dtrace_hdl_t *dtp, GElf_Addr addr, 1330 GElf_Sym *symp, dtrace_syminfo_t *sip) 1331 { 1332 dt_module_t *dmp; 1333 uint_t id; 1334 const dtrace_vector_t *v = dtp->dt_vector; 1335 1336 if (v != NULL) 1337 return (v->dtv_lookup_by_addr(dtp->dt_varg, addr, symp, sip)); 1338 1339 for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL; 1340 dmp = dt_list_next(dmp)) { 1341 if (addr - dmp->dm_text_va < dmp->dm_text_size || 1342 addr - dmp->dm_data_va < dmp->dm_data_size || 1343 addr - dmp->dm_bss_va < dmp->dm_bss_size) 1344 break; 1345 } 1346 1347 if (dmp == NULL) 1348 return (dt_set_errno(dtp, EDT_NOSYMADDR)); 1349 1350 if (dt_module_load(dtp, dmp) == -1) 1351 return (-1); /* dt_errno is set for us */ 1352 1353 if (symp != NULL) { 1354 if (dmp->dm_ops->do_symaddr(dmp, addr, symp, &id) == NULL) 1355 return (dt_set_errno(dtp, EDT_NOSYMADDR)); 1356 } 1357 1358 if (sip != NULL) { 1359 sip->dts_object = dmp->dm_name; 1360 1361 if (symp != NULL) { 1362 sip->dts_name = (const char *) 1363 dmp->dm_strtab.cts_data + symp->st_name; 1364 sip->dts_id = id; 1365 } else { 1366 sip->dts_name = NULL; 1367 sip->dts_id = 0; 1368 } 1369 } 1370 1371 return (0); 1372 } 1373 1374 /* 1375 * We've been asked to try to find a type that's in a module that corresponds to 1376 * a user process. There are multiple CTF libraries that are associated with 1377 * this module (hopefully) and we will find the one that matches this type. The 1378 * type "name" that we get may have a particular CTF object named in it. The way 1379 * that the D compiler structures this is that it's a qualifier on the name of 1380 * the type, but may keep the type keyword (struct, union, or enum) first. That 1381 * means we may have something that looks like any of the following: 1382 * 1383 * - struct foo 1384 * - foo_t 1385 * - libc.so.1`bar_t 1386 * - a.out`bar_t (replace a.out with the program's executable name) 1387 * - struct a.out`foo_t 1388 * 1389 * When we have an object to search we need to pull that out and make sure that 1390 * we include that keyword as part of the name. 1391 */ 1392 static int 1393 dtrace_lookup_by_type_user(dtrace_hdl_t *dtp, dt_module_t *dmp, 1394 const char *name, ctf_file_t **fpp, ctf_id_t *idp) 1395 { 1396 size_t obj_off; 1397 char *dup, *obj_end, *type_buf = NULL; 1398 const char *obj, *type; 1399 ctf_file_t *fp; 1400 ctf_id_t id; 1401 1402 if (dmp->dm_nctflibs == 0) { 1403 *fpp = NULL; 1404 *idp = CTF_ERR; 1405 return (0); 1406 } 1407 1408 /* 1409 * When there is no backtick in the name, then there is no object 1410 * specified in the type name. As a result, we don't have to tear apart 1411 * and reassemble the type name. Unfortunately it does mean we have to 1412 * search all of the module's CTF containers to try to find it. We'll 1413 * take the first one that we find. 1414 */ 1415 if (strchr(name, '`') == NULL) { 1416 uint_t i; 1417 1418 for (i = 0; i < dmp->dm_nctflibs; i++) { 1419 id = ctf_lookup_by_name(dmp->dm_libctfp[i], name); 1420 if (id != CTF_ERR) { 1421 *fpp = dmp->dm_libctfp[i]; 1422 *idp = id; 1423 return (0); 1424 } 1425 } 1426 1427 *fpp = NULL; 1428 *idp = CTF_ERR; 1429 return (0); 1430 } 1431 1432 /* 1433 * We have an object name. Check to see if it begins with a struct, 1434 * enum, or union. Note the space is intentional here as if it's present 1435 * the space should always be here and we want to ensure that we skip 1436 * past it. 1437 */ 1438 if (strncmp(name, "struct ", strlen("struct ")) == 0) { 1439 obj_off = strlen("struct "); 1440 } else if (strncmp(name, "union ", strlen("union ")) == 0) { 1441 obj_off = strlen("union "); 1442 } else if (strncmp(name, "enum ", strlen("enum ")) == 0) { 1443 obj_off = strlen("enum "); 1444 } else { 1445 obj_off = 0; 1446 } 1447 1448 dup = strdup(name); 1449 if (dup == NULL) { 1450 return (dt_set_errno(dtp, EDT_NOMEM)); 1451 } 1452 1453 obj_end = strchr(dup, '`'); 1454 *obj_end = '\0'; 1455 if (obj_off != 0) { 1456 obj = dup + obj_off; 1457 dup[obj_off - 1] = '\0'; 1458 if (asprintf(&type_buf, "%s %s", dup, obj_end + 1) == -1) { 1459 free(dup); 1460 return (dt_set_errno(dtp, EDT_NOMEM)); 1461 } 1462 type = type_buf; 1463 } else { 1464 obj = dup; 1465 type = obj_end + 1; 1466 } 1467 1468 fp = dt_module_getctflib(dtp, dmp, obj); 1469 if (fp != NULL && ((id = ctf_lookup_by_name(fp, type)) != CTF_ERR)) { 1470 *fpp = fp; 1471 *idp = id; 1472 } else { 1473 *fpp = NULL; 1474 *idp = CTF_ERR; 1475 } 1476 1477 free(dup); 1478 free(type_buf); 1479 return (0); 1480 } 1481 1482 int 1483 dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, 1484 dtrace_typeinfo_t *tip) 1485 { 1486 dtrace_typeinfo_t ti; 1487 dt_module_t *dmp; 1488 int found = 0; 1489 ctf_id_t id; 1490 uint_t n, i; 1491 int justone; 1492 ctf_file_t *fp; 1493 char *buf, *p, *q; 1494 1495 uint_t mask = 0; /* mask of dt_module flags to match */ 1496 uint_t bits = 0; /* flag bits that must be present */ 1497 1498 if (object != DTRACE_OBJ_EVERY && 1499 object != DTRACE_OBJ_KMODS && 1500 object != DTRACE_OBJ_UMODS) { 1501 if ((dmp = dt_module_from_object(dtp, object)) == NULL) 1502 return (-1); /* dt_errno is set for us */ 1503 1504 if (dt_module_load(dtp, dmp) == -1) 1505 return (-1); /* dt_errno is set for us */ 1506 n = 1; 1507 justone = 1; 1508 } else { 1509 if (object == DTRACE_OBJ_KMODS) 1510 mask = bits = DT_DM_KERNEL; 1511 else if (object == DTRACE_OBJ_UMODS) 1512 mask = DT_DM_KERNEL; 1513 1514 dmp = dt_list_next(&dtp->dt_modlist); 1515 n = dtp->dt_nmods; 1516 justone = 0; 1517 } 1518 1519 if (tip == NULL) 1520 tip = &ti; 1521 1522 for (; n > 0; n--, dmp = dt_list_next(dmp)) { 1523 if ((dmp->dm_flags & mask) != bits) 1524 continue; /* failed to match required attributes */ 1525 1526 /* 1527 * If we can't load the CTF container, continue on to the next 1528 * module. If our search was scoped to only one module then 1529 * return immediately leaving dt_errno unmodified. 1530 */ 1531 if (dt_module_hasctf(dtp, dmp) == 0) { 1532 if (justone) 1533 return (-1); 1534 continue; 1535 } 1536 1537 /* 1538 * Look up the type in the module's CTF container. If our 1539 * match is a forward declaration tag, save this choice in 1540 * 'tip' and keep going in the hope that we will locate the 1541 * underlying structure definition. Otherwise just return. 1542 */ 1543 if (dmp->dm_pid == 0) { 1544 id = ctf_lookup_by_name(dmp->dm_ctfp, name); 1545 fp = dmp->dm_ctfp; 1546 } else { 1547 if (dtrace_lookup_by_type_user(dtp, dmp, name, 1548 &fp, &id) != 0) { 1549 return (-1); 1550 } 1551 } 1552 if (id != CTF_ERR) { 1553 tip->dtt_object = dmp->dm_name; 1554 tip->dtt_ctfp = fp; 1555 tip->dtt_type = id; 1556 if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) != 1557 CTF_K_FORWARD) 1558 return (0); 1559 1560 found++; 1561 } 1562 } 1563 1564 if (found == 0) 1565 return (dt_set_errno(dtp, EDT_NOTYPE)); 1566 1567 return (0); 1568 } 1569 1570 int 1571 dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp, 1572 const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip) 1573 { 1574 dt_module_t *dmp; 1575 1576 tip->dtt_object = NULL; 1577 tip->dtt_ctfp = NULL; 1578 tip->dtt_type = CTF_ERR; 1579 tip->dtt_flags = 0; 1580 1581 if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL) 1582 return (dt_set_errno(dtp, EDT_NOMOD)); 1583 1584 if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) { 1585 dt_ident_t *idp = 1586 dt_idhash_lookup(dmp->dm_extern, sip->dts_name); 1587 1588 if (idp == NULL) 1589 return (dt_set_errno(dtp, EDT_NOSYM)); 1590 1591 tip->dtt_ctfp = idp->di_ctfp; 1592 tip->dtt_type = idp->di_type; 1593 1594 } else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) { 1595 if (dt_module_getctf(dtp, dmp) == NULL) 1596 return (-1); /* errno is set for us */ 1597 1598 tip->dtt_ctfp = dmp->dm_ctfp; 1599 tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id); 1600 1601 if (tip->dtt_type == CTF_ERR) { 1602 dtp->dt_ctferr = ctf_errno(tip->dtt_ctfp); 1603 return (dt_set_errno(dtp, EDT_CTF)); 1604 } 1605 1606 } else { 1607 tip->dtt_ctfp = DT_FPTR_CTFP(dtp); 1608 tip->dtt_type = DT_FPTR_TYPE(dtp); 1609 } 1610 1611 tip->dtt_object = dmp->dm_name; 1612 return (0); 1613 } 1614 1615 static dtrace_objinfo_t * 1616 dt_module_info(const dt_module_t *dmp, dtrace_objinfo_t *dto) 1617 { 1618 dto->dto_name = dmp->dm_name; 1619 dto->dto_file = dmp->dm_file; 1620 dto->dto_id = dmp->dm_modid; 1621 dto->dto_flags = 0; 1622 1623 if (dmp->dm_flags & DT_DM_KERNEL) 1624 dto->dto_flags |= DTRACE_OBJ_F_KERNEL; 1625 if (dmp->dm_flags & DT_DM_PRIMARY) 1626 dto->dto_flags |= DTRACE_OBJ_F_PRIMARY; 1627 1628 dto->dto_text_va = dmp->dm_text_va; 1629 dto->dto_text_size = dmp->dm_text_size; 1630 dto->dto_data_va = dmp->dm_data_va; 1631 dto->dto_data_size = dmp->dm_data_size; 1632 dto->dto_bss_va = dmp->dm_bss_va; 1633 dto->dto_bss_size = dmp->dm_bss_size; 1634 1635 return (dto); 1636 } 1637 1638 int 1639 dtrace_object_iter(dtrace_hdl_t *dtp, dtrace_obj_f *func, void *data) 1640 { 1641 const dt_module_t *dmp = dt_list_next(&dtp->dt_modlist); 1642 dtrace_objinfo_t dto; 1643 int rv; 1644 1645 for (; dmp != NULL; dmp = dt_list_next(dmp)) { 1646 if ((rv = (*func)(dtp, dt_module_info(dmp, &dto), data)) != 0) 1647 return (rv); 1648 } 1649 1650 return (0); 1651 } 1652 1653 int 1654 dtrace_object_info(dtrace_hdl_t *dtp, const char *object, dtrace_objinfo_t *dto) 1655 { 1656 dt_module_t *dmp; 1657 1658 if (object == DTRACE_OBJ_EVERY || object == DTRACE_OBJ_KMODS || 1659 object == DTRACE_OBJ_UMODS || dto == NULL) 1660 return (dt_set_errno(dtp, EINVAL)); 1661 1662 if ((dmp = dt_module_from_object(dtp, object)) == NULL) 1663 return (-1); /* dt_errno is set for us */ 1664 1665 if (dt_module_load(dtp, dmp) == -1) 1666 return (-1); /* dt_errno is set for us */ 1667 1668 (void) dt_module_info(dmp, dto); 1669 return (0); 1670 } 1671