Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>


   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 #include <sys/types.h>
  27 #include <sys/modctl.h>
  28 #include <sys/kobj.h>
  29 #include <sys/kobj_impl.h>
  30 #include <sys/sysmacros.h>
  31 #include <sys/elf.h>
  32 #include <sys/task.h>
  33 
  34 #include <unistd.h>
  35 #include <project.h>
  36 #include <strings.h>
  37 #include <stdlib.h>
  38 #include <libelf.h>
  39 #include <limits.h>
  40 #include <assert.h>
  41 #include <errno.h>
  42 #include <dirent.h>
  43 
  44 #include <dt_strtab.h>


 401         return (NULL);
 402 }
 403 
 404 static const dt_modops_t dt_modops_32 = {
 405         dt_module_syminit32,
 406         dt_module_symsort32,
 407         dt_module_symname32,
 408         dt_module_symaddr32
 409 };
 410 
 411 static const dt_modops_t dt_modops_64 = {
 412         dt_module_syminit64,
 413         dt_module_symsort64,
 414         dt_module_symname64,
 415         dt_module_symaddr64
 416 };
 417 
 418 dt_module_t *
 419 dt_module_create(dtrace_hdl_t *dtp, const char *name)
 420 {



 421         uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
 422         dt_module_t *dmp;
 423 
 424         for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
 425                 if (strcmp(dmp->dm_name, name) == 0)
 426                         return (dmp);
 427         }
 428 
 429         if ((dmp = malloc(sizeof (dt_module_t))) == NULL)
 430                 return (NULL); /* caller must handle allocation failure */
 431 
 432         bzero(dmp, sizeof (dt_module_t));
 433         (void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name));
 434         dt_list_append(&dtp->dt_modlist, dmp);
 435         dmp->dm_next = dtp->dt_mods[h];
 436         dtp->dt_mods[h] = dmp;
 437         dtp->dt_nmods++;
 438 
 439         if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
 440                 dmp->dm_ops = &dt_modops_64;
 441         else
 442                 dmp->dm_ops = &dt_modops_32;
 443 


























 444         return (dmp);
 445 }
 446 
 447 dt_module_t *
 448 dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
 449 {
 450         uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
 451         dt_module_t *dmp;
 452 
 453         for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
 454                 if (strcmp(dmp->dm_name, name) == 0)
 455                         return (dmp);
 456         }
 457 
 458         return (NULL);
 459 }
 460 
 461 /*ARGSUSED*/
 462 dt_module_t *
 463 dt_module_lookup_by_ctf(dtrace_hdl_t *dtp, ctf_file_t *ctfp)


 487                     strcmp(s, ctsp->cts_name) == 0)
 488                         break; /* section matches specification */
 489         }
 490 
 491         /*
 492          * If the section isn't found, return success but leave cts_data set
 493          * to NULL and cts_size set to zero for our caller.
 494          */
 495         if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL)
 496                 return (0);
 497 
 498         ctsp->cts_data = dp->d_buf;
 499         ctsp->cts_size = dp->d_size;
 500 
 501         dt_dprintf("loaded %s [%s] (%lu bytes)\n",
 502             dmp->dm_name, ctsp->cts_name, (ulong_t)ctsp->cts_size);
 503 
 504         return (0);
 505 }
 506 


























































































































































 507 int
 508 dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp)
 509 {
 510         if (dmp->dm_flags & DT_DM_LOADED)
 511                 return (0); /* module is already loaded */
 512 



 513         dmp->dm_ctdata.cts_name = ".SUNW_ctf";
 514         dmp->dm_ctdata.cts_type = SHT_PROGBITS;
 515         dmp->dm_ctdata.cts_flags = 0;
 516         dmp->dm_ctdata.cts_data = NULL;
 517         dmp->dm_ctdata.cts_size = 0;
 518         dmp->dm_ctdata.cts_entsize = 0;
 519         dmp->dm_ctdata.cts_offset = 0;
 520 
 521         dmp->dm_symtab.cts_name = ".symtab";
 522         dmp->dm_symtab.cts_type = SHT_SYMTAB;
 523         dmp->dm_symtab.cts_flags = 0;
 524         dmp->dm_symtab.cts_data = NULL;
 525         dmp->dm_symtab.cts_size = 0;
 526         dmp->dm_symtab.cts_entsize = dmp->dm_ops == &dt_modops_64 ?
 527             sizeof (Elf64_Sym) : sizeof (Elf32_Sym);
 528         dmp->dm_symtab.cts_offset = 0;
 529 
 530         dmp->dm_strtab.cts_name = ".strtab";
 531         dmp->dm_strtab.cts_type = SHT_STRTAB;
 532         dmp->dm_strtab.cts_flags = 0;


 578          */
 579         dmp->dm_asrsv = dmp->dm_ops->do_syminit(dmp);
 580 
 581         dt_dprintf("hashed %s [%s] (%u symbols)\n",
 582             dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_symfree - 1);
 583 
 584         if ((dmp->dm_asmap = malloc(sizeof (void *) * dmp->dm_asrsv)) == NULL) {
 585                 dt_module_unload(dtp, dmp);
 586                 return (dt_set_errno(dtp, EDT_NOMEM));
 587         }
 588 
 589         dmp->dm_ops->do_symsort(dmp);
 590 
 591         dt_dprintf("sorted %s [%s] (%u symbols)\n",
 592             dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_aslen);
 593 
 594         dmp->dm_flags |= DT_DM_LOADED;
 595         return (0);
 596 }
 597 








 598 ctf_file_t *
 599 dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
 600 {
 601         const char *parent;
 602         dt_module_t *pmp;
 603         ctf_file_t *pfp;
 604         int model;
 605 
 606         if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)
 607                 return (dmp->dm_ctfp);
 608 
 609         if (dmp->dm_ops == &dt_modops_64)
 610                 model = CTF_MODEL_LP64;
 611         else
 612                 model = CTF_MODEL_ILP32;
 613 
 614         /*
 615          * If the data model of the module does not match our program data
 616          * model, then do not permit CTF from this module to be opened and
 617          * returned to the compiler.  If we support mixed data models in the


 651                         (void) dt_set_errno(dtp, EDT_CTF);
 652                         goto err;
 653                 }
 654         }
 655 
 656         dt_dprintf("loaded CTF container for %s (%p)\n",
 657             dmp->dm_name, (void *)dmp->dm_ctfp);
 658 
 659         return (dmp->dm_ctfp);
 660 
 661 err:
 662         ctf_close(dmp->dm_ctfp);
 663         dmp->dm_ctfp = NULL;
 664         return (NULL);
 665 }
 666 
 667 /*ARGSUSED*/
 668 void
 669 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 670 {


 671         ctf_close(dmp->dm_ctfp);
 672         dmp->dm_ctfp = NULL;
 673 











 674         bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));
 675         bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));
 676         bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));
 677 
 678         if (dmp->dm_symbuckets != NULL) {
 679                 free(dmp->dm_symbuckets);
 680                 dmp->dm_symbuckets = NULL;
 681         }
 682 
 683         if (dmp->dm_symchains != NULL) {
 684                 free(dmp->dm_symchains);
 685                 dmp->dm_symchains = NULL;
 686         }
 687 
 688         if (dmp->dm_asmap != NULL) {
 689                 free(dmp->dm_asmap);
 690                 dmp->dm_asmap = NULL;
 691         }
 692 
 693         dmp->dm_symfree = 0;
 694         dmp->dm_nsymbuckets = 0;
 695         dmp->dm_nsymelems = 0;
 696         dmp->dm_asrsv = 0;
 697         dmp->dm_aslen = 0;
 698 
 699         dmp->dm_text_va = NULL;
 700         dmp->dm_text_size = 0;
 701         dmp->dm_data_va = NULL;
 702         dmp->dm_data_size = 0;
 703         dmp->dm_bss_va = NULL;
 704         dmp->dm_bss_size = 0;
 705 
 706         if (dmp->dm_extern != NULL) {
 707                 dt_idhash_destroy(dmp->dm_extern);
 708                 dmp->dm_extern = NULL;
 709         }
 710 
 711         (void) elf_end(dmp->dm_elf);
 712         dmp->dm_elf = NULL;
 713 


 714         dmp->dm_flags &= ~DT_DM_LOADED;
 715 }
 716 
 717 void
 718 dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp)
 719 {
 720         uint_t h = dt_strtab_hash(dmp->dm_name, NULL) % dtp->dt_modbuckets;
 721         dt_module_t **dmpp = &dtp->dt_mods[h];
 722 
 723         dt_list_delete(&dtp->dt_modlist, dmp);
 724         assert(dtp->dt_nmods != 0);
 725         dtp->dt_nmods--;
 726 
 727         /*
 728          * Now remove this module from its hash chain.  We expect to always
 729          * find the module on its hash chain, so in this loop we assert that
 730          * we don't run off the end of the list.
 731          */
 732         while (*dmpp != dmp) {
 733                 dmpp = &((*dmpp)->dm_next);


 782         sip->dts_object = dmp->dm_name;
 783         sip->dts_name = idp->di_name;
 784         sip->dts_id = idp->di_id;
 785 
 786         idp->di_data = sip;
 787         idp->di_ctfp = tip->dtt_ctfp;
 788         idp->di_type = tip->dtt_type;
 789 
 790         return (idp);
 791 }
 792 
 793 const char *
 794 dt_module_modelname(dt_module_t *dmp)
 795 {
 796         if (dmp->dm_ops == &dt_modops_64)
 797                 return ("64-bit");
 798         else
 799                 return ("32-bit");
 800 }
 801 




























 802 /*
 803  * Update our module cache by adding an entry for the specified module 'name'.
 804  * We create the dt_module_t and populate it using /system/object/<name>/.
 805  */
 806 static void
 807 dt_module_update(dtrace_hdl_t *dtp, const char *name)
 808 {
 809         char fname[MAXPATHLEN];
 810         struct stat64 st;
 811         int fd, err, bits;
 812 
 813         dt_module_t *dmp;
 814         const char *s;
 815         size_t shstrs;
 816         GElf_Shdr sh;
 817         Elf_Data *dp;
 818         Elf_Scn *sp;
 819 
 820         (void) snprintf(fname, sizeof (fname),
 821             "%s/%s/object", OBJFS_ROOT, name);


1123                         sip->dts_name = (const char *)
1124                             dmp->dm_strtab.cts_data + symp->st_name;
1125                         sip->dts_id = id;
1126                 } else {
1127                         sip->dts_name = NULL;
1128                         sip->dts_id = 0;
1129                 }
1130         }
1131 
1132         return (0);
1133 }
1134 
1135 int
1136 dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
1137     dtrace_typeinfo_t *tip)
1138 {
1139         dtrace_typeinfo_t ti;
1140         dt_module_t *dmp;
1141         int found = 0;
1142         ctf_id_t id;
1143         uint_t n;
1144         int justone;


1145 
1146         uint_t mask = 0; /* mask of dt_module flags to match */
1147         uint_t bits = 0; /* flag bits that must be present */
1148 
1149         if (object != DTRACE_OBJ_EVERY &&
1150             object != DTRACE_OBJ_KMODS &&
1151             object != DTRACE_OBJ_UMODS) {
1152                 if ((dmp = dt_module_from_object(dtp, object)) == NULL)
1153                         return (-1); /* dt_errno is set for us */
1154 
1155                 if (dt_module_load(dtp, dmp) == -1)
1156                         return (-1); /* dt_errno is set for us */
1157                 n = 1;
1158                 justone = 1;
1159 
1160         } else {
1161                 if (object == DTRACE_OBJ_KMODS)
1162                         mask = bits = DT_DM_KERNEL;
1163                 else if (object == DTRACE_OBJ_UMODS)
1164                         mask = DT_DM_KERNEL;
1165 
1166                 dmp = dt_list_next(&dtp->dt_modlist);
1167                 n = dtp->dt_nmods;
1168                 justone = 0;
1169         }
1170 
1171         if (tip == NULL)
1172                 tip = &ti;
1173 
1174         for (; n > 0; n--, dmp = dt_list_next(dmp)) {
1175                 if ((dmp->dm_flags & mask) != bits)
1176                         continue; /* failed to match required attributes */
1177 
1178                 /*
1179                  * If we can't load the CTF container, continue on to the next
1180                  * module.  If our search was scoped to only one module then
1181                  * return immediately leaving dt_errno unmodified.
1182                  */
1183                 if (dt_module_getctf(dtp, dmp) == NULL) {
1184                         if (justone)
1185                                 return (-1);
1186                         continue;
1187                 }
1188 
1189                 /*
1190                  * Look up the type in the module's CTF container.  If our
1191                  * match is a forward declaration tag, save this choice in
1192                  * 'tip' and keep going in the hope that we will locate the
1193                  * underlying structure definition.  Otherwise just return.
1194                  */
1195                 if ((id = ctf_lookup_by_name(dmp->dm_ctfp, name)) != CTF_ERR) {


























1196                         tip->dtt_object = dmp->dm_name;
1197                         tip->dtt_ctfp = dmp->dm_ctfp;
1198                         tip->dtt_type = id;
1199 
1200                         if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve(
1201                             dmp->dm_ctfp, id)) != CTF_K_FORWARD)
1202                                 return (0);
1203 
1204                         found++;
1205                 }
1206         }
1207 
1208         if (found == 0)
1209                 return (dt_set_errno(dtp, EDT_NOTYPE));
1210 
1211         return (0);
1212 }
1213 
1214 int
1215 dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
1216     const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
1217 {
1218         dt_module_t *dmp;
1219 
1220         tip->dtt_object = NULL;
1221         tip->dtt_ctfp = NULL;
1222         tip->dtt_type = CTF_ERR;

1223 
1224         if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)
1225                 return (dt_set_errno(dtp, EDT_NOMOD));
1226 
1227         if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) {
1228                 dt_ident_t *idp =
1229                     dt_idhash_lookup(dmp->dm_extern, sip->dts_name);
1230 
1231                 if (idp == NULL)
1232                         return (dt_set_errno(dtp, EDT_NOSYM));
1233 
1234                 tip->dtt_ctfp = idp->di_ctfp;
1235                 tip->dtt_type = idp->di_type;
1236 
1237         } else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) {
1238                 if (dt_module_getctf(dtp, dmp) == NULL)
1239                         return (-1); /* errno is set for us */
1240 
1241                 tip->dtt_ctfp = dmp->dm_ctfp;
1242                 tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id);




   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  */
  28 
  29 #include <sys/types.h>
  30 #include <sys/modctl.h>
  31 #include <sys/kobj.h>
  32 #include <sys/kobj_impl.h>
  33 #include <sys/sysmacros.h>
  34 #include <sys/elf.h>
  35 #include <sys/task.h>
  36 
  37 #include <unistd.h>
  38 #include <project.h>
  39 #include <strings.h>
  40 #include <stdlib.h>
  41 #include <libelf.h>
  42 #include <limits.h>
  43 #include <assert.h>
  44 #include <errno.h>
  45 #include <dirent.h>
  46 
  47 #include <dt_strtab.h>


 404         return (NULL);
 405 }
 406 
 407 static const dt_modops_t dt_modops_32 = {
 408         dt_module_syminit32,
 409         dt_module_symsort32,
 410         dt_module_symname32,
 411         dt_module_symaddr32
 412 };
 413 
 414 static const dt_modops_t dt_modops_64 = {
 415         dt_module_syminit64,
 416         dt_module_symsort64,
 417         dt_module_symname64,
 418         dt_module_symaddr64
 419 };
 420 
 421 dt_module_t *
 422 dt_module_create(dtrace_hdl_t *dtp, const char *name)
 423 {
 424         long pid;
 425         char *eptr;
 426         dt_ident_t *idp;
 427         uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
 428         dt_module_t *dmp;
 429 
 430         for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
 431                 if (strcmp(dmp->dm_name, name) == 0)
 432                         return (dmp);
 433         }
 434 
 435         if ((dmp = malloc(sizeof (dt_module_t))) == NULL)
 436                 return (NULL); /* caller must handle allocation failure */
 437 
 438         bzero(dmp, sizeof (dt_module_t));
 439         (void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name));
 440         dt_list_append(&dtp->dt_modlist, dmp);
 441         dmp->dm_next = dtp->dt_mods[h];
 442         dtp->dt_mods[h] = dmp;
 443         dtp->dt_nmods++;
 444 
 445         if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
 446                 dmp->dm_ops = &dt_modops_64;
 447         else
 448                 dmp->dm_ops = &dt_modops_32;
 449 
 450         /*
 451          * Modules for userland processes are special. They always refer to a
 452          * specific process and have a copy of their CTF data from a specific
 453          * instant in time. Any dt_module_t that begins with 'pid' is a module
 454          * for a specific process, much like how any probe description that
 455          * begins with 'pid' is special. pid123 refers to process 123. A module
 456          * that is just 'pid' refers specifically to pid$target. This is
 457          * generally done as D does not currently allow for macros to be
 458          * evaluated when working with types.
 459          */
 460         if (strncmp(dmp->dm_name, "pid", 3) == 0) {
 461                 errno = 0;
 462                 if (dmp->dm_name[3] == '\0') {
 463                         idp = dt_idhash_lookup(dtp->dt_macros, "target");
 464                         if (idp != NULL && idp->di_id != 0)
 465                                 dmp->dm_pid = idp->di_id;
 466                 } else {
 467                         pid = strtol(dmp->dm_name + 3, &eptr, 10);
 468                         if (errno == 0 && *eptr == '\0')
 469                                 dmp->dm_pid = (pid_t)pid;
 470                         else
 471                                 dt_dprintf("encountered malformed pid "
 472                                     "module: %s\n", dmp->dm_name);
 473                 }
 474         }
 475 
 476         return (dmp);
 477 }
 478 
 479 dt_module_t *
 480 dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
 481 {
 482         uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
 483         dt_module_t *dmp;
 484 
 485         for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
 486                 if (strcmp(dmp->dm_name, name) == 0)
 487                         return (dmp);
 488         }
 489 
 490         return (NULL);
 491 }
 492 
 493 /*ARGSUSED*/
 494 dt_module_t *
 495 dt_module_lookup_by_ctf(dtrace_hdl_t *dtp, ctf_file_t *ctfp)


 519                     strcmp(s, ctsp->cts_name) == 0)
 520                         break; /* section matches specification */
 521         }
 522 
 523         /*
 524          * If the section isn't found, return success but leave cts_data set
 525          * to NULL and cts_size set to zero for our caller.
 526          */
 527         if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL)
 528                 return (0);
 529 
 530         ctsp->cts_data = dp->d_buf;
 531         ctsp->cts_size = dp->d_size;
 532 
 533         dt_dprintf("loaded %s [%s] (%lu bytes)\n",
 534             dmp->dm_name, ctsp->cts_name, (ulong_t)ctsp->cts_size);
 535 
 536         return (0);
 537 }
 538 
 539 typedef struct dt_module_cb_arg {
 540         struct ps_prochandle *dpa_proc;
 541         dtrace_hdl_t *dpa_dtp;
 542         dt_module_t *dpa_dmp;
 543         uint_t dpa_count;
 544 } dt_module_cb_arg_t;
 545 
 546 /* ARGSUSED */
 547 static int
 548 dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj)
 549 {
 550         ctf_file_t *fp;
 551         dt_module_cb_arg_t *dcp = arg;
 552 
 553         /* Try to grab a ctf container if it exists */
 554         fp = Pname_to_ctf(dcp->dpa_proc, obj);
 555         if (fp != NULL)
 556                 dcp->dpa_count++;
 557         return (0);
 558 }
 559 
 560 /* ARGSUSED */
 561 static int
 562 dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj)
 563 {
 564         ctf_file_t *fp;
 565         char buf[MAXPATHLEN], *p;
 566         dt_module_cb_arg_t *dcp = arg;
 567         int count = dcp->dpa_count;
 568         Lmid_t lmid;
 569 
 570         fp = Pname_to_ctf(dcp->dpa_proc, obj);
 571         if (fp == NULL)
 572                 return (0);
 573         fp = ctf_dup(fp);
 574         if (fp == NULL)
 575                 return (0);
 576         dcp->dpa_dmp->dm_libctfp[count] = fp;
 577         /*
 578          * While it'd be nice to simply use objname here, because of our prior
 579          * actions we'll always get a resolved object name to its on disk file.
 580          * Like the pid provider, we need to tell a bit of a lie here. The type
 581          * that the user thinks of is in terms of the libraries they requested,
 582          * eg. libc.so.1, they don't care about the fact that it's
 583          * libc_hwcap.so.1.
 584          */
 585         (void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf));
 586         if ((p = strrchr(buf, '/')) == NULL)
 587                 p = buf;
 588         else
 589                 p++;
 590 
 591         /*
 592          * If for some reason we can't find a link map id for this module, which
 593          * would be really quite weird. We instead just say the link map id is
 594          * zero.
 595          */
 596         if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0)
 597                 lmid = 0;
 598 
 599         if (lmid == 0)
 600                 dcp->dpa_dmp->dm_libctfn[count] = strdup(p);
 601         else
 602                 (void) asprintf(&dcp->dpa_dmp->dm_libctfn[count],
 603                     "LM%lx`%s", lmid, p);
 604         if (dcp->dpa_dmp->dm_libctfn[count] == NULL)
 605                 return (1);
 606         ctf_setspecific(fp, dcp->dpa_dmp);
 607         dcp->dpa_count++;
 608         return (0);
 609 }
 610 
 611 /*
 612  * We've been asked to load data that belongs to another process. As such we're
 613  * going to pgrab it at this instant, load everything that we might ever care
 614  * about, and then drive on. The reason for this is that the process that we're
 615  * interested in might be changing. As long as we have grabbed it, then this
 616  * can't be a problem for us.
 617  *
 618  * For now, we're actually going to punt on most things and just try to get CTF
 619  * data, nothing else. Basically this is only useful as a source of type
 620  * information, we can't go and do the stacktrace lookups, etc.
 621  */
 622 static int
 623 dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp)
 624 {
 625         struct ps_prochandle *p;
 626         dt_module_cb_arg_t arg;
 627 
 628         /*
 629          * Note that on success we do not release this hold. We must hold this
 630          * for our life time.
 631          */
 632         p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
 633         if (p == NULL) {
 634                 dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid);
 635                 return (dt_set_errno(dtp, EDT_CANTLOAD));
 636         }
 637         dt_proc_lock(dtp, p);
 638 
 639         arg.dpa_proc = p;
 640         arg.dpa_dtp = dtp;
 641         arg.dpa_dmp = dmp;
 642         arg.dpa_count = 0;
 643         if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) {
 644                 dt_dprintf("failed to iterate objects\n");
 645                 dt_proc_release(dtp, p);
 646                 return (dt_set_errno(dtp, EDT_CANTLOAD));
 647         }
 648 
 649         if (arg.dpa_count == 0) {
 650                 dt_dprintf("no ctf data present\n");
 651                 dt_proc_unlock(dtp, p);
 652                 dt_proc_release(dtp, p);
 653                 return (dt_set_errno(dtp, EDT_CANTLOAD));
 654         }
 655 
 656         dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count);
 657         if (dmp->dm_libctfp == NULL) {
 658                 dt_proc_unlock(dtp, p);
 659                 dt_proc_release(dtp, p);
 660                 return (dt_set_errno(dtp, EDT_NOMEM));
 661         }
 662         bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count);
 663 
 664         dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count);
 665         if (dmp->dm_libctfn == NULL) {
 666                 free(dmp->dm_libctfp);
 667                 dt_proc_unlock(dtp, p);
 668                 dt_proc_release(dtp, p);
 669                 return (dt_set_errno(dtp, EDT_NOMEM));
 670         }
 671         bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count);
 672 
 673         dmp->dm_nctflibs = arg.dpa_count;
 674 
 675         arg.dpa_count = 0;
 676         if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) {
 677                 dt_proc_unlock(dtp, p);
 678                 dt_module_unload(dtp, dmp);
 679                 dt_proc_release(dtp, p);
 680                 return (dt_set_errno(dtp, EDT_CANTLOAD));
 681         }
 682         assert(arg.dpa_count == dmp->dm_nctflibs);
 683         dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count,
 684             (int)dmp->dm_pid);
 685 
 686         dt_proc_unlock(dtp, p);
 687         dt_proc_release(dtp, p);
 688         dmp->dm_flags |= DT_DM_LOADED;
 689 
 690         return (0);
 691 }
 692 
 693 int
 694 dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp)
 695 {
 696         if (dmp->dm_flags & DT_DM_LOADED)
 697                 return (0); /* module is already loaded */
 698 
 699         if (dmp->dm_pid != 0)
 700                 return (dt_module_load_proc(dtp, dmp));
 701 
 702         dmp->dm_ctdata.cts_name = ".SUNW_ctf";
 703         dmp->dm_ctdata.cts_type = SHT_PROGBITS;
 704         dmp->dm_ctdata.cts_flags = 0;
 705         dmp->dm_ctdata.cts_data = NULL;
 706         dmp->dm_ctdata.cts_size = 0;
 707         dmp->dm_ctdata.cts_entsize = 0;
 708         dmp->dm_ctdata.cts_offset = 0;
 709 
 710         dmp->dm_symtab.cts_name = ".symtab";
 711         dmp->dm_symtab.cts_type = SHT_SYMTAB;
 712         dmp->dm_symtab.cts_flags = 0;
 713         dmp->dm_symtab.cts_data = NULL;
 714         dmp->dm_symtab.cts_size = 0;
 715         dmp->dm_symtab.cts_entsize = dmp->dm_ops == &dt_modops_64 ?
 716             sizeof (Elf64_Sym) : sizeof (Elf32_Sym);
 717         dmp->dm_symtab.cts_offset = 0;
 718 
 719         dmp->dm_strtab.cts_name = ".strtab";
 720         dmp->dm_strtab.cts_type = SHT_STRTAB;
 721         dmp->dm_strtab.cts_flags = 0;


 767          */
 768         dmp->dm_asrsv = dmp->dm_ops->do_syminit(dmp);
 769 
 770         dt_dprintf("hashed %s [%s] (%u symbols)\n",
 771             dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_symfree - 1);
 772 
 773         if ((dmp->dm_asmap = malloc(sizeof (void *) * dmp->dm_asrsv)) == NULL) {
 774                 dt_module_unload(dtp, dmp);
 775                 return (dt_set_errno(dtp, EDT_NOMEM));
 776         }
 777 
 778         dmp->dm_ops->do_symsort(dmp);
 779 
 780         dt_dprintf("sorted %s [%s] (%u symbols)\n",
 781             dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_aslen);
 782 
 783         dmp->dm_flags |= DT_DM_LOADED;
 784         return (0);
 785 }
 786 
 787 int
 788 dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
 789 {
 790         if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0)
 791                 return (1);
 792         return (dt_module_getctf(dtp, dmp) != NULL);
 793 }
 794 
 795 ctf_file_t *
 796 dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
 797 {
 798         const char *parent;
 799         dt_module_t *pmp;
 800         ctf_file_t *pfp;
 801         int model;
 802 
 803         if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)
 804                 return (dmp->dm_ctfp);
 805 
 806         if (dmp->dm_ops == &dt_modops_64)
 807                 model = CTF_MODEL_LP64;
 808         else
 809                 model = CTF_MODEL_ILP32;
 810 
 811         /*
 812          * If the data model of the module does not match our program data
 813          * model, then do not permit CTF from this module to be opened and
 814          * returned to the compiler.  If we support mixed data models in the


 848                         (void) dt_set_errno(dtp, EDT_CTF);
 849                         goto err;
 850                 }
 851         }
 852 
 853         dt_dprintf("loaded CTF container for %s (%p)\n",
 854             dmp->dm_name, (void *)dmp->dm_ctfp);
 855 
 856         return (dmp->dm_ctfp);
 857 
 858 err:
 859         ctf_close(dmp->dm_ctfp);
 860         dmp->dm_ctfp = NULL;
 861         return (NULL);
 862 }
 863 
 864 /*ARGSUSED*/
 865 void
 866 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 867 {
 868         int i;
 869 
 870         ctf_close(dmp->dm_ctfp);
 871         dmp->dm_ctfp = NULL;
 872 
 873         if (dmp->dm_libctfp != NULL) {
 874                 for (i = 0; i < dmp->dm_nctflibs; i++) {
 875                         ctf_close(dmp->dm_libctfp[i]);
 876                         free(dmp->dm_libctfn[i]);
 877                 }
 878                 free(dmp->dm_libctfp);
 879                 free(dmp->dm_libctfn);
 880                 dmp->dm_libctfp = NULL;
 881                 dmp->dm_nctflibs = 0;
 882         }
 883 
 884         bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));
 885         bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));
 886         bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));
 887 
 888         if (dmp->dm_symbuckets != NULL) {
 889                 free(dmp->dm_symbuckets);
 890                 dmp->dm_symbuckets = NULL;
 891         }
 892 
 893         if (dmp->dm_symchains != NULL) {
 894                 free(dmp->dm_symchains);
 895                 dmp->dm_symchains = NULL;
 896         }
 897 
 898         if (dmp->dm_asmap != NULL) {
 899                 free(dmp->dm_asmap);
 900                 dmp->dm_asmap = NULL;
 901         }
 902 
 903         dmp->dm_symfree = 0;
 904         dmp->dm_nsymbuckets = 0;
 905         dmp->dm_nsymelems = 0;
 906         dmp->dm_asrsv = 0;
 907         dmp->dm_aslen = 0;
 908 
 909         dmp->dm_text_va = NULL;
 910         dmp->dm_text_size = 0;
 911         dmp->dm_data_va = NULL;
 912         dmp->dm_data_size = 0;
 913         dmp->dm_bss_va = NULL;
 914         dmp->dm_bss_size = 0;
 915 
 916         if (dmp->dm_extern != NULL) {
 917                 dt_idhash_destroy(dmp->dm_extern);
 918                 dmp->dm_extern = NULL;
 919         }
 920 
 921         (void) elf_end(dmp->dm_elf);
 922         dmp->dm_elf = NULL;
 923 
 924         dmp->dm_pid = 0;
 925 
 926         dmp->dm_flags &= ~DT_DM_LOADED;
 927 }
 928 
 929 void
 930 dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp)
 931 {
 932         uint_t h = dt_strtab_hash(dmp->dm_name, NULL) % dtp->dt_modbuckets;
 933         dt_module_t **dmpp = &dtp->dt_mods[h];
 934 
 935         dt_list_delete(&dtp->dt_modlist, dmp);
 936         assert(dtp->dt_nmods != 0);
 937         dtp->dt_nmods--;
 938 
 939         /*
 940          * Now remove this module from its hash chain.  We expect to always
 941          * find the module on its hash chain, so in this loop we assert that
 942          * we don't run off the end of the list.
 943          */
 944         while (*dmpp != dmp) {
 945                 dmpp = &((*dmpp)->dm_next);


 994         sip->dts_object = dmp->dm_name;
 995         sip->dts_name = idp->di_name;
 996         sip->dts_id = idp->di_id;
 997 
 998         idp->di_data = sip;
 999         idp->di_ctfp = tip->dtt_ctfp;
1000         idp->di_type = tip->dtt_type;
1001 
1002         return (idp);
1003 }
1004 
1005 const char *
1006 dt_module_modelname(dt_module_t *dmp)
1007 {
1008         if (dmp->dm_ops == &dt_modops_64)
1009                 return ("64-bit");
1010         else
1011                 return ("32-bit");
1012 }
1013 
1014 /* ARGSUSED */
1015 int
1016 dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp)
1017 {
1018         int i;
1019 
1020         for (i = 0; i < dmp->dm_nctflibs; i++) {
1021                 if (dmp->dm_libctfp[i] == fp)
1022                         return (i);
1023         }
1024 
1025         return (-1);
1026 }
1027 
1028 /* ARGSUSED */
1029 ctf_file_t *
1030 dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
1031 {
1032         int i;
1033 
1034         for (i = 0; i < dmp->dm_nctflibs; i++) {
1035                 if (strcmp(dmp->dm_libctfn[i], name) == 0)
1036                         return (dmp->dm_libctfp[i]);
1037         }
1038 
1039         return (NULL);
1040 }
1041 
1042 /*
1043  * Update our module cache by adding an entry for the specified module 'name'.
1044  * We create the dt_module_t and populate it using /system/object/<name>/.
1045  */
1046 static void
1047 dt_module_update(dtrace_hdl_t *dtp, const char *name)
1048 {
1049         char fname[MAXPATHLEN];
1050         struct stat64 st;
1051         int fd, err, bits;
1052 
1053         dt_module_t *dmp;
1054         const char *s;
1055         size_t shstrs;
1056         GElf_Shdr sh;
1057         Elf_Data *dp;
1058         Elf_Scn *sp;
1059 
1060         (void) snprintf(fname, sizeof (fname),
1061             "%s/%s/object", OBJFS_ROOT, name);


1363                         sip->dts_name = (const char *)
1364                             dmp->dm_strtab.cts_data + symp->st_name;
1365                         sip->dts_id = id;
1366                 } else {
1367                         sip->dts_name = NULL;
1368                         sip->dts_id = 0;
1369                 }
1370         }
1371 
1372         return (0);
1373 }
1374 
1375 int
1376 dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
1377     dtrace_typeinfo_t *tip)
1378 {
1379         dtrace_typeinfo_t ti;
1380         dt_module_t *dmp;
1381         int found = 0;
1382         ctf_id_t id;
1383         uint_t n, i;
1384         int justone;
1385         ctf_file_t *fp;
1386         char *buf, *p, *q;
1387 
1388         uint_t mask = 0; /* mask of dt_module flags to match */
1389         uint_t bits = 0; /* flag bits that must be present */
1390 
1391         if (object != DTRACE_OBJ_EVERY &&
1392             object != DTRACE_OBJ_KMODS &&
1393             object != DTRACE_OBJ_UMODS) {
1394                 if ((dmp = dt_module_from_object(dtp, object)) == NULL)
1395                         return (-1); /* dt_errno is set for us */
1396 
1397                 if (dt_module_load(dtp, dmp) == -1)
1398                         return (-1); /* dt_errno is set for us */
1399                 n = 1;
1400                 justone = 1;

1401         } else {
1402                 if (object == DTRACE_OBJ_KMODS)
1403                         mask = bits = DT_DM_KERNEL;
1404                 else if (object == DTRACE_OBJ_UMODS)
1405                         mask = DT_DM_KERNEL;
1406 
1407                 dmp = dt_list_next(&dtp->dt_modlist);
1408                 n = dtp->dt_nmods;
1409                 justone = 0;
1410         }
1411 
1412         if (tip == NULL)
1413                 tip = &ti;
1414 
1415         for (; n > 0; n--, dmp = dt_list_next(dmp)) {
1416                 if ((dmp->dm_flags & mask) != bits)
1417                         continue; /* failed to match required attributes */
1418 
1419                 /*
1420                  * If we can't load the CTF container, continue on to the next
1421                  * module.  If our search was scoped to only one module then
1422                  * return immediately leaving dt_errno unmodified.
1423                  */
1424                 if (dt_module_hasctf(dtp, dmp) == 0) {
1425                         if (justone)
1426                                 return (-1);
1427                         continue;
1428                 }
1429 
1430                 /*
1431                  * Look up the type in the module's CTF container.  If our
1432                  * match is a forward declaration tag, save this choice in
1433                  * 'tip' and keep going in the hope that we will locate the
1434                  * underlying structure definition.  Otherwise just return.
1435                  */
1436                 if (dmp->dm_pid == 0) {
1437                         id = ctf_lookup_by_name(dmp->dm_ctfp, name);
1438                         fp = dmp->dm_ctfp;
1439                 } else {
1440                         if ((p = strchr(name, '`')) != NULL) {
1441                                 buf = strdup(name);
1442                                 if (buf == NULL)
1443                                         return (dt_set_errno(dtp, EDT_NOMEM));
1444                                 p = strchr(buf, '`');
1445                                 if ((q = strchr(p + 1, '`')) != NULL)
1446                                         p = q;
1447                                 *p = '\0';
1448                                 fp = dt_module_getctflib(dtp, dmp, buf);
1449                                 if (fp == NULL || (id = ctf_lookup_by_name(fp,
1450                                     p + 1)) == CTF_ERR)
1451                                         id = CTF_ERR;
1452                                 free(buf);
1453                         } else {
1454                                 for (i = 0; i < dmp->dm_nctflibs; i++) {
1455                                         fp = dmp->dm_libctfp[i];
1456                                         id = ctf_lookup_by_name(fp, name);
1457                                         if (id != CTF_ERR)
1458                                                 break;
1459                                 }
1460                         }
1461                 }
1462                 if (id != CTF_ERR) {
1463                         tip->dtt_object = dmp->dm_name;
1464                         tip->dtt_ctfp = fp;
1465                         tip->dtt_type = id;
1466                         if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
1467                             CTF_K_FORWARD)

1468                                 return (0);
1469 
1470                         found++;
1471                 }
1472         }
1473 
1474         if (found == 0)
1475                 return (dt_set_errno(dtp, EDT_NOTYPE));
1476 
1477         return (0);
1478 }
1479 
1480 int
1481 dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
1482     const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
1483 {
1484         dt_module_t *dmp;
1485 
1486         tip->dtt_object = NULL;
1487         tip->dtt_ctfp = NULL;
1488         tip->dtt_type = CTF_ERR;
1489         tip->dtt_flags = 0;
1490 
1491         if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)
1492                 return (dt_set_errno(dtp, EDT_NOMOD));
1493 
1494         if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) {
1495                 dt_ident_t *idp =
1496                     dt_idhash_lookup(dmp->dm_extern, sip->dts_name);
1497 
1498                 if (idp == NULL)
1499                         return (dt_set_errno(dtp, EDT_NOSYM));
1500 
1501                 tip->dtt_ctfp = idp->di_ctfp;
1502                 tip->dtt_type = idp->di_type;
1503 
1504         } else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) {
1505                 if (dt_module_getctf(dtp, dmp) == NULL)
1506                         return (-1); /* errno is set for us */
1507 
1508                 tip->dtt_ctfp = dmp->dm_ctfp;
1509                 tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id);