dt_dof.c
来自「Sun Solaris 10 中的 DTrace 组件的源代码。请参看: htt」· C语言 代码 · 共 1,107 行 · 第 1/3 页
C
1,107 行
{ dof_probe_info_t *dpip = data; dt_probe_instance_t *pip; dt_probe_t *prp = idp->di_data; dof_stridx_t name, nargv, xargv; uint32_t argidx; dt_node_t *dnp; char buf[256]; int i; name = dpip->dpi_strlen; (void) strcpy(dpip->dpi_strtab + dpip->dpi_strlen, prp->pr_ident->di_name); dpip->dpi_strlen += strlen(prp->pr_ident->di_name) + 1; nargv = dpip->dpi_strlen; for (i = 0, dnp = prp->pr_nargs; i < prp->pr_nargc; i++, dnp = dnp->dn_list) { assert(dnp->dn_kind == DT_NODE_TYPE); (void) ctf_type_name(dnp->dn_ctfp, dnp->dn_type, buf, sizeof (buf)); (void) strcpy(dpip->dpi_strtab + dpip->dpi_strlen, buf); dpip->dpi_strlen += strlen(buf) + 1; } xargv = dpip->dpi_strlen; argidx = dpip->dpi_nargs; for (i = 0, dnp = prp->pr_xargs; i < prp->pr_xargc; i++, dnp = dnp->dn_list) { assert(dnp->dn_kind == DT_NODE_TYPE); (void) ctf_type_name(dnp->dn_ctfp, dnp->dn_type, buf, sizeof (buf)); (void) strcpy(dpip->dpi_strtab + dpip->dpi_strlen, buf); dpip->dpi_strlen += strlen(buf) + 1; dpip->dpi_args[dpip->dpi_nargs++] = (dnp->dn_string == NULL) ? i : dof_find_arg(prp->pr_nargs, prp->pr_nargc, dnp->dn_string); } for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) { dof_probe_t *dofprp = &dpip->dpi_probes[dpip->dpi_nprobes]; dof_relodesc_t *dofrp = &dpip->dpi_rel[dpip->dpi_nprobes]; int i; dpip->dpi_nprobes++; dofprp->dofpr_addr = 0; dofprp->dofpr_func = dpip->dpi_strlen; (void) strcpy(dpip->dpi_strtab + dpip->dpi_strlen, pip->pi_fname); dpip->dpi_strlen += strlen(pip->pi_fname) + 1; dofprp->dofpr_name = name; dofprp->dofpr_nargv = nargv; dofprp->dofpr_xargv = xargv; dofprp->dofpr_argidx = argidx; dofprp->dofpr_nargc = prp->pr_nargc; dofprp->dofpr_xargc = prp->pr_xargc; dofprp->dofpr_offidx = dpip->dpi_noffs; dofprp->dofpr_noffs = pip->pi_noffs; for (i = 0; i < dofprp->dofpr_noffs; i++) { dpip->dpi_offs[dpip->dpi_noffs++] = pip->pi_offs[i]; } dofrp->dofr_name = dofprp->dofpr_func; dofrp->dofr_type = DOF_RELO_SETX; dofrp->dofr_offset = (char *)&dofprp->dofpr_addr - (char *)dpip->dpi_probes; }}static dof_attr_tdof_attr(const dtrace_attribute_t *ap){ return (DOF_ATTR(ap->dtat_name, ap->dtat_data, ap->dtat_class));}static intdof_provider_save(dtrace_hdl_t *dtp, dt_dof_t *ddo, const dt_provider_t *pvp){ dof_provider_t dofpv; dof_probe_info_t dpi; dof_relohdr_t dofr; /* * Ignore providers that aren't user defined. */ if (pvp->pv_probes == NULL) return (0); dofpv.dofpv_provattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_provider); dofpv.dofpv_modattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_mod); dofpv.dofpv_funcattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_func); dofpv.dofpv_nameattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_name); dofpv.dofpv_argsattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_args); dpi.dpi_nprobes = 0; dpi.dpi_nargs = 0; dpi.dpi_noffs = 0; dpi.dpi_strlen = 1; /* leading '\0' */ dpi.dpi_strlen += strlen(pvp->pv_desc.dtvd_name) + 1; (void) dt_idhash_iter(pvp->pv_probes, dof_probe_size, &dpi); if ((dpi.dpi_probes = calloc(dpi.dpi_nprobes, sizeof (dof_probe_t))) == NULL) { return (dt_set_errno(dtp, EDT_NOMEM)); } if ((dpi.dpi_args = calloc(dpi.dpi_nargs, sizeof (uint8_t))) == NULL) { free(dpi.dpi_probes); return (dt_set_errno(dtp, EDT_NOMEM)); } if ((dpi.dpi_offs = calloc(dpi.dpi_noffs, sizeof (uint32_t))) == NULL) { free(dpi.dpi_probes); free(dpi.dpi_args); return (dt_set_errno(dtp, EDT_NOMEM)); } if ((dpi.dpi_strtab = malloc(dpi.dpi_strlen)) == NULL) { free(dpi.dpi_probes); free(dpi.dpi_args); free(dpi.dpi_offs); return (dt_set_errno(dtp, EDT_NOMEM)); } if ((dpi.dpi_rel = calloc(dpi.dpi_nprobes, sizeof (dof_relodesc_t))) == NULL) { free(dpi.dpi_probes); free(dpi.dpi_args); free(dpi.dpi_offs); free(dpi.dpi_strtab); return (dt_set_errno(dtp, EDT_NOMEM)); } dpi.dpi_nprobes = 0; dpi.dpi_nargs = 0; dpi.dpi_noffs = 0; dpi.dpi_strtab[0] = '\0'; dpi.dpi_strlen = 1; dofpv.dofpv_name = dpi.dpi_strlen; (void) strcpy(dpi.dpi_strtab + dpi.dpi_strlen, pvp->pv_desc.dtvd_name); dpi.dpi_strlen += strlen(pvp->pv_desc.dtvd_name) + 1; (void) dt_idhash_iter(pvp->pv_probes, dof_probe_save, &dpi); dofpv.dofpv_strtab = dof_add_lsect(ddo, dpi.dpi_strtab, DOF_SECT_STRTAB, sizeof (char), DOF_SECF_LOAD, 0, dpi.dpi_strlen); dofpv.dofpv_probes = dof_add_lsect(ddo, dpi.dpi_probes, DOF_SECT_PROBES, sizeof (uint64_t), DOF_SECF_LOAD, sizeof (dof_probe_t), sizeof (dof_probe_t) * dpi.dpi_nprobes); dofpv.dofpv_prargs = dof_add_lsect(ddo, dpi.dpi_args, DOF_SECT_PRARGS, sizeof (uint_t), DOF_SECF_LOAD, sizeof (uint8_t), sizeof (uint8_t) * dpi.dpi_nargs); dofpv.dofpv_proffs = dof_add_lsect(ddo, dpi.dpi_offs, DOF_SECT_PROFFS, sizeof (uint_t), DOF_SECF_LOAD, sizeof (uint32_t), sizeof (uint32_t) * dpi.dpi_noffs); (void) dof_add_lsect(ddo, &dofpv, DOF_SECT_PROVIDER, sizeof (uint_t), DOF_SECF_LOAD, 0, sizeof (dof_provider_t)); dofr.dofr_strtab = dofpv.dofpv_strtab; dofr.dofr_relsec = dof_add_lsect(ddo, dpi.dpi_rel, DOF_SECT_RELTAB, sizeof (uint64_t), DOF_SECF_LOAD, sizeof (dof_relodesc_t), sizeof (dof_relodesc_t) * dpi.dpi_nprobes); dofr.dofr_tgtsec = dofpv.dofpv_probes; (void) dof_add_lsect(ddo, &dofr, DOF_SECT_URELHDR, sizeof (dof_secidx_t), DOF_SECF_LOAD, 0, sizeof (dof_relohdr_t)); free(dpi.dpi_probes); free(dpi.dpi_args); free(dpi.dpi_offs); free(dpi.dpi_strtab); free(dpi.dpi_rel); return (0);}static intdtrace_dof_hdr(dtrace_hdl_t *dtp, dof_hdr_t *hp){ /* * If our config values cannot fit in a uint8_t, we can't generate a * DOF header since the values won't fit. This can only happen if the * user forcibly compiles a program with an artificial configuration. */ if (dtp->dt_conf.dtc_difversion > UINT8_MAX || dtp->dt_conf.dtc_difintregs > UINT8_MAX || dtp->dt_conf.dtc_diftupregs > UINT8_MAX) { return (dt_set_errno(dtp, EOVERFLOW)); } bzero(hp, sizeof (dof_hdr_t)); hp->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0; hp->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1; hp->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2; hp->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3; if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) hp->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_LP64; else hp->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_ILP32; hp->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE; hp->dofh_ident[DOF_ID_VERSION] = DOF_VERSION_1; hp->dofh_ident[DOF_ID_DIFVERS] = dtp->dt_conf.dtc_difversion; hp->dofh_ident[DOF_ID_DIFIREG] = dtp->dt_conf.dtc_difintregs; hp->dofh_ident[DOF_ID_DIFTREG] = dtp->dt_conf.dtc_diftupregs; hp->dofh_flags = 0; hp->dofh_hdrsize = sizeof (dof_hdr_t); hp->dofh_secsize = sizeof (dof_sec_t); hp->dofh_secoff = sizeof (dof_hdr_t); hp->dofh_pad = 0; return (0);}void *dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags){ const dtrace_ecbdesc_t *edp, *last; const dtrace_probedesc_t *pdp; const dtrace_actdesc_t *ap; const dt_stmt_t *stp, *next; dof_secidx_t strsec; char *strtab, *strp; size_t stroff; dof_hdr_t *hp; dof_sec_t *secbase; dt_dof_t ddo; dof_stridx_t strndx; dof_secidx_t *actsecs; uint_t maxacts = 0; if (flags & ~DTRACE_D_MASK) { (void) dt_set_errno(dtp, EINVAL); return (NULL); } bzero(&ddo, sizeof (dt_dof_t)); ddo.ddo_lsize = sizeof (dof_hdr_t); /* * First, iterate through the statements and compute the total size of * the DOF file we will need to create. We use the statements to find * the unique set of ECB descriptions associated with the program, * each of which results in a set of sections in the DOF file. To that * we must add a file header, section header table, and string table. */ stp = dt_list_next(&pgp->dp_stmts); last = NULL; for (; stp != NULL; stp = dt_list_next(stp)) { uint_t nacts = 0; dtrace_stmtdesc_t *sdp = stp->ds_desc; dtrace_actdesc_t *ap = sdp->dtsd_action; /* * If the action associated with this statement has format * data, we must allocate space for it in the string table. */ if (ap != NULL && sdp->dtsd_fmtdata != NULL) { ddo.ddo_strs += dtrace_printf_format(dtp, sdp->dtsd_fmtdata, NULL, 0) + 1; } if ((edp = sdp->dtsd_ecbdesc) == last) continue; /* same ecb as previous statement */ pdp = &edp->dted_probe; last = edp; ddo.ddo_lsize = roundup(ddo.ddo_lsize, sizeof (dof_secidx_t)) + sizeof (dof_probedesc_t); ddo.ddo_secs++; /* DOF_SECT_PROBEDESC */ if (pdp->dtpd_provider[0] != '\0') ddo.ddo_strs += strlen(pdp->dtpd_provider) + 1; if (pdp->dtpd_mod[0] != '\0') ddo.ddo_strs += strlen(pdp->dtpd_mod) + 1; if (pdp->dtpd_func[0] != '\0') ddo.ddo_strs += strlen(pdp->dtpd_func) + 1; if (pdp->dtpd_name[0] != '\0') ddo.ddo_strs += strlen(pdp->dtpd_name) + 1; if (edp->dted_pred.dtpdd_difo != NULL) dof_difo_size(&ddo, edp->dted_pred.dtpdd_difo); for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) { if (ap->dtad_difo != NULL) dof_difo_size(&ddo, ap->dtad_difo); nacts++; } maxacts = MAX(maxacts, nacts); /* track biggest ecbdesc */ if (nacts != 0) { ddo.ddo_lsize = roundup(ddo.ddo_lsize, sizeof (uint64_t)) + sizeof (dof_actdesc_t) * nacts; ddo.ddo_secs++; /* DOF_SECT_ACTDESC */ } ddo.ddo_lsize = roundup(ddo.ddo_lsize, sizeof (uint64_t)) + sizeof (dof_ecbdesc_t); ddo.ddo_secs++; /* DOF_SECT_ECBDESC */ } if (flags & DTRACE_D_PROBES) { uint_t h; dt_provider_t *pvp; for (h = 0; h < dtp->dt_provbuckets; h++) { for (pvp = dtp->dt_provs[h]; pvp != NULL; pvp = pvp->pv_next) { dof_provider_size(&ddo, pvp); } } } ddo.ddo_lsize += ddo.ddo_strs + 1; ddo.ddo_secs++; /* DOF_SECT_STRTAB */ /* * Now that we've added up all the sections, add in the size of the * section header table. We know that the dof_hdr_t is aligned so that * that dof_sec_t's can follow it, and that dof_sec_t is aligned so * that the first section (PROBEDESC) can follow it. As a result, * no extra padding bytes are required between either of these things. */ ddo.ddo_lsize += sizeof (dof_sec_t) * ddo.ddo_secs; stroff = ddo.ddo_lsize - (ddo.ddo_strs + 1); /* * If our DOF file has unloadable data (ddo_usize), then round up * the loadable size to a 64-byte boundary and include it in the * final file size. Otherwise the file size is the loadable size. */ if (ddo.ddo_usize != 0) ddo.ddo_fsize = roundup(ddo.ddo_lsize, 64) + ddo.ddo_usize; else ddo.ddo_fsize = ddo.ddo_lsize; /* * Allocate a buffer for the entire DOF file, bzero it so padding does * not "leak" uninitialized memory values, and then fill in the header. */ if ((ddo.ddo_buf = malloc(ddo.ddo_fsize)) == NULL) { (void) dt_set_errno(dtp, EDT_NOMEM); return (NULL); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?