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

*** 22,35 **** --- 22,37 ---- * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright 2023 Oxide Computer Company */ #include <stdarg.h> #include <string.h> + #include <errno.h> #include "Pcontrol.h" /* * This file implements the process services declared in <proc_service.h>. * This enables libproc to be used in conjunction with libc_db and
*** 165,176 **** return (PS_OK); return (PS_BADLID); } - #if defined(sparc) || defined(__sparc) - ps_err_e ps_lgetxregsize(struct ps_prochandle *P, lwpid_t lwpid, int *xrsize) { char fname[PATH_MAX]; struct stat statb; --- 167,176 ----
*** 180,193 **** lwp_info_t *lwp; for (lwp = list_head(&core->core_lwp_head); lwp != NULL; lwp = list_next(&core->core_lwp_head, lwp)) { if (lwp->lwp_id == lwpid) { ! if (lwp->lwp_xregs != NULL) ! *xrsize = sizeof (prxregset_t); ! else *xrsize = 0; return (PS_OK); } } return (PS_BADLID); --- 180,199 ---- lwp_info_t *lwp; for (lwp = list_head(&core->core_lwp_head); lwp != NULL; lwp = list_next(&core->core_lwp_head, lwp)) { if (lwp->lwp_id == lwpid) { ! if (lwp->lwp_xregs != NULL && ! lwp->lwp_xregsize > 0) { ! if (lwp->lwp_xregsize >= INT_MAX) { ! return (PS_ERR); ! } ! ! *xrsize = (int)lwp->lwp_xregsize; ! } else { *xrsize = 0; + } return (PS_OK); } } return (PS_BADLID);
*** 197,225 **** procfs_path, (int)P->status.pr_pid, (int)lwpid); if (stat(fname, &statb) != 0) return (PS_BADLID); *xrsize = (int)statb.st_size; return (PS_OK); } ps_err_e ps_lgetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs) { if (P->state != PS_STOP && P->state != PS_DEAD) return (PS_ERR); ! /* LINTED - alignment */ ! if (Plwp_getxregs(P, lwpid, (prxregset_t *)xregs) == 0) return (PS_OK); return (PS_BADLID); } ps_err_e ps_lsetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs) { if (P->state != PS_STOP) return (PS_ERR); /* LINTED - alignment */ --- 203,272 ---- procfs_path, (int)P->status.pr_pid, (int)lwpid); if (stat(fname, &statb) != 0) return (PS_BADLID); + if (statb.st_size > INT_MAX) + return (PS_ERR); + *xrsize = (int)statb.st_size; return (PS_OK); } ps_err_e ps_lgetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs) { + size_t xregsize; + prxregset_t *prx; + if (P->state != PS_STOP && P->state != PS_DEAD) return (PS_ERR); ! if (Plwp_getxregs(P, lwpid, &prx, &xregsize) == 0) { ! (void) memcpy(xregs, prx, xregsize); ! Plwp_freexregs(P, prx, xregsize); return (PS_OK); + } + if (errno == ENODATA) + return (PS_NOXREGS); + return (PS_BADLID); } ps_err_e ps_lsetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs) + { + size_t xregsize = 0; + + if (P->state != PS_STOP) + return (PS_ERR); + + /* + * libproc asks the caller for the size of the extended register set. + * Unfortunately, right now we aren't given the actual size of this + * ourselves and we don't want to break the ABI that folks have used + * historically. Therefore, we reach in and ask the structure in a + * platform-specific way about what this should be. Sorry, this is a bit + * unfortunate. This really shouldn't be a platform-specific #ifdef. + */ + #if defined(__i386) || defined(__amd64) + prxregset_hdr_t *hdr = (prxregset_hdr_t *)xregs; + xregsize = hdr->pr_size; + #endif + if (xregsize == 0) + return (PS_ERR); + + if (Plwp_setxregs(P, lwpid, (prxregset_t *)xregs, xregsize) == 0) + return (PS_OK); + + return (PS_BADLID); + } + + #if defined(sparc) || defined(__sparc) + ps_err_e + ps_lsetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs) { if (P->state != PS_STOP) return (PS_ERR); /* LINTED - alignment */