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

📄 pgcore.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 3 页
字号:
			    pgc->pgc_doff) != 0)				return (1);		}	}#ifdef __sparcv9	if (P->status.pr_dmodel == PR_MODEL_LP64) {		asrset_t asrs;		if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) {			if (write_note(pgc->pgc_fd, NT_ASRS, &asrs,			    sizeof (asrset_t), pgc->pgc_doff) != 0)				return (1);		}	}#endif	/* __sparcv9 */#endif	/* sparc */	return (0);}static uint_tcount_sections(pgcore_t *pgc){	struct ps_prochandle *P = pgc->P;	file_info_t *fptr;	uint_t cnt;	uint_t nshdrs = 0;	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))		return (0);	fptr = list_next(&P->file_head);	for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {		int hit_symtab = 0;		Pbuild_file_symtab(P, fptr);		if ((pgc->pgc_content & CC_CONTENT_CTF) &&		    Pbuild_file_ctf(P, fptr) != NULL) {			sym_tbl_t *sym;			nshdrs++;			if (fptr->file_ctf_dyn) {				sym = &fptr->file_dynsym;			} else {				sym = &fptr->file_symtab;				hit_symtab = 1;			}			if (sym->sym_data != NULL && sym->sym_symn != 0 &&			    sym->sym_strs != NULL)				nshdrs += 2;		}		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&		    fptr->file_symtab.sym_data != NULL &&		    fptr->file_symtab.sym_symn != 0 &&		    fptr->file_symtab.sym_strs != NULL) {			nshdrs += 2;		}	}	return (nshdrs == 0 ? 0 : nshdrs + 2);}static intwrite_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags,    uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info,    uintptr_t addralign, uintptr_t entsize){	if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) {		Elf32_Shdr shdr;		bzero(&shdr, sizeof (shdr));		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);		shdr.sh_type = type;		shdr.sh_flags = flags;		shdr.sh_addr = (Elf32_Addr)addr;		shdr.sh_offset = offset;		shdr.sh_size = size;		shdr.sh_link = link;		shdr.sh_info = info;		shdr.sh_addralign = addralign;		shdr.sh_entsize = entsize;		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),		    *pgc->pgc_soff) != sizeof (shdr))			return (-1);		*pgc->pgc_soff += sizeof (shdr);#ifdef _LP64	} else {		Elf64_Shdr shdr;		bzero(&shdr, sizeof (shdr));		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);		shdr.sh_type = type;		shdr.sh_flags = flags;		shdr.sh_addr = addr;		shdr.sh_offset = offset;		shdr.sh_size = size;		shdr.sh_link = link;		shdr.sh_info = info;		shdr.sh_addralign = addralign;		shdr.sh_entsize = entsize;		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),		    *pgc->pgc_soff) != sizeof (shdr))			return (-1);		*pgc->pgc_soff += sizeof (shdr);#endif	/* _LP64 */	}	return (0);}static intdump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym){	sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab;	shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB;	shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB;	uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB;	size_t size;	uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr;	if (sym->sym_data == NULL || sym->sym_symn == 0 ||	    sym->sym_strs == NULL)		return (0);	size = sym->sym_hdr.sh_size;	if (pwrite64(pgc->pgc_fd, sym->sym_data->d_buf, size,	    *pgc->pgc_doff) != size)		return (-1);	if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size,	    index + 1, sym->sym_hdr.sh_info, sym->sym_hdr.sh_addralign,	    sym->sym_hdr.sh_entsize) != 0)		return (-1);	*pgc->pgc_doff += roundup(size, 8);	size = sym->sym_strhdr.sh_size;	if (pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != size)		return (-1);	if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr,	    *pgc->pgc_doff, size, 0, 0, 1, 0) != 0)		return (-1);	*pgc->pgc_doff += roundup(size, 8);	return (0);}static intdump_sections(pgcore_t *pgc){	struct ps_prochandle *P = pgc->P;	file_info_t *fptr;	uint_t cnt;	uint_t index = 1;	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))		return (0);	fptr = list_next(&P->file_head);	for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {		int hit_symtab = 0;		Pbuild_file_symtab(P, fptr);		if ((pgc->pgc_content & CC_CONTENT_CTF) &&		    Pbuild_file_ctf(P, fptr) != NULL) {			sym_tbl_t *sym;			uint_t dynsym;			uint_t symindex = 0;			/*			 * Write the symtab out first so we can correctly			 * set the sh_link field in the CTF section header.			 * symindex will be 0 if there is no corresponding			 * symbol table section.			 */			if (fptr->file_ctf_dyn) {				sym = &fptr->file_dynsym;				dynsym = 1;			} else {				sym = &fptr->file_symtab;				dynsym = 0;				hit_symtab = 1;			}			if (sym->sym_data != NULL && sym->sym_symn != 0 &&			    sym->sym_strs != NULL) {				symindex = index;				if (dump_symtab(pgc, fptr, index, dynsym) != 0)				    return (-1);				index += 2;			}			/*			 * Write the CTF data that we've read out of the			 * file itself into the core file.			 */			if (pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,			    fptr->file_ctf_size, *pgc->pgc_doff) !=			    fptr->file_ctf_size)				return (-1);			if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0,			    fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff,			    fptr->file_ctf_size, symindex, 0, 4, 0) != 0)				return (-1);			index++;			*pgc->pgc_doff += roundup(fptr->file_ctf_size, 8);		}		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&		    fptr->file_symtab.sym_data != NULL &&		    fptr->file_symtab.sym_symn != 0 &&		    fptr->file_symtab.sym_strs != NULL) {			if (dump_symtab(pgc, fptr, index, 0) != 0)				return (-1);			index += 2;		}	}	return (0);}/*ARGSUSED*/static intdump_map(void *data, const prmap_t *pmp, const char *name){	pgcore_t *pgc = data;	struct ps_prochandle *P = pgc->P;#ifdef _LP64	Elf64_Phdr phdr;#else	Elf32_Phdr phdr;#endif	size_t n;	bzero(&phdr, sizeof (phdr));	phdr.p_type = PT_LOAD;	phdr.p_vaddr = pmp->pr_vaddr;	phdr.p_memsz = pmp->pr_size;	if (pmp->pr_mflags & MA_READ)		phdr.p_flags |= PF_R;	if (pmp->pr_mflags & MA_WRITE)		phdr.p_flags |= PF_W;	if (pmp->pr_mflags & MA_EXEC)		phdr.p_flags |= PF_X;	if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase &&	    pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) {		if (!(pgc->pgc_content & CC_CONTENT_STACK))			goto exclude;	} else if ((pmp->pr_mflags & MA_ANON) &&	    pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase &&	    pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) {		if (!(pgc->pgc_content & CC_CONTENT_HEAP))			goto exclude;	} else if (pmp->pr_mflags & MA_ISM) {		if (pmp->pr_mflags & MA_NORESERVE) {			if (!(pgc->pgc_content & CC_CONTENT_DISM))				goto exclude;		} else {			if (!(pgc->pgc_content & CC_CONTENT_ISM))				goto exclude;		}	} else if (pmp->pr_mflags & MA_SHM) {		if (!(pgc->pgc_content & CC_CONTENT_SHM))			goto exclude;	} else if (pmp->pr_mflags & MA_SHARED) {		if (pmp->pr_mflags & MA_ANON) {			if (!(pgc->pgc_content & CC_CONTENT_SHANON))				goto exclude;		} else {			if (!(pgc->pgc_content & CC_CONTENT_SHFILE))				goto exclude;		}	} else if (pmp->pr_mflags & MA_ANON) {		if (!(pgc->pgc_content & CC_CONTENT_ANON))			goto exclude;	} else if (phdr.p_flags == (PF_R | PF_X)) {		if (!(pgc->pgc_content & CC_CONTENT_TEXT))			goto exclude;	} else if (phdr.p_flags == PF_R) {		if (!(pgc->pgc_content & CC_CONTENT_RODATA))			goto exclude;	} else {		if (!(pgc->pgc_content & CC_CONTENT_DATA))			goto exclude;	}	n = 0;	while (n < pmp->pr_size) {		size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz);		/*		 * If we can't read out part of the victim's address		 * space for some reason ignore that failure and try to		 * emit a partial core file without that mapping's data.		 * As in the kernel, we mark these failures with the		 * PF_SUNW_FAILURE flag and store the errno where the		 * mapping would have been.		 */		if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) != csz ||		    pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,		    *pgc->pgc_doff + n) != csz) {			int err = errno;			(void) pwrite64(pgc->pgc_fd, &err, sizeof (err),			    *pgc->pgc_doff);			*pgc->pgc_doff += roundup(sizeof (err), 8);			phdr.p_flags |= PF_SUNW_FAILURE;			(void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff);			goto exclude;		}		n += csz;	}	phdr.p_offset = *pgc->pgc_doff;	phdr.p_filesz = pmp->pr_size;	*pgc->pgc_doff += roundup(phdr.p_filesz, 8);exclude:	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {		if (pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),		    *pgc->pgc_poff) != sizeof (phdr))			return (1);		*pgc->pgc_poff += sizeof (phdr);#ifdef _LP64	} else {		Elf32_Phdr phdr32;		bzero(&phdr32, sizeof (phdr32));		phdr32.p_type = phdr.p_type;		phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr;		phdr32.p_memsz = (Elf32_Word)phdr.p_memsz;		phdr32.p_flags = phdr.p_flags;		phdr32.p_offset = (Elf32_Off)phdr.p_offset;		phdr32.p_filesz = (Elf32_Word)phdr.p_filesz;		if (pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),		    *pgc->pgc_poff) != sizeof (phdr32))			return (1);		*pgc->pgc_poff += sizeof (phdr32);#endif	/* _LP64 */	}	return (0);}intwrite_shstrtab(struct ps_prochandle *P, pgcore_t *pgc){	off64_t off = *pgc->pgc_doff;	size_t size = 0;	shstrtab_t *s = &pgc->pgc_shstrtab;	int i, ndx;	if (shstrtab_size(s) == 1)		return (0);	/*	 * Preemptively stick the name of the shstrtab in the string table.	 */	(void) shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);	size = shstrtab_size(s);	if (pwrite64(pgc->pgc_fd, "", 1, off) != 1)		return (1);	/*	 * Dump all the strings that we used being sure we include the	 * terminating null character.	 */	for (i = 0; i < STR_NUM; i++) {		if ((ndx = s->sst_ndx[i]) != 0) {			const char *str = shstrtab_data[i];			size_t len = strlen(str) + 1;			if (pwrite64(pgc->pgc_fd, str, len, off + ndx) != len)				return (1);		}	}	if (P->status.pr_dmodel == PR_MODEL_ILP32) {		Elf32_Shdr shdr;		bzero(&shdr, sizeof (shdr));		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);		shdr.sh_size = size;		shdr.sh_offset = *pgc->pgc_doff;		shdr.sh_addralign = 1;		shdr.sh_flags = SHF_STRINGS;		shdr.sh_type = SHT_STRTAB;		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),		    *pgc->pgc_soff) != sizeof (shdr))			return (1);		*pgc->pgc_soff += sizeof (shdr);#ifdef _LP64	} else {		Elf64_Shdr shdr;		bzero(&shdr, sizeof (shdr));		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);		shdr.sh_size = size;		shdr.sh_offset = *pgc->pgc_doff;		shdr.sh_addralign = 1;		shdr.sh_flags = SHF_STRINGS;		shdr.sh_type = SHT_STRTAB;		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),		    *pgc->pgc_soff) != sizeof (shdr))			return (1);		*pgc->pgc_soff += sizeof (shdr);#endif	/* _LP64 */	}	*pgc->pgc_doff += roundup(size, 8);	return (0);}/* * Don't explicity stop the process; that's up to the consumer. */intPfgcore(struct ps_prochandle *P, int fd, core_content_t content){	char plat[SYS_NMLN];	char zonename[ZONENAME_MAX];	int platlen = -1;	pgcore_t pgc;	off64_t poff, soff, doff, boff;	struct utsname uts;	uint_t nphdrs, nshdrs;	if (ftruncate64(fd, 0) != 0)		return (-1);	if (content == CC_CONTENT_INVALID) {		errno = EINVAL;		return (-1);	}	/*	 * Cache the mappings and other useful data.	 */	(void) Prd_agent(P);	(void) Ppsinfo(P);	pgc.P = P;	pgc.pgc_fd = fd;	pgc.pgc_poff = &poff;	pgc.pgc_soff = &soff;	pgc.pgc_doff = &doff;	pgc.pgc_content = content;	pgc.pgc_chunksz = PAGESIZE;	if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL)		return (-1);	shstrtab_init(&pgc.pgc_shstrtab);	/*	 * There are two PT_NOTE program headers for ancillary data, and	 * one for each mapping.	 */	nphdrs = 2 + P->map_count;	nshdrs = count_sections(&pgc);	(void) Pplatform(P, plat, sizeof (plat));	platlen = strlen(plat) + 1;	Preadauxvec(P);	(void) Puname(P, &uts);	if (Pzonename(P, zonename, sizeof (zonename)) == NULL)		zonename[0] = '\0';	/*	 * Set up the ELF header.	 */	if (P->status.pr_dmodel == PR_MODEL_ILP32) {		Elf32_Ehdr ehdr;		bzero(&ehdr, sizeof (ehdr));		ehdr.e_ident[EI_MAG0] = ELFMAG0;

⌨️ 快捷键说明

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