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 */