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 2021 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
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 #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 return (0);
457 }
458
459 static int
460 new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
461 {
462 pgcore_t *pgc = data;
463 struct ps_prochandle *P = pgc->P;
464 prlwpname_t name = { 0, "" };
465 psinfo_t ps;
466
467 /*
468 * If lsp is NULL this indicates that this is a zombie LWP in
469 * which case we dump only the lwpsinfo_t structure and none of
470 * the other ancillary LWP state data.
471 */
472 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
473 if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
474 sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
475 return (1);
478 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
479 sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
480 return (1);
481 #ifdef _LP64
482 } else {
483 lwpsinfo32_t li32;
484 lwpstatus32_t ls32;
485 lwpsinfo_n_to_32(lip, &li32);
486 if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
487 sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
488 return (1);
489 if (lsp == NULL)
490 return (0);
491 lwpstatus_n_to_32(lsp, &ls32);
492 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
493 sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
494 return (1);
495 #endif /* _LP64 */
496 }
497
498 #ifdef sparc
499 {
500 prxregset_t xregs;
501 gwindows_t gwins;
502 size_t size;
503
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,
516 pgc->pgc_doff) != 0)
517 return (1);
518 }
519
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);
528 }
529 }
530 #endif /* __sparcv9 */
531 #endif /* sparc */
532
533 if (Plwp_getname(P, lsp->pr_lwpid, name.pr_lwpname,
534 sizeof (name.pr_lwpname)) == 0) {
535 name.pr_lwpid = lsp->pr_lwpid;
536 if (write_note(pgc->pgc_fd, NT_LWPNAME, &name,
537 sizeof (name), pgc->pgc_doff) != 0)
538 return (1);
539 }
540
541 if (!(lsp->pr_flags & PR_AGENT))
542 return (0);
543
544 if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0)
545 return (0);
546
547 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
548 if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps,
549 sizeof (psinfo_t), pgc->pgc_doff) != 0)
550 return (1);
551 #ifdef _LP64
|
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 2023 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
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
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
457 /*
458 * If lsp is NULL this indicates that this is a zombie LWP in
459 * which case we dump only the lwpsinfo_t structure and none of
460 * the other ancillary LWP state data.
461 */
462 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
463 if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
464 sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
465 return (1);
468 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
469 sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
470 return (1);
471 #ifdef _LP64
472 } else {
473 lwpsinfo32_t li32;
474 lwpstatus32_t ls32;
475 lwpsinfo_n_to_32(lip, &li32);
476 if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
477 sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
478 return (1);
479 if (lsp == NULL)
480 return (0);
481 lwpstatus_n_to_32(lsp, &ls32);
482 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
483 sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
484 return (1);
485 #endif /* _LP64 */
486 }
487
488 {
489 prxregset_t *xregs;
490 size_t size;
491
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,
501 pgc->pgc_doff) != 0)
502 return (1);
503
504 Plwp_freexregs(P, xregs, size);
505 }
506 }
507
508 if (Plwp_getname(P, lsp->pr_lwpid, name.pr_lwpname,
509 sizeof (name.pr_lwpname)) == 0) {
510 name.pr_lwpid = lsp->pr_lwpid;
511 if (write_note(pgc->pgc_fd, NT_LWPNAME, &name,
512 sizeof (name), pgc->pgc_doff) != 0)
513 return (1);
514 }
515
516 if (!(lsp->pr_flags & PR_AGENT))
517 return (0);
518
519 if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0)
520 return (0);
521
522 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
523 if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps,
524 sizeof (psinfo_t), pgc->pgc_doff) != 0)
525 return (1);
526 #ifdef _LP64
|