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