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

📄 ctf_open.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	ctf_dprintf("%lu total types processed\n", fp->ctf_typemax);	ctf_dprintf("%u enum names hashed\n", ctf_hash_size(&fp->ctf_enums));	ctf_dprintf("%u struct names hashed (%d long)\n",	    ctf_hash_size(&fp->ctf_structs), nlstructs);	ctf_dprintf("%u union names hashed (%d long)\n",	    ctf_hash_size(&fp->ctf_unions), nlunions);	ctf_dprintf("%u base type names hashed\n",	    ctf_hash_size(&fp->ctf_names));	/*	 * Make an additional pass through the pointer table to find pointers	 * that point to anonymous typedef nodes.  If we find one, modify the	 * pointer table so that the pointer is also known to point to the	 * node that is referenced by the anonymous typedef node.	 */	for (id = 1; id <= fp->ctf_typemax; id++) {		if ((dst = fp->ctf_ptrtab[id]) != 0) {			tp = LCTF_INDEX_TO_TYPEPTR(fp, id);			if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_TYPEDEF &&			    strcmp(ctf_strptr(fp, tp->ctt_name), "") == 0 &&			    CTF_TYPE_ISCHILD(tp->ctt_type) == child &&			    CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax)				fp->ctf_ptrtab[				    CTF_TYPE_TO_INDEX(tp->ctt_type)] = dst;		}	}	return (0);}/* * Decode the specified CTF buffer and optional symbol table and create a new * CTF container representing the symbolic debugging information.  This code * can be used directly by the debugger, or it can be used as the engine for * ctf_fdopen() or ctf_open(), below. */ctf_file_t *ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,    const ctf_sect_t *strsect, int *errp){	const ctf_preamble_t *pp;	ctf_header_t hp;	ctf_file_t *fp;	void *buf, *base;	size_t size, hdrsz;	int err;	if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL)))		return (ctf_set_open_errno(errp, EINVAL));	if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&	    symsect->cts_entsize != sizeof (Elf64_Sym))		return (ctf_set_open_errno(errp, ECTF_SYMTAB));	if (symsect != NULL && symsect->cts_data == NULL)		return (ctf_set_open_errno(errp, ECTF_SYMBAD));	if (strsect != NULL && strsect->cts_data == NULL)		return (ctf_set_open_errno(errp, ECTF_STRBAD));	if (ctfsect->cts_size < sizeof (ctf_preamble_t))		return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));	pp = (const ctf_preamble_t *)ctfsect->cts_data;	ctf_dprintf("ctf_bufopen: magic=0x%x version=%u\n",	    pp->ctp_magic, pp->ctp_version);	/*	 * Validate each part of the CTF header (either V1 or V2).	 * First, we validate the preamble (common to all versions).  At that	 * point, we know specific header version, and can validate the	 * version-specific parts including section offsets and alignments.	 */	if (pp->ctp_magic != CTF_MAGIC)		return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));	if (pp->ctp_version == CTF_VERSION_2) {		if (ctfsect->cts_size < sizeof (ctf_header_t))			return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));		bcopy(ctfsect->cts_data, &hp, sizeof (hp));		hdrsz = sizeof (ctf_header_t);	} else if (pp->ctp_version == CTF_VERSION_1) {		const ctf_header_v1_t *h1p =		    (const ctf_header_v1_t *)ctfsect->cts_data;		if (ctfsect->cts_size < sizeof (ctf_header_v1_t))			return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));		bzero(&hp, sizeof (hp));		hp.cth_preamble = h1p->cth_preamble;		hp.cth_objtoff = h1p->cth_objtoff;		hp.cth_funcoff = h1p->cth_funcoff;		hp.cth_typeoff = h1p->cth_typeoff;		hp.cth_stroff = h1p->cth_stroff;		hp.cth_strlen = h1p->cth_strlen;		hdrsz = sizeof (ctf_header_v1_t);	} else		return (ctf_set_open_errno(errp, ECTF_CTFVERS));	size = hp.cth_stroff + hp.cth_strlen;	ctf_dprintf("ctf_bufopen: uncompressed size=%lu\n", (ulong_t)size);	if (hp.cth_lbloff > size || hp.cth_objtoff > size ||	    hp.cth_funcoff > size || hp.cth_typeoff > size ||	    hp.cth_stroff > size)		return (ctf_set_open_errno(errp, ECTF_CORRUPT));	if (hp.cth_lbloff > hp.cth_objtoff ||	    hp.cth_objtoff > hp.cth_funcoff ||	    hp.cth_funcoff > hp.cth_typeoff ||	    hp.cth_typeoff > hp.cth_stroff)		return (ctf_set_open_errno(errp, ECTF_CORRUPT));	if ((hp.cth_lbloff & 3) || (hp.cth_objtoff & 1) ||	    (hp.cth_funcoff & 1) || (hp.cth_typeoff & 3))		return (ctf_set_open_errno(errp, ECTF_CORRUPT));	/*	 * Once everything is determined to be valid, attempt to decompress	 * the CTF data buffer if it is compressed.  Otherwise we just put	 * the data section's buffer pointer into ctf_buf, below.	 */	if (hp.cth_flags & CTF_F_COMPRESS) {		size_t srclen, dstlen;		const void *src;		int rc = Z_OK;		if (ctf_zopen(errp) == NULL)			return (NULL); /* errp is set for us */		if ((base = ctf_data_alloc(size + hdrsz)) == MAP_FAILED)			return (ctf_set_open_errno(errp, ECTF_ZALLOC));		bcopy(ctfsect->cts_data, base, hdrsz);		((ctf_preamble_t *)base)->ctp_flags &= ~CTF_F_COMPRESS;		buf = (uchar_t *)base + hdrsz;		src = (uchar_t *)ctfsect->cts_data + hdrsz;		srclen = ctfsect->cts_size - hdrsz;		dstlen = size;		if ((rc = z_uncompress(buf, &dstlen, src, srclen)) != Z_OK) {			ctf_dprintf("zlib inflate err: %s\n", z_strerror(rc));			ctf_data_free(base, size + hdrsz);			return (ctf_set_open_errno(errp, ECTF_DECOMPRESS));		}		if (dstlen != size) {			ctf_dprintf("zlib inflate short -- got %lu of %lu "			    "bytes\n", (ulong_t)dstlen, (ulong_t)size);			ctf_data_free(base, size + hdrsz);			return (ctf_set_open_errno(errp, ECTF_CORRUPT));		}		ctf_data_protect(base, size + hdrsz);	} else {		base = (void *)ctfsect->cts_data;		buf = (uchar_t *)base + hdrsz;	}	/*	 * Once we have uncompressed and validated the CTF data buffer, we can	 * proceed with allocating a ctf_file_t and initializing it.	 */	if ((fp = ctf_alloc(sizeof (ctf_file_t))) == NULL)		return (ctf_set_open_errno(errp, EAGAIN));	bzero(fp, sizeof (ctf_file_t));	fp->ctf_version = hp.cth_version;	fp->ctf_fileops = &ctf_fileops[hp.cth_version];	bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t));	if (symsect != NULL) {		bcopy(symsect, &fp->ctf_symtab, sizeof (ctf_sect_t));		bcopy(strsect, &fp->ctf_strtab, sizeof (ctf_sect_t));	}	if (fp->ctf_data.cts_name != NULL)		fp->ctf_data.cts_name = ctf_strdup(fp->ctf_data.cts_name);	if (fp->ctf_symtab.cts_name != NULL)		fp->ctf_symtab.cts_name = ctf_strdup(fp->ctf_symtab.cts_name);	if (fp->ctf_strtab.cts_name != NULL)		fp->ctf_strtab.cts_name = ctf_strdup(fp->ctf_strtab.cts_name);	if (fp->ctf_data.cts_name == NULL)		fp->ctf_data.cts_name = _CTF_NULLSTR;	if (fp->ctf_symtab.cts_name == NULL)		fp->ctf_symtab.cts_name = _CTF_NULLSTR;	if (fp->ctf_strtab.cts_name == NULL)		fp->ctf_strtab.cts_name = _CTF_NULLSTR;	fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *)buf + hp.cth_stroff;	fp->ctf_str[CTF_STRTAB_0].cts_len = hp.cth_strlen;	if (strsect != NULL) {		fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;		fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;	}	fp->ctf_base = base;	fp->ctf_buf = buf;	fp->ctf_size = size + hdrsz;	/*	 * If we have a parent container name and label, store the relocated	 * string pointers in the CTF container for easy access later.	 */	if (hp.cth_parlabel != 0)		fp->ctf_parlabel = ctf_strptr(fp, hp.cth_parlabel);	if (hp.cth_parname != 0)		fp->ctf_parname = ctf_strptr(fp, hp.cth_parname);	ctf_dprintf("ctf_bufopen: parent name %s (label %s)\n",	    fp->ctf_parname ? fp->ctf_parname : "<NULL>",	    fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>");	/*	 * If we have a symbol table section, allocate and initialize	 * the symtab translation table, pointed to by ctf_sxlate.	 */	if (symsect != NULL) {		fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize;		fp->ctf_sxlate = ctf_alloc(fp->ctf_nsyms * sizeof (uint_t));		if (fp->ctf_sxlate == NULL) {			(void) ctf_set_open_errno(errp, EAGAIN);			goto bad;		}		if ((err = init_symtab(fp, &hp, symsect, strsect)) != 0) {			(void) ctf_set_open_errno(errp, err);			goto bad;		}	}	if ((err = init_types(fp, &hp)) != 0) {		(void) ctf_set_open_errno(errp, err);		goto bad;	}	/*	 * Initialize the ctf_lookup_by_name top-level dictionary.  We keep an	 * array of type name prefixes and the corresponding ctf_hash to use.	 * NOTE: This code must be kept in sync with the code in ctf_update().	 */	fp->ctf_lookups[0].ctl_prefix = "struct";	fp->ctf_lookups[0].ctl_len = strlen(fp->ctf_lookups[0].ctl_prefix);	fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;	fp->ctf_lookups[1].ctl_prefix = "union";	fp->ctf_lookups[1].ctl_len = strlen(fp->ctf_lookups[1].ctl_prefix);	fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;	fp->ctf_lookups[2].ctl_prefix = "enum";	fp->ctf_lookups[2].ctl_len = strlen(fp->ctf_lookups[2].ctl_prefix);	fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;	fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;	fp->ctf_lookups[3].ctl_len = strlen(fp->ctf_lookups[3].ctl_prefix);	fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;	fp->ctf_lookups[4].ctl_prefix = NULL;	fp->ctf_lookups[4].ctl_len = 0;	fp->ctf_lookups[4].ctl_hash = NULL;	if (symsect != NULL) {		if (symsect->cts_entsize == sizeof (Elf64_Sym))			(void) ctf_setmodel(fp, CTF_MODEL_LP64);		else			(void) ctf_setmodel(fp, CTF_MODEL_ILP32);	} else		(void) ctf_setmodel(fp, CTF_MODEL_NATIVE);	fp->ctf_refcnt = 1;	return (fp);bad:	ctf_close(fp);	return (NULL);}/* * Close the specified CTF container and free associated data structures.  Note * that ctf_close() is a reference counted operation: if the specified file is * the parent of other active containers, its reference count will be greater * than one and it will be freed later when no active children exist. */voidctf_close(ctf_file_t *fp){	ctf_dtdef_t *dtd, *ntd;	ctf_dmdef_t *dmd, *nmd;	if (fp == NULL)		return; /* allow ctf_close(NULL) to simplify caller code */	ctf_dprintf("ctf_close(%p) refcnt=%u\n", (void *)fp, fp->ctf_refcnt);	if (fp->ctf_refcnt > 1) {		fp->ctf_refcnt--;		return;	}	for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {		switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {		case CTF_K_STRUCT:		case CTF_K_UNION:		case CTF_K_ENUM:			for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);			    dmd != NULL; dmd = nmd) {				if (dmd->dmd_name != NULL) {					ctf_free(dmd->dmd_name,					    strlen(dmd->dmd_name) + 1);				}				nmd = ctf_list_next(dmd);				ctf_free(dmd, sizeof (ctf_dmdef_t));			}			break;		case CTF_K_FUNCTION:			ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *			    CTF_INFO_VLEN(dtd->dtd_data.ctt_info));			break;		}		if (dtd->dtd_name != NULL)			ctf_free(dtd->dtd_name, strlen(dtd->dtd_name) + 1);		ntd = ctf_list_next(dtd);		ctf_free(dtd, sizeof (ctf_dtdef_t));	}	if (fp->ctf_parent != NULL)		ctf_close(fp->ctf_parent);	if (fp->ctf_flags & LCTF_MMAP) {		if (fp->ctf_data.cts_data != NULL)			ctf_sect_munmap(&fp->ctf_data);		if (fp->ctf_symtab.cts_data != NULL)			ctf_sect_munmap(&fp->ctf_symtab);		if (fp->ctf_strtab.cts_data != NULL)			ctf_sect_munmap(&fp->ctf_strtab);	}	if (fp->ctf_data.cts_name != _CTF_NULLSTR &&	    fp->ctf_data.cts_name != NULL) {		ctf_free((char *)fp->ctf_data.cts_name,		    strlen(fp->ctf_data.cts_name) + 1);	}	if (fp->ctf_symtab.cts_name != _CTF_NULLSTR &&	    fp->ctf_symtab.cts_name != NULL) {		ctf_free((char *)fp->ctf_symtab.cts_name,		    strlen(fp->ctf_symtab.cts_name) + 1);	}	if (fp->ctf_strtab.cts_name != _CTF_NULLSTR &&	    fp->ctf_strtab.cts_name != NULL) {		ctf_free((char *)fp->ctf_strtab.cts_name,		    strlen(fp->ctf_strtab.cts_name) + 1);	}	if (fp->ctf_base != fp->ctf_data.cts_data && fp->ctf_base != NULL)		ctf_data_free((void *)fp->ctf_base, fp->ctf_size);	if (fp->ctf_sxlate != NULL)		ctf_free(fp->ctf_sxlate, sizeof (uint_t) * fp->ctf_nsyms);	if (fp->ctf_txlate != NULL) {		ctf_free(fp->ctf_txlate,		    sizeof (uint_t) * (fp->ctf_typemax + 1));	}	if (fp->ctf_ptrtab != NULL) {		ctf_free(fp->ctf_ptrtab,		    sizeof (ushort_t) * (fp->ctf_typemax + 1));	}	ctf_hash_destroy(&fp->ctf_structs);	ctf_hash_destroy(&fp->ctf_unions);	ctf_hash_destroy(&fp->ctf_enums);	ctf_hash_destroy(&fp->ctf_names);	ctf_free(fp, sizeof (ctf_file_t));}/* * Return the CTF handle for the parent CTF container, if one exists. * Otherwise return NULL to indicate this container has no imported parent. */ctf_file_t *ctf_parent_file(ctf_file_t *fp){	return (fp->ctf_parent);}/* * Return the name of the parent CTF container, if one exists.  Otherwise * return NULL to indicate this container is a root container. */const char *ctf_parent_name(ctf_file_t *fp){	return (fp->ctf_parname);}/* * Import the types from the specified parent container by storing a pointer * to it in ctf_parent and incrementing its reference count.  Only one parent * is allowed: if a parent already exists, it is replaced by the new parent. */intctf_import(ctf_file_t *fp, ctf_file_t *pfp){	if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))		return (ctf_set_errno(fp, EINVAL));	if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)		return (ctf_set_errno(fp, ECTF_DMODEL));	if (fp->ctf_parent != NULL)		ctf_close(fp->ctf_parent);	if (pfp != NULL) {		fp->ctf_flags |= LCTF_CHILD;		pfp->ctf_refcnt++;	}	fp->ctf_parent = pfp;	return (0);}/* * Set the data model constant for the CTF container. */intctf_setmodel(ctf_file_t *fp, int model){	const ctf_dmodel_t *dp;	for (dp = _libctf_models; dp->ctd_name != NULL; dp++) {		if (dp->ctd_code == model) {			fp->ctf_dmodel = dp;			return (0);		}	}	return (ctf_set_errno(fp, EINVAL));}/* * Return the data model constant for the CTF container. */intctf_getmodel(ctf_file_t *fp){	return (fp->ctf_dmodel->ctd_code);}

⌨️ 快捷键说明

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