📄 pcore.c
字号:
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 + -