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
 
 |