dt_module_t * dt_module_create(dtrace_hdl_t *dtp, const char *name) { uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets; dt_module_t *dmp; for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) { if (strcmp(dmp->dm_name, name) == 0) return (dmp); } if ((dmp = malloc(sizeof (dt_module_t))) == NULL) return (NULL); /* caller must handle allocation failure */ bzero(dmp, sizeof (dt_module_t)); (void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name)); dt_list_append(&dtp->dt_modlist, dmp); dmp->dm_next = dtp->dt_mods[h]; dtp->dt_mods[h] = dmp; dtp->dt_nmods++; if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) dmp->dm_ops = &dt_modops_64; else dmp->dm_ops = &dt_modops_32; return (dmp); }
dt_module_t * dt_module_create(dtrace_hdl_t *dtp, const char *name) { long pid; char *eptr; dt_ident_t *idp; uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets; dt_module_t *dmp; for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) { if (strcmp(dmp->dm_name, name) == 0) return (dmp); } if ((dmp = malloc(sizeof (dt_module_t))) == NULL) return (NULL); /* caller must handle allocation failure */ bzero(dmp, sizeof (dt_module_t)); (void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name)); dt_list_append(&dtp->dt_modlist, dmp); dmp->dm_next = dtp->dt_mods[h]; dtp->dt_mods[h] = dmp; dtp->dt_nmods++; if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) dmp->dm_ops = &dt_modops_64; else dmp->dm_ops = &dt_modops_32; /* * Modules for userland processes are special. They always refer to a * specific process and have a copy of their CTF data from a specific * instant in time. Any dt_module_t that begins with 'pid' is a module * for a specific process, much like how any probe description that * begins with 'pid' is special. pid123 refers to process 123. A module * that is just 'pid' refers specifically to pid$target. This is * generally done as D does not currently allow for macros to be * evaluated when working with types. */ if (strncmp(dmp->dm_name, "pid", 3) == 0) { errno = 0; if (dmp->dm_name[3] == '\0') { idp = dt_idhash_lookup(dtp->dt_macros, "target"); if (idp != NULL && idp->di_id != 0) dmp->dm_pid = idp->di_id; } else { pid = strtol(dmp->dm_name + 3, &eptr, 10); if (errno == 0 && *eptr == '\0') dmp->dm_pid = (pid_t)pid; else dt_dprintf("encountered malformed pid " "module: %s\n", dmp->dm_name); } } return (dmp); }
static dt_provider_t * dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h) { dt_list_append(&dtp->dt_provlist, pvp); pvp->pv_next = dtp->dt_provs[h]; dtp->dt_provs[h] = pvp; dtp->dt_nprovs++; return (pvp); }
/*ARGSUSED*/ static int dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) { dt_dirpath_t *dp; if (arg == NULL) return (dt_set_errno(dtp, EDT_BADOPTVAL)); if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL || (dp->dir_path = strdup(arg)) == NULL) { free(dp); return (dt_set_errno(dtp, EDT_NOMEM)); } dt_list_append(&dtp->dt_lib_path, dp); return (0); }
dtrace_prog_t * dt_program_create(dtrace_hdl_t *dtp) { dtrace_prog_t *pgp = dt_zalloc(dtp, sizeof (dtrace_prog_t)); if (pgp != NULL) { dt_list_append(&dtp->dt_programs, pgp); } else { (void) dt_set_errno(dtp, EDT_NOMEM); return (NULL); } /* * By default, programs start with DOF version 1 so that output files * containing DOF are backward compatible. If a program requires new * DOF features, the version is increased as needed. */ pgp->dp_dofversion = DOF_VERSION_1; return (pgp); }
static dt_bkpt_t * dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data) { struct ps_prochandle *P = dpr->dpr_proc; dt_bkpt_t *dbp; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); if ((dbp = dt_zalloc(dpr->dpr_hdl, sizeof (dt_bkpt_t))) != NULL) { dbp->dbp_func = func; dbp->dbp_data = data; dbp->dbp_addr = addr; if (Psetbkpt(P, dbp->dbp_addr, &dbp->dbp_instr) == 0) dbp->dbp_active = B_TRUE; dt_list_append(&dpr->dpr_bps, dbp); } return (dbp); }
dtrace_prog_t * dt_program_create(dtrace_hdl_t *dtp) { dtrace_prog_t *pgp = dt_zalloc(dtp, sizeof (dtrace_prog_t)); if (pgp != NULL) dt_list_append(&dtp->dt_programs, pgp); else (void) dt_set_errno(dtp, EDT_NOMEM); /* * By default, programs start with DOF version 1 so that output files * containing DOF are backward compatible. If a program requires new * DOF features, the version is increased as needed. */ /* * APPLE NOTE: The earliest DOF version Leopard will support is v3. * This includes relative offsets for probes, and is-enabled probes. */ pgp->dp_dofversion = DOF_VERSION_3; return (pgp); }
dt_xlator_t * dt_xlator_create(dtrace_hdl_t *dtp, const dtrace_typeinfo_t *src, const dtrace_typeinfo_t *dst, const char *name, dt_node_t *members, dt_node_t *nodes) { dt_xlator_t *dxp = dt_zalloc(dtp, sizeof (dt_xlator_t)); dtrace_typeinfo_t ptr = *dst; dt_xlator_t **map; dt_node_t *dnp; uint_t kind; if (dxp == NULL) return (NULL); dxp->dx_hdl = dtp; dxp->dx_id = dtp->dt_xlatorid++; dxp->dx_gen = dtp->dt_gen; dxp->dx_arg = -1; if ((map = dt_alloc(dtp, sizeof (void *) * (dxp->dx_id + 1))) == NULL) { dt_free(dtp, dxp); return (NULL); } dt_list_append(&dtp->dt_xlators, dxp); bcopy(dtp->dt_xlatormap, map, sizeof (void *) * dxp->dx_id); dt_free(dtp, dtp->dt_xlatormap); dtp->dt_xlatormap = map; dtp->dt_xlatormap[dxp->dx_id] = dxp; if (dt_type_pointer(&ptr) == -1) { ptr.dtt_ctfp = NULL; ptr.dtt_type = CTF_ERR; } dxp->dx_ident = dt_ident_create(name ? name : "T", DT_IDENT_SCALAR, DT_IDFLG_REF | DT_IDFLG_ORPHAN, 0, _dtrace_defattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen); if (dxp->dx_ident == NULL) goto err; /* no memory for identifier */ dxp->dx_ident->di_ctfp = src->dtt_ctfp; dxp->dx_ident->di_type = src->dtt_type; /* * If an input parameter name is given, this is a static translator * definition: create an idhash and identifier for the parameter. */ if (name != NULL) { dxp->dx_locals = dt_idhash_create("xlparams", NULL, 0, 0); if (dxp->dx_locals == NULL) goto err; /* no memory for identifier hash */ dt_idhash_xinsert(dxp->dx_locals, dxp->dx_ident); } dxp->dx_souid.di_name = "translator"; dxp->dx_souid.di_kind = DT_IDENT_XLSOU; dxp->dx_souid.di_flags = DT_IDFLG_REF; dxp->dx_souid.di_id = dxp->dx_id; dxp->dx_souid.di_attr = _dtrace_defattr; dxp->dx_souid.di_ops = &dt_idops_thaw; dxp->dx_souid.di_data = dxp; dxp->dx_souid.di_ctfp = dst->dtt_ctfp; dxp->dx_souid.di_type = dst->dtt_type; dxp->dx_souid.di_gen = dtp->dt_gen; dxp->dx_ptrid.di_name = "translator"; dxp->dx_ptrid.di_kind = DT_IDENT_XLPTR; dxp->dx_ptrid.di_flags = DT_IDFLG_REF; dxp->dx_ptrid.di_id = dxp->dx_id; dxp->dx_ptrid.di_attr = _dtrace_defattr; dxp->dx_ptrid.di_ops = &dt_idops_thaw; dxp->dx_ptrid.di_data = dxp; dxp->dx_ptrid.di_ctfp = ptr.dtt_ctfp; dxp->dx_ptrid.di_type = ptr.dtt_type; dxp->dx_ptrid.di_gen = dtp->dt_gen; /* * If a deferred pragma is pending on the keyword "translator", run all * the deferred pragmas on dx_souid and then copy results to dx_ptrid. * See the code in dt_pragma.c for details on deferred ident pragmas. */ if (dtp->dt_globals->dh_defer != NULL && yypcb->pcb_pragmas != NULL && dt_idhash_lookup(yypcb->pcb_pragmas, "translator") != NULL) { dtp->dt_globals->dh_defer(dtp->dt_globals, &dxp->dx_souid); dxp->dx_ptrid.di_attr = dxp->dx_souid.di_attr; dxp->dx_ptrid.di_vers = dxp->dx_souid.di_vers; } dxp->dx_src_ctfp = src->dtt_ctfp; dxp->dx_src_type = src->dtt_type; dxp->dx_src_base = ctf_type_resolve(src->dtt_ctfp, src->dtt_type); dxp->dx_dst_ctfp = dst->dtt_ctfp; dxp->dx_dst_type = dst->dtt_type; dxp->dx_dst_base = ctf_type_resolve(dst->dtt_ctfp, dst->dtt_type); kind = ctf_type_kind(dst->dtt_ctfp, dxp->dx_dst_base); assert(kind == CTF_K_STRUCT || kind == CTF_K_UNION); /* * If no input parameter is given, we're making a dynamic translator: * create member nodes for every member of the output type. Otherwise * retain the member and allocation node lists presented by the parser. */ if (name == NULL) { if (ctf_member_iter(dxp->dx_dst_ctfp, dxp->dx_dst_base, dt_xlator_create_member, dxp) != 0) goto err; } else { dxp->dx_members = members; dxp->dx_nodes = nodes; } /* * Assign member IDs to each member and allocate space for DIFOs * if and when this translator is eventually compiled. */ for (dnp = dxp->dx_members; dnp != NULL; dnp = dnp->dn_list) { dnp->dn_membxlator = dxp; dnp->dn_membid = dxp->dx_nmembers++; } dxp->dx_membdif = dt_zalloc(dtp, sizeof (dtrace_difo_t *) * dxp->dx_nmembers); if (dxp->dx_membdif == NULL) { dxp->dx_nmembers = 0; goto err; } return (dxp); err: dt_xlator_destroy(dtp, dxp); return (NULL); }
void dt_idstack_push(dt_idstack_t *sp, dt_idhash_t *dhp) { dt_list_append(&sp->dids_list, dhp); }