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

📄 pcore.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 4 页
字号:
		if ((P->auxv = malloc(sizeof (auxv_t) * (n + 1))) == NULL)			return (-1);		for (i = 0; i < n; i++)			auxv_32_to_n(&a32[i], &P->auxv[i]);	} else {#endif		n = nbytes / sizeof (auxv_t);		nbytes = n * sizeof (auxv_t);		if ((P->auxv = malloc(nbytes + sizeof (auxv_t))) == NULL)			return (-1);		if (read(P->asfd, P->auxv, nbytes) != nbytes) {			free(P->auxv);			P->auxv = NULL;			return (-1);		}#ifdef _LP64	}#endif	if (_libproc_debug) {		for (i = 0; i < n; i++) {			dprintf("P->auxv[%lu] = ( %d, 0x%lx )\n", (ulong_t)i,			    P->auxv[i].a_type, P->auxv[i].a_un.a_val);		}	}	/*	 * Defensive coding for loops which depend upon the auxv array being	 * terminated by an AT_NULL element; in each case, we've allocated	 * P->auxv to have an additional element which we force to be AT_NULL.	 */	P->auxv[n].a_type = AT_NULL;	P->auxv[n].a_un.a_val = 0L;	P->nauxv = (int)n;	return (0);}#ifdef __sparcstatic intnote_xreg(struct ps_prochandle *P, size_t nbytes){	lwp_info_t *lwp = P->core->core_lwp;	size_t xbytes = sizeof (prxregset_t);	prxregset_t *xregs;	if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)		return (0);	/* No lwp yet, already seen, or bad size */	if ((xregs = malloc(xbytes)) == NULL)		return (-1);	if (read(P->asfd, xregs, xbytes) != xbytes) {		dprintf("Pgrab_core: failed to read NT_PRXREG\n");		free(xregs);		return (-1);	}	lwp->lwp_xregs = xregs;	return (0);}static intnote_gwindows(struct ps_prochandle *P, size_t nbytes){	lwp_info_t *lwp = P->core->core_lwp;	if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)		return (0);	/* No lwp yet or already seen or no data */	if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)		return (-1);	/*	 * Since the amount of gwindows data varies with how many windows were	 * actually saved, we just read up to the minimum of the note size	 * and the size of the gwindows_t type.  It doesn't matter if the read	 * fails since we have to zero out gwindows first anyway.	 */#ifdef _LP64	if (P->core->core_dmodel == PR_MODEL_ILP32) {		gwindows32_t g32;		(void) memset(&g32, 0, sizeof (g32));		(void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32)));		gwindows_32_to_n(&g32, lwp->lwp_gwins);	} else {#endif		(void) memset(lwp->lwp_gwins, 0, sizeof (gwindows_t));		(void) read(P->asfd, lwp->lwp_gwins,		    MIN(nbytes, sizeof (gwindows_t)));#ifdef _LP64	}#endif	return (0);}#ifdef __sparcv9static intnote_asrs(struct ps_prochandle *P, size_t nbytes){	lwp_info_t *lwp = P->core->core_lwp;	int64_t *asrs;	if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t))		return (0);	/* No lwp yet, already seen, or bad size */	if ((asrs = malloc(sizeof (asrset_t))) == NULL)		return (-1);	if (read(P->asfd, asrs, sizeof (asrset_t)) != sizeof (asrset_t)) {		dprintf("Pgrab_core: failed to read NT_ASRS\n");		free(asrs);		return (-1);	}	lwp->lwp_asrs = asrs;	return (0);}#endif	/* __sparcv9 */#endif	/* __sparc *//*ARGSUSED*/static intnote_notsup(struct ps_prochandle *P, size_t nbytes){	dprintf("skipping unsupported note type\n");	return (0);}/* * Populate a table of function pointers indexed by Note type with our * functions to process each type of core file note: */static int (*nhdlrs[])(struct ps_prochandle *, size_t) = {	note_notsup,		/*  0	unassigned		*/	note_notsup,		/*  1	NT_PRSTATUS (old)	*/	note_notsup,		/*  2	NT_PRFPREG (old)	*/	note_notsup,		/*  3	NT_PRPSINFO (old)	*/#ifdef __sparc	note_xreg,		/*  4	NT_PRXREG		*/#else	note_notsup,		/*  4	NT_PRXREG		*/#endif	note_platform,		/*  5	NT_PLATFORM		*/	note_auxv,		/*  6	NT_AUXV			*/#ifdef __sparc	note_gwindows,		/*  7	NT_GWINDOWS		*/#ifdef __sparcv9	note_asrs,		/*  8	NT_ASRS			*/#else	note_notsup,		/*  8	NT_ASRS			*/#endif#else	note_notsup,		/*  7	NT_GWINDOWS		*/	note_notsup,		/*  8	NT_ASRS			*/#endif#if defined(__i386) || defined(__amd64)	note_ldt,		/*  9	NT_LDT			*/#else	note_notsup,		/*  9	NT_LDT			*/#endif	note_pstatus,		/* 10	NT_PSTATUS		*/	note_notsup,		/* 11	unassigned		*/	note_notsup,		/* 12	unassigned		*/	note_psinfo,		/* 13	NT_PSINFO		*/	note_cred,		/* 14	NT_PRCRED		*/	note_utsname,		/* 15	NT_UTSNAME		*/	note_lwpstatus,		/* 16	NT_LWPSTATUS		*/	note_lwpsinfo,		/* 17	NT_LWPSINFO		*/	note_priv,		/* 18	NT_PRPRIV		*/	note_priv_info,		/* 19	NT_PRPRIVINFO		*/	note_content,		/* 20	NT_CONTENT		*/	note_zonename,		/* 21	NT_ZONENAME		*/};/* * Add information on the address space mapping described by the given * PT_LOAD program header.  We fill in more information on the mapping later. */static intcore_add_mapping(struct ps_prochandle *P, GElf_Phdr *php){	map_info_t *mp;	int err = 0;	dprintf("mapping base %llx filesz %llu memsz %llu offset %llu\n",	    (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,	    (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);	mp = &P->mappings[P->map_count++];	mp->map_offset = php->p_offset;	mp->map_file = NULL;	mp->map_pmap.pr_vaddr = (uintptr_t)php->p_vaddr;	mp->map_pmap.pr_size = php->p_memsz;	/*	 * If Pgcore() or elfcore() fail to write a mapping, they will set	 * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us.	 */	if (php->p_flags & PF_SUNW_FAILURE) {		(void) pread64(P->asfd, &err,		    sizeof (err), (off64_t)php->p_offset);		Perror_printf(P, "core file data for mapping at %p not saved: "		    "%s\n", (void *)(uintptr_t)php->p_vaddr, strerror(err));		dprintf("core file data for mapping at %p not saved: %s\n",		    (void *)(uintptr_t)php->p_vaddr, strerror(err));	} else if (php->p_filesz != 0 && mp->map_offset >= P->core->core_size) {		Perror_printf(P, "core file may be corrupt -- data for mapping "		    "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);		dprintf("core file may be corrupt -- data for mapping "		    "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);	}	/*	 * The mapping name and offset will hopefully be filled in	 * by the librtld_db agent.  Unfortunately, if it isn't a	 * shared library mapping, this information is gone forever.	 */	mp->map_pmap.pr_mapname[0] = '\0';	mp->map_pmap.pr_offset = 0;	mp->map_pmap.pr_mflags = 0;	if (php->p_flags & PF_R)		mp->map_pmap.pr_mflags |= MA_READ;	if (php->p_flags & PF_W)		mp->map_pmap.pr_mflags |= MA_WRITE;	if (php->p_flags & PF_X)		mp->map_pmap.pr_mflags |= MA_EXEC;	if (php->p_filesz == 0)		mp->map_pmap.pr_mflags |= MA_RESERVED1;	/*	 * At the time of adding this mapping, we just zero the pagesize.	 * Once we've processed more of the core file, we'll have the	 * pagesize from the auxv's AT_PAGESZ element and we can fill this in.	 */	mp->map_pmap.pr_pagesize = 0;	/*	 * Unfortunately whether or not the mapping was a System V	 * shared memory segment is lost.  We use -1 to mark it as not shm.	 */	mp->map_pmap.pr_shmid = -1;	return (0);}/* * Order mappings based on virtual address.  We use this function as the * callback for sorting the array of map_info_t pointers. */static intcore_cmp_mapping(const void *lhsp, const void *rhsp){	const map_info_t *lhs = lhsp;	const map_info_t *rhs = rhsp;	if (lhs->map_pmap.pr_vaddr == rhs->map_pmap.pr_vaddr)		return (0);	return (lhs->map_pmap.pr_vaddr < rhs->map_pmap.pr_vaddr ? -1 : 1);}/* * Given a virtual address, name the mapping at that address using the * specified name, and return the map_info_t pointer. */static map_info_t *core_name_mapping(struct ps_prochandle *P, uintptr_t addr, const char *name){	map_info_t *mp = Paddr2mptr(P, addr);	if (mp != NULL) {		(void) strncpy(mp->map_pmap.pr_mapname, name, PRMAPSZ);		mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';	}	return (mp);}/* * libproc uses libelf for all of its symbol table manipulation. This function * takes a symbol table and string table from a core file and places them * in a memory backed elf file. */static voidfake_up_symtab(struct ps_prochandle *P, GElf_Ehdr *ehdr,    GElf_Shdr *symtab, GElf_Shdr *strtab){	size_t size;	off64_t off, base;	map_info_t *mp;	file_info_t *fp;	Elf_Scn *scn;	Elf_Data *data;	if (symtab->sh_addr == 0 ||	    (mp = Paddr2mptr(P, symtab->sh_addr)) == NULL ||	    (fp = mp->map_file) == NULL ||	    fp->file_symtab.sym_data != NULL)		return;	if (P->status.pr_dmodel == PR_MODEL_ILP32) {		struct {			Elf32_Ehdr ehdr;			Elf32_Shdr shdr[3];			char data[1];		} *b;		base = sizeof (b->ehdr) + sizeof (b->shdr);		size = base + symtab->sh_size + strtab->sh_size;		if ((b = calloc(1, size)) == NULL)			return;		(void) memcpy(&b->ehdr, ehdr, offsetof(GElf_Ehdr, e_entry));		b->ehdr.e_ehsize = sizeof (b->ehdr);		b->ehdr.e_shoff = sizeof (b->ehdr);		b->ehdr.e_shentsize = sizeof (b->shdr[0]);		b->ehdr.e_shnum = 3;		off = 0;		b->shdr[1].sh_size = symtab->sh_size;		b->shdr[1].sh_type = SHT_SYMTAB;		b->shdr[1].sh_offset = off + base;		b->shdr[1].sh_entsize = sizeof (Elf32_Sym);		b->shdr[1].sh_link = 2;		b->shdr[1].sh_info =  symtab->sh_info;		b->shdr[1].sh_addralign = symtab->sh_addralign;		if (pread64(P->asfd, &b->data[off], b->shdr[1].sh_size,		    symtab->sh_offset) != b->shdr[1].sh_size) {			free(b);			return;		}		off += b->shdr[1].sh_size;		b->shdr[2].sh_flags = SHF_STRINGS;		b->shdr[2].sh_size = strtab->sh_size;		b->shdr[2].sh_type = SHT_STRTAB;		b->shdr[2].sh_offset = off + base;		b->shdr[2].sh_info =  strtab->sh_info;		b->shdr[2].sh_addralign = 1;		if (pread64(P->asfd, &b->data[off], b->shdr[2].sh_size,		    strtab->sh_offset) != b->shdr[2].sh_size) {			free(b);			return;		}		off += b->shdr[2].sh_size;		fp->file_symtab.sym_elf = elf_memory((char *)b, size);		if (fp->file_symtab.sym_elf == NULL) {			free(b);			return;		}		fp->file_symtab.sym_elfmem = b;#ifdef _LP64	} else {		struct {			Elf64_Ehdr ehdr;			Elf64_Shdr shdr[3];			char data[1];		} *b;		base = sizeof (b->ehdr) + sizeof (b->shdr);		size = base + symtab->sh_size + strtab->sh_size;		if ((b = calloc(1, size)) == NULL)			return;		(void) memcpy(&b->ehdr, ehdr, offsetof(GElf_Ehdr, e_entry));		b->ehdr.e_ehsize = sizeof (b->ehdr);		b->ehdr.e_shoff = sizeof (b->ehdr);		b->ehdr.e_shentsize = sizeof (b->shdr[0]);		b->ehdr.e_shnum = 3;		off = 0;		b->shdr[1].sh_size = symtab->sh_size;		b->shdr[1].sh_type = SHT_SYMTAB;		b->shdr[1].sh_offset = off + base;		b->shdr[1].sh_entsize = sizeof (Elf64_Sym);		b->shdr[1].sh_link = 2;		b->shdr[1].sh_info =  symtab->sh_info;		b->shdr[1].sh_addralign = symtab->sh_addralign;		if (pread64(P->asfd, &b->data[off], b->shdr[1].sh_size,		    symtab->sh_offset) != b->shdr[1].sh_size) {			free(b);			return;		}		off += b->shdr[1].sh_size;		b->shdr[2].sh_flags = SHF_STRINGS;		b->shdr[2].sh_size = strtab->sh_size;		b->shdr[2].sh_type = SHT_STRTAB;		b->shdr[2].sh_offset = off + base;		b->shdr[2].sh_info =  strtab->sh_info;		b->shdr[2].sh_addralign = 1;		if (pread64(P->asfd, &b->data[off], b->shdr[2].sh_size,		    strtab->sh_offset) != b->shdr[2].sh_size) {			free(b);			return;		}		off += b->shdr[2].sh_size;		fp->file_symtab.sym_elf = elf_memory((char *)b, size);		if (fp->file_symtab.sym_elf == NULL) {			free(b);			return;		}		fp->file_symtab.sym_elfmem = b;#endif	}	if ((scn = elf_getscn(fp->file_symtab.sym_elf, 1)) == NULL ||	    (fp->file_symtab.sym_data = elf_getdata(scn, NULL)) == NULL ||	    (scn = elf_getscn(fp->file_symtab.sym_elf, 2)) == NULL ||	    (data = elf_getdata(scn, NULL)) == NULL)		goto err;	fp->file_symtab.sym_strs = data->d_buf;	fp->file_symtab.sym_strsz = data->d_size;	fp->file_symtab.sym_symn = symtab->sh_size / symtab->sh_entsize;	fp->file_symtab.sym_hdr = *symtab;	fp->file_symtab.sym_strhdr = *strtab;	optimize_symtab(&fp->file_symtab);	return;err:	(void) elf_end(fp->file_symtab.sym_elf);	free(fp->file_symtab.sym_elfmem);	fp->file_symtab.sym_elf = NULL;	fp->file_symtab.sym_elfmem = NULL;}static voidcore_ehdr_to_gelf(const Elf32_Ehdr *src, GElf_Ehdr *dst){	(void) memcpy(dst->e_ident, src->e_ident, EI_NIDENT);	dst->e_type = src->e_type;	dst->e_machine = src->e_machine;	dst->e_version = src->e_version;	dst->e_entry = (Elf64_Addr)src->e_entry;	dst->e_phoff = (Elf64_Off)src->e_phoff;	dst->e_shoff = (Elf64_Off)src->e_shoff;	dst->e_flags = src->e_flags;	dst->e_ehsize = src->e_ehsize;	dst->e_phentsize = src->e_phentsize;	dst->e_phnum = src->e_phnum;	dst->e_shentsize = src->e_shentsize;	dst->e_shnum = src->e_shnum;	dst->e_shstrndx = src->e_shstrndx;}static voidcore_phdr_to_gelf(const Elf32_Phdr *src, GElf_Phdr *dst){	dst->p_type = src->p_type;	dst->p_flags = src->p_flags;	dst->p_offset = (Elf64_Off)src->p_offset;	dst->p_vaddr = (Elf64_Addr)src->p_vaddr;	dst->p_paddr = (Elf64_Addr)src->p_paddr;	dst->p_filesz = (Elf64_Xword)src->p_filesz;	dst->p_memsz = (Elf64_Xword)src->p_memsz;	dst->p_align = (Elf64_Xword)src->p_align;}static voidcore_shdr_to_gelf(const Elf32_Shdr *src, GElf_Shdr *dst){	dst->sh_name = src->sh_name;	dst->sh_type = src->sh_type;	dst->sh_flags = (Elf64_Xword)src->sh_flags;	dst->sh_addr = (Elf64_Addr)src->sh_addr;	dst->sh_offset = (Elf64_Off)src->sh_offset;	dst->sh_size = (Elf64_Xword)src->sh_size;	dst->sh_link = src->sh_link;	dst->sh_info = src->sh_info;	dst->sh_addralign = (Elf64_Xword)src->sh_addralign;	dst->sh_entsize = (Elf64_Xword)src->sh_entsize;}/* * Perform elf_begin on efp->e_fd and verify the ELF file's type and class. */static intcore_elf_fdopen(elf_file_t *efp, GElf_Half type, int *perr)

⌨️ 快捷键说明

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