Print this page
13925 core files should include DWARF (fix mismerge)
13925 core files should include DWARF
Reviewed by: Rich Lowe <richlowe@richlowe.net>
Reviewed by: C Fraire <cfraire@me.com>
Reviewed by: Adam Leventhal <adam.leventhal@gmail.com>
Approved by: Dan McDonald <danmcd@joyent.com>


  52 #include <sys/auxv.h>
  53 #include <sys/exec.h>
  54 #include <sys/prsystm.h>
  55 #include <vm/as.h>
  56 #include <vm/rm.h>
  57 #include <vm/seg.h>
  58 #include <vm/seg_vn.h>
  59 #include <sys/modctl.h>
  60 #include <sys/systeminfo.h>
  61 #include <sys/vmparam.h>
  62 #include <sys/machelf.h>
  63 #include <sys/shm_impl.h>
  64 #include <sys/archsystm.h>
  65 #include <sys/fasttrap.h>
  66 #include <sys/brand.h>
  67 #include "elf_impl.h"
  68 #include <sys/sdt.h>
  69 #include <sys/siginfo.h>
  70 #include <sys/random.h>
  71 


  72 #if defined(__x86)
  73 #include <sys/comm_page_util.h>
  74 #include <sys/fp.h>
  75 #endif /* defined(__x86) */
  76 
  77 
  78 extern int at_flags;
  79 extern volatile size_t aslr_max_brk_skew;
  80 
  81 #define ORIGIN_STR      "ORIGIN"
  82 #define ORIGIN_STR_SIZE 6
  83 
  84 static int getelfhead(vnode_t *, cred_t *, Ehdr *, uint_t *, uint_t *,
  85     uint_t *);
  86 static int getelfphdr(vnode_t *, cred_t *, const Ehdr *, uint_t, caddr_t *,
  87     size_t *);
  88 static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, uint_t, uint_t,
  89     caddr_t *, size_t *, caddr_t *, size_t *);
  90 static size_t elfsize(const Ehdr *, uint_t, const caddr_t, uintptr_t *);
  91 static int mapelfexec(vnode_t *, Ehdr *, uint_t, caddr_t, Phdr **, Phdr **,
  92     Phdr **, Phdr **, Phdr *, caddr_t *, caddr_t *, intptr_t *, uintptr_t *,
  93     size_t, size_t *, size_t *);
  94 
  95 #ifdef _ELF32_COMPAT
  96 /* Link against the non-compat instances when compiling the 32-bit version. */
  97 extern size_t elf_datasz_max;
  98 extern size_t elf_zeropg_sz;
  99 extern void elf_ctx_resize_scratch(elf_core_ctx_t *, size_t);
 100 extern uint_t elf_nphdr_max;
 101 extern uint_t elf_nshdr_max;
 102 extern size_t elf_shstrtab_max;
 103 #else
 104 size_t elf_datasz_max = 1 * 1024 * 1024;
 105 size_t elf_zeropg_sz = 4 * 1024;
 106 uint_t elf_nphdr_max = 1000;
 107 uint_t elf_nshdr_max = 10000;
 108 size_t elf_shstrtab_max = 100 * 1024;
 109 #endif
 110 
 111 
 112 
 113 typedef enum {
 114         STR_CTF,
 115         STR_SYMTAB,
 116         STR_DYNSYM,
 117         STR_STRTAB,
 118         STR_DYNSTR,
 119         STR_SHSTRTAB,
 120         STR_NUM
 121 } shstrtype_t;
 122 
 123 static const char *shstrtab_data[] = {
 124         ".SUNW_ctf",
 125         ".symtab",
 126         ".dynsym",
 127         ".strtab",
 128         ".dynstr",
 129         ".shstrtab"
 130 };
 131 
 132 typedef struct shstrtab {
 133         uint_t  sst_ndx[STR_NUM];
 134         uint_t  sst_cur;
 135 } shstrtab_t;
 136 
 137 static void
 138 shstrtab_init(shstrtab_t *s)
 139 {
 140         bzero(&s->sst_ndx, sizeof (s->sst_ndx));
 141         s->sst_cur = 1;
 142 }
 143 
 144 static uint_t
 145 shstrtab_ndx(shstrtab_t *s, shstrtype_t type)
 146 {
 147         uint_t ret;
 148 
 149         if ((ret = s->sst_ndx[type]) != 0)
 150                 return (ret);
 151 
 152         ret = s->sst_ndx[type] = s->sst_cur;
 153         s->sst_cur += strlen(shstrtab_data[type]) + 1;
 154 
 155         return (ret);
 156 }
 157 
 158 static size_t
 159 shstrtab_size(const shstrtab_t *s)
 160 {
 161         return (s->sst_cur);
 162 }
 163 
 164 static void
 165 shstrtab_dump(const shstrtab_t *s, char *buf)
 166 {
 167         uint_t i, ndx;
 168 
 169         *buf = '\0';
 170         for (i = 0; i < STR_NUM; i++) {
 171                 if ((ndx = s->sst_ndx[i]) != 0)
 172                         (void) strcpy(buf + ndx, shstrtab_data[i]);
 173         }
 174 }
 175 
 176 static int
 177 dtrace_safe_phdr(Phdr *phdrp, struct uarg *args, uintptr_t base)
 178 {
 179         ASSERT(phdrp->p_type == PT_SUNWDTRACE);
 180 
 181         /*
 182          * See the comment in fasttrap.h for information on how to safely
 183          * update this program header.
 184          */
 185         if (phdrp->p_memsz < PT_SUNWDTRACE_SIZE ||
 186             (phdrp->p_flags & (PF_R | PF_W | PF_X)) != (PF_R | PF_W | PF_X))
 187                 return (-1);
 188 
 189         args->thrptr = phdrp->p_vaddr + base;
 190 
 191         return (0);
 192 }
 193 
 194 static int
 195 handle_secflag_dt(proc_t *p, uint_t dt, uint_t val)


1957                     UIO_SYSSPACE, 0, (rlim64_t)0, credp, &resid) != 0 ||
1958                     resid >= len || resid < 0 ||
1959                     core_write(dst_vp, UIO_SYSSPACE, (offset_t)(doff + off),
1960                     buf, len - resid, ctx->ecc_rlimit, credp) != 0) {
1961                         dst->sh_size = 0;
1962                         dst->sh_offset = 0;
1963                         return;
1964                 }
1965 
1966                 ASSERT(n >= len - resid);
1967 
1968                 n -= len - resid;
1969                 off += len - resid;
1970         }
1971 
1972         ctx->ecc_doffset += src->sh_size;
1973 }
1974 
1975 /*
1976  * Walk sections for a given ELF object, counting (or copying) those of
1977  * interest (CTF, symtab, strtab).


1978  */
1979 static uint_t
1980 elf_process_obj_scns(elf_core_ctx_t *ctx, vnode_t *mvp, caddr_t saddr,
1981     Shdr *v, uint_t idx, uint_t remain, shstrtab_t *shstrtab)
1982 {
1983         Ehdr ehdr;
1984         const core_content_t content = ctx->ecc_content;
1985         cred_t *credp = ctx->ecc_credp;
1986         Shdr *ctf = NULL, *symtab = NULL, *strtab = NULL;
1987         uintptr_t off = 0;
1988         uint_t nshdrs, shstrndx, nphdrs, count = 0;
1989         u_offset_t *doffp = &ctx->ecc_doffset;
1990         boolean_t ctf_link = B_FALSE;
1991         caddr_t shbase;
1992         size_t shsize, shstrsize;
1993         char *shstrbase;
1994 
1995         if ((content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)) == 0) {

1996                 return (0);
1997         }
1998 
1999         if (getelfhead(mvp, credp, &ehdr, &nshdrs, &shstrndx, &nphdrs) != 0 ||
2000             getelfshdr(mvp, credp, &ehdr, nshdrs, shstrndx, &shbase, &shsize,
2001             &shstrbase, &shstrsize) != 0) {
2002                 return (0);
2003         }
2004 
2005         /* Starting at index 1 skips SHT_NULL which is expected at index 0 */
2006         off = ehdr.e_shentsize;
2007         for (uint_t i = 1; i < nshdrs; i++, off += ehdr.e_shentsize) {
2008                 Shdr *shdr, *symchk = NULL, *strchk;
2009                 const char *name;
2010 
2011                 shdr = (Shdr *)(shbase + off);
2012                 if (shdr->sh_name >= shstrsize || shdr->sh_type == SHT_NULL)
2013                         continue;
2014 
2015                 name = shstrbase + shdr->sh_name;
2016 
2017                 if (ctf == NULL &&
2018                     (content & CC_CONTENT_CTF) != 0 &&
2019                     strcmp(name, shstrtab_data[STR_CTF]) == 0) {
2020                         ctf = shdr;
2021                         if (ctf->sh_link != 0 && ctf->sh_link < nshdrs) {
2022                                 /* check linked symtab below */
2023                                 symchk = (Shdr *)(shbase +
2024                                     shdr->sh_link * ehdr.e_shentsize);
2025                                 ctf_link = B_TRUE;
2026                         } else {
2027                                 continue;
2028                         }
2029                 } else if (symtab == NULL &&
2030                     (content & CC_CONTENT_SYMTAB) != 0 &&
2031                     strcmp(name, shstrtab_data[STR_SYMTAB]) == 0) {
2032                         symchk = shdr;














































2033                 } else {
2034                         continue;
2035                 }
2036 
2037                 ASSERT(symchk != NULL);
2038                 if ((symchk->sh_type != SHT_DYNSYM &&
2039                     symchk->sh_type != SHT_SYMTAB) ||
2040                     symchk->sh_link == 0 || symchk->sh_link >= nshdrs) {
2041                         ctf_link = B_FALSE;
2042                         continue;
2043                 }
2044                 strchk = (Shdr *)(shbase + symchk->sh_link * ehdr.e_shentsize);
2045                 if (strchk->sh_type != SHT_STRTAB) {
2046                         ctf_link = B_FALSE;
2047                         continue;
2048                 }
2049                 symtab = symchk;
2050                 strtab = strchk;
2051 
2052                 if (symtab != NULL && ctf != NULL) {

2053                         /* No other shdrs are of interest at this point */
2054                         break;
2055                 }
2056         }
2057 
2058         if (ctf != NULL)
2059                 count += 1;
2060         if (symtab != NULL)
2061                 count += 2;

2062         if (v == NULL || count == 0 || count > remain) {
2063                 count = MIN(count, remain);
2064                 goto done;
2065         }
2066 
2067         /* output CTF section */
2068         if (ctf != NULL) {
2069                 elf_ctx_resize_scratch(ctx, ctf->sh_size);
2070 
2071                 v[idx].sh_name = shstrtab_ndx(shstrtab, STR_CTF);





2072                 v[idx].sh_addr = (Addr)(uintptr_t)saddr;
2073                 v[idx].sh_type = SHT_PROGBITS;
2074                 v[idx].sh_addralign = 4;
2075                 *doffp = roundup(*doffp, v[idx].sh_addralign);
2076                 v[idx].sh_offset = *doffp;
2077                 v[idx].sh_size = ctf->sh_size;
2078 
2079                 if (ctf_link) {
2080                         /*
2081                          * The linked symtab (and strtab) will be output
2082                          * immediately after this CTF section.  Its shdr index
2083                          * directly follows this one.
2084                          */
2085                         v[idx].sh_link = idx + 1;
2086                         ASSERT(symtab != NULL);
2087                 } else {
2088                         v[idx].sh_link = 0;
2089                 }
2090                 elf_copy_scn(ctx, ctf, mvp, &v[idx]);
2091                 idx++;
2092         }
2093 
2094         /* output SYMTAB/STRTAB sections */
2095         if (symtab != NULL) {
2096                 uint_t symtab_name, strtab_name;
2097 
2098                 elf_ctx_resize_scratch(ctx,
2099                     MAX(symtab->sh_size, strtab->sh_size));
2100 
2101                 if (symtab->sh_type == SHT_DYNSYM) {
2102                         symtab_name = shstrtab_ndx(shstrtab, STR_DYNSYM);
2103                         strtab_name = shstrtab_ndx(shstrtab, STR_DYNSTR);





2104                 } else {
2105                         symtab_name = shstrtab_ndx(shstrtab, STR_SYMTAB);
2106                         strtab_name = shstrtab_ndx(shstrtab, STR_STRTAB);




2107                 }

2108 
2109                 v[idx].sh_name = symtab_name;
2110                 v[idx].sh_type = symtab->sh_type;
2111                 v[idx].sh_addr = symtab->sh_addr;
2112                 if (ehdr.e_type == ET_DYN || v[idx].sh_addr == 0)
2113                         v[idx].sh_addr += (Addr)(uintptr_t)saddr;
2114                 v[idx].sh_addralign = symtab->sh_addralign;
2115                 *doffp = roundup(*doffp, v[idx].sh_addralign);
2116                 v[idx].sh_offset = *doffp;
2117                 v[idx].sh_size = symtab->sh_size;
2118                 v[idx].sh_link = idx + 1;
2119                 v[idx].sh_entsize = symtab->sh_entsize;
2120                 v[idx].sh_info = symtab->sh_info;
2121 
2122                 elf_copy_scn(ctx, symtab, mvp, &v[idx]);
2123                 idx++;
2124 
2125                 v[idx].sh_name = strtab_name;
2126                 v[idx].sh_type = SHT_STRTAB;
2127                 v[idx].sh_flags = SHF_STRINGS;


2147  * Walk mappings in process address space, examining those which correspond to
2148  * loaded objects.  It is called twice from elfcore: Once to simply count
2149  * relevant sections, and again later to copy those sections once an adequate
2150  * buffer has been allocated for the shdr details.
2151  */
2152 static int
2153 elf_process_scns(elf_core_ctx_t *ctx, Shdr *v, uint_t nv, uint_t *nshdrsp)
2154 {
2155         vnode_t *lastvp = NULL;
2156         struct seg *seg;
2157         uint_t idx = 0, remain;
2158         shstrtab_t shstrtab;
2159         struct as *as = ctx->ecc_p->p_as;
2160         int error = 0;
2161 
2162         ASSERT(AS_WRITE_HELD(as));
2163 
2164         if (v != NULL) {
2165                 ASSERT(nv != 0);
2166 
2167                 shstrtab_init(&shstrtab);

2168                 remain = nv;
2169         } else {
2170                 ASSERT(nv == 0);
2171 
2172                 /*
2173                  * The shdrs are being counted, rather than outputting them
2174                  * into a buffer.  Leave room for two entries: the SHT_NULL at
2175                  * index 0 and the shstrtab at the end.
2176                  */
2177                 remain = UINT_MAX - 2;
2178         }
2179 
2180         /* Per the ELF spec, shdr index 0 is reserved. */
2181         idx = 1;
2182         for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
2183                 vnode_t *mvp;
2184                 void *tmp = NULL;
2185                 caddr_t saddr = seg->s_base, naddr, eaddr;
2186                 size_t segsize;
2187                 uint_t count, prot;


2195                  */
2196                 if (seg->s_ops != &segvn_ops ||
2197                     SEGOP_GETVP(seg, seg->s_base, &mvp) != 0 ||
2198                     mvp == lastvp || mvp == NULL || mvp->v_type != VREG ||
2199                     (segsize = pr_getsegsize(seg, 1)) == 0)
2200                         continue;
2201 
2202                 eaddr = saddr + segsize;
2203                 prot = pr_getprot(seg, 1, &tmp, &saddr, &naddr, eaddr);
2204                 pr_getprot_done(&tmp);
2205 
2206                 /*
2207                  * Skip this segment unless the protection bits look like
2208                  * what we'd expect for a text segment.
2209                  */
2210                 if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
2211                         continue;
2212 
2213                 count = elf_process_obj_scns(ctx, mvp, saddr, v, idx, remain,
2214                     &shstrtab);




2215 
2216                 ASSERT(count <= remain);
2217                 ASSERT(v == NULL || (idx + count) < nv);
2218 
2219                 remain -= count;
2220                 idx += count;
2221                 lastvp = mvp;
2222         }
2223 
2224         if (v == NULL) {
2225                 if (idx == 1) {
2226                         *nshdrsp = 0;
2227                 } else {
2228                         /* Include room for the shrstrtab at the end */
2229                         *nshdrsp = idx + 1;
2230                 }

2231                 return (0);
2232         }
2233 
2234         if (idx != nv - 1) {
2235                 cmn_err(CE_WARN, "elfcore: core dump failed for "
2236                     "process %d; address space is changing",
2237                     ctx->ecc_p->p_pid);
2238                 return (EIO);

2239         }
2240 
2241         v[idx].sh_name = shstrtab_ndx(&shstrtab, STR_SHSTRTAB);




2242         v[idx].sh_size = shstrtab_size(&shstrtab);
2243         v[idx].sh_addralign = 1;
2244         v[idx].sh_offset = ctx->ecc_doffset;
2245         v[idx].sh_flags = SHF_STRINGS;
2246         v[idx].sh_type = SHT_STRTAB;
2247 
2248         elf_ctx_resize_scratch(ctx, v[idx].sh_size);
2249         VERIFY3U(ctx->ecc_bufsz, >=, v[idx].sh_size);
2250         shstrtab_dump(&shstrtab, ctx->ecc_buf);
2251 
2252         error = core_write(ctx->ecc_vp, UIO_SYSSPACE, ctx->ecc_doffset,
2253             ctx->ecc_buf, v[idx].sh_size, ctx->ecc_rlimit, ctx->ecc_credp);
2254         if (error == 0) {
2255                 ctx->ecc_doffset += v[idx].sh_size;
2256         }
2257 



2258         return (error);
2259 }
2260 
2261 int
2262 elfcore(vnode_t *vp, proc_t *p, cred_t *credp, rlim64_t rlimit, int sig,
2263     core_content_t content)
2264 {
2265         u_offset_t poffset, soffset, doffset;
2266         int error;
2267         uint_t i, nphdrs, nshdrs;
2268         struct seg *seg;
2269         struct as *as = p->p_as;
2270         void *bigwad, *zeropg = NULL;
2271         size_t bigsize, phdrsz, shdrsz;
2272         Ehdr *ehdr;
2273         Phdr *phdr;
2274         Shdr shdr0;
2275         caddr_t brkbase, stkbase;
2276         size_t brksize, stksize;
2277         boolean_t overflowed = B_FALSE, retried = B_FALSE;


2285                 .ecc_doffset = 0,
2286                 .ecc_buf = NULL,
2287                 .ecc_bufsz = 0
2288         };
2289 
2290 top:
2291         /*
2292          * Make sure we have everything we need (registers, etc.).
2293          * All other lwps have already stopped and are in an orderly state.
2294          */
2295         ASSERT(p == ttoproc(curthread));
2296         prstop(0, 0);
2297 
2298         AS_LOCK_ENTER(as, RW_WRITER);
2299         nphdrs = prnsegs(as, 0) + 2;            /* two CORE note sections */
2300 
2301         /*
2302          * Count the number of section headers we're going to need.
2303          */
2304         nshdrs = 0;
2305         if (content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)) {
2306                 VERIFY0(elf_process_scns(&ctx, NULL, 0, &nshdrs));
2307         }
2308         AS_LOCK_EXIT(as);
2309 
2310         /*
2311          * The core file contents may require zero section headers, but if
2312          * we overflow the 16 bits allotted to the program header count in
2313          * the ELF header, we'll need that program header at index zero.
2314          */
2315         if (nshdrs == 0 && nphdrs >= PN_XNUM) {
2316                 nshdrs = 1;
2317         }
2318 
2319         /*
2320          * Allocate a buffer which is sized adequately to hold the ehdr, phdrs
2321          * or shdrs needed to produce the core file.  It is used for the three
2322          * tasks sequentially, not simultaneously, so it does not need space
2323          * for all three data at once, only the largest one.

2324          */
2325         VERIFY(nphdrs >= 2);
2326         phdrsz = nphdrs * sizeof (Phdr);
2327         shdrsz = nshdrs * sizeof (Shdr);
2328         bigsize = MAX(sizeof (Ehdr), MAX(phdrsz, shdrsz));
2329         bigwad = kmem_alloc(bigsize, KM_SLEEP);
2330 
2331         ehdr = (Ehdr *)bigwad;
2332         bzero(ehdr, sizeof (*ehdr));
2333 
2334         ehdr->e_ident[EI_MAG0] = ELFMAG0;
2335         ehdr->e_ident[EI_MAG1] = ELFMAG1;
2336         ehdr->e_ident[EI_MAG2] = ELFMAG2;
2337         ehdr->e_ident[EI_MAG3] = ELFMAG3;
2338         ehdr->e_ident[EI_CLASS] = ELFCLASS;
2339         ehdr->e_type = ET_CORE;
2340 
2341 #if !defined(_LP64) || defined(_ELF32_COMPAT)
2342 
2343 #if defined(__sparc)




  52 #include <sys/auxv.h>
  53 #include <sys/exec.h>
  54 #include <sys/prsystm.h>
  55 #include <vm/as.h>
  56 #include <vm/rm.h>
  57 #include <vm/seg.h>
  58 #include <vm/seg_vn.h>
  59 #include <sys/modctl.h>
  60 #include <sys/systeminfo.h>
  61 #include <sys/vmparam.h>
  62 #include <sys/machelf.h>
  63 #include <sys/shm_impl.h>
  64 #include <sys/archsystm.h>
  65 #include <sys/fasttrap.h>
  66 #include <sys/brand.h>
  67 #include "elf_impl.h"
  68 #include <sys/sdt.h>
  69 #include <sys/siginfo.h>
  70 #include <sys/random.h>
  71 
  72 #include <core_shstrtab.h>
  73 
  74 #if defined(__x86)
  75 #include <sys/comm_page_util.h>
  76 #include <sys/fp.h>
  77 #endif /* defined(__x86) */
  78 
  79 
  80 extern int at_flags;
  81 extern volatile size_t aslr_max_brk_skew;
  82 
  83 #define ORIGIN_STR      "ORIGIN"
  84 #define ORIGIN_STR_SIZE 6
  85 
  86 static int getelfhead(vnode_t *, cred_t *, Ehdr *, uint_t *, uint_t *,
  87     uint_t *);
  88 static int getelfphdr(vnode_t *, cred_t *, const Ehdr *, uint_t, caddr_t *,
  89     size_t *);
  90 static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, uint_t, uint_t,
  91     caddr_t *, size_t *, caddr_t *, size_t *);
  92 static size_t elfsize(const Ehdr *, uint_t, const caddr_t, uintptr_t *);
  93 static int mapelfexec(vnode_t *, Ehdr *, uint_t, caddr_t, Phdr **, Phdr **,
  94     Phdr **, Phdr **, Phdr *, caddr_t *, caddr_t *, intptr_t *, uintptr_t *,
  95     size_t, size_t *, size_t *);
  96 
  97 #ifdef _ELF32_COMPAT
  98 /* Link against the non-compat instances when compiling the 32-bit version. */
  99 extern size_t elf_datasz_max;
 100 extern size_t elf_zeropg_sz;
 101 extern void elf_ctx_resize_scratch(elf_core_ctx_t *, size_t);
 102 extern uint_t elf_nphdr_max;
 103 extern uint_t elf_nshdr_max;
 104 extern size_t elf_shstrtab_max;
 105 #else
 106 size_t elf_datasz_max = 1 * 1024 * 1024;
 107 size_t elf_zeropg_sz = 4 * 1024;
 108 uint_t elf_nphdr_max = 1000;
 109 uint_t elf_nshdr_max = 10000;
 110 size_t elf_shstrtab_max = 100 * 1024;
 111 #endif
 112 

































































 113 static int
 114 dtrace_safe_phdr(Phdr *phdrp, struct uarg *args, uintptr_t base)
 115 {
 116         ASSERT(phdrp->p_type == PT_SUNWDTRACE);
 117 
 118         /*
 119          * See the comment in fasttrap.h for information on how to safely
 120          * update this program header.
 121          */
 122         if (phdrp->p_memsz < PT_SUNWDTRACE_SIZE ||
 123             (phdrp->p_flags & (PF_R | PF_W | PF_X)) != (PF_R | PF_W | PF_X))
 124                 return (-1);
 125 
 126         args->thrptr = phdrp->p_vaddr + base;
 127 
 128         return (0);
 129 }
 130 
 131 static int
 132 handle_secflag_dt(proc_t *p, uint_t dt, uint_t val)


1894                     UIO_SYSSPACE, 0, (rlim64_t)0, credp, &resid) != 0 ||
1895                     resid >= len || resid < 0 ||
1896                     core_write(dst_vp, UIO_SYSSPACE, (offset_t)(doff + off),
1897                     buf, len - resid, ctx->ecc_rlimit, credp) != 0) {
1898                         dst->sh_size = 0;
1899                         dst->sh_offset = 0;
1900                         return;
1901                 }
1902 
1903                 ASSERT(n >= len - resid);
1904 
1905                 n -= len - resid;
1906                 off += len - resid;
1907         }
1908 
1909         ctx->ecc_doffset += src->sh_size;
1910 }
1911 
1912 /*
1913  * Walk sections for a given ELF object, counting (or copying) those of
1914  * interest (CTF, symtab, strtab, DWARF debug).
1915  *
1916  * Returns UINT_MAX upon low-memory.
1917  */
1918 static uint_t
1919 elf_process_obj_scns(elf_core_ctx_t *ctx, vnode_t *mvp, caddr_t saddr,
1920     Shdr *v, uint_t idx, uint_t remain, shstrtab_t *shstrtab)
1921 {
1922         Ehdr ehdr;
1923         const core_content_t content = ctx->ecc_content;
1924         cred_t *credp = ctx->ecc_credp;
1925         Shdr *ctf = NULL, *symtab = NULL, *strtab = NULL;
1926         uintptr_t off = 0;
1927         uint_t nshdrs, shstrndx, nphdrs, count = 0;
1928         u_offset_t *doffp = &ctx->ecc_doffset;
1929         boolean_t ctf_link = B_FALSE;
1930         caddr_t shbase;
1931         size_t shsize, shstrsize;
1932         char *shstrbase;
1933 
1934         if ((content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB | CC_CONTENT_DEBUG))
1935             == 0) {
1936                 return (0);
1937         }
1938 
1939         if (getelfhead(mvp, credp, &ehdr, &nshdrs, &shstrndx, &nphdrs) != 0 ||
1940             getelfshdr(mvp, credp, &ehdr, nshdrs, shstrndx, &shbase, &shsize,
1941             &shstrbase, &shstrsize) != 0) {
1942                 return (0);
1943         }
1944 
1945         /* Starting at index 1 skips SHT_NULL which is expected at index 0 */
1946         off = ehdr.e_shentsize;
1947         for (uint_t i = 1; i < nshdrs; i++, off += ehdr.e_shentsize) {
1948                 Shdr *shdr, *symchk = NULL, *strchk;
1949                 const char *name;
1950 
1951                 shdr = (Shdr *)(shbase + off);
1952                 if (shdr->sh_name >= shstrsize || shdr->sh_type == SHT_NULL)
1953                         continue;
1954 
1955                 name = shstrbase + shdr->sh_name;
1956 
1957                 if (ctf == NULL &&
1958                     (content & CC_CONTENT_CTF) != 0 &&
1959                     strcmp(name, shstrtab_data[STR_CTF]) == 0) {
1960                         ctf = shdr;
1961                         if (ctf->sh_link != 0 && ctf->sh_link < nshdrs) {
1962                                 /* check linked symtab below */
1963                                 symchk = (Shdr *)(shbase +
1964                                     shdr->sh_link * ehdr.e_shentsize);
1965                                 ctf_link = B_TRUE;
1966                         } else {
1967                                 continue;
1968                         }
1969                 } else if (symtab == NULL &&
1970                     (content & CC_CONTENT_SYMTAB) != 0 &&
1971                     strcmp(name, shstrtab_data[STR_SYMTAB]) == 0) {
1972                         symchk = shdr;
1973                 } else if ((content & CC_CONTENT_DEBUG) != 0 &&
1974                     strncmp(name, ".debug_", strlen(".debug_")) == 0) {
1975                         /*
1976                          * The design of the above check is intentional.  In
1977                          * particular, we want to capture any sections that
1978                          * begin with '.debug_' for a few reasons:
1979                          *
1980                          * 1) Various revisions to the DWARF spec end up
1981                          * changing the set of section headers that
1982                          * exist. This ensures that we don't need to change
1983                          * the kernel to get a new version.
1984                          *
1985                          * 2) Other software uses .debug_ sections for things
1986                          * which aren't DWARF. This allows them to be captured
1987                          * as well.
1988                          *
1989                          * Because of this, we emit straight here, unlike the
1990                          * other two sections where we wait until we're done
1991                          * scanning.
1992                          */
1993 
1994                         /* We're only counting, don't emit! */
1995                         if (v == NULL) {
1996                                 count++;
1997                                 continue;
1998                         }
1999 
2000                         elf_ctx_resize_scratch(ctx, shdr->sh_size);
2001                         if (!shstrtab_ndx(shstrtab, name, &v[idx].sh_name)) {
2002                                 count = UINT_MAX;
2003                                 goto done;
2004                         }
2005                         v[idx].sh_addr = (Addr)(uintptr_t)saddr;
2006                         v[idx].sh_type = shdr->sh_type;
2007                         v[idx].sh_addralign = shdr->sh_addralign;
2008                         *doffp = roundup(*doffp, v[idx].sh_addralign);
2009                         v[idx].sh_offset = *doffp;
2010                         v[idx].sh_size = shdr->sh_size;
2011                         v[idx].sh_link = 0;
2012                         v[idx].sh_entsize = shdr->sh_entsize;
2013                         v[idx].sh_info = shdr->sh_info;
2014 
2015                         elf_copy_scn(ctx, shdr, mvp, &v[idx]);
2016                         count++;
2017                         idx++;
2018                         continue;
2019                 } else {
2020                         continue;
2021                 }
2022 
2023                 ASSERT(symchk != NULL);
2024                 if ((symchk->sh_type != SHT_DYNSYM &&
2025                     symchk->sh_type != SHT_SYMTAB) ||
2026                     symchk->sh_link == 0 || symchk->sh_link >= nshdrs) {
2027                         ctf_link = B_FALSE;
2028                         continue;
2029                 }
2030                 strchk = (Shdr *)(shbase + symchk->sh_link * ehdr.e_shentsize);
2031                 if (strchk->sh_type != SHT_STRTAB) {
2032                         ctf_link = B_FALSE;
2033                         continue;
2034                 }
2035                 symtab = symchk;
2036                 strtab = strchk;
2037 
2038                 if (symtab != NULL && ctf != NULL &&
2039                     (content & CC_CONTENT_DEBUG) == 0) {
2040                         /* No other shdrs are of interest at this point */
2041                         break;
2042                 }
2043         }
2044 
2045         if (ctf != NULL)
2046                 count += 1;
2047         if (symtab != NULL)
2048                 count += 2;
2049 
2050         if (v == NULL || count == 0 || count > remain) {
2051                 count = MIN(count, remain);
2052                 goto done;
2053         }
2054 
2055         /* output CTF section */
2056         if (ctf != NULL) {
2057                 elf_ctx_resize_scratch(ctx, ctf->sh_size);
2058 
2059                 if (!shstrtab_ndx(shstrtab, shstrtab_data[STR_CTF],
2060                     &v[idx].sh_name)) {
2061                         count = UINT_MAX;
2062                         goto done;
2063                 }
2064 
2065                 v[idx].sh_addr = (Addr)(uintptr_t)saddr;
2066                 v[idx].sh_type = SHT_PROGBITS;
2067                 v[idx].sh_addralign = 4;
2068                 *doffp = roundup(*doffp, v[idx].sh_addralign);
2069                 v[idx].sh_offset = *doffp;
2070                 v[idx].sh_size = ctf->sh_size;
2071 
2072                 if (ctf_link) {
2073                         /*
2074                          * The linked symtab (and strtab) will be output
2075                          * immediately after this CTF section.  Its shdr index
2076                          * directly follows this one.
2077                          */
2078                         v[idx].sh_link = idx + 1;
2079                         ASSERT(symtab != NULL);
2080                 } else {
2081                         v[idx].sh_link = 0;
2082                 }
2083                 elf_copy_scn(ctx, ctf, mvp, &v[idx]);
2084                 idx++;
2085         }
2086 
2087         /* output SYMTAB/STRTAB sections */
2088         if (symtab != NULL) {
2089                 uint_t symtab_name, strtab_name;
2090 
2091                 elf_ctx_resize_scratch(ctx,
2092                     MAX(symtab->sh_size, strtab->sh_size));
2093 
2094                 if (symtab->sh_type == SHT_DYNSYM) {
2095                         if (!shstrtab_ndx(shstrtab, shstrtab_data[STR_DYNSYM],
2096                             &symtab_name) ||
2097                             !shstrtab_ndx(shstrtab, shstrtab_data[STR_DYNSTR],
2098                             &strtab_name)) {
2099                                 count = UINT_MAX;
2100                                 goto done;
2101                         }
2102                 } else {
2103                         if (!shstrtab_ndx(shstrtab, shstrtab_data[STR_SYMTAB],
2104                             &symtab_name) ||
2105                             !shstrtab_ndx(shstrtab, shstrtab_data[STR_STRTAB],
2106                             &strtab_name)) {
2107                                 count = UINT_MAX;
2108                                 goto done;
2109                         }
2110                 }
2111 
2112                 v[idx].sh_name = symtab_name;
2113                 v[idx].sh_type = symtab->sh_type;
2114                 v[idx].sh_addr = symtab->sh_addr;
2115                 if (ehdr.e_type == ET_DYN || v[idx].sh_addr == 0)
2116                         v[idx].sh_addr += (Addr)(uintptr_t)saddr;
2117                 v[idx].sh_addralign = symtab->sh_addralign;
2118                 *doffp = roundup(*doffp, v[idx].sh_addralign);
2119                 v[idx].sh_offset = *doffp;
2120                 v[idx].sh_size = symtab->sh_size;
2121                 v[idx].sh_link = idx + 1;
2122                 v[idx].sh_entsize = symtab->sh_entsize;
2123                 v[idx].sh_info = symtab->sh_info;
2124 
2125                 elf_copy_scn(ctx, symtab, mvp, &v[idx]);
2126                 idx++;
2127 
2128                 v[idx].sh_name = strtab_name;
2129                 v[idx].sh_type = SHT_STRTAB;
2130                 v[idx].sh_flags = SHF_STRINGS;


2150  * Walk mappings in process address space, examining those which correspond to
2151  * loaded objects.  It is called twice from elfcore: Once to simply count
2152  * relevant sections, and again later to copy those sections once an adequate
2153  * buffer has been allocated for the shdr details.
2154  */
2155 static int
2156 elf_process_scns(elf_core_ctx_t *ctx, Shdr *v, uint_t nv, uint_t *nshdrsp)
2157 {
2158         vnode_t *lastvp = NULL;
2159         struct seg *seg;
2160         uint_t idx = 0, remain;
2161         shstrtab_t shstrtab;
2162         struct as *as = ctx->ecc_p->p_as;
2163         int error = 0;
2164 
2165         ASSERT(AS_WRITE_HELD(as));
2166 
2167         if (v != NULL) {
2168                 ASSERT(nv != 0);
2169 
2170                 if (!shstrtab_init(&shstrtab))
2171                         return (ENOMEM);
2172                 remain = nv;
2173         } else {
2174                 ASSERT(nv == 0);
2175 
2176                 /*
2177                  * The shdrs are being counted, rather than outputting them
2178                  * into a buffer.  Leave room for two entries: the SHT_NULL at
2179                  * index 0 and the shstrtab at the end.
2180                  */
2181                 remain = UINT_MAX - 2;
2182         }
2183 
2184         /* Per the ELF spec, shdr index 0 is reserved. */
2185         idx = 1;
2186         for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
2187                 vnode_t *mvp;
2188                 void *tmp = NULL;
2189                 caddr_t saddr = seg->s_base, naddr, eaddr;
2190                 size_t segsize;
2191                 uint_t count, prot;


2199                  */
2200                 if (seg->s_ops != &segvn_ops ||
2201                     SEGOP_GETVP(seg, seg->s_base, &mvp) != 0 ||
2202                     mvp == lastvp || mvp == NULL || mvp->v_type != VREG ||
2203                     (segsize = pr_getsegsize(seg, 1)) == 0)
2204                         continue;
2205 
2206                 eaddr = saddr + segsize;
2207                 prot = pr_getprot(seg, 1, &tmp, &saddr, &naddr, eaddr);
2208                 pr_getprot_done(&tmp);
2209 
2210                 /*
2211                  * Skip this segment unless the protection bits look like
2212                  * what we'd expect for a text segment.
2213                  */
2214                 if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
2215                         continue;
2216 
2217                 count = elf_process_obj_scns(ctx, mvp, saddr, v, idx, remain,
2218                     &shstrtab);
2219                 if (count == UINT_MAX) {
2220                         error = ENOMEM;
2221                         goto done;
2222                 }
2223 
2224                 ASSERT(count <= remain);
2225                 ASSERT(v == NULL || (idx + count) < nv);
2226 
2227                 remain -= count;
2228                 idx += count;
2229                 lastvp = mvp;
2230         }
2231 
2232         if (v == NULL) {
2233                 if (idx == 1) {
2234                         *nshdrsp = 0;
2235                 } else {
2236                         /* Include room for the shrstrtab at the end */
2237                         *nshdrsp = idx + 1;
2238                 }
2239                 /* No need to free up shstrtab so we can just return. */
2240                 return (0);
2241         }
2242 
2243         if (idx != nv - 1) {
2244                 cmn_err(CE_WARN, "elfcore: core dump failed for "
2245                     "process %d; address space is changing",
2246                     ctx->ecc_p->p_pid);
2247                 error = EIO;
2248                 goto done;
2249         }
2250 
2251         if (!shstrtab_ndx(&shstrtab, shstrtab_data[STR_SHSTRTAB],
2252             &v[idx].sh_name)) {
2253                 error = ENOMEM;
2254                 goto done;
2255         }
2256         v[idx].sh_size = shstrtab_size(&shstrtab);
2257         v[idx].sh_addralign = 1;
2258         v[idx].sh_offset = ctx->ecc_doffset;
2259         v[idx].sh_flags = SHF_STRINGS;
2260         v[idx].sh_type = SHT_STRTAB;
2261 
2262         elf_ctx_resize_scratch(ctx, v[idx].sh_size);
2263         VERIFY3U(ctx->ecc_bufsz, >=, v[idx].sh_size);
2264         shstrtab_dump(&shstrtab, ctx->ecc_buf);
2265 
2266         error = core_write(ctx->ecc_vp, UIO_SYSSPACE, ctx->ecc_doffset,
2267             ctx->ecc_buf, v[idx].sh_size, ctx->ecc_rlimit, ctx->ecc_credp);
2268         if (error == 0) {
2269                 ctx->ecc_doffset += v[idx].sh_size;
2270         }
2271 
2272 done:
2273         if (v != NULL)
2274                 shstrtab_fini(&shstrtab);
2275         return (error);
2276 }
2277 
2278 int
2279 elfcore(vnode_t *vp, proc_t *p, cred_t *credp, rlim64_t rlimit, int sig,
2280     core_content_t content)
2281 {
2282         u_offset_t poffset, soffset, doffset;
2283         int error;
2284         uint_t i, nphdrs, nshdrs;
2285         struct seg *seg;
2286         struct as *as = p->p_as;
2287         void *bigwad, *zeropg = NULL;
2288         size_t bigsize, phdrsz, shdrsz;
2289         Ehdr *ehdr;
2290         Phdr *phdr;
2291         Shdr shdr0;
2292         caddr_t brkbase, stkbase;
2293         size_t brksize, stksize;
2294         boolean_t overflowed = B_FALSE, retried = B_FALSE;


2302                 .ecc_doffset = 0,
2303                 .ecc_buf = NULL,
2304                 .ecc_bufsz = 0
2305         };
2306 
2307 top:
2308         /*
2309          * Make sure we have everything we need (registers, etc.).
2310          * All other lwps have already stopped and are in an orderly state.
2311          */
2312         ASSERT(p == ttoproc(curthread));
2313         prstop(0, 0);
2314 
2315         AS_LOCK_ENTER(as, RW_WRITER);
2316         nphdrs = prnsegs(as, 0) + 2;            /* two CORE note sections */
2317 
2318         /*
2319          * Count the number of section headers we're going to need.
2320          */
2321         nshdrs = 0;
2322         if (content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB | CC_CONTENT_DEBUG))
2323                 VERIFY0(elf_process_scns(&ctx, NULL, 0, &nshdrs));

2324         AS_LOCK_EXIT(as);
2325 
2326         /*
2327          * The core file contents may require zero section headers, but if
2328          * we overflow the 16 bits allotted to the program header count in
2329          * the ELF header, we'll need that program header at index zero.
2330          */
2331         if (nshdrs == 0 && nphdrs >= PN_XNUM) {
2332                 nshdrs = 1;
2333         }
2334 
2335         /*
2336          * Allocate a buffer which is sized adequately to hold the ehdr,
2337          * phdrs, DWARF debug, or shdrs needed to produce the core file.  It
2338          * is used for the four tasks sequentially, not simultaneously, so it
2339          * does not need space for all four data at once, only the largest
2340          * one.
2341          */
2342         VERIFY(nphdrs >= 2);
2343         phdrsz = nphdrs * sizeof (Phdr);
2344         shdrsz = nshdrs * sizeof (Shdr);
2345         bigsize = MAX(sizeof (Ehdr), MAX(phdrsz, shdrsz));
2346         bigwad = kmem_alloc(bigsize, KM_SLEEP);
2347 
2348         ehdr = (Ehdr *)bigwad;
2349         bzero(ehdr, sizeof (*ehdr));
2350 
2351         ehdr->e_ident[EI_MAG0] = ELFMAG0;
2352         ehdr->e_ident[EI_MAG1] = ELFMAG1;
2353         ehdr->e_ident[EI_MAG2] = ELFMAG2;
2354         ehdr->e_ident[EI_MAG3] = ELFMAG3;
2355         ehdr->e_ident[EI_CLASS] = ELFCLASS;
2356         ehdr->e_type = ET_CORE;
2357 
2358 #if !defined(_LP64) || defined(_ELF32_COMPAT)
2359 
2360 #if defined(__sparc)