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

📄 dt_module.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 3 页
字号:
dt_module_t *dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name){	uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;	dt_module_t *dmp;	for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {		if (strcmp(dmp->dm_name, name) == 0)			return (dmp);	}	return (NULL);}dt_module_t *dt_module_lookup_by_ctf(dtrace_hdl_t *dtp, ctf_file_t *ctfp){	dt_module_t *dmp;	for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL;	    dmp = dt_list_next(dmp)) {		if (dmp->dm_ctfp == ctfp)			return (dmp);	}	return (NULL);}static intdt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp){	const char *s;	size_t shstrs;	GElf_Shdr sh;	Elf_Data *dp;	Elf_Scn *sp;	if (elf_getshstrndx(dmp->dm_elf, &shstrs) == 0)		return (dt_set_errno(dtp, EDT_NOTLOADED));	for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {		if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||		    (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)			continue; /* skip any malformed sections */		if (sh.sh_type == ctsp->cts_type &&		    sh.sh_entsize == ctsp->cts_entsize &&		    strcmp(s, ctsp->cts_name) == 0)			break; /* section matches specification */	}	/*	 * If the section isn't found, return success but leave cts_data set	 * to NULL and cts_size set to zero for our caller.	 */	if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL)		return (0);	ctsp->cts_data = dp->d_buf;	ctsp->cts_size = dp->d_size;	dt_dprintf("loaded %s [%s] (%lu bytes)\n",	    dmp->dm_name, ctsp->cts_name, (ulong_t)ctsp->cts_size);	return (0);}intdt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp){	if (dmp->dm_flags & DT_DM_LOADED)		return (0); /* module is already loaded */	dmp->dm_ctdata.cts_name = ".SUNW_ctf";	dmp->dm_ctdata.cts_type = SHT_PROGBITS;	dmp->dm_ctdata.cts_flags = 0;	dmp->dm_ctdata.cts_data = NULL;	dmp->dm_ctdata.cts_size = 0;	dmp->dm_ctdata.cts_entsize = 0;	dmp->dm_ctdata.cts_offset = 0;	dmp->dm_symtab.cts_name = ".symtab";	dmp->dm_symtab.cts_type = SHT_SYMTAB;	dmp->dm_symtab.cts_flags = 0;	dmp->dm_symtab.cts_data = NULL;	dmp->dm_symtab.cts_size = 0;	dmp->dm_symtab.cts_entsize = dmp->dm_ops == &dt_modops_64 ?	    sizeof (Elf64_Sym) : sizeof (Elf32_Sym);	dmp->dm_symtab.cts_offset = 0;	dmp->dm_strtab.cts_name = ".strtab";	dmp->dm_strtab.cts_type = SHT_STRTAB;	dmp->dm_strtab.cts_flags = 0;	dmp->dm_strtab.cts_data = NULL;	dmp->dm_strtab.cts_size = 0;	dmp->dm_strtab.cts_entsize = 0;	dmp->dm_strtab.cts_offset = 0;	/*	 * Attempt to load the module's CTF section, symbol table section, and	 * string table section.  Note that modules may not contain CTF data:	 * this will result in a successful load_sect but data of size zero.	 * We will then fail if dt_module_getctf() is called, as shown below.	 */	if (dt_module_load_sect(dtp, dmp, &dmp->dm_ctdata) == -1 ||	    dt_module_load_sect(dtp, dmp, &dmp->dm_symtab) == -1 ||	    dt_module_load_sect(dtp, dmp, &dmp->dm_strtab) == -1) {		dt_module_unload(dtp, dmp);		return (-1); /* dt_errno is set for us */	}	/*	 * Allocate the hash chains and hash buckets for symbol name lookup.	 * This is relatively simple since the symbol table is of fixed size	 * and is known in advance.  We allocate one extra element since we	 * use element indices instead of pointers and zero is our sentinel.	 */	dmp->dm_nsymelems =	    dmp->dm_symtab.cts_size / dmp->dm_symtab.cts_entsize;	dmp->dm_nsymbuckets = _dtrace_strbuckets;	dmp->dm_symfree = 1;		/* first free element is index 1 */	dmp->dm_symbuckets = malloc(sizeof (uint_t) * dmp->dm_nsymbuckets);	dmp->dm_symchains = malloc(sizeof (dt_sym_t) * dmp->dm_nsymelems + 1);	if (dmp->dm_symbuckets == NULL || dmp->dm_symchains == NULL) {		dt_module_unload(dtp, dmp);		return (dt_set_errno(dtp, EDT_NOMEM));	}	bzero(dmp->dm_symbuckets, sizeof (uint_t) * dmp->dm_nsymbuckets);	bzero(dmp->dm_symchains, sizeof (dt_sym_t) * dmp->dm_nsymelems + 1);	/*	 * Iterate over the symbol table data buffer and insert each symbol	 * name into the name hash if the name and type are valid.  Then	 * allocate the address map, fill it in, and sort it.	 */	dmp->dm_asrsv = dmp->dm_ops->do_syminit(dmp);	dt_dprintf("hashed %s [%s] (%u symbols)\n",	    dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_symfree - 1);	if ((dmp->dm_asmap = malloc(sizeof (void *) * dmp->dm_asrsv)) == NULL) {		dt_module_unload(dtp, dmp);		return (dt_set_errno(dtp, EDT_NOMEM));	}	dmp->dm_ops->do_symsort(dmp);	dt_dprintf("sorted %s [%s] (%u symbols)\n",	    dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_aslen);	dmp->dm_flags |= DT_DM_LOADED;	return (0);}ctf_file_t *dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp){	const char *parent;	dt_module_t *pmp;	ctf_file_t *pfp;	int model;	if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)		return (dmp->dm_ctfp);	if (dmp->dm_ops == &dt_modops_64)		model = CTF_MODEL_LP64;	else		model = CTF_MODEL_ILP32;	/*	 * If the data model of the module does not match our program data	 * model, then do not permit CTF from this module to be opened and	 * returned to the compiler.  If we support mixed data models in the	 * future for combined kernel/user tracing, this can be removed.	 */	if (dtp->dt_conf.dtc_ctfmodel != model) {		(void) dt_set_errno(dtp, EDT_DATAMODEL);		return (NULL);	}	if (dmp->dm_ctdata.cts_size == 0) {		(void) dt_set_errno(dtp, EDT_NOCTF);		return (NULL);	}	dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,	    &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);	if (dmp->dm_ctfp == NULL || ctf_setmodel(dmp->dm_ctfp, model) != 0) {		(void) dt_set_errno(dtp, EDT_CTF);		return (NULL);	}	if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {		if ((pmp = dt_module_create(dtp, parent)) == NULL ||		    (pfp = dt_module_getctf(dtp, pmp)) == NULL) {			if (pmp == NULL)				(void) dt_set_errno(dtp, EDT_NOMEM);			goto err;		}		if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {			dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);			(void) dt_set_errno(dtp, EDT_CTF);			goto err;		}	}	dt_dprintf("loaded CTF container for %s (%p)\n",	    dmp->dm_name, (void *)dmp->dm_ctfp);	return (dmp->dm_ctfp);err:	ctf_close(dmp->dm_ctfp);	dmp->dm_ctfp = NULL;	return (NULL);}/*ARGSUSED*/voiddt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp){	ctf_close(dmp->dm_ctfp);	dmp->dm_ctfp = NULL;	bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));	bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));	bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));	if (dmp->dm_symbuckets != NULL) {		free(dmp->dm_symbuckets);		dmp->dm_symbuckets = NULL;	}	if (dmp->dm_symchains != NULL) {		free(dmp->dm_symchains);		dmp->dm_symchains = NULL;	}	if (dmp->dm_asmap != NULL) {		free(dmp->dm_asmap);		dmp->dm_asmap = NULL;	}	dmp->dm_symfree = 0;	dmp->dm_nsymbuckets = 0;	dmp->dm_nsymelems = 0;	dmp->dm_asrsv = 0;	dmp->dm_aslen = 0;	dmp->dm_text_va = NULL;	dmp->dm_text_size = 0;	dmp->dm_data_va = NULL;	dmp->dm_data_size = 0;	dmp->dm_bss_va = NULL;	dmp->dm_bss_size = 0;	if (dmp->dm_extern != NULL) {		dt_idhash_destroy(dmp->dm_extern);		dmp->dm_extern = NULL;	}	(void) elf_end(dmp->dm_elf);	dmp->dm_elf = NULL;	dmp->dm_flags &= ~DT_DM_LOADED;}voiddt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp){	dt_list_delete(&dtp->dt_modlist, dmp);	assert(dtp->dt_nmods != 0);	dtp->dt_nmods--;	dt_module_unload(dtp, dmp);	free(dmp);}/* * Insert a new external symbol reference into the specified module.  The new * symbol will be marked as undefined and is assigned a symbol index beyond * any existing cached symbols from this module.  We use the ident's di_data * field to store a pointer to a copy of the dtrace_syminfo_t for this symbol. */dt_ident_t *dt_module_extern(dtrace_hdl_t *dtp, dt_module_t *dmp,    const char *name, const dtrace_typeinfo_t *tip){	dtrace_syminfo_t *sip;	dt_ident_t *idp;	uint_t id;	if (dmp->dm_extern == NULL && (dmp->dm_extern = dt_idhash_create(	    "extern", NULL, dmp->dm_nsymelems, UINT_MAX)) == NULL) {		(void) dt_set_errno(dtp, EDT_NOMEM);		return (NULL);	}	if (dt_idhash_nextid(dmp->dm_extern, &id) == -1) {		(void) dt_set_errno(dtp, EDT_SYMOFLOW);		return (NULL);	}	if ((sip = malloc(sizeof (dtrace_syminfo_t))) == NULL) {		(void) dt_set_errno(dtp, EDT_NOMEM);		return (NULL);	}	idp = dt_idhash_insert(dmp->dm_extern, name, DT_IDENT_SYMBOL, 0, id,	    _dtrace_symattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);	if (idp == NULL) {		(void) dt_set_errno(dtp, EDT_NOMEM);		free(sip);		return (NULL);	}	sip->dts_object = dmp->dm_name;	sip->dts_name = idp->di_name;	sip->dts_id = idp->di_id;	idp->di_data = sip;	idp->di_ctfp = tip->dtt_ctfp;	idp->di_type = tip->dtt_type;	return (idp);}const char *dt_module_modelname(dt_module_t *dmp){	if (dmp->dm_ops == &dt_modops_64)		return ("64-bit");	else		return ("32-bit");}/* * Update our module cache by adding an entry for the specified module 'name'. * We create the dt_module_t and populate it using /system/object/<name>/. */static voiddt_module_update(dtrace_hdl_t *dtp, const char *name){	char fname[MAXPATHLEN];	struct stat64 st;	int fd, err, bits;	dt_module_t *dmp;	const char *s;	size_t shstrs;	GElf_Shdr sh;	Elf_Data *dp;	Elf_Scn *sp;	(void) snprintf(fname, sizeof (fname),	    "%s/%s/object", OBJFS_ROOT, name);	if ((fd = open(fname, O_RDONLY)) == -1 || fstat64(fd, &st) == -1 ||	    (dmp = dt_module_create(dtp, name)) == NULL) {		dt_dprintf("failed to open %s: %s\n", fname, strerror(errno));		(void) close(fd);		return;	}	/*	 * Since the module can unload out from under us (and /system/object	 * will return ENOENT), tell libelf to cook the entire file now and	 * then close the underlying file descriptor immediately.  If this	 * succeeds, we know that we can continue safely using dmp->dm_elf.	 */	dmp->dm_elf = elf_begin(fd, ELF_C_READ, NULL);	err = elf_cntl(dmp->dm_elf, ELF_C_FDREAD);	(void) close(fd);	if (dmp->dm_elf == NULL || err == -1 ||	    elf_getshstrndx(dmp->dm_elf, &shstrs) == 0) {		dt_dprintf("failed to load %s: %s\n",		    fname, elf_errmsg(elf_errno()));		dt_module_destroy(dtp, dmp);		return;	}	switch (gelf_getclass(dmp->dm_elf)) {	case ELFCLASS32:		dmp->dm_ops = &dt_modops_32;		bits = 32;		break;	case ELFCLASS64:		dmp->dm_ops = &dt_modops_64;		bits = 64;		break;	default:		dt_dprintf("failed to load %s: unknown ELF class\n", fname);		dt_module_destroy(dtp, dmp);		return;	}	/*	 * Iterate over the section headers locating various sections of	 * interest and use their attributes to flesh out the dt_module_t.	 */	for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {		if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||		    (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)			continue; /* skip any malformed sections */		if (strcmp(s, ".text") == 0) {			dmp->dm_text_size = sh.sh_size;			dmp->dm_text_va = sh.sh_addr;		} else if (strcmp(s, ".data") == 0) {			dmp->dm_data_size = sh.sh_size;			dmp->dm_data_va = sh.sh_addr;		} else if (strcmp(s, ".bss") == 0) {			dmp->dm_bss_size = sh.sh_size;			dmp->dm_bss_va = sh.sh_addr;		} else if (strcmp(s, ".info") == 0 &&		    (dp = elf_getdata(sp, NULL)) != NULL) {			bcopy(dp->d_buf, &dmp->dm_info,			    MIN(sh.sh_size, sizeof (dmp->dm_info)));		} else if (strcmp(s, ".filename") == 0 &&

⌨️ 快捷键说明

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