dt_cc.c
来自「Sun Solaris 10 中的 DTrace 组件的源代码。请参看: htt」· C语言 代码 · 共 2,025 行 · 第 1/4 页
C
2,025 行
break; case DT_NODE_AGG: format = NULL; anp = dnp->dn_args; argr = 1; break; default: format = NULL; anp = dnp->dn_args; argr = 1; } if (argc != argr) { dnerror(dnp, D_PRINTA_PROTO, "%s( ) prototype mismatch: %d args passed, %d expected\n", dnp->dn_ident->di_name, argc, argr); } if (anp->dn_kind != DT_NODE_AGG) { dnerror(dnp, D_PRINTA_AGGARG, "%s( ) argument #%d is incompatible with prototype:\n" "\tprototype: aggregation\n\t argument: %s\n", dnp->dn_ident->di_name, argr, dt_node_type_name(anp, n, sizeof (n))); } aid = anp->dn_ident; fid = aid->di_iarg; if (aid->di_gen == dtp->dt_gen && !(aid->di_flags & DT_IDFLG_MOD)) { dnerror(dnp, D_PRINTA_AGGBAD, "undefined aggregation: @%s\n", aid->di_name); } if (format != NULL) { yylineno = dnp->dn_line; sdp->dtsd_fmtdata = dt_printf_create(yypcb->pcb_hdl, format); dt_printf_validate(sdp->dtsd_fmtdata, DT_PRINTF_AGGREGATION, dnp->dn_ident, 1, fid->di_id, ((dt_idsig_t *)aid->di_data)->dis_args); } ap = dt_stmt_action(dtp, sdp); dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_PRINTA);}static voiddt_action_printflike(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp, dtrace_actkind_t kind){ dt_node_t *anp, *arg1; dtrace_actdesc_t *ap = NULL; char n[DT_TYPE_NAMELEN]; assert(DTRACEACT_ISPRINTFLIKE(kind)); if (dnp->dn_args->dn_kind != DT_NODE_STRING) { dnerror(dnp, D_PRINTF_ARG_FMT, "%s( ) argument #1 is incompatible with prototype:\n" "\tprototype: string constant\n\t argument: %s\n", dnp->dn_ident->di_name, dt_node_type_name(dnp->dn_args, n, sizeof (n))); } arg1 = dnp->dn_args->dn_list; yylineno = dnp->dn_line; sdp->dtsd_fmtdata = dt_printf_create(yypcb->pcb_hdl, dnp->dn_args->dn_string); dt_printf_validate(sdp->dtsd_fmtdata, DT_PRINTF_EXACTLEN, dnp->dn_ident, 1, DTRACEACT_AGGREGATION, arg1); if (arg1 == NULL) { dif_instr_t *dbuf; dtrace_difo_t *dp; if ((dbuf = malloc(sizeof (dif_instr_t))) == NULL || (dp = malloc(sizeof (dtrace_difo_t))) == NULL) { free(dbuf); longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); } dbuf[0] = DIF_INSTR_RET(DIF_REG_R0); /* ret %r0 */ bzero(dp, sizeof (dtrace_difo_t)); dp->dtdo_buf = dbuf; dp->dtdo_len = 1; dp->dtdo_rtype = dt_int_rtype; dp->dtdo_refcnt = 1; ap = dt_stmt_action(dtp, sdp); ap->dtad_difo = dp; ap->dtad_kind = kind; return; } for (anp = arg1; anp != NULL; anp = anp->dn_list) { ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, anp); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = kind; }}static voiddt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); if (dt_node_is_void(dnp->dn_args)) { dnerror(dnp->dn_args, D_TRACE_VOID, "trace( ) may not be applied to a void expression\n"); } if (dt_node_is_dynamic(dnp->dn_args)) { dnerror(dnp->dn_args, D_TRACE_DYN, "trace( ) may not be applied to a dynamic expression\n"); } dt_cg(yypcb, dnp->dn_args); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_DIFEXPR;}static voiddt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_node_t *addr = dnp->dn_args; dt_node_t *size = dnp->dn_args->dn_list; char n[DT_TYPE_NAMELEN]; if (dt_node_is_integer(addr) == 0 && dt_node_is_pointer(addr) == 0) { dnerror(addr, D_TRACEMEM_ADDR, "tracemem( ) argument #1 is incompatible with " "prototype:\n\tprototype: pointer or integer\n" "\t argument: %s\n", dt_node_type_name(addr, n, sizeof (n))); } if (dt_node_is_posconst(size) == 0) { dnerror(size, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must " "be a non-zero positive integral constant expression\n"); } dt_cg(yypcb, addr); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_DIFEXPR; ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF; ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value;}static voiddt_action_stack_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap, dt_node_t *arg0){ ap->dtad_kind = DTRACEACT_STACK; if (dtp->dt_options[DTRACEOPT_STACKFRAMES] != DTRACEOPT_UNSET) { ap->dtad_arg = dtp->dt_options[DTRACEOPT_STACKFRAMES]; } else { ap->dtad_arg = 0; } if (arg0 != NULL) { if (arg0->dn_list != NULL) { dnerror(arg0, D_STACK_PROTO, "stack( ) prototype " "mismatch: too many arguments\n"); } if (dt_node_is_posconst(arg0) == 0) { dnerror(arg0, D_STACK_SIZE, "stack( ) size must be a " "non-zero positive integral constant expression\n"); } ap->dtad_arg = arg0->dn_value; }}static voiddt_action_stack(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_action_stack_args(dtp, ap, dnp->dn_args);}static voiddt_action_ustack_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap, dt_node_t *dnp){ uint32_t nframes = 0; uint32_t strsize = 0; /* default string table size */ dt_node_t *arg0 = dnp->dn_args; dt_node_t *arg1 = arg0 != NULL ? arg0->dn_list : NULL; assert(dnp->dn_ident->di_id == DT_ACT_JSTACK || dnp->dn_ident->di_id == DT_ACT_USTACK); if (dnp->dn_ident->di_id == DT_ACT_JSTACK) { if (dtp->dt_options[DTRACEOPT_JSTACKFRAMES] != DTRACEOPT_UNSET) nframes = dtp->dt_options[DTRACEOPT_JSTACKFRAMES]; if (dtp->dt_options[DTRACEOPT_JSTACKSTRSIZE] != DTRACEOPT_UNSET) strsize = dtp->dt_options[DTRACEOPT_JSTACKSTRSIZE]; ap->dtad_kind = DTRACEACT_JSTACK; } else { assert(dnp->dn_ident->di_id == DT_ACT_USTACK); if (dtp->dt_options[DTRACEOPT_USTACKFRAMES] != DTRACEOPT_UNSET) nframes = dtp->dt_options[DTRACEOPT_USTACKFRAMES]; ap->dtad_kind = DTRACEACT_USTACK; } if (arg0 != NULL) { if (!dt_node_is_posconst(arg0)) { dnerror(arg0, D_USTACK_FRAMES, "ustack( ) argument #1 " "must be a non-zero positive integer constant\n"); } nframes = (uint32_t)arg0->dn_value; } if (arg1 != NULL) { if (arg1->dn_kind != DT_NODE_INT || ((arg1->dn_flags & DT_NF_SIGNED) && (int64_t)arg1->dn_value < 0)) { dnerror(arg1, D_USTACK_STRSIZE, "ustack( ) argument #2 " "must be a positive integer constant\n"); } if (arg1->dn_list != NULL) { dnerror(arg1, D_USTACK_PROTO, "ustack( ) prototype " "mismatch: too many arguments\n"); } strsize = (uint32_t)arg1->dn_value; } ap->dtad_arg = DTRACE_USTACK_ARG(nframes, strsize);}static voiddt_action_ustack(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_action_ustack_args(dtp, ap, dnp);}/*ARGSUSED*/static voiddt_action_ftruncate(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); /* * Library actions need a DIFO that serves as an argument. As * ftruncate() doesn't take an argument, we generate the constant 0 * in a DIFO; this constant will be ignored when the ftruncate() is * processed. */ dt_action_difconst(ap, 0, DTRACEACT_LIBACT); ap->dtad_arg = DT_ACT_FTRUNCATE;}/*ARGSUSED*/static voiddt_action_stop(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); ap->dtad_kind = DTRACEACT_STOP; ap->dtad_arg = 0;}/*ARGSUSED*/static voiddt_action_breakpoint(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); ap->dtad_kind = DTRACEACT_BREAKPOINT; ap->dtad_arg = 0;}/*ARGSUSED*/static voiddt_action_panic(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); ap->dtad_kind = DTRACEACT_PANIC; ap->dtad_arg = 0;}static voiddt_action_chill(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, dnp->dn_args); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_CHILL;}static voiddt_action_raise(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, dnp->dn_args); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_RAISE;}static voiddt_action_exit(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, dnp->dn_args); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_EXIT; ap->dtad_difo->dtdo_rtype.dtdt_size = sizeof (int);}static voiddt_action_speculate(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, dnp->dn_args); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_SPECULATE;}static voiddt_action_commit(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, dnp->dn_args); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_COMMIT;}static voiddt_action_discard(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, dnp->dn_args); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_DISCARD;}static voiddt_compile_fun(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ switch (dnp->dn_expr->dn_ident->di_id) { case DT_ACT_BREAKPOINT: dt_action_breakpoint(dtp, dnp->dn_expr, sdp); break; case DT_ACT_CHILL: dt_action_chill(dtp, dnp->dn_expr, sdp); break; case DT_ACT_CLEAR: dt_action_clear(dtp, dnp->dn_expr, sdp); break; case DT_ACT_COMMIT: dt_action_commit(dtp, dnp->dn_expr, sdp); break; case DT_ACT_DENORMALIZE: dt_action_normalize(dtp, dnp->dn_expr, sdp); break; case DT_ACT_DISCARD: dt_action_discard(dtp, dnp->dn_expr, sdp); break; case DT_ACT_EXIT: dt_action_exit(dtp, dnp->dn_expr, sdp); break; case DT_ACT_FTRUNCATE: dt_action_ftruncate(dtp, dnp->dn_expr, sdp); break; case DT_ACT_NORMALIZE: dt_action_normalize(dtp, dnp->dn_expr, sdp); break; case DT_ACT_PANIC: dt_action_panic(dtp, dnp->dn_expr, sdp); break; case DT_ACT_PRINTA: dt_action_printa(dtp, dnp->dn_expr, sdp); break; case DT_ACT_PRINTF: dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_PRINTF); break; case DT_ACT_RAISE: dt_action_raise(dtp, dnp->dn_expr, sdp); break; case DT_ACT_SPECULATE: dt_action_speculate(dtp, dnp->dn_expr, sdp); break; case DT_ACT_STACK: dt_action_stack(dtp, dnp->dn_expr, sdp); break; case DT_ACT_STOP: dt_action_stop(dtp, dnp->dn_expr, sdp); break; case DT_ACT_SYSTEM: dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_SYSTEM); break; case DT_ACT_TRACE: dt_action_trace(dtp, dnp->dn_expr, sdp); break; case DT_ACT_TRACEMEM: dt_action_tracemem(dtp, dnp->dn_expr, sdp); break; case DT_ACT_TRUNC: dt_action_trunc(dtp, dnp->dn_expr, sdp); break; case DT_ACT_USTACK: case DT_ACT_JSTACK: dt_action_ustack(dtp, dnp->dn_expr, sdp); break; default: dnerror(dnp->dn_expr, D_UNKNOWN, "tracing function %s( ) is " "not yet supported\n", dnp->dn_expr->dn_ident->di_name); }}static voiddt_compile_exp(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); dt_cg(yypcb, dnp->dn_expr); ap->dtad_difo = dt_as(yypcb); ap->dtad_difo->dtdo_rtype = dt_void_rtype; ap->dtad_kind = DTRACEACT_DIFEXPR;}static voiddt_compile_agg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp){ dt_ident_t *aid, *fid; dt_node_t *anp; dtrace_actdesc_t *ap; uint_t n = 1; /* * If the aggregation has no aggregating function applied to it, then * this statement has no effect. Flag this as a programming error. */ if (dnp->dn_aggfun == NULL) { dnerror(dnp, D_AGG_NULL, "expression has null effect: @%s\n", dnp->dn_ident->di_name); } aid = dnp->dn_ident; fid = dnp->dn_aggfun->dn_ident; if (dnp->dn_aggfun->dn_args != NULL && dt_node_is_scalar(dnp->dn_aggfun->dn_args) == 0) { dnerror(dnp->dn_aggfun, D_AGG_SCALAR, "%s( ) argument #1 must " "be of scalar type\n", fid->di_name); } /* * The ID of the aggregation itself is implicitly recorded as the first * member of each aggregation tuple so we can distinguish them later. */ ap = dt_stmt_action(dtp, sdp); dt_action_difconst(ap, aid->di_id, DTRACEACT_DIFEXPR); for (anp = dnp->dn_aggtup; anp != NULL; anp = anp->dn_list) { ap = dt_stmt_action(dtp, sdp); n++; if (anp->dn_kind == DT_NODE_FUNC) { if (anp->dn_ident->di_id == DT_ACT_STACK) { dt_action_stack_args(dtp, ap, anp->dn_args); continue; } if (anp->dn_ident->di_id == DT_ACT_USTACK || anp->dn_ident->di_id == DT_ACT_JSTACK) { dt_action_ustack_args(dtp, ap, anp); continue; } } dt_cg(yypcb, anp); ap->dtad_difo = dt_as(yypcb); ap->dtad_kind = DTRACEACT_DIFEXPR; } assert(sdp->dtsd_aggdata == NULL); sdp->dtsd_aggdata = aid; ap = dt_stmt_action(dtp, sdp); assert(fid->di_kind == DT_IDENT_AGGFUNC); assert(DTRACEACT_ISAGG(fid->di_id)); ap->dtad_kind = fid->di_id; ap->dtad_ntuple = n;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?