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

📄 dt_module.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 3 页
字号:
		    (dp = elf_getdata(sp, NULL)) != NULL) {			(void) strlcpy(dmp->dm_file,			    dp->d_buf, sizeof (dmp->dm_file));		}	}	dmp->dm_flags |= DT_DM_KERNEL;	dmp->dm_modid = (int)OBJFS_MODID(st.st_ino);	if (dmp->dm_info.objfs_info_primary)		dmp->dm_flags |= DT_DM_PRIMARY;	dt_dprintf("opened %d-bit module %s (%s) [%d]\n",	    bits, dmp->dm_name, dmp->dm_file, dmp->dm_modid);}/* * Unload all the loaded modules and then refresh the module cache with the * latest list of loaded modules and their address ranges. */voiddtrace_update(dtrace_hdl_t *dtp){	dt_module_t *dmp;	DIR *dirp;	for (dmp = dt_list_next(&dtp->dt_modlist);	    dmp != NULL; dmp = dt_list_next(dmp))		dt_module_unload(dtp, dmp);	/*	 * Open /system/object and attempt to create a libdtrace module for	 * each kernel module that is loaded on the current system.	 */	if (!(dtp->dt_oflags & DTRACE_O_NOSYS) &&	    (dirp = opendir(OBJFS_ROOT)) != NULL) {		struct dirent *dp, *ep;		ep = alloca(sizeof (struct dirent) + PATH_MAX + 1);		bzero(ep, sizeof (struct dirent) + PATH_MAX + 1);		while (readdir_r(dirp, ep, &dp) == 0 && dp != NULL) {			if (dp->d_name[0] != '.')				dt_module_update(dtp, dp->d_name);		}		(void) closedir(dirp);	}	/*	 * Look up all the macro identifiers and set di_id to the latest value.	 * This code collaborates with dt_lex.l on the use of di_id.  We will	 * need to implement something fancier if we need to support non-ints.	 */	dt_idhash_lookup(dtp->dt_macros, "egid")->di_id = getegid();	dt_idhash_lookup(dtp->dt_macros, "euid")->di_id = geteuid();	dt_idhash_lookup(dtp->dt_macros, "gid")->di_id = getgid();	dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid();	dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0);	dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid();	dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid();	dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0);	dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid();	dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid();	/*	 * Cache the pointers to the modules representing the base executable	 * and the run-time linker in the dtrace client handle.  We should	 * probably have a more generic way of inquiring as to their names.	 */	dtp->dt_exec = dt_module_lookup_by_name(dtp, "genunix");	dtp->dt_rtld = dt_module_lookup_by_name(dtp, "krtld");	/*	 * If this is the first time we are initializing the module list,	 * remove the module for genunix from the module list and then move it	 * to the front of the module list.  We do this so that type and symbol	 * queries encounter genunix and thereby optimize for the common case	 * in dtrace_lookup_by_name() and dtrace_lookup_by_type(), below.	 */	if (dtp->dt_exec != NULL &&	    dtp->dt_cdefs == NULL && dtp->dt_ddefs == NULL) {		dt_list_delete(&dtp->dt_modlist, dtp->dt_exec);		dt_list_prepend(&dtp->dt_modlist, dtp->dt_exec);	}}static dt_module_t *dt_module_from_object(dtrace_hdl_t *dtp, const char *object){	int err = EDT_NOMOD;	dt_module_t *dmp;	switch ((uintptr_t)object) {	case (uintptr_t)DTRACE_OBJ_EXEC:		dmp = dtp->dt_exec;		break;	case (uintptr_t)DTRACE_OBJ_RTLD:		dmp = dtp->dt_rtld;		break;	case (uintptr_t)DTRACE_OBJ_CDEFS:		dmp = dtp->dt_cdefs;		break;	case (uintptr_t)DTRACE_OBJ_DDEFS:		dmp = dtp->dt_ddefs;		break;	default:		dmp = dt_module_create(dtp, object);		err = EDT_NOMEM;	}	if (dmp == NULL)		(void) dt_set_errno(dtp, err);	return (dmp);}/* * Exported interface to look up a symbol by name.  We return the GElf_Sym and * complete symbol information for the matching symbol. */intdtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,    GElf_Sym *symp, dtrace_syminfo_t *sip){	dt_module_t *dmp;	dt_ident_t *idp;	uint_t n, id;	GElf_Sym sym;	uint_t mask = 0; /* mask of dt_module flags to match */	uint_t bits = 0; /* flag bits that must be present */	if (object != DTRACE_OBJ_EVERY &&	    object != DTRACE_OBJ_KMODS &&	    object != DTRACE_OBJ_UMODS) {		if ((dmp = dt_module_from_object(dtp, object)) == NULL)			return (-1); /* dt_errno is set for us */		if (dt_module_load(dtp, dmp) == -1)			return (-1); /* dt_errno is set for us */		n = 1;	} else {		if (object == DTRACE_OBJ_KMODS)			mask = bits = DT_DM_KERNEL;		else if (object == DTRACE_OBJ_UMODS)			mask = DT_DM_KERNEL;		dmp = dt_list_next(&dtp->dt_modlist);		n = dtp->dt_nmods;	}	if (symp == NULL)		symp = &sym;	for (; n > 0; n--, dmp = dt_list_next(dmp)) {		if ((dmp->dm_flags & mask) != bits)			continue; /* failed to match required attributes */		if (dt_module_load(dtp, dmp) == -1)			continue; /* failed to load symbol table */		if (dmp->dm_ops->do_symname(dmp, name, symp, &id) != NULL) {			if (sip != NULL) {				sip->dts_object = dmp->dm_name;				sip->dts_name = (const char *)				    dmp->dm_strtab.cts_data + symp->st_name;				sip->dts_id = id;			}			return (0);		}		if (dmp->dm_extern != NULL &&		    (idp = dt_idhash_lookup(dmp->dm_extern, name)) != NULL) {			if (symp != &sym) {				symp->st_name = (uintptr_t)idp->di_name;				symp->st_info =				    GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);				symp->st_other = 0;				symp->st_shndx = SHN_UNDEF;				symp->st_value = 0;				symp->st_size =				    ctf_type_size(idp->di_ctfp, idp->di_type);			}			if (sip != NULL) {				sip->dts_object = dmp->dm_name;				sip->dts_name = idp->di_name;				sip->dts_id = idp->di_id;			}			return (0);		}	}	return (dt_set_errno(dtp, EDT_NOSYM));}/* * Exported interface to look up a symbol by address.  We return the GElf_Sym * and complete symbol information for the matching symbol. */intdtrace_lookup_by_addr(dtrace_hdl_t *dtp, GElf_Addr addr,    GElf_Sym *symp, dtrace_syminfo_t *sip){	dt_module_t *dmp;	uint_t id;	const dtrace_vector_t *v = dtp->dt_vector;	if (v != NULL)		return (v->dtv_lookup_by_addr(dtp->dt_varg, addr, symp, sip));	for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL;	    dmp = dt_list_next(dmp)) {		if (addr - dmp->dm_text_va < dmp->dm_text_size ||		    addr - dmp->dm_data_va < dmp->dm_data_size ||		    addr - dmp->dm_bss_va < dmp->dm_bss_size)			break;	}	if (dmp == NULL)		return (dt_set_errno(dtp, EDT_NOSYMADDR));	if (dt_module_load(dtp, dmp) == -1)		return (-1); /* dt_errno is set for us */	if (symp != NULL) {		if (dmp->dm_ops->do_symaddr(dmp, addr, symp, &id) == NULL)			return (dt_set_errno(dtp, EDT_NOSYMADDR));	}	if (sip != NULL) {		sip->dts_object = dmp->dm_name;		if (symp != NULL) {			sip->dts_name = (const char *)			    dmp->dm_strtab.cts_data + symp->st_name;			sip->dts_id = id;		} else {			sip->dts_name = NULL;			sip->dts_id = 0;		}	}	return (0);}intdtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,    dtrace_typeinfo_t *tip){	dtrace_typeinfo_t ti;	dt_module_t *dmp;	int found = 0;	ctf_id_t id;	uint_t n;	uint_t mask = 0; /* mask of dt_module flags to match */	uint_t bits = 0; /* flag bits that must be present */	if (object != DTRACE_OBJ_EVERY &&	    object != DTRACE_OBJ_KMODS &&	    object != DTRACE_OBJ_UMODS) {		if ((dmp = dt_module_from_object(dtp, object)) == NULL)			return (-1); /* dt_errno is set for us */		if (dt_module_load(dtp, dmp) == -1)			return (-1); /* dt_errno is set for us */		n = 1;	} else {		if (object == DTRACE_OBJ_KMODS)			mask = bits = DT_DM_KERNEL;		else if (object == DTRACE_OBJ_UMODS)			mask = DT_DM_KERNEL;		dmp = dt_list_next(&dtp->dt_modlist);		n = dtp->dt_nmods;	}	if (tip == NULL)		tip = &ti;	for (; n > 0; n--, dmp = dt_list_next(dmp)) {		if ((dmp->dm_flags & mask) != bits)			continue; /* failed to match required attributes */		/*		 * If we can't load the CTF container, continue on to the next		 * module.  If our search was scoped to only one module (n = 1)		 * then return immediately, leaving dt_errno set to the error		 * from dt_module_getctf() on the module given by the caller.		 */		if (dt_module_getctf(dtp, dmp) == NULL) {			if (n == 1)				return (-1);			continue;		}		/*		 * Look up the type in the module's CTF container.  If our		 * match is a forward declaration tag, save this choice in		 * 'tip' and keep going in the hope that we will locate the		 * underlying structure definition.  Otherwise just return.		 */		if ((id = ctf_lookup_by_name(dmp->dm_ctfp, name)) != CTF_ERR) {			tip->dtt_object = dmp->dm_name;			tip->dtt_ctfp = dmp->dm_ctfp;			tip->dtt_type = id;			if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve(			    dmp->dm_ctfp, id)) != CTF_K_FORWARD)				return (0);			found++;		}	}	if (found == 0)		return (dt_set_errno(dtp, EDT_NOTYPE));	return (0);}intdtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,    const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip){	dt_module_t *dmp;	tip->dtt_object = NULL;	tip->dtt_ctfp = NULL;	tip->dtt_type = CTF_ERR;	if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)		return (dt_set_errno(dtp, EDT_NOMOD));	if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) {		dt_ident_t *idp =		    dt_idhash_lookup(dmp->dm_extern, sip->dts_name);		if (idp == NULL)			return (dt_set_errno(dtp, EDT_NOSYM));		tip->dtt_ctfp = idp->di_ctfp;		tip->dtt_type = idp->di_type;	} else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) {		if (dt_module_getctf(dtp, dmp) == NULL)			return (-1); /* errno is set for us */		tip->dtt_ctfp = dmp->dm_ctfp;		tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id);		if (tip->dtt_type == CTF_ERR) {			dtp->dt_ctferr = ctf_errno(tip->dtt_ctfp);			return (dt_set_errno(dtp, EDT_CTF));		}	} else {		tip->dtt_ctfp = DT_FPTR_CTFP(dtp);		tip->dtt_type = DT_FPTR_TYPE(dtp);	}	tip->dtt_object = dmp->dm_name;	return (0);}static dtrace_objinfo_t *dt_module_info(const dt_module_t *dmp, dtrace_objinfo_t *dto){	dto->dto_name = dmp->dm_name;	dto->dto_file = dmp->dm_file;	dto->dto_id = dmp->dm_modid;	dto->dto_flags = 0;	if (dmp->dm_flags & DT_DM_KERNEL)		dto->dto_flags |= DTRACE_OBJ_F_KERNEL;	if (dmp->dm_flags & DT_DM_PRIMARY)		dto->dto_flags |= DTRACE_OBJ_F_PRIMARY;	dto->dto_text_va = dmp->dm_text_va;	dto->dto_text_size = dmp->dm_text_size;	dto->dto_data_va = dmp->dm_data_va;	dto->dto_data_size = dmp->dm_data_size;	dto->dto_bss_va = dmp->dm_bss_va;	dto->dto_bss_size = dmp->dm_bss_size;	return (dto);}intdtrace_object_iter(dtrace_hdl_t *dtp, dtrace_obj_f *func, void *data){	const dt_module_t *dmp = dt_list_next(&dtp->dt_modlist);	dtrace_objinfo_t dto;	int rv;	for (; dmp != NULL; dmp = dt_list_next(dmp)) {		if ((rv = (*func)(dtp, dt_module_info(dmp, &dto), data)) != 0)			return (rv);	}	return (0);}intdtrace_object_info(dtrace_hdl_t *dtp, const char *object, dtrace_objinfo_t *dto){	dt_module_t *dmp;	if (object == DTRACE_OBJ_EVERY || object == DTRACE_OBJ_KMODS ||	    object == DTRACE_OBJ_UMODS || dto == NULL)		return (dt_set_errno(dtp, EINVAL));	if ((dmp = dt_module_from_object(dtp, object)) == NULL)		return (-1); /* dt_errno is set for us */	if (dt_module_load(dtp, dmp) == -1)		return (-1); /* dt_errno is set for us */	(void) dt_module_info(dmp, dto);	return (0);}

⌨️ 快捷键说明

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