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


  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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2018, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2013 by Delphix. All rights reserved.
  29  * Copyright 2015 Gary Mills
  30  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  31  * Copyright 2021 Oxide Computer Company
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/utsname.h>
  36 #include <sys/sysmacros.h>
  37 #include <sys/proc.h>
  38 
  39 #include <alloca.h>
  40 #include <rtld_db.h>
  41 #include <libgen.h>
  42 #include <limits.h>
  43 #include <string.h>
  44 #include <stdlib.h>
  45 #include <unistd.h>
  46 #include <errno.h>
  47 #include <gelf.h>
  48 #include <stddef.h>
  49 #include <signal.h>
  50 
  51 #include "libproc.h"


1064 
1065         if (_libproc_debug) {
1066                 for (i = 0; i < n; i++) {
1067                         dprintf("P->auxv[%lu] = ( %d, 0x%lx )\n", (ulong_t)i,
1068                             P->auxv[i].a_type, P->auxv[i].a_un.a_val);
1069                 }
1070         }
1071 
1072         /*
1073          * Defensive coding for loops which depend upon the auxv array being
1074          * terminated by an AT_NULL element; in each case, we've allocated
1075          * P->auxv to have an additional element which we force to be AT_NULL.
1076          */
1077         P->auxv[n].a_type = AT_NULL;
1078         P->auxv[n].a_un.a_val = 0L;
1079         P->nauxv = (int)n;
1080 
1081         return (0);
1082 }
1083 
1084 #ifdef __sparc







1085 static int
1086 note_xreg(struct ps_prochandle *P, size_t nbytes)
1087 {
1088         core_info_t *core = P->data;
1089         lwp_info_t *lwp = core->core_lwp;
1090         size_t xbytes = sizeof (prxregset_t);
1091         prxregset_t *xregs;

1092 
1093         if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)
1094                 return (0);     /* No lwp yet, already seen, or bad size */
1095 
1096         if ((xregs = malloc(xbytes)) == NULL)
1097                 return (-1);
1098 
1099         if (read(P->asfd, xregs, xbytes) != xbytes) {

1100                 dprintf("Pgrab_core: failed to read NT_PRXREG\n");
1101                 free(xregs);
1102                 return (-1);
1103         }
1104 
1105         lwp->lwp_xregs = xregs;

1106         return (0);
1107 }
1108 

1109 static int
1110 note_gwindows(struct ps_prochandle *P, size_t nbytes)
1111 {
1112         core_info_t *core = P->data;
1113         lwp_info_t *lwp = core->core_lwp;
1114 
1115         if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)
1116                 return (0);     /* No lwp yet or already seen or no data */
1117 
1118         if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
1119                 return (-1);
1120 
1121         /*
1122          * Since the amount of gwindows data varies with how many windows were
1123          * actually saved, we just read up to the minimum of the note size
1124          * and the size of the gwindows_t type.  It doesn't matter if the read
1125          * fails since we have to zero out gwindows first anyway.
1126          */
1127 #ifdef _LP64
1128         if (core->core_dmodel == PR_MODEL_ILP32) {


1237         return (0);
1238 }
1239 
1240 /*
1241  * Populate a table of function pointers indexed by Note type with our
1242  * functions to process each type of core file note:
1243  */
1244 static int (*nhdlrs[])(struct ps_prochandle *, size_t) = {
1245         note_notsup,            /*  0   unassigned              */
1246 #ifdef __x86
1247         note_linux_prstatus,            /*  1   NT_PRSTATUS (old)       */
1248 #else
1249         note_notsup,            /*  1   NT_PRSTATUS (old)       */
1250 #endif
1251         note_notsup,            /*  2   NT_PRFPREG (old)        */
1252 #ifdef __x86
1253         note_linux_psinfo,              /*  3   NT_PRPSINFO (old)       */
1254 #else
1255         note_notsup,            /*  3   NT_PRPSINFO (old)       */
1256 #endif
1257 #ifdef __sparc
1258         note_xreg,              /*  4   NT_PRXREG               */
1259 #else
1260         note_notsup,            /*  4   NT_PRXREG               */
1261 #endif
1262         note_platform,          /*  5   NT_PLATFORM             */
1263         note_auxv,              /*  6   NT_AUXV                 */
1264 #ifdef __sparc
1265         note_gwindows,          /*  7   NT_GWINDOWS             */
1266 #ifdef __sparcv9
1267         note_asrs,              /*  8   NT_ASRS                 */
1268 #else
1269         note_notsup,            /*  8   NT_ASRS                 */
1270 #endif
1271 #else
1272         note_notsup,            /*  7   NT_GWINDOWS             */
1273         note_notsup,            /*  8   NT_ASRS                 */
1274 #endif
1275 #ifdef __x86
1276         note_ldt,               /*  9   NT_LDT                  */
1277 #else
1278         note_notsup,            /*  9   NT_LDT                  */
1279 #endif
1280         note_pstatus,           /* 10   NT_PSTATUS              */
1281         note_notsup,            /* 11   unassigned              */




  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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2018, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2013 by Delphix. All rights reserved.
  29  * Copyright 2015 Gary Mills
  30  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  31  * Copyright 2023 Oxide Computer Company
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/utsname.h>
  36 #include <sys/sysmacros.h>
  37 #include <sys/proc.h>
  38 
  39 #include <alloca.h>
  40 #include <rtld_db.h>
  41 #include <libgen.h>
  42 #include <limits.h>
  43 #include <string.h>
  44 #include <stdlib.h>
  45 #include <unistd.h>
  46 #include <errno.h>
  47 #include <gelf.h>
  48 #include <stddef.h>
  49 #include <signal.h>
  50 
  51 #include "libproc.h"


1064 
1065         if (_libproc_debug) {
1066                 for (i = 0; i < n; i++) {
1067                         dprintf("P->auxv[%lu] = ( %d, 0x%lx )\n", (ulong_t)i,
1068                             P->auxv[i].a_type, P->auxv[i].a_un.a_val);
1069                 }
1070         }
1071 
1072         /*
1073          * Defensive coding for loops which depend upon the auxv array being
1074          * terminated by an AT_NULL element; in each case, we've allocated
1075          * P->auxv to have an additional element which we force to be AT_NULL.
1076          */
1077         P->auxv[n].a_type = AT_NULL;
1078         P->auxv[n].a_un.a_val = 0L;
1079         P->nauxv = (int)n;
1080 
1081         return (0);
1082 }
1083 
1084 /*
1085  * The xregs are not a fixed size on all architectures (notably x86) and in
1086  * general the prxregset_t has become opaque to deal with this. This means that
1087  * validating the note itself can be a little more challenging. Especially as
1088  * this can change across time. In this case we require that our consumers
1089  * perform this validation right now ala what mdb does before using the xregs
1090  * data.
1091  */
1092 static int
1093 note_xreg(struct ps_prochandle *P, size_t nbytes)
1094 {
1095         core_info_t *core = P->data;
1096         lwp_info_t *lwp = core->core_lwp;

1097         prxregset_t *xregs;
1098         ssize_t sret;
1099 
1100         if (lwp == NULL || lwp->lwp_xregs != NULL)
1101                 return (0);     /* No lwp yet, already seen, or bad size */
1102 
1103         if ((xregs = malloc(nbytes)) == NULL)
1104                 return (-1);
1105 
1106         sret = read(P->asfd, xregs, nbytes);
1107         if (sret < 0 || (size_t)sret != nbytes) {
1108                 dprintf("Pgrab_core: failed to read NT_PRXREG\n");
1109                 free(xregs);
1110                 return (-1);
1111         }
1112 
1113         lwp->lwp_xregs = xregs;
1114         lwp->lwp_xregsize = nbytes;
1115         return (0);
1116 }
1117 
1118 #ifdef __sparc
1119 static int
1120 note_gwindows(struct ps_prochandle *P, size_t nbytes)
1121 {
1122         core_info_t *core = P->data;
1123         lwp_info_t *lwp = core->core_lwp;
1124 
1125         if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)
1126                 return (0);     /* No lwp yet or already seen or no data */
1127 
1128         if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
1129                 return (-1);
1130 
1131         /*
1132          * Since the amount of gwindows data varies with how many windows were
1133          * actually saved, we just read up to the minimum of the note size
1134          * and the size of the gwindows_t type.  It doesn't matter if the read
1135          * fails since we have to zero out gwindows first anyway.
1136          */
1137 #ifdef _LP64
1138         if (core->core_dmodel == PR_MODEL_ILP32) {


1247         return (0);
1248 }
1249 
1250 /*
1251  * Populate a table of function pointers indexed by Note type with our
1252  * functions to process each type of core file note:
1253  */
1254 static int (*nhdlrs[])(struct ps_prochandle *, size_t) = {
1255         note_notsup,            /*  0   unassigned              */
1256 #ifdef __x86
1257         note_linux_prstatus,            /*  1   NT_PRSTATUS (old)       */
1258 #else
1259         note_notsup,            /*  1   NT_PRSTATUS (old)       */
1260 #endif
1261         note_notsup,            /*  2   NT_PRFPREG (old)        */
1262 #ifdef __x86
1263         note_linux_psinfo,              /*  3   NT_PRPSINFO (old)       */
1264 #else
1265         note_notsup,            /*  3   NT_PRPSINFO (old)       */
1266 #endif

1267         note_xreg,              /*  4   NT_PRXREG               */



1268         note_platform,          /*  5   NT_PLATFORM             */
1269         note_auxv,              /*  6   NT_AUXV                 */
1270 #ifdef __sparc
1271         note_gwindows,          /*  7   NT_GWINDOWS             */
1272 #ifdef __sparcv9
1273         note_asrs,              /*  8   NT_ASRS                 */
1274 #else
1275         note_notsup,            /*  8   NT_ASRS                 */
1276 #endif
1277 #else
1278         note_notsup,            /*  7   NT_GWINDOWS             */
1279         note_notsup,            /*  8   NT_ASRS                 */
1280 #endif
1281 #ifdef __x86
1282         note_ldt,               /*  9   NT_LDT                  */
1283 #else
1284         note_notsup,            /*  9   NT_LDT                  */
1285 #endif
1286         note_pstatus,           /* 10   NT_PSTATUS              */
1287         note_notsup,            /* 11   unassigned              */