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