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

📄 ctf_types.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 2 页
字号:
	case CTF_K_ENUM:		return (fp->ctf_dmodel->ctd_int);	default:		return (ctf_get_ctt_size(fp, tp, NULL, NULL));	}}/* * Return the kind (CTF_K_* constant) for the specified type ID. */intctf_type_kind(ctf_file_t *fp, ctf_id_t type){	const ctf_type_t *tp;	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (CTF_ERR); /* errno is set for us */	return (LCTF_INFO_KIND(fp, tp->ctt_info));}/* * If the type is one that directly references another type (such as POINTER), * then return the ID of the type to which it refers. */ctf_id_tctf_type_reference(ctf_file_t *fp, ctf_id_t type){	ctf_file_t *ofp = fp;	const ctf_type_t *tp;	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (CTF_ERR); /* errno is set for us */	switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {	case CTF_K_POINTER:	case CTF_K_TYPEDEF:	case CTF_K_VOLATILE:	case CTF_K_CONST:	case CTF_K_RESTRICT:		return (tp->ctt_type);	default:		return (ctf_set_errno(ofp, ECTF_NOTREF));	}}/* * Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a * pointer to the given type, see if we can compute a pointer to the type * resulting from resolving the type down to its base type and use that * instead.  This helps with cases where the CTF data includes "struct foo *" * but not "foo_t *" and the user accesses "foo_t *" in the debugger. */ctf_id_tctf_type_pointer(ctf_file_t *fp, ctf_id_t type){	ctf_file_t *ofp = fp;	ctf_id_t ntype;	if (ctf_lookup_by_id(&fp, type) == NULL)		return (CTF_ERR); /* errno is set for us */	if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)		return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));	if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)		return (ctf_set_errno(ofp, ECTF_NOTYPE));	if (ctf_lookup_by_id(&fp, type) == NULL)		return (ctf_set_errno(ofp, ECTF_NOTYPE));	if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)		return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));	return (ctf_set_errno(ofp, ECTF_NOTYPE));}/* * Return the encoding for the specified INTEGER or FLOAT. */intctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep){	ctf_file_t *ofp = fp;	const ctf_type_t *tp;	ssize_t increment;	uint_t data;	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (CTF_ERR); /* errno is set for us */	(void) ctf_get_ctt_size(fp, tp, NULL, &increment);	switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {	case CTF_K_INTEGER:		data = *(const uint_t *)((uintptr_t)tp + increment);		ep->cte_format = CTF_INT_ENCODING(data);		ep->cte_offset = CTF_INT_OFFSET(data);		ep->cte_bits = CTF_INT_BITS(data);		break;	case CTF_K_FLOAT:		data = *(const uint_t *)((uintptr_t)tp + increment);		ep->cte_format = CTF_FP_ENCODING(data);		ep->cte_offset = CTF_FP_OFFSET(data);		ep->cte_bits = CTF_FP_BITS(data);		break;	default:		return (ctf_set_errno(ofp, ECTF_NOTINTFP));	}	return (0);}intctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype){	int rval;	if (ltype < rtype)		rval = -1;	else if (ltype > rtype)		rval = 1;	else		rval = 0;	if (lfp == rfp)		return (rval);	if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL)		lfp = lfp->ctf_parent;	if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL)		rfp = rfp->ctf_parent;	if (lfp < rfp)		return (-1);	if (lfp > rfp)		return (1);	return (rval);}/* * Return a boolean value indicating if two types are compatible integers or * floating-pointer values.  This function returns true if the two types are * the same, or if they have the same ASCII name and encoding properties. * This function could be extended to test for compatibility for other kinds. */intctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,    ctf_file_t *rfp, ctf_id_t rtype){	const ctf_type_t *ltp, *rtp;	ctf_encoding_t le, re;	ctf_arinfo_t la, ra;	uint_t lkind, rkind;	if (ctf_type_cmp(lfp, ltype, rfp, rtype) == 0)		return (1);	ltype = ctf_type_resolve(lfp, ltype);	lkind = ctf_type_kind(lfp, ltype);	rtype = ctf_type_resolve(rfp, rtype);	rkind = ctf_type_kind(rfp, rtype);	if (lkind != rkind ||	    (ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL ||	    (rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL ||	    strcmp(ctf_strptr(lfp, ltp->ctt_name),	    ctf_strptr(rfp, rtp->ctt_name)) != 0)		return (0);	switch (lkind) {	case CTF_K_INTEGER:	case CTF_K_FLOAT:		return (ctf_type_encoding(lfp, ltype, &le) == 0 &&		    ctf_type_encoding(rfp, rtype, &re) == 0 &&		    bcmp(&le, &re, sizeof (ctf_encoding_t)) == 0);	case CTF_K_POINTER:		return (ctf_type_compat(lfp, ctf_type_reference(lfp, ltype),		    rfp, ctf_type_reference(rfp, rtype)));	case CTF_K_ARRAY:		return (ctf_array_info(lfp, ltype, &la) == 0 &&		    ctf_array_info(rfp, rtype, &ra) == 0 &&		    la.ctr_nelems == ra.ctr_nelems && ctf_type_compat(		    lfp, la.ctr_contents, rfp, ra.ctr_contents) &&		    ctf_type_compat(lfp, la.ctr_index, rfp, ra.ctr_index));	case CTF_K_STRUCT:	case CTF_K_UNION:		return (ctf_type_size(lfp, ltype) == ctf_type_size(rfp, rtype));	case CTF_K_ENUM:	case CTF_K_FORWARD:		return (1); /* no other checks required for these type kinds */	default:		return (0); /* should not get here since we did a resolve */	}}/* * Return the type and offset for a given member of a STRUCT or UNION. */intctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,    ctf_membinfo_t *mip){	ctf_file_t *ofp = fp;	const ctf_type_t *tp;	ssize_t size, increment;	uint_t kind, n;	if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)		return (CTF_ERR); /* errno is set for us */	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (CTF_ERR); /* errno is set for us */	(void) ctf_get_ctt_size(fp, tp, &size, &increment);	kind = LCTF_INFO_KIND(fp, tp->ctt_info);	if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)		return (ctf_set_errno(ofp, ECTF_NOTSOU));	if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {		const ctf_member_t *mp = (const ctf_member_t *)		    ((uintptr_t)tp + increment);		for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {			if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {				mip->ctm_type = mp->ctm_type;				mip->ctm_offset = mp->ctm_offset;				return (0);			}		}	} else {		const ctf_lmember_t *lmp = (const ctf_lmember_t *)		    ((uintptr_t)tp + increment);		for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {			if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {				mip->ctm_type = lmp->ctlm_type;				mip->ctm_offset = (ulong_t)CTF_LMEM_OFFSET(lmp);				return (0);			}		}	}	return (ctf_set_errno(ofp, ECTF_NOMEMBNAM));}/* * Return the array type, index, and size information for the specified ARRAY. */intctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp){	ctf_file_t *ofp = fp;	const ctf_type_t *tp;	const ctf_array_t *ap;	ssize_t increment;	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (CTF_ERR); /* errno is set for us */	if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY)		return (ctf_set_errno(ofp, ECTF_NOTARRAY));	(void) ctf_get_ctt_size(fp, tp, NULL, &increment);	ap = (const ctf_array_t *)((uintptr_t)tp + increment);	arp->ctr_contents = ap->cta_contents;	arp->ctr_index = ap->cta_index;	arp->ctr_nelems = ap->cta_nelems;	return (0);}/* * Convert the specified value to the corresponding enum member name, if a * matching name can be found.  Otherwise NULL is returned. */const char *ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value){	ctf_file_t *ofp = fp;	const ctf_type_t *tp;	const ctf_enum_t *ep;	ssize_t increment;	uint_t n;	if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)		return (NULL); /* errno is set for us */	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (NULL); /* errno is set for us */	if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {		(void) ctf_set_errno(ofp, ECTF_NOTENUM);		return (NULL);	}	(void) ctf_get_ctt_size(fp, tp, NULL, &increment);	ep = (const ctf_enum_t *)((uintptr_t)tp + increment);	for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {		if (ep->cte_value == value)			return (ctf_strptr(fp, ep->cte_name));	}	(void) ctf_set_errno(ofp, ECTF_NOENUMNAM);	return (NULL);}/* * Convert the specified enum tag name to the corresponding value, if a * matching name can be found.  Otherwise CTF_ERR is returned. */intctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp){	ctf_file_t *ofp = fp;	const ctf_type_t *tp;	const ctf_enum_t *ep;	ssize_t size, increment;	uint_t n;	if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)		return (NULL); /* errno is set for us */	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (NULL); /* errno is set for us */	if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {		(void) ctf_set_errno(ofp, ECTF_NOTENUM);		return (NULL);	}	(void) ctf_get_ctt_size(fp, tp, &size, &increment);	ep = (const ctf_enum_t *)((uintptr_t)tp + increment);	for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {		if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) {			if (valp != NULL)				*valp = ep->cte_value;			return (0);		}	}	(void) ctf_set_errno(ofp, ECTF_NOENUMNAM);	return (CTF_ERR);}/* * Recursively visit the members of any type.  This function is used as the * engine for ctf_type_visit, below.  We resolve the input type, recursively * invoke ourself for each type member if the type is a struct or union, and * then invoke the callback function on the current type.  If any callback * returns non-zero, we abort and percolate the error code back up to the top. */static intctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,    const char *name, ulong_t offset, int depth){	ctf_id_t otype = type;	const ctf_type_t *tp;	ssize_t size, increment;	uint_t kind, n;	int rc;	if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)		return (CTF_ERR); /* errno is set for us */	if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)		return (CTF_ERR); /* errno is set for us */	if ((rc = func(name, otype, offset, depth, arg)) != 0)		return (rc);	kind = LCTF_INFO_KIND(fp, tp->ctt_info);	if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)		return (0);	(void) ctf_get_ctt_size(fp, tp, &size, &increment);	if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {		const ctf_member_t *mp = (const ctf_member_t *)		    ((uintptr_t)tp + increment);		for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {			if ((rc = ctf_type_rvisit(fp, mp->ctm_type,			    func, arg, ctf_strptr(fp, mp->ctm_name),			    offset + mp->ctm_offset, depth + 1)) != 0)				return (rc);		}	} else {		const ctf_lmember_t *lmp = (const ctf_lmember_t *)		    ((uintptr_t)tp + increment);		for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {			if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type,			    func, arg, ctf_strptr(fp, lmp->ctlm_name),			    offset + (ulong_t)CTF_LMEM_OFFSET(lmp),			    depth + 1)) != 0)				return (rc);		}	}	return (0);}/* * Recursively visit the members of any type.  We pass the name, member * type, and offset of each member to the specified callback function. */intctf_type_visit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg){	return (ctf_type_rvisit(fp, type, func, arg, "", 0, 0));}

⌨️ 快捷键说明

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