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