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