xref: /illumos-gate/usr/src/lib/libproc/common/Pgcore.c (revision f1cd2b6cd01a74ce00b051c8a3028a8d47c8e5ac)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
28  * Copyright 2018 Joyent, Inc.
29  * Copyright (c) 2013 by Delphix. All rights reserved.
30  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
31  * Copyright 2024 Oxide Computer Company
32  */
33 
34 #define	_STRUCTURED_PROC	1
35 
36 #include <assert.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39 #include <string.h>
40 #include <strings.h>
41 #include <errno.h>
42 #include <procfs.h>
43 #include <priv.h>
44 #include <sys/elf.h>
45 #include <sys/machelf.h>
46 #include <sys/sysmacros.h>
47 #include <sys/systeminfo.h>
48 #include <sys/proc.h>
49 #include <sys/utsname.h>
50 #include <core_shstrtab.h>
51 
52 #include <sys/old_procfs.h>
53 
54 #include "Pcontrol.h"
55 #include "P32ton.h"
56 #include "proc_fd.h"
57 
58 typedef struct {
59 	struct ps_prochandle *P;
60 	int		pgc_fd;
61 	off64_t		*pgc_poff;
62 	off64_t		*pgc_soff;
63 	off64_t		*pgc_doff;
64 	core_content_t	pgc_content;
65 	void		*pgc_chunk;
66 	size_t		pgc_chunksz;
67 
68 	shstrtab_t	pgc_shstrtab;
69 } pgcore_t;
70 
71 typedef struct {
72 	int		fd_fd;
73 	off64_t		*fd_doff;
74 } fditer_t;
75 
76 static int
gc_pwrite64(int fd,const void * buf,size_t len,off64_t off)77 gc_pwrite64(int fd, const void *buf, size_t len, off64_t off)
78 {
79 	int err;
80 
81 	err = pwrite64(fd, buf, len, off);
82 
83 	if (err < 0)
84 		return (err);
85 
86 	/*
87 	 * We will take a page from ZFS's book here and use the otherwise
88 	 * unused EBADE to mean a short write.  Typically this will actually
89 	 * result from ENOSPC or EDQUOT, but we can't be sure.
90 	 */
91 	if (err < len) {
92 		errno = EBADE;
93 		return (-1);
94 	}
95 
96 	return (0);
97 }
98 
99 int
Pgcore(struct ps_prochandle * P,const char * fname,core_content_t content)100 Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content)
101 {
102 	int fd;
103 	int err;
104 	int saved_errno;
105 
106 	if ((fd = creat64(fname, 0666)) < 0)
107 		return (-1);
108 
109 	if ((err = Pfgcore(P, fd, content)) != 0) {
110 		saved_errno = errno;
111 		(void) close(fd);
112 		(void) unlink(fname);
113 		errno = saved_errno;
114 		return (err);
115 	}
116 
117 	return (close(fd));
118 }
119 
120 /*
121  * Since we don't want to use the old-school procfs interfaces, we use the
122  * new-style data structures we already have to construct the old-style
123  * data structures. We include these data structures in core files for
124  * backward compatability.
125  */
126 
127 static void
mkprstatus(struct ps_prochandle * P,const lwpstatus_t * lsp,const lwpsinfo_t * lip,prstatus_t * psp)128 mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp,
129     const lwpsinfo_t *lip, prstatus_t *psp)
130 {
131 	bzero(psp, sizeof (*psp));
132 
133 	if (lsp->pr_flags & PR_STOPPED)
134 		psp->pr_flags = 0x0001;
135 	if (lsp->pr_flags & PR_ISTOP)
136 		psp->pr_flags = 0x0002;
137 	if (lsp->pr_flags & PR_DSTOP)
138 		psp->pr_flags = 0x0004;
139 	if (lsp->pr_flags & PR_ASLEEP)
140 		psp->pr_flags = 0x0008;
141 	if (lsp->pr_flags & PR_FORK)
142 		psp->pr_flags = 0x0010;
143 	if (lsp->pr_flags & PR_RLC)
144 		psp->pr_flags = 0x0020;
145 	/*
146 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
147 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
148 	 */
149 	if (lsp->pr_flags & PR_PCINVAL)
150 		psp->pr_flags = 0x0080;
151 	if (lsp->pr_flags & PR_ISSYS)
152 		psp->pr_flags = 0x0100;
153 	if (lsp->pr_flags & PR_STEP)
154 		psp->pr_flags = 0x0200;
155 	if (lsp->pr_flags & PR_KLC)
156 		psp->pr_flags = 0x0400;
157 	if (lsp->pr_flags & PR_ASYNC)
158 		psp->pr_flags = 0x0800;
159 	if (lsp->pr_flags & PR_PTRACE)
160 		psp->pr_flags = 0x1000;
161 	if (lsp->pr_flags & PR_MSACCT)
162 		psp->pr_flags = 0x2000;
163 	if (lsp->pr_flags & PR_BPTADJ)
164 		psp->pr_flags = 0x4000;
165 	if (lsp->pr_flags & PR_ASLWP)
166 		psp->pr_flags = 0x8000;
167 
168 	psp->pr_why = lsp->pr_why;
169 	psp->pr_what = lsp->pr_what;
170 	psp->pr_info = lsp->pr_info;
171 	psp->pr_cursig = lsp->pr_cursig;
172 	psp->pr_nlwp = P->status.pr_nlwp;
173 	psp->pr_sigpend = P->status.pr_sigpend;
174 	psp->pr_sighold = lsp->pr_lwphold;
175 	psp->pr_altstack = lsp->pr_altstack;
176 	psp->pr_action = lsp->pr_action;
177 	psp->pr_pid = P->status.pr_pid;
178 	psp->pr_ppid = P->status.pr_ppid;
179 	psp->pr_pgrp = P->status.pr_pgid;
180 	psp->pr_sid = P->status.pr_sid;
181 	psp->pr_utime = P->status.pr_utime;
182 	psp->pr_stime = P->status.pr_stime;
183 	psp->pr_cutime = P->status.pr_cutime;
184 	psp->pr_cstime = P->status.pr_cstime;
185 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
186 	psp->pr_syscall = lsp->pr_syscall;
187 	psp->pr_nsysarg = lsp->pr_nsysarg;
188 	bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
189 	psp->pr_who = lsp->pr_lwpid;
190 	psp->pr_lwppend = lsp->pr_lwppend;
191 	psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext;
192 	psp->pr_brkbase = (caddr_t)P->status.pr_brkbase;
193 	psp->pr_brksize = P->status.pr_brksize;
194 	psp->pr_stkbase = (caddr_t)P->status.pr_stkbase;
195 	psp->pr_stksize = P->status.pr_stksize;
196 	psp->pr_processor = (short)lip->pr_onpro;
197 	psp->pr_bind = (short)lip->pr_bindpro;
198 	psp->pr_instr = lsp->pr_instr;
199 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
200 }
201 
202 static void
mkprpsinfo(struct ps_prochandle * P,prpsinfo_t * psp)203 mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp)
204 {
205 	bzero(psp, sizeof (*psp));
206 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
207 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
208 	psp->pr_zomb = (psp->pr_state == SZOMB);
209 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
210 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
211 	psp->pr_uid = P->psinfo.pr_uid;
212 	psp->pr_gid = P->psinfo.pr_gid;
213 	psp->pr_pid = P->psinfo.pr_pid;
214 	psp->pr_ppid = P->psinfo.pr_ppid;
215 	psp->pr_pgrp = P->psinfo.pr_pgid;
216 	psp->pr_sid = P->psinfo.pr_sid;
217 	psp->pr_addr = (caddr_t)P->psinfo.pr_addr;
218 	psp->pr_size = P->psinfo.pr_size;
219 	psp->pr_rssize = P->psinfo.pr_rssize;
220 	psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan;
221 	psp->pr_start = P->psinfo.pr_start;
222 	psp->pr_time = P->psinfo.pr_time;
223 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
224 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
225 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
226 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
227 	psp->pr_lttydev = P->psinfo.pr_ttydev;
228 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
229 	    sizeof (psp->pr_clname));
230 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
231 	    sizeof (psp->pr_fname));
232 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
233 	    sizeof (psp->pr_psargs));
234 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
235 	psp->pr_ctime = P->psinfo.pr_ctime;
236 	psp->pr_bysize = psp->pr_size * PAGESIZE;
237 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
238 	psp->pr_argc = P->psinfo.pr_argc;
239 	psp->pr_argv = (char **)P->psinfo.pr_argv;
240 	psp->pr_envp = (char **)P->psinfo.pr_envp;
241 	psp->pr_wstat = P->psinfo.pr_wstat;
242 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
243 	psp->pr_pctmem = P->psinfo.pr_pctmem;
244 	psp->pr_euid = P->psinfo.pr_euid;
245 	psp->pr_egid = P->psinfo.pr_egid;
246 	psp->pr_aslwpid = 0;
247 	psp->pr_dmodel = P->psinfo.pr_dmodel;
248 }
249 
250 #ifdef _LP64
251 
252 static void
mkprstatus32(struct ps_prochandle * P,const lwpstatus_t * lsp,const lwpsinfo_t * lip,prstatus32_t * psp)253 mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp,
254     const lwpsinfo_t *lip, prstatus32_t *psp)
255 {
256 	bzero(psp, sizeof (*psp));
257 
258 	if (lsp->pr_flags & PR_STOPPED)
259 		psp->pr_flags = 0x0001;
260 	if (lsp->pr_flags & PR_ISTOP)
261 		psp->pr_flags = 0x0002;
262 	if (lsp->pr_flags & PR_DSTOP)
263 		psp->pr_flags = 0x0004;
264 	if (lsp->pr_flags & PR_ASLEEP)
265 		psp->pr_flags = 0x0008;
266 	if (lsp->pr_flags & PR_FORK)
267 		psp->pr_flags = 0x0010;
268 	if (lsp->pr_flags & PR_RLC)
269 		psp->pr_flags = 0x0020;
270 	/*
271 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
272 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
273 	 */
274 	if (lsp->pr_flags & PR_PCINVAL)
275 		psp->pr_flags = 0x0080;
276 	if (lsp->pr_flags & PR_ISSYS)
277 		psp->pr_flags = 0x0100;
278 	if (lsp->pr_flags & PR_STEP)
279 		psp->pr_flags = 0x0200;
280 	if (lsp->pr_flags & PR_KLC)
281 		psp->pr_flags = 0x0400;
282 	if (lsp->pr_flags & PR_ASYNC)
283 		psp->pr_flags = 0x0800;
284 	if (lsp->pr_flags & PR_PTRACE)
285 		psp->pr_flags = 0x1000;
286 	if (lsp->pr_flags & PR_MSACCT)
287 		psp->pr_flags = 0x2000;
288 	if (lsp->pr_flags & PR_BPTADJ)
289 		psp->pr_flags = 0x4000;
290 	if (lsp->pr_flags & PR_ASLWP)
291 		psp->pr_flags = 0x8000;
292 
293 	psp->pr_why = lsp->pr_why;
294 	psp->pr_what = lsp->pr_what;
295 	siginfo_n_to_32(&lsp->pr_info, &psp->pr_info);
296 	psp->pr_cursig = lsp->pr_cursig;
297 	psp->pr_nlwp = P->status.pr_nlwp;
298 	psp->pr_sigpend = P->status.pr_sigpend;
299 	psp->pr_sighold = lsp->pr_lwphold;
300 	stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack);
301 	sigaction_n_to_32(&lsp->pr_action, &psp->pr_action);
302 	psp->pr_pid = P->status.pr_pid;
303 	psp->pr_ppid = P->status.pr_ppid;
304 	psp->pr_pgrp = P->status.pr_pgid;
305 	psp->pr_sid = P->status.pr_sid;
306 	timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime);
307 	timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime);
308 	timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime);
309 	timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime);
310 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
311 	psp->pr_syscall = lsp->pr_syscall;
312 	psp->pr_nsysarg = lsp->pr_nsysarg;
313 	bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
314 	psp->pr_who = lsp->pr_lwpid;
315 	psp->pr_lwppend = lsp->pr_lwppend;
316 	psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext;
317 	psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase;
318 	psp->pr_brksize = P->status.pr_brksize;
319 	psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase;
320 	psp->pr_stksize = P->status.pr_stksize;
321 	psp->pr_processor = (short)lip->pr_onpro;
322 	psp->pr_bind = (short)lip->pr_bindpro;
323 	psp->pr_instr = lsp->pr_instr;
324 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
325 }
326 
327 static void
mkprpsinfo32(struct ps_prochandle * P,prpsinfo32_t * psp)328 mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp)
329 {
330 	bzero(psp, sizeof (*psp));
331 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
332 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
333 	psp->pr_zomb = (psp->pr_state == SZOMB);
334 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
335 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
336 	psp->pr_uid = P->psinfo.pr_uid;
337 	psp->pr_gid = P->psinfo.pr_gid;
338 	psp->pr_pid = P->psinfo.pr_pid;
339 	psp->pr_ppid = P->psinfo.pr_ppid;
340 	psp->pr_pgrp = P->psinfo.pr_pgid;
341 	psp->pr_sid = P->psinfo.pr_sid;
342 	psp->pr_addr = (caddr32_t)P->psinfo.pr_addr;
343 	psp->pr_size = P->psinfo.pr_size;
344 	psp->pr_rssize = P->psinfo.pr_rssize;
345 	psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan;
346 	timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start);
347 	timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time);
348 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
349 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
350 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
351 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
352 	psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev);
353 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
354 	    sizeof (psp->pr_clname));
355 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
356 	    sizeof (psp->pr_fname));
357 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
358 	    sizeof (psp->pr_psargs));
359 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
360 	timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime);
361 	psp->pr_bysize = psp->pr_size * PAGESIZE;
362 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
363 	psp->pr_argc = P->psinfo.pr_argc;
364 	psp->pr_argv = (caddr32_t)P->psinfo.pr_argv;
365 	psp->pr_envp = (caddr32_t)P->psinfo.pr_envp;
366 	psp->pr_wstat = P->psinfo.pr_wstat;
367 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
368 	psp->pr_pctmem = P->psinfo.pr_pctmem;
369 	psp->pr_euid = P->psinfo.pr_euid;
370 	psp->pr_egid = P->psinfo.pr_egid;
371 	psp->pr_aslwpid = 0;
372 	psp->pr_dmodel = P->psinfo.pr_dmodel;
373 }
374 
375 #endif	/* _LP64 */
376 
377 static int
write_note(int fd,uint_t type,const void * desc,size_t descsz,off64_t * offp)378 write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp)
379 {
380 	/*
381 	 * Note headers are the same regardless of the data model of the
382 	 * ELF file; we arbitrarily use Elf64_Nhdr here.
383 	 */
384 	struct {
385 		Elf64_Nhdr nhdr;
386 		char name[8];
387 	} n;
388 
389 	bzero(&n, sizeof (n));
390 	bcopy("CORE", n.name, 4);
391 	n.nhdr.n_type = type;
392 	n.nhdr.n_namesz = 5;
393 	n.nhdr.n_descsz = roundup(descsz, 4);
394 
395 	if (gc_pwrite64(fd, &n, sizeof (n), *offp) != 0)
396 		return (-1);
397 
398 	*offp += sizeof (n);
399 
400 	if (gc_pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != 0)
401 		return (-1);
402 
403 	*offp += n.nhdr.n_descsz;
404 
405 	return (0);
406 }
407 
408 static int
old_per_lwp(void * data,const lwpstatus_t * lsp,const lwpsinfo_t * lip)409 old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
410 {
411 	pgcore_t *pgc = data;
412 	struct ps_prochandle *P = pgc->P;
413 
414 	/*
415 	 * Legacy core files don't contain information about zombie LWPs.
416 	 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure
417 	 * more cheaply.
418 	 */
419 	if (lsp == NULL)
420 		return (0);
421 
422 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
423 		prstatus_t prstatus;
424 		mkprstatus(P, lsp, lip, &prstatus);
425 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus,
426 		    sizeof (prstatus_t), pgc->pgc_doff) != 0)
427 			return (0);
428 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg,
429 		    sizeof (prfpregset_t), pgc->pgc_doff) != 0)
430 			return (1);
431 #ifdef _LP64
432 	} else {
433 		prstatus32_t pr32;
434 		prfpregset32_t pf32;
435 		mkprstatus32(P, lsp, lip, &pr32);
436 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32,
437 		    sizeof (prstatus32_t), pgc->pgc_doff) != 0)
438 			return (1);
439 		prfpregset_n_to_32(&lsp->pr_fpreg, &pf32);
440 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32,
441 		    sizeof (prfpregset32_t), pgc->pgc_doff) != 0)
442 			return (1);
443 #endif	/* _LP64 */
444 	}
445 
446 	return (0);
447 }
448 
449 static int
new_per_lwp(void * data,const lwpstatus_t * lsp,const lwpsinfo_t * lip)450 new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
451 {
452 	pgcore_t *pgc = data;
453 	struct ps_prochandle *P = pgc->P;
454 	prlwpname_t name = { 0, "" };
455 	psinfo_t ps;
456 	prxregset_t *xregs;
457 	size_t size;
458 
459 	/*
460 	 * If lsp is NULL this indicates that this is a zombie LWP in
461 	 * which case we dump only the lwpsinfo_t structure and none of
462 	 * the other ancillary LWP state data.
463 	 */
464 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
465 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
466 		    sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
467 			return (1);
468 		if (lsp == NULL)
469 			return (0);
470 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
471 		    sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
472 			return (1);
473 #ifdef _LP64
474 	} else {
475 		lwpsinfo32_t li32;
476 		lwpstatus32_t ls32;
477 		lwpsinfo_n_to_32(lip, &li32);
478 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
479 		    sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
480 			return (1);
481 		if (lsp == NULL)
482 			return (0);
483 		lwpstatus_n_to_32(lsp, &ls32);
484 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
485 		    sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
486 			return (1);
487 #endif	/* _LP64 */
488 	}
489 
490 	if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs, &size) == 0) {
491 		if (write_note(pgc->pgc_fd, NT_PRXREG, xregs, size,
492 		    pgc->pgc_doff) != 0)
493 			return (1);
494 
495 		Plwp_freexregs(P, xregs, size);
496 	}
497 
498 	if (Plwp_getname(P, lsp->pr_lwpid, name.pr_lwpname,
499 	    sizeof (name.pr_lwpname)) == 0) {
500 		name.pr_lwpid = lsp->pr_lwpid;
501 		if (write_note(pgc->pgc_fd, NT_LWPNAME, &name,
502 		    sizeof (name), pgc->pgc_doff) != 0)
503 			return (1);
504 	}
505 
506 	if (!(lsp->pr_flags & PR_AGENT))
507 		return (0);
508 
509 	if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0)
510 		return (0);
511 
512 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
513 		if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps,
514 		    sizeof (psinfo_t), pgc->pgc_doff) != 0)
515 			return (1);
516 #ifdef _LP64
517 	} else {
518 		psinfo32_t ps32;
519 		psinfo_n_to_32(&ps, &ps32);
520 		if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps32,
521 		    sizeof (psinfo32_t), pgc->pgc_doff) != 0)
522 			return (1);
523 #endif	/* _LP64 */
524 	}
525 
526 
527 	return (0);
528 }
529 
530 static int
iter_fd(void * data,const prfdinfo_t * fdinfo)531 iter_fd(void *data, const prfdinfo_t *fdinfo)
532 {
533 	fditer_t *iter = data;
534 	prfdinfo_core_t core;
535 	int ret = 0;
536 
537 	if (proc_fdinfo_to_core(fdinfo, &core) != 0)
538 		return (1);
539 
540 	ret = write_note(iter->fd_fd, NT_FDINFO, &core,
541 	    sizeof (core), iter->fd_doff);
542 
543 	if (ret != 0)
544 		return (1);
545 	return (0);
546 }
547 
548 /*
549  * Look for sections that begin with the string '.debug_'. In particular, this
550  * will catch all DWARF related sections and it will catch those that different
551  * folks use that are not related to DWARF, but still begin with this prefix
552  * (e.g. .debug_gdb_scripts). Notably though, this does not catch something like
553  * stabs (though it could). This really is filtering based on the section name,
554  * less so intent.
555  */
556 static boolean_t
is_debug_section(file_info_t * fptr,GElf_Shdr * shdr)557 is_debug_section(file_info_t *fptr, GElf_Shdr *shdr)
558 {
559 	if (shdr->sh_name == 0 || shdr->sh_name > fptr->file_shstrsz)
560 		return (B_FALSE);
561 
562 	if (strncmp(fptr->file_shstrs + shdr->sh_name, ".debug_",
563 	    strlen(".debug_")) != 0) {
564 		return (B_FALSE);
565 	}
566 
567 	return (B_TRUE);
568 }
569 
570 static uint_t
count_debug(file_info_t * fptr)571 count_debug(file_info_t *fptr)
572 {
573 	uint_t count = 0;
574 	Elf_Scn *scn = NULL;
575 
576 	if (fptr->file_elf == NULL || fptr->file_shstrsz <= 1) {
577 		return (0);
578 	}
579 
580 	while ((scn = elf_nextscn(fptr->file_elf, scn)) != NULL) {
581 		GElf_Shdr shdr;
582 
583 		if (gelf_getshdr(scn, &shdr) == NULL)
584 			continue;
585 
586 		if (is_debug_section(fptr, &shdr))
587 			count++;
588 	}
589 
590 	return (count);
591 }
592 
593 static uint_t
count_sections(pgcore_t * pgc)594 count_sections(pgcore_t *pgc)
595 {
596 	struct ps_prochandle *P = pgc->P;
597 	file_info_t *fptr;
598 	uint_t nshdrs = 0;
599 
600 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB |
601 	    CC_CONTENT_DEBUG))) {
602 		return (0);
603 	}
604 
605 	for (fptr = list_head(&P->file_head); fptr != NULL;
606 	    fptr = list_next(&P->file_head, fptr)) {
607 		int hit_symtab = 0;
608 
609 		Pbuild_file_symtab(P, fptr);
610 
611 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
612 		    Pbuild_file_ctf(P, fptr) != NULL) {
613 			sym_tbl_t *sym;
614 
615 			nshdrs++;
616 
617 			if (fptr->file_ctf_dyn) {
618 				sym = &fptr->file_dynsym;
619 			} else {
620 				sym = &fptr->file_symtab;
621 				hit_symtab = 1;
622 			}
623 
624 			if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
625 			    sym->sym_strs != NULL)
626 				nshdrs += 2;
627 		}
628 
629 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
630 		    fptr->file_symtab.sym_data_pri != NULL &&
631 		    fptr->file_symtab.sym_symn != 0 &&
632 		    fptr->file_symtab.sym_strs != NULL) {
633 			nshdrs += 2;
634 		}
635 
636 		if ((pgc->pgc_content & CC_CONTENT_DEBUG) != 0)
637 			nshdrs += count_debug(fptr);
638 	}
639 
640 	return (nshdrs == 0 ? 0 : nshdrs + 2);
641 }
642 
643 static int
write_shdr(pgcore_t * pgc,const char * 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)644 write_shdr(pgcore_t *pgc, const char *name, uint_t type, ulong_t flags,
645     uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info,
646     uintptr_t addralign, uintptr_t entsize)
647 {
648 	if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) {
649 		Elf32_Shdr shdr;
650 
651 		bzero(&shdr, sizeof (shdr));
652 		if (!shstrtab_ndx(&pgc->pgc_shstrtab, name, &shdr.sh_name)) {
653 			return (-1);
654 		}
655 		shdr.sh_type = type;
656 		shdr.sh_flags = flags;
657 		shdr.sh_addr = (Elf32_Addr)addr;
658 		shdr.sh_offset = offset;
659 		shdr.sh_size = size;
660 		shdr.sh_link = link;
661 		shdr.sh_info = info;
662 		shdr.sh_addralign = addralign;
663 		shdr.sh_entsize = entsize;
664 
665 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
666 		    *pgc->pgc_soff) != 0)
667 			return (-1);
668 
669 		*pgc->pgc_soff += sizeof (shdr);
670 #ifdef _LP64
671 	} else {
672 		Elf64_Shdr shdr;
673 
674 		bzero(&shdr, sizeof (shdr));
675 		if (!shstrtab_ndx(&pgc->pgc_shstrtab, name, &shdr.sh_name)) {
676 			return (-1);
677 		}
678 		shdr.sh_type = type;
679 		shdr.sh_flags = flags;
680 		shdr.sh_addr = addr;
681 		shdr.sh_offset = offset;
682 		shdr.sh_size = size;
683 		shdr.sh_link = link;
684 		shdr.sh_info = info;
685 		shdr.sh_addralign = addralign;
686 		shdr.sh_entsize = entsize;
687 
688 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
689 		    *pgc->pgc_soff) != 0)
690 			return (-1);
691 
692 		*pgc->pgc_soff += sizeof (shdr);
693 #endif	/* _LP64 */
694 	}
695 
696 	return (0);
697 }
698 
699 static int
dump_symtab(pgcore_t * pgc,file_info_t * fptr,uint_t index,int dynsym)700 dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
701 {
702 	sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab;
703 	shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB;
704 	shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB;
705 	uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB;
706 	size_t size;
707 	uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr;
708 
709 	if (sym->sym_data_pri == NULL || sym->sym_symn == 0 ||
710 	    sym->sym_strs == NULL)
711 		return (0);
712 
713 	size = sym->sym_hdr_pri.sh_size;
714 	if (gc_pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size,
715 	    *pgc->pgc_doff) != 0)
716 		return (-1);
717 
718 	if (write_shdr(pgc, shstrtab_data[symname], symtype, 0, addr,
719 	    *pgc->pgc_doff, size, index + 1, sym->sym_hdr_pri.sh_info,
720 	    sym->sym_hdr_pri.sh_addralign, sym->sym_hdr_pri.sh_entsize) != 0)
721 		return (-1);
722 
723 	*pgc->pgc_doff += roundup(size, 8);
724 
725 	size = sym->sym_strhdr.sh_size;
726 	if (gc_pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != 0)
727 		return (-1);
728 
729 	if (write_shdr(pgc, shstrtab_data[strname], SHT_STRTAB, SHF_STRINGS,
730 	    addr, *pgc->pgc_doff, size, 0, 0, 1, 0) != 0)
731 		return (-1);
732 
733 	*pgc->pgc_doff += roundup(size, 8);
734 
735 	return (0);
736 }
737 
738 static int
dump_debug(pgcore_t * pgc,file_info_t * fptr,uint_t * indexp)739 dump_debug(pgcore_t *pgc, file_info_t *fptr, uint_t *indexp)
740 {
741 	Elf_Scn *scn = NULL;
742 
743 	if (fptr->file_elf == NULL || fptr->file_shstrsz <= 1) {
744 		return (0);
745 	}
746 
747 	while ((scn = elf_nextscn(fptr->file_elf, scn)) != NULL) {
748 		GElf_Shdr shdr;
749 		Elf_Data *data;
750 
751 		if (gelf_getshdr(scn, &shdr) == NULL)
752 			continue;
753 
754 		if (!is_debug_section(fptr, &shdr))
755 			continue;
756 
757 		if ((data = elf_getdata(scn, NULL)) == NULL) {
758 			return (-1);
759 		}
760 
761 		if (gc_pwrite64(pgc->pgc_fd, data->d_buf, data->d_size,
762 		    *pgc->pgc_doff) != 0)
763 			return (-1);
764 
765 		if (write_shdr(pgc, fptr->file_shstrs + shdr.sh_name,
766 		    shdr.sh_type, shdr.sh_flags,
767 		    fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff,
768 		    data->d_size, 0, shdr.sh_info, shdr.sh_addralign,
769 		    shdr.sh_entsize) != 0) {
770 			return (-1);
771 		}
772 
773 		*indexp = *indexp + 1;
774 		*pgc->pgc_doff += roundup(data->d_size, 8);
775 	}
776 
777 	return (0);
778 }
779 
780 static int
dump_sections(pgcore_t * pgc)781 dump_sections(pgcore_t *pgc)
782 {
783 	struct ps_prochandle *P = pgc->P;
784 	file_info_t *fptr;
785 	uint_t index = 1;
786 
787 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB |
788 	    CC_CONTENT_DEBUG))) {
789 		return (0);
790 	}
791 
792 	for (fptr = list_head(&P->file_head); fptr != NULL;
793 	    fptr = list_next(&P->file_head, fptr)) {
794 		int hit_symtab = 0;
795 
796 		Pbuild_file_symtab(P, fptr);
797 
798 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
799 		    Pbuild_file_ctf(P, fptr) != NULL) {
800 			sym_tbl_t *sym;
801 			uint_t dynsym;
802 			uint_t symindex = 0;
803 
804 			/*
805 			 * Write the symtab out first so we can correctly
806 			 * set the sh_link field in the CTF section header.
807 			 * symindex will be 0 if there is no corresponding
808 			 * symbol table section.
809 			 */
810 			if (fptr->file_ctf_dyn) {
811 				sym = &fptr->file_dynsym;
812 				dynsym = 1;
813 			} else {
814 				sym = &fptr->file_symtab;
815 				dynsym = 0;
816 				hit_symtab = 1;
817 			}
818 
819 			if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
820 			    sym->sym_strs != NULL) {
821 				symindex = index;
822 				if (dump_symtab(pgc, fptr, index, dynsym) != 0)
823 					return (-1);
824 				index += 2;
825 			}
826 
827 			/*
828 			 * Write the CTF data that we've read out of the
829 			 * file itself into the core file.
830 			 */
831 			if (gc_pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
832 			    fptr->file_ctf_size, *pgc->pgc_doff) != 0)
833 				return (-1);
834 
835 			if (write_shdr(pgc, shstrtab_data[STR_CTF],
836 			    SHT_PROGBITS, 0, fptr->file_map->map_pmap.pr_vaddr,
837 			    *pgc->pgc_doff, fptr->file_ctf_size, symindex, 0,
838 			    4, 0) != 0)
839 				return (-1);
840 
841 			index++;
842 			*pgc->pgc_doff += roundup(fptr->file_ctf_size, 8);
843 		}
844 
845 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
846 		    fptr->file_symtab.sym_data_pri != NULL &&
847 		    fptr->file_symtab.sym_symn != 0 &&
848 		    fptr->file_symtab.sym_strs != NULL) {
849 			if (dump_symtab(pgc, fptr, index, 0) != 0)
850 				return (-1);
851 			index += 2;
852 		}
853 
854 		if ((pgc->pgc_content & CC_CONTENT_DEBUG) != 0 &&
855 		    dump_debug(pgc, fptr, &index) != 0) {
856 			return (-1);
857 		}
858 	}
859 
860 	return (0);
861 }
862 
863 /*ARGSUSED*/
864 static int
dump_map(void * data,const prmap_t * pmp,const char * name)865 dump_map(void *data, const prmap_t *pmp, const char *name)
866 {
867 	pgcore_t *pgc = data;
868 	struct ps_prochandle *P = pgc->P;
869 #ifdef _LP64
870 	Elf64_Phdr phdr;
871 #else
872 	Elf32_Phdr phdr;
873 #endif
874 	size_t n;
875 
876 	bzero(&phdr, sizeof (phdr));
877 	phdr.p_type = PT_LOAD;
878 	phdr.p_vaddr = pmp->pr_vaddr;
879 	phdr.p_memsz = pmp->pr_size;
880 	if (pmp->pr_mflags & MA_READ)
881 		phdr.p_flags |= PF_R;
882 	if (pmp->pr_mflags & MA_WRITE)
883 		phdr.p_flags |= PF_W;
884 	if (pmp->pr_mflags & MA_EXEC)
885 		phdr.p_flags |= PF_X;
886 
887 	if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase &&
888 	    pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) {
889 		if (!(pgc->pgc_content & CC_CONTENT_STACK))
890 			goto exclude;
891 
892 	} else if ((pmp->pr_mflags & MA_ANON) &&
893 	    pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase &&
894 	    pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) {
895 		if (!(pgc->pgc_content & CC_CONTENT_HEAP))
896 			goto exclude;
897 
898 	} else if (pmp->pr_mflags & MA_ISM) {
899 		if (pmp->pr_mflags & MA_NORESERVE) {
900 			if (!(pgc->pgc_content & CC_CONTENT_DISM))
901 				goto exclude;
902 		} else {
903 			if (!(pgc->pgc_content & CC_CONTENT_ISM))
904 				goto exclude;
905 		}
906 
907 	} else if (pmp->pr_mflags & MA_SHM) {
908 		if (!(pgc->pgc_content & CC_CONTENT_SHM))
909 			goto exclude;
910 
911 	} else if (pmp->pr_mflags & MA_SHARED) {
912 		if (pmp->pr_mflags & MA_ANON) {
913 			if (!(pgc->pgc_content & CC_CONTENT_SHANON))
914 				goto exclude;
915 		} else {
916 			if (!(pgc->pgc_content & CC_CONTENT_SHFILE))
917 				goto exclude;
918 		}
919 
920 	} else if (pmp->pr_mflags & MA_ANON) {
921 		if (!(pgc->pgc_content & CC_CONTENT_ANON))
922 			goto exclude;
923 
924 	} else if (phdr.p_flags == (PF_R | PF_X)) {
925 		if (!(pgc->pgc_content & CC_CONTENT_TEXT))
926 			goto exclude;
927 
928 	} else if (phdr.p_flags == PF_R) {
929 		if (!(pgc->pgc_content & CC_CONTENT_RODATA))
930 			goto exclude;
931 
932 	} else {
933 		if (!(pgc->pgc_content & CC_CONTENT_DATA))
934 			goto exclude;
935 	}
936 
937 	n = 0;
938 	while (n < pmp->pr_size) {
939 		size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz);
940 		ssize_t ret;
941 
942 		/*
943 		 * If we happen to have a PROT_NONE mapping, don't try to read
944 		 * from the address space.
945 		 */
946 		if ((pmp->pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) == 0) {
947 			bzero(pgc->pgc_chunk, csz);
948 			ret = csz;
949 		} else {
950 			ret = Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n);
951 		}
952 
953 		/*
954 		 * If we can't read out part of the victim's address
955 		 * space for some reason ignore that failure and try to
956 		 * emit a partial core file without that mapping's data.
957 		 * As in the kernel, we mark these failures with the
958 		 * PF_SUNW_FAILURE flag and store the errno where the
959 		 * mapping would have been.
960 		 */
961 		if (ret != csz || gc_pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,
962 		    *pgc->pgc_doff + n) != 0) {
963 			int err = errno;
964 			(void) gc_pwrite64(pgc->pgc_fd, &err, sizeof (err),
965 			    *pgc->pgc_doff);
966 			*pgc->pgc_doff += roundup(sizeof (err), 8);
967 
968 			phdr.p_flags |= PF_SUNW_FAILURE;
969 			(void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff);
970 			goto exclude;
971 		}
972 
973 		n += csz;
974 	}
975 
976 	phdr.p_offset = *pgc->pgc_doff;
977 	phdr.p_filesz = pmp->pr_size;
978 	*pgc->pgc_doff += roundup(phdr.p_filesz, 8);
979 
980 exclude:
981 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
982 		if (gc_pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),
983 		    *pgc->pgc_poff) != 0)
984 			return (1);
985 
986 		*pgc->pgc_poff += sizeof (phdr);
987 #ifdef _LP64
988 	} else {
989 		Elf32_Phdr phdr32;
990 
991 		bzero(&phdr32, sizeof (phdr32));
992 		phdr32.p_type = phdr.p_type;
993 		phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr;
994 		phdr32.p_memsz = (Elf32_Word)phdr.p_memsz;
995 		phdr32.p_flags = phdr.p_flags;
996 		phdr32.p_offset = (Elf32_Off)phdr.p_offset;
997 		phdr32.p_filesz = (Elf32_Word)phdr.p_filesz;
998 
999 		if (gc_pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),
1000 		    *pgc->pgc_poff) != 0)
1001 			return (1);
1002 
1003 		*pgc->pgc_poff += sizeof (phdr32);
1004 #endif	/* _LP64 */
1005 	}
1006 
1007 	return (0);
1008 }
1009 
1010 int
write_shstrtab(struct ps_prochandle * P,pgcore_t * pgc)1011 write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
1012 {
1013 	off64_t off = *pgc->pgc_doff;
1014 	size_t size = 0;
1015 	shstrtab_t *s = &pgc->pgc_shstrtab;
1016 
1017 	if (shstrtab_size(s) == 1)
1018 		return (0);
1019 
1020 	/*
1021 	 * Preemptively stick the name of the shstrtab in the string table.
1022 	 */
1023 	if (!shstrtab_ndx(&pgc->pgc_shstrtab,
1024 	    shstrtab_data[STR_SHSTRTAB], NULL)) {
1025 		return (1);
1026 	}
1027 	size = shstrtab_size(s);
1028 
1029 	/*
1030 	 * Dump all the strings that we used being sure we include the
1031 	 * terminating null character.
1032 	 */
1033 	for (shstrtab_ent_t *ent = list_head(&s->sst_names); ent != NULL;
1034 	    ent = list_next(&s->sst_names, ent)) {
1035 		if (gc_pwrite64(pgc->pgc_fd, ent->sste_name, ent->sste_len,
1036 		    off + ent->sste_offset) != 0) {
1037 			return (1);
1038 		}
1039 	}
1040 
1041 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1042 		Elf32_Shdr shdr;
1043 
1044 		bzero(&shdr, sizeof (shdr));
1045 		if (!shstrtab_ndx(&pgc->pgc_shstrtab,
1046 		    shstrtab_data[STR_SHSTRTAB], &shdr.sh_name)) {
1047 			return (1);
1048 		}
1049 		shdr.sh_size = size;
1050 		shdr.sh_offset = *pgc->pgc_doff;
1051 		shdr.sh_addralign = 1;
1052 		shdr.sh_flags = SHF_STRINGS;
1053 		shdr.sh_type = SHT_STRTAB;
1054 
1055 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
1056 		    *pgc->pgc_soff) != 0)
1057 			return (1);
1058 
1059 		*pgc->pgc_soff += sizeof (shdr);
1060 #ifdef _LP64
1061 	} else {
1062 		Elf64_Shdr shdr;
1063 
1064 		bzero(&shdr, sizeof (shdr));
1065 		if (!shstrtab_ndx(&pgc->pgc_shstrtab,
1066 		    shstrtab_data[STR_SHSTRTAB], &shdr.sh_name)) {
1067 			return (1);
1068 		}
1069 		shdr.sh_size = size;
1070 		shdr.sh_offset = *pgc->pgc_doff;
1071 		shdr.sh_addralign = 1;
1072 		shdr.sh_flags = SHF_STRINGS;
1073 		shdr.sh_type = SHT_STRTAB;
1074 
1075 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
1076 		    *pgc->pgc_soff) != 0)
1077 			return (1);
1078 
1079 		*pgc->pgc_soff += sizeof (shdr);
1080 #endif	/* _LP64 */
1081 	}
1082 
1083 	*pgc->pgc_doff += roundup(size, 8);
1084 
1085 	return (0);
1086 }
1087 
1088 /*
1089  * Don't explicity stop the process; that's up to the consumer.
1090  */
1091 int
Pfgcore(struct ps_prochandle * P,int fd,core_content_t content)1092 Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
1093 {
1094 	char plat[SYS_NMLN];
1095 	char zonename[ZONENAME_MAX];
1096 	int platlen = -1;
1097 	pgcore_t pgc;
1098 	off64_t poff, soff, doff, boff;
1099 	struct utsname uts;
1100 	uint_t nphdrs, nshdrs;
1101 
1102 	if (ftruncate64(fd, 0) != 0)
1103 		return (-1);
1104 
1105 	if (content == CC_CONTENT_INVALID) {
1106 		errno = EINVAL;
1107 		return (-1);
1108 	}
1109 
1110 	/*
1111 	 * Cache the mappings and other useful data.
1112 	 */
1113 	(void) Prd_agent(P);
1114 	(void) Ppsinfo(P);
1115 
1116 	(void) memset(&pgc, 0, sizeof (pgc));
1117 	pgc.P = P;
1118 	pgc.pgc_fd = fd;
1119 	pgc.pgc_poff = &poff;
1120 	pgc.pgc_soff = &soff;
1121 	pgc.pgc_doff = &doff;
1122 	pgc.pgc_content = content;
1123 	pgc.pgc_chunksz = PAGESIZE;
1124 	if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL)
1125 		return (-1);
1126 
1127 	if (!shstrtab_init(&pgc.pgc_shstrtab)) {
1128 		goto err;
1129 	}
1130 
1131 	/*
1132 	 * There are two PT_NOTE program headers for ancillary data, and
1133 	 * one for each mapping.
1134 	 */
1135 	nphdrs = 2 + P->map_count;
1136 	nshdrs = count_sections(&pgc);
1137 
1138 	(void) Pplatform(P, plat, sizeof (plat));
1139 	platlen = strlen(plat) + 1;
1140 	Preadauxvec(P);
1141 	(void) Puname(P, &uts);
1142 	if (Pzonename(P, zonename, sizeof (zonename)) == NULL)
1143 		zonename[0] = '\0';
1144 
1145 	/*
1146 	 * The core file contents may required zero section headers, but if we
1147 	 * overflow the 16 bits allotted to the program header count in the ELF
1148 	 * header, we'll need that program header at index zero.
1149 	 */
1150 	if (nshdrs == 0 && nphdrs >= PN_XNUM)
1151 		nshdrs = 1;
1152 
1153 	/*
1154 	 * Set up the ELF header.
1155 	 */
1156 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1157 		Elf32_Ehdr ehdr;
1158 
1159 		bzero(&ehdr, sizeof (ehdr));
1160 		ehdr.e_ident[EI_MAG0] = ELFMAG0;
1161 		ehdr.e_ident[EI_MAG1] = ELFMAG1;
1162 		ehdr.e_ident[EI_MAG2] = ELFMAG2;
1163 		ehdr.e_ident[EI_MAG3] = ELFMAG3;
1164 		ehdr.e_type = ET_CORE;
1165 
1166 		ehdr.e_ident[EI_CLASS] = ELFCLASS32;
1167 #if defined(__sparc)
1168 		ehdr.e_machine = EM_SPARC;
1169 		ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
1170 #elif defined(__i386) || defined(__amd64)
1171 		ehdr.e_machine = EM_386;
1172 		ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
1173 #else
1174 #error "unknown machine type"
1175 #endif
1176 		ehdr.e_ident[EI_VERSION] = EV_CURRENT;
1177 
1178 		ehdr.e_version = EV_CURRENT;
1179 		ehdr.e_ehsize = sizeof (ehdr);
1180 
1181 		if (nphdrs >= PN_XNUM)
1182 			ehdr.e_phnum = PN_XNUM;
1183 		else
1184 			ehdr.e_phnum = (unsigned short)nphdrs;
1185 
1186 		ehdr.e_phentsize = sizeof (Elf32_Phdr);
1187 		ehdr.e_phoff = ehdr.e_ehsize;
1188 
1189 		if (nshdrs > 0) {
1190 			if (nshdrs >= SHN_LORESERVE)
1191 				ehdr.e_shnum = 0;
1192 			else
1193 				ehdr.e_shnum = (unsigned short)nshdrs;
1194 
1195 			if (nshdrs - 1 >= SHN_LORESERVE)
1196 				ehdr.e_shstrndx = SHN_XINDEX;
1197 			else
1198 				ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
1199 
1200 			ehdr.e_shentsize = sizeof (Elf32_Shdr);
1201 			ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
1202 		}
1203 
1204 		if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
1205 			goto err;
1206 
1207 		poff = ehdr.e_phoff;
1208 		soff = ehdr.e_shoff;
1209 		doff = boff = ehdr.e_ehsize +
1210 		    ehdr.e_phentsize * nphdrs +
1211 		    ehdr.e_shentsize * nshdrs;
1212 
1213 #ifdef _LP64
1214 	} else {
1215 		Elf64_Ehdr ehdr;
1216 
1217 		bzero(&ehdr, sizeof (ehdr));
1218 		ehdr.e_ident[EI_MAG0] = ELFMAG0;
1219 		ehdr.e_ident[EI_MAG1] = ELFMAG1;
1220 		ehdr.e_ident[EI_MAG2] = ELFMAG2;
1221 		ehdr.e_ident[EI_MAG3] = ELFMAG3;
1222 		ehdr.e_type = ET_CORE;
1223 
1224 		ehdr.e_ident[EI_CLASS] = ELFCLASS64;
1225 #if defined(__sparc)
1226 		ehdr.e_machine = EM_SPARCV9;
1227 		ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
1228 #elif defined(__i386) || defined(__amd64)
1229 		ehdr.e_machine = EM_AMD64;
1230 		ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
1231 #else
1232 #error "unknown machine type"
1233 #endif
1234 		ehdr.e_ident[EI_VERSION] = EV_CURRENT;
1235 
1236 		ehdr.e_version = EV_CURRENT;
1237 		ehdr.e_ehsize = sizeof (ehdr);
1238 
1239 		if (nphdrs >= PN_XNUM)
1240 			ehdr.e_phnum = PN_XNUM;
1241 		else
1242 			ehdr.e_phnum = (unsigned short)nphdrs;
1243 
1244 		ehdr.e_phentsize = sizeof (Elf64_Phdr);
1245 		ehdr.e_phoff = ehdr.e_ehsize;
1246 
1247 		if (nshdrs > 0) {
1248 			if (nshdrs >= SHN_LORESERVE)
1249 				ehdr.e_shnum = 0;
1250 			else
1251 				ehdr.e_shnum = (unsigned short)nshdrs;
1252 
1253 			if (nshdrs - 1 >= SHN_LORESERVE)
1254 				ehdr.e_shstrndx = SHN_XINDEX;
1255 			else
1256 				ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
1257 
1258 			ehdr.e_shentsize = sizeof (Elf64_Shdr);
1259 			ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
1260 		}
1261 
1262 		if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
1263 			goto err;
1264 
1265 		poff = ehdr.e_phoff;
1266 		soff = ehdr.e_shoff;
1267 		doff = boff = ehdr.e_ehsize +
1268 		    ehdr.e_phentsize * nphdrs +
1269 		    ehdr.e_shentsize * nshdrs;
1270 
1271 #endif	/* _LP64 */
1272 	}
1273 
1274 	/*
1275 	 * Write the zero indexed section if it exists.
1276 	 */
1277 	if (nshdrs > 0 && write_shdr(&pgc, shstrtab_data[STR_NONE], 0, 0, 0, 0,
1278 	    nshdrs >= SHN_LORESERVE ? nshdrs : 0,
1279 	    nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0,
1280 	    nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0)
1281 		goto err;
1282 
1283 	/*
1284 	 * Construct the old-style note header and section.
1285 	 */
1286 
1287 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
1288 		prpsinfo_t prpsinfo;
1289 
1290 		mkprpsinfo(P, &prpsinfo);
1291 		if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t),
1292 		    &doff) != 0) {
1293 			goto err;
1294 		}
1295 		if (write_note(fd, NT_AUXV, P->auxv,
1296 		    P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
1297 			goto err;
1298 		}
1299 #ifdef _LP64
1300 	} else {
1301 		prpsinfo32_t pi32;
1302 		auxv32_t *av32;
1303 		size_t size = sizeof (auxv32_t) * P->nauxv;
1304 		int i;
1305 
1306 		mkprpsinfo32(P, &pi32);
1307 		if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t),
1308 		    &doff) != 0) {
1309 			goto err;
1310 		}
1311 
1312 		if ((av32 = malloc(size)) == NULL)
1313 			goto err;
1314 
1315 		for (i = 0; i < P->nauxv; i++) {
1316 			auxv_n_to_32(&P->auxv[i], &av32[i]);
1317 		}
1318 
1319 		if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
1320 			free(av32);
1321 			goto err;
1322 		}
1323 
1324 		free(av32);
1325 #endif	/* _LP64 */
1326 	}
1327 
1328 	if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0)
1329 		goto err;
1330 
1331 	if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0)
1332 		goto err;
1333 
1334 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1335 		Elf32_Phdr phdr;
1336 
1337 		bzero(&phdr, sizeof (phdr));
1338 		phdr.p_type = PT_NOTE;
1339 		phdr.p_flags = PF_R;
1340 		phdr.p_offset = (Elf32_Off)boff;
1341 		phdr.p_filesz = doff - boff;
1342 		boff = doff;
1343 
1344 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1345 			goto err;
1346 		poff += sizeof (phdr);
1347 #ifdef _LP64
1348 	} else {
1349 		Elf64_Phdr phdr;
1350 
1351 		bzero(&phdr, sizeof (phdr));
1352 		phdr.p_type = PT_NOTE;
1353 		phdr.p_flags = PF_R;
1354 		phdr.p_offset = boff;
1355 		phdr.p_filesz = doff - boff;
1356 		boff = doff;
1357 
1358 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1359 			goto err;
1360 		poff += sizeof (phdr);
1361 #endif	/* _LP64 */
1362 	}
1363 
1364 	/*
1365 	 * Construct the new-style note header and section.
1366 	 */
1367 
1368 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
1369 		if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t),
1370 		    &doff) != 0) {
1371 			goto err;
1372 		}
1373 		if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t),
1374 		    &doff) != 0) {
1375 			goto err;
1376 		}
1377 		if (write_note(fd, NT_AUXV, P->auxv,
1378 		    P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
1379 			goto err;
1380 		}
1381 #ifdef _LP64
1382 	} else {
1383 		psinfo32_t pi32;
1384 		pstatus32_t ps32;
1385 		auxv32_t *av32;
1386 		size_t size = sizeof (auxv32_t) * P->nauxv;
1387 		int i;
1388 
1389 		psinfo_n_to_32(&P->psinfo, &pi32);
1390 		if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t),
1391 		    &doff) != 0) {
1392 			goto err;
1393 		}
1394 		pstatus_n_to_32(&P->status, &ps32);
1395 		if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t),
1396 		    &doff) != 0) {
1397 			goto err;
1398 		}
1399 		if ((av32 = malloc(size)) == NULL)
1400 			goto err;
1401 
1402 		for (i = 0; i < P->nauxv; i++) {
1403 			auxv_n_to_32(&P->auxv[i], &av32[i]);
1404 		}
1405 
1406 		if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
1407 			free(av32);
1408 			goto err;
1409 		}
1410 
1411 		free(av32);
1412 #endif	/* _LP64 */
1413 	}
1414 
1415 	if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 ||
1416 	    write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 ||
1417 	    write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0)
1418 		goto err;
1419 
1420 	{
1421 		prcred_t cred, *cp;
1422 		size_t size = sizeof (prcred_t);
1423 
1424 		if (Pcred(P, &cred, 0) != 0)
1425 			goto err;
1426 
1427 		if (cred.pr_ngroups > 0)
1428 			size += sizeof (gid_t) * (cred.pr_ngroups - 1);
1429 		if ((cp = malloc(size)) == NULL)
1430 			goto err;
1431 
1432 		if (Pcred(P, cp, cred.pr_ngroups) != 0 ||
1433 		    write_note(fd, NT_PRCRED, cp, size, &doff) != 0) {
1434 			free(cp);
1435 			goto err;
1436 		}
1437 
1438 		free(cp);
1439 	}
1440 
1441 	{
1442 		prpriv_t *ppriv = NULL;
1443 		const priv_impl_info_t *pinfo;
1444 		size_t pprivsz, pinfosz;
1445 
1446 		if (Ppriv(P, &ppriv) == -1)
1447 			goto err;
1448 		pprivsz = PRIV_PRPRIV_SIZE(ppriv);
1449 
1450 		if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) {
1451 			Ppriv_free(P, ppriv);
1452 			goto err;
1453 		}
1454 		Ppriv_free(P, ppriv);
1455 
1456 		if ((pinfo = getprivimplinfo()) == NULL)
1457 			goto err;
1458 		pinfosz = PRIV_IMPL_INFO_SIZE(pinfo);
1459 
1460 		if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0)
1461 			goto err;
1462 	}
1463 
1464 	if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1,
1465 	    &doff) != 0)
1466 		goto err;
1467 
1468 	{
1469 		fditer_t iter;
1470 		iter.fd_fd = fd;
1471 		iter.fd_doff = &doff;
1472 
1473 		if (Pfdinfo_iter(P, iter_fd, &iter) != 0)
1474 			goto err;
1475 	}
1476 
1477 
1478 	{
1479 		prsecflags_t *psf = NULL;
1480 
1481 		if (Psecflags(P, &psf) != 0)
1482 			goto err;
1483 
1484 		if (write_note(fd, NT_SECFLAGS, psf,
1485 		    sizeof (prsecflags_t), &doff) != 0) {
1486 			Psecflags_free(psf);
1487 			goto err;
1488 		}
1489 
1490 		Psecflags_free(psf);
1491 	}
1492 
1493 	{
1494 		prcwd_t *cwd = NULL;
1495 
1496 		if (Pcwd(P, &cwd) != 0)
1497 			goto err;
1498 
1499 		if (write_note(fd, NT_CWD, cwd,
1500 		    sizeof (prcwd_t), &doff) != 0) {
1501 			Pcwd_free(cwd);
1502 			goto err;
1503 		}
1504 
1505 		Pcwd_free(cwd);
1506 	}
1507 
1508 #if defined(__i386) || defined(__amd64)
1509 	/* CSTYLED */
1510 	{
1511 		struct ssd *ldtp;
1512 		size_t size;
1513 		int nldt;
1514 
1515 		/*
1516 		 * Only dump out non-zero sized LDT notes.
1517 		 */
1518 		if ((nldt = Pldt(P, NULL, 0)) != 0) {
1519 			size = sizeof (struct ssd) * nldt;
1520 			if ((ldtp = malloc(size)) == NULL)
1521 				goto err;
1522 
1523 			if (Pldt(P, ldtp, nldt) == -1 ||
1524 			    write_note(fd, NT_LDT, ldtp, size, &doff) != 0) {
1525 				free(ldtp);
1526 				goto err;
1527 			}
1528 
1529 			free(ldtp);
1530 		}
1531 	}
1532 #endif	/* __i386 || __amd64 */
1533 
1534 	if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0)
1535 		goto err;
1536 
1537 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1538 		Elf32_Phdr phdr;
1539 
1540 		bzero(&phdr, sizeof (phdr));
1541 		phdr.p_type = PT_NOTE;
1542 		phdr.p_flags = PF_R;
1543 		phdr.p_offset = (Elf32_Off)boff;
1544 		phdr.p_filesz = doff - boff;
1545 		boff = doff;
1546 
1547 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1548 			goto err;
1549 		poff += sizeof (phdr);
1550 #ifdef _LP64
1551 	} else {
1552 		Elf64_Phdr phdr;
1553 
1554 		bzero(&phdr, sizeof (phdr));
1555 		phdr.p_type = PT_NOTE;
1556 		phdr.p_flags = PF_R;
1557 		phdr.p_offset = boff;
1558 		phdr.p_filesz = doff - boff;
1559 		boff = doff;
1560 
1561 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1562 			goto err;
1563 		poff += sizeof (phdr);
1564 #endif	/* _LP64 */
1565 	}
1566 
1567 	/*
1568 	 * Construct the headers for each mapping and write out its data
1569 	 * if the content parameter indicates that it should be present
1570 	 * in the core file.
1571 	 */
1572 	if (Pmapping_iter(P, dump_map, &pgc) != 0)
1573 		goto err;
1574 
1575 	if (dump_sections(&pgc) != 0)
1576 		goto err;
1577 
1578 	if (write_shstrtab(P, &pgc) != 0)
1579 		goto err;
1580 
1581 	free(pgc.pgc_chunk);
1582 	shstrtab_fini(&pgc.pgc_shstrtab);
1583 
1584 	return (0);
1585 
1586 err:
1587 	/*
1588 	 * Wipe out anything we may have written if there was an error.
1589 	 */
1590 	(void) ftruncate64(fd, 0);
1591 	free(pgc.pgc_chunk);
1592 	shstrtab_fini(&pgc.pgc_shstrtab);
1593 
1594 	return (-1);
1595 }
1596 
1597 static const char *content_str[] = {
1598 	"stack",	/* CC_CONTENT_STACK */
1599 	"heap",		/* CC_CONTENT_HEAP */
1600 	"shfile",	/* CC_CONTENT_SHFILE */
1601 	"shanon",	/* CC_CONTENT_SHANON */
1602 	"text",		/* CC_CONTENT_TEXT */
1603 	"data",		/* CC_CONTENT_DATA */
1604 	"rodata",	/* CC_CONTENT_RODATA */
1605 	"anon",		/* CC_CONTENT_ANON */
1606 	"shm",		/* CC_CONTENT_SHM */
1607 	"ism",		/* CC_CONTENT_ISM */
1608 	"dism",		/* CC_CONTENT_DISM */
1609 	"ctf",		/* CC_CONTENT_CTF */
1610 	"symtab",	/* CC_CONTENT_SYMTAB */
1611 	"debug"		/* CC_CONTENT_DEBUG */
1612 };
1613 
1614 static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]);
1615 
1616 #define	STREQ(a, b, n)	(strlen(b) == (n) && strncmp(a, b, n) == 0)
1617 
1618 int
proc_str2content(const char * str,core_content_t * cp)1619 proc_str2content(const char *str, core_content_t *cp)
1620 {
1621 	const char *cur = str;
1622 	int add = 1;
1623 	core_content_t mask, content = 0;
1624 
1625 	for (;;) {
1626 		for (cur = str; isalpha(*cur); cur++)
1627 			continue;
1628 
1629 		if (STREQ(str, "default", cur - str)) {
1630 			mask = CC_CONTENT_DEFAULT;
1631 		} else if (STREQ(str, "all", cur - str)) {
1632 			mask = CC_CONTENT_ALL;
1633 		} else if (STREQ(str, "none", cur - str)) {
1634 			mask = 0;
1635 		} else {
1636 			int i = 0;
1637 
1638 			while (!STREQ(str, content_str[i], cur - str)) {
1639 				i++;
1640 
1641 				if (i >= ncontent_str)
1642 					return (-1);
1643 			}
1644 
1645 			mask = (core_content_t)1 << i;
1646 		}
1647 
1648 		if (add)
1649 			content |= mask;
1650 		else
1651 			content &= ~mask;
1652 
1653 		switch (*cur) {
1654 		case '\0':
1655 			*cp = content;
1656 			return (0);
1657 		case '+':
1658 			add = 1;
1659 			break;
1660 		case '-':
1661 			add = 0;
1662 			break;
1663 		default:
1664 			return (-1);
1665 		}
1666 
1667 		str = cur + 1;
1668 	}
1669 }
1670 
1671 static int
popc(core_content_t x)1672 popc(core_content_t x)
1673 {
1674 	int i;
1675 
1676 	for (i = 0; x != 0; i++)
1677 		x &= x - 1;
1678 
1679 	return (i);
1680 }
1681 
1682 int
proc_content2str(core_content_t content,char * buf,size_t size)1683 proc_content2str(core_content_t content, char *buf, size_t size)
1684 {
1685 	int nonecnt, defcnt, allcnt;
1686 	core_content_t mask, bit;
1687 	int first;
1688 	uint_t index;
1689 	size_t n, tot = 0;
1690 
1691 	if (content == 0)
1692 		return ((int)strlcpy(buf, "none", size));
1693 
1694 	if (content & ~CC_CONTENT_ALL)
1695 		return ((int)strlcpy(buf, "<invalid>", size));
1696 
1697 	nonecnt = popc(content);
1698 	defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT);
1699 	allcnt = 1 + popc(content ^ CC_CONTENT_ALL);
1700 
1701 	if (defcnt <= nonecnt && defcnt <= allcnt) {
1702 		mask = content ^ CC_CONTENT_DEFAULT;
1703 		first = 0;
1704 		tot += (n = strlcpy(buf, "default", size));
1705 		if (n > size)
1706 			n = size;
1707 		buf += n;
1708 		size -= n;
1709 	} else if (allcnt < nonecnt) {
1710 		mask = content ^ CC_CONTENT_ALL;
1711 		first = 0;
1712 		tot += (n = strlcpy(buf, "all", size));
1713 		if (n > size)
1714 			n = size;
1715 		buf += n;
1716 		size -= n;
1717 	} else {
1718 		mask = content;
1719 		first = 1;
1720 	}
1721 
1722 	while (mask != 0) {
1723 		bit = mask ^ (mask & (mask - 1));
1724 
1725 		if (!first) {
1726 			if (size > 1) {
1727 				*buf = (bit & content) ? '+' : '-';
1728 				buf++;
1729 				size--;
1730 			}
1731 
1732 			tot++;
1733 		}
1734 		index = popc(bit - 1);
1735 		tot += (n = strlcpy(buf, content_str[index], size));
1736 		if (n > size)
1737 			n = size;
1738 		buf += n;
1739 		size -= n;
1740 
1741 		mask ^= bit;
1742 		first = 0;
1743 	}
1744 
1745 	return ((int)tot);
1746 }
1747