⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dt_parser.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 5 页
字号:
	dnp->dn_kind = (uchar_t)kind;	dnp->dn_flags = 0;	dnp->dn_op = 0;	dnp->dn_line = yylineno;	dnp->dn_reg = -1;	dnp->dn_attr = _dtrace_defattr;	dnp->dn_list = NULL;	dnp->dn_link = yypcb->pcb_list;	yypcb->pcb_list = dnp;	bzero(&dnp->dn_u, sizeof (dnp->dn_u));	return (dnp);}voiddt_node_free(dt_node_t *dnp){	uchar_t kind = dnp->dn_kind;	dnp->dn_kind = DT_NODE_FREE;	switch (kind) {	case DT_NODE_STRING:	case DT_NODE_IDENT:	case DT_NODE_TYPE:		free(dnp->dn_string);		dnp->dn_string = NULL;		break;	case DT_NODE_VAR:	case DT_NODE_FUNC:		dt_node_list_free(&dnp->dn_args);		break;	case DT_NODE_OP1:		if (dnp->dn_child != NULL) {			dt_node_free(dnp->dn_child);			dnp->dn_child = NULL;		}		break;	case DT_NODE_OP3:		if (dnp->dn_expr != NULL) {			dt_node_free(dnp->dn_expr);			dnp->dn_expr = NULL;		}		/*FALLTHRU*/	case DT_NODE_OP2:		if (dnp->dn_left != NULL) {			dt_node_free(dnp->dn_left);			dnp->dn_left = NULL;		}		if (dnp->dn_right != NULL) {			dt_node_free(dnp->dn_right);			dnp->dn_right = NULL;		}		break;	case DT_NODE_DEXPR:	case DT_NODE_DFUNC:		if (dnp->dn_expr != NULL) {			dt_node_free(dnp->dn_expr);			dnp->dn_expr = NULL;		}		break;	case DT_NODE_AGG:		if (dnp->dn_aggfun != NULL) {			dt_node_free(dnp->dn_aggfun);			dnp->dn_aggfun = NULL;		}		dt_node_list_free(&dnp->dn_aggtup);		break;	case DT_NODE_PDESC:		free(dnp->dn_spec);		dnp->dn_spec = NULL;		free(dnp->dn_desc);		dnp->dn_desc = NULL;		break;	case DT_NODE_CLAUSE:		if (dnp->dn_pred != NULL)			dt_node_free(dnp->dn_pred);		if (dnp->dn_locals != NULL)			dt_idhash_destroy(dnp->dn_locals);		dt_node_list_free(&dnp->dn_pdescs);		dt_node_list_free(&dnp->dn_acts);		break;	case DT_NODE_MEMBER:		free(dnp->dn_membname);		dnp->dn_membname = NULL;		if (dnp->dn_membexpr != NULL) {			dt_node_free(dnp->dn_membexpr);			dnp->dn_membexpr = NULL;		}		break;	case DT_NODE_PROBE:		if (dnp->dn_ident != NULL) {			dt_ident_destroy(dnp->dn_ident);			dnp->dn_ident = NULL;		}		break;	case DT_NODE_PROVIDER:		dt_node_list_free(&dnp->dn_list);		free(dnp->dn_string);		dnp->dn_string = NULL;		break;	case DT_NODE_PROG:		dt_node_list_free(&dnp->dn_list);		break;	}}voiddt_node_attr_assign(dt_node_t *dnp, dtrace_attribute_t attr){	if ((yypcb->pcb_cflags & DTRACE_C_EATTR) &&	    (dt_attr_cmp(attr, yypcb->pcb_amin) < 0)) {		char a[DTRACE_ATTR2STR_MAX];		char s[BUFSIZ];		dnerror(dnp, D_ATTR_MIN, "attributes for %s (%s) are less than "		    "predefined minimum\n", dt_node_name(dnp, s, sizeof (s)),		    dtrace_attr2str(attr, a, sizeof (a)));	}	dnp->dn_attr = attr;}voiddt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type){	ctf_id_t base = ctf_type_resolve(fp, type);	uint_t kind = ctf_type_kind(fp, base);	ctf_encoding_t e;	dnp->dn_flags &=	    ~(DT_NF_SIGNED | DT_NF_REF | DT_NF_BITFIELD | DT_NF_USERLAND);	if (kind == CTF_K_INTEGER && ctf_type_encoding(fp, base, &e) == 0) {		size_t size = e.cte_bits / NBBY;		if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1)))			dnp->dn_flags |= DT_NF_BITFIELD;		if (e.cte_format & CTF_INT_SIGNED)			dnp->dn_flags |= DT_NF_SIGNED;	}	if (kind == CTF_K_FLOAT && ctf_type_encoding(fp, base, &e) == 0) {		if (e.cte_bits / NBBY > sizeof (uint64_t))			dnp->dn_flags |= DT_NF_REF;	}	if (kind == CTF_K_STRUCT || kind == CTF_K_UNION ||	    kind == CTF_K_FORWARD ||	    kind == CTF_K_ARRAY || kind == CTF_K_FUNCTION)		dnp->dn_flags |= DT_NF_REF;	else if (fp == DT_DYN_CTFP(yypcb->pcb_hdl) &&	    type == DT_DYN_TYPE(yypcb->pcb_hdl))		dnp->dn_flags |= DT_NF_REF;	dnp->dn_flags |= DT_NF_COOKED;	dnp->dn_ctfp = fp;	dnp->dn_type = type;}voiddt_node_type_propagate(const dt_node_t *src, dt_node_t *dst){	assert(src->dn_flags & DT_NF_COOKED);	dst->dn_flags = src->dn_flags & ~DT_NF_LVALUE;	dst->dn_ctfp = src->dn_ctfp;	dst->dn_type = src->dn_type;}const char *dt_node_type_name(const dt_node_t *dnp, char *buf, size_t len){	if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL) {		(void) snprintf(buf, len, "%s",		    dt_idkind_name(dnp->dn_ident->di_kind));		return (buf);	}	if (dnp->dn_flags & DT_NF_USERLAND) {		size_t n = snprintf(buf, len, "userland ");		len = len > n ? len - n : 0;		(void) dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf + n, len);		return (buf);	}	return (dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf, len));}size_tdt_node_type_size(const dt_node_t *dnp){	if (dnp->dn_kind == DT_NODE_STRING)		return (strlen(dnp->dn_string) + 1);	if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL)		return (dt_ident_size(dnp->dn_ident));	return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type));}size_tdt_node_sizeof(const dt_node_t *dnp){	dtrace_syminfo_t *sip;	GElf_Sym sym;	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	/*	 * The size of the node as used for the sizeof() operator depends on	 * the kind of the node.  If the node is a SYM, the size is obtained	 * from the symbol table; if it is not a SYM, the size is determined	 * from the node's type.  This is slightly different from C's sizeof()	 * operator in that (for example) when applied to a function, sizeof()	 * will evaluate to the length of the function rather than the size of	 * the function type.	 */	if (dnp->dn_kind != DT_NODE_SYM)		return (dt_node_type_size(dnp));	sip = dnp->dn_ident->di_data;	if (dtrace_lookup_by_name(dtp, sip->dts_object,	    sip->dts_name, &sym, NULL) == -1)		return (0);	return (sym.st_size);}intdt_node_is_integer(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	ctf_encoding_t e;	ctf_id_t type;	uint_t kind;	assert(dnp->dn_flags & DT_NF_COOKED);	type = ctf_type_resolve(fp, dnp->dn_type);	kind = ctf_type_kind(fp, type);	if (kind == CTF_K_INTEGER &&	    ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e))		return (0); /* void integer */	return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM);}intdt_node_is_float(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	ctf_encoding_t e;	ctf_id_t type;	uint_t kind;	assert(dnp->dn_flags & DT_NF_COOKED);	type = ctf_type_resolve(fp, dnp->dn_type);	kind = ctf_type_kind(fp, type);	return (kind == CTF_K_FLOAT &&	    ctf_type_encoding(dnp->dn_ctfp, type, &e) == 0 && (	    e.cte_format == CTF_FP_SINGLE || e.cte_format == CTF_FP_DOUBLE ||	    e.cte_format == CTF_FP_LDOUBLE));}intdt_node_is_scalar(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	ctf_encoding_t e;	ctf_id_t type;	uint_t kind;	assert(dnp->dn_flags & DT_NF_COOKED);	type = ctf_type_resolve(fp, dnp->dn_type);	kind = ctf_type_kind(fp, type);	if (kind == CTF_K_INTEGER &&	    ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e))		return (0); /* void cannot be used as a scalar */	return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM ||	    kind == CTF_K_POINTER);}intdt_node_is_arith(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	ctf_encoding_t e;	ctf_id_t type;	uint_t kind;	assert(dnp->dn_flags & DT_NF_COOKED);	type = ctf_type_resolve(fp, dnp->dn_type);	kind = ctf_type_kind(fp, type);	if (kind == CTF_K_INTEGER)		return (ctf_type_encoding(fp, type, &e) == 0 && !IS_VOID(e));	else		return (kind == CTF_K_ENUM);}intdt_node_is_vfptr(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	ctf_encoding_t e;	ctf_id_t type;	uint_t kind;	assert(dnp->dn_flags & DT_NF_COOKED);	type = ctf_type_resolve(fp, dnp->dn_type);	if (ctf_type_kind(fp, type) != CTF_K_POINTER)		return (0); /* type is not a pointer */	type = ctf_type_resolve(fp, ctf_type_reference(fp, type));	kind = ctf_type_kind(fp, type);	return (kind == CTF_K_FUNCTION || (kind == CTF_K_INTEGER &&	    ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)));}intdt_node_is_dynamic(const dt_node_t *dnp){	return (dnp->dn_ctfp == DT_DYN_CTFP(yypcb->pcb_hdl) &&	    dnp->dn_type == DT_DYN_TYPE(yypcb->pcb_hdl));}intdt_node_is_string(const dt_node_t *dnp){	return (dnp->dn_ctfp == DT_STR_CTFP(yypcb->pcb_hdl) &&	    dnp->dn_type == DT_STR_TYPE(yypcb->pcb_hdl));}intdt_node_is_stack(const dt_node_t *dnp){	return (dnp->dn_ctfp == DT_STACK_CTFP(yypcb->pcb_hdl) &&	    dnp->dn_type == DT_STACK_TYPE(yypcb->pcb_hdl));}intdt_node_is_strcompat(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	ctf_encoding_t e;	ctf_arinfo_t r;	ctf_id_t base;	uint_t kind;	assert(dnp->dn_flags & DT_NF_COOKED);	base = ctf_type_resolve(fp, dnp->dn_type);	kind = ctf_type_kind(fp, base);	if (kind == CTF_K_POINTER &&	    (base = ctf_type_reference(fp, base)) != CTF_ERR &&	    (base = ctf_type_resolve(fp, base)) != CTF_ERR &&	    ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e))		return (1); /* promote char pointer to string */	if (kind == CTF_K_ARRAY && ctf_array_info(fp, base, &r) == 0 &&	    (base = ctf_type_resolve(fp, r.ctr_contents)) != CTF_ERR &&	    ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e))		return (1); /* promote char array to string */	return (0);}intdt_node_is_pointer(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	uint_t kind;	assert(dnp->dn_flags & DT_NF_COOKED);	if (dt_node_is_string(dnp))		return (0); /* string are pass-by-ref but act like structs */	kind = ctf_type_kind(fp, ctf_type_resolve(fp, dnp->dn_type));	return (kind == CTF_K_POINTER || kind == CTF_K_ARRAY);}intdt_node_is_void(const dt_node_t *dnp){	ctf_file_t *fp = dnp->dn_ctfp;	ctf_encoding_t e;	ctf_id_t type;	if (dt_node_is_dynamic(dnp))		return (0); /* <DYN> is an alias for void but not the same */	if (dt_node_is_stack(dnp))		return (0);	type = ctf_type_resolve(fp, dnp->dn_type);	return (ctf_type_kind(fp, type) == CTF_K_INTEGER &&	    ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e));}intdt_node_is_ptrcompat(const dt_node_t *lp, const dt_node_t *rp,    ctf_file_t **fpp, ctf_id_t *tp){	ctf_file_t *lfp = lp->dn_ctfp;	ctf_file_t *rfp = rp->dn_ctfp;	ctf_id_t lbase = CTF_ERR, rbase = CTF_ERR;	ctf_id_t lref = CTF_ERR, rref = CTF_ERR;	int lp_is_void, rp_is_void, lp_is_int, rp_is_int, compat;	uint_t lkind, rkind;	ctf_encoding_t e;	ctf_arinfo_t r;	assert(lp->dn_flags & DT_NF_COOKED);	assert(rp->dn_flags & DT_NF_COOKED);	if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp))		return (0); /* fail if either node is a dynamic variable */	lp_is_int = dt_node_is_integer(lp);	rp_is_int = dt_node_is_integer(rp);	if (lp_is_int && rp_is_int)		return (0); /* fail if both nodes are integers */	if (lp_is_int && (lp->dn_kind != DT_NODE_INT || lp->dn_value != 0))		return (0); /* fail if lp is an integer that isn't 0 constant */	if (rp_is_int && (rp->dn_kind != DT_NODE_INT || rp->dn_value != 0))		return (0); /* fail if rp is an integer that isn't 0 constant */	if ((lp_is_int == 0 && rp_is_int == 0) && (	    (lp->dn_flags & DT_NF_USERLAND) ^ (rp->dn_flags & DT_NF_USERLAND)))		return (0); /* fail if only one pointer is a userland address */	/*	 * Resolve the left-hand and right-hand types to their base type, and	 * then resolve the referenced type as well (assuming the base type	 * is CTF_K_POINTER or CTF_K_ARRAY).  Otherwise [lr]ref = CTF_ERR.	 */	if (!lp_is_int) {		lbase = ctf_type_resolve(lfp, lp->dn_type);		lkind = ctf_type_kind(lfp, lbase);		if (lkind == CTF_K_POINTER) {			lref = ctf_type_resolve(lfp,			    ctf_type_reference(lfp, lbase));		} else if (lkind == CTF_K_ARRAY &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -