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 + -
显示快捷键?