142 if (core->core_cred != NULL) {
143 /*
144 * Avoid returning more supplementary group data than the
145 * caller has allocated in their buffer. We expect them to
146 * check pr_ngroups afterward and potentially call us again.
147 */
148 ngroups = MIN(ngroups, core->core_cred->pr_ngroups);
149
150 (void) memcpy(pcrp, core->core_cred,
151 sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t));
152
153 return (0);
154 }
155
156 errno = ENODATA;
157 return (-1);
158 }
159
160 /*ARGSUSED*/
161 static int
162 Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data)
163 {
164 core_info_t *core = data;
165
166 if (core->core_priv == NULL) {
167 errno = ENODATA;
168 return (-1);
169 }
170
171 *pprv = malloc(core->core_priv_size);
172 if (*pprv == NULL) {
173 return (-1);
174 }
175
176 (void) memcpy(*pprv, core->core_priv, core->core_priv_size);
177 return (0);
178 }
179
180 /*ARGSUSED*/
181 static const psinfo_t *
205 if (lwp->lwp_asrs != NULL)
206 free(lwp->lwp_asrs);
207 #endif
208 free(lwp);
209 }
210
211 if (core->core_platform != NULL)
212 free(core->core_platform);
213 if (core->core_uts != NULL)
214 free(core->core_uts);
215 if (core->core_cred != NULL)
216 free(core->core_cred);
217 if (core->core_priv != NULL)
218 free(core->core_priv);
219 if (core->core_privinfo != NULL)
220 __priv_free_info(core->core_privinfo);
221 if (core->core_ppii != NULL)
222 free(core->core_ppii);
223 if (core->core_zonename != NULL)
224 free(core->core_zonename);
225 #ifdef __x86
226 if (core->core_ldt != NULL)
227 free(core->core_ldt);
228 #endif
229
230 free(core);
231 }
232 }
233
234 /*ARGSUSED*/
235 static char *
236 Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data)
237 {
238 core_info_t *core = data;
239
240 if (core->core_platform == NULL) {
241 errno = ENODATA;
242 return (NULL);
243 }
244 (void) strncpy(s, core->core_platform, n - 1);
291 nldt * sizeof (struct ssd));
292
293 return (nldt);
294 }
295
296 errno = ENODATA;
297 return (-1);
298 }
299 #endif
300
301 static const ps_ops_t P_core_ops = {
302 .pop_pread = Pread_core,
303 .pop_pwrite = Pwrite_core,
304 .pop_cred = Pcred_core,
305 .pop_priv = Ppriv_core,
306 .pop_psinfo = Ppsinfo_core,
307 .pop_fini = Pfini_core,
308 .pop_platform = Pplatform_core,
309 .pop_uname = Puname_core,
310 .pop_zonename = Pzonename_core,
311 #ifdef __x86
312 .pop_ldt = Pldt_core
313 #endif
314 };
315
316 /*
317 * Return the lwp_info_t for the given lwpid. If no such lwpid has been
318 * encountered yet, allocate a new structure and return a pointer to it.
319 * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
320 */
321 static lwp_info_t *
322 lwpid2info(struct ps_prochandle *P, lwpid_t id)
323 {
324 core_info_t *core = P->data;
325 lwp_info_t *lwp = list_next(&core->core_lwp_head);
326 lwp_info_t *next;
327 uint_t i;
328
329 for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
330 if (lwp->lwp_id == id) {
729 core_info_t *core = P->data;
730 char *plat;
731
732 if (core->core_platform != NULL)
733 return (0); /* Already seen */
734
735 if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
736 if (read(P->asfd, plat, nbytes) != nbytes) {
737 dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
738 free(plat);
739 return (-1);
740 }
741 plat[nbytes - 1] = '\0';
742 core->core_platform = plat;
743 }
744
745 return (0);
746 }
747
748 static int
749 note_utsname(struct ps_prochandle *P, size_t nbytes)
750 {
751 core_info_t *core = P->data;
752 size_t ubytes = sizeof (struct utsname);
753 struct utsname *utsp;
754
755 if (core->core_uts != NULL || nbytes < ubytes)
756 return (0); /* Already seen or bad size */
757
758 if ((utsp = malloc(ubytes)) == NULL)
759 return (-1);
760
761 if (read(P->asfd, utsp, ubytes) != ubytes) {
762 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
763 free(utsp);
764 return (-1);
765 }
766
767 if (_libproc_debug) {
768 dprintf("uts.sysname = \"%s\"\n", utsp->sysname);
1163 #endif
1164 #ifdef __x86
1165 note_ldt, /* 9 NT_LDT */
1166 #else
1167 note_notsup, /* 9 NT_LDT */
1168 #endif
1169 note_pstatus, /* 10 NT_PSTATUS */
1170 note_notsup, /* 11 unassigned */
1171 note_notsup, /* 12 unassigned */
1172 note_psinfo, /* 13 NT_PSINFO */
1173 note_cred, /* 14 NT_PRCRED */
1174 note_utsname, /* 15 NT_UTSNAME */
1175 note_lwpstatus, /* 16 NT_LWPSTATUS */
1176 note_lwpsinfo, /* 17 NT_LWPSINFO */
1177 note_priv, /* 18 NT_PRPRIV */
1178 note_priv_info, /* 19 NT_PRPRIVINFO */
1179 note_content, /* 20 NT_CONTENT */
1180 note_zonename, /* 21 NT_ZONENAME */
1181 note_fdinfo, /* 22 NT_FDINFO */
1182 note_spymaster, /* 23 NT_SPYMASTER */
1183 };
1184
1185 static void
1186 core_report_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1187 {
1188 prkillinfo_t killinfo;
1189 siginfo_t *si = &killinfo.prk_info;
1190 char signame[SIG2STR_MAX], sig[64], info[64];
1191 void *addr = (void *)(uintptr_t)php->p_vaddr;
1192
1193 const char *errfmt = "core file data for mapping at %p not saved: %s\n";
1194 const char *incfmt = "core file incomplete due to %s%s\n";
1195 const char *msgfmt = "mappings at and above %p are missing\n";
1196
1197 if (!(php->p_flags & PF_SUNW_KILLED)) {
1198 int err = 0;
1199
1200 (void) pread64(P->asfd, &err,
1201 sizeof (err), (off64_t)php->p_offset);
1202
|
142 if (core->core_cred != NULL) {
143 /*
144 * Avoid returning more supplementary group data than the
145 * caller has allocated in their buffer. We expect them to
146 * check pr_ngroups afterward and potentially call us again.
147 */
148 ngroups = MIN(ngroups, core->core_cred->pr_ngroups);
149
150 (void) memcpy(pcrp, core->core_cred,
151 sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t));
152
153 return (0);
154 }
155
156 errno = ENODATA;
157 return (-1);
158 }
159
160 /*ARGSUSED*/
161 static int
162 Psecflags_core(struct ps_prochandle *P, prsecflags_t **psf, void *data)
163 {
164 core_info_t *core = data;
165
166 if (core->core_secflags == NULL) {
167 errno = ENODATA;
168 return (-1);
169 }
170
171 if ((*psf = calloc(1, sizeof (prsecflags_t))) == NULL)
172 return (-1);
173
174 (void) memcpy(*psf, core->core_secflags, sizeof (prsecflags_t));
175
176 return (0);
177 }
178
179 /*ARGSUSED*/
180 static int
181 Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data)
182 {
183 core_info_t *core = data;
184
185 if (core->core_priv == NULL) {
186 errno = ENODATA;
187 return (-1);
188 }
189
190 *pprv = malloc(core->core_priv_size);
191 if (*pprv == NULL) {
192 return (-1);
193 }
194
195 (void) memcpy(*pprv, core->core_priv, core->core_priv_size);
196 return (0);
197 }
198
199 /*ARGSUSED*/
200 static const psinfo_t *
224 if (lwp->lwp_asrs != NULL)
225 free(lwp->lwp_asrs);
226 #endif
227 free(lwp);
228 }
229
230 if (core->core_platform != NULL)
231 free(core->core_platform);
232 if (core->core_uts != NULL)
233 free(core->core_uts);
234 if (core->core_cred != NULL)
235 free(core->core_cred);
236 if (core->core_priv != NULL)
237 free(core->core_priv);
238 if (core->core_privinfo != NULL)
239 __priv_free_info(core->core_privinfo);
240 if (core->core_ppii != NULL)
241 free(core->core_ppii);
242 if (core->core_zonename != NULL)
243 free(core->core_zonename);
244 if (core->core_secflags != NULL)
245 free(core->core_secflags);
246 #ifdef __x86
247 if (core->core_ldt != NULL)
248 free(core->core_ldt);
249 #endif
250
251 free(core);
252 }
253 }
254
255 /*ARGSUSED*/
256 static char *
257 Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data)
258 {
259 core_info_t *core = data;
260
261 if (core->core_platform == NULL) {
262 errno = ENODATA;
263 return (NULL);
264 }
265 (void) strncpy(s, core->core_platform, n - 1);
312 nldt * sizeof (struct ssd));
313
314 return (nldt);
315 }
316
317 errno = ENODATA;
318 return (-1);
319 }
320 #endif
321
322 static const ps_ops_t P_core_ops = {
323 .pop_pread = Pread_core,
324 .pop_pwrite = Pwrite_core,
325 .pop_cred = Pcred_core,
326 .pop_priv = Ppriv_core,
327 .pop_psinfo = Ppsinfo_core,
328 .pop_fini = Pfini_core,
329 .pop_platform = Pplatform_core,
330 .pop_uname = Puname_core,
331 .pop_zonename = Pzonename_core,
332 .pop_secflags = Psecflags_core,
333 #ifdef __x86
334 .pop_ldt = Pldt_core
335 #endif
336 };
337
338 /*
339 * Return the lwp_info_t for the given lwpid. If no such lwpid has been
340 * encountered yet, allocate a new structure and return a pointer to it.
341 * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
342 */
343 static lwp_info_t *
344 lwpid2info(struct ps_prochandle *P, lwpid_t id)
345 {
346 core_info_t *core = P->data;
347 lwp_info_t *lwp = list_next(&core->core_lwp_head);
348 lwp_info_t *next;
349 uint_t i;
350
351 for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
352 if (lwp->lwp_id == id) {
751 core_info_t *core = P->data;
752 char *plat;
753
754 if (core->core_platform != NULL)
755 return (0); /* Already seen */
756
757 if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
758 if (read(P->asfd, plat, nbytes) != nbytes) {
759 dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
760 free(plat);
761 return (-1);
762 }
763 plat[nbytes - 1] = '\0';
764 core->core_platform = plat;
765 }
766
767 return (0);
768 }
769
770 static int
771 note_secflags(struct ps_prochandle *P, size_t nbytes)
772 {
773 core_info_t *core = P->data;
774 prsecflags_t *psf;
775
776 if (core->core_secflags != NULL)
777 return (0); /* Already seen */
778
779 if (sizeof (*psf) != nbytes) {
780 dprintf("Pgrab_core: NT_SECFLAGS changed size."
781 " Need to handle a version change?\n");
782 return (-1);
783 }
784
785 if (nbytes != 0 && ((psf = malloc(nbytes)) != NULL)) {
786 if (read(P->asfd, psf, nbytes) != nbytes) {
787 dprintf("Pgrab_core: failed to read NT_SECFLAGS\n");
788 free(psf);
789 return (-1);
790 }
791
792 core->core_secflags = psf;
793 }
794
795 return (0);
796 }
797
798 static int
799 note_utsname(struct ps_prochandle *P, size_t nbytes)
800 {
801 core_info_t *core = P->data;
802 size_t ubytes = sizeof (struct utsname);
803 struct utsname *utsp;
804
805 if (core->core_uts != NULL || nbytes < ubytes)
806 return (0); /* Already seen or bad size */
807
808 if ((utsp = malloc(ubytes)) == NULL)
809 return (-1);
810
811 if (read(P->asfd, utsp, ubytes) != ubytes) {
812 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
813 free(utsp);
814 return (-1);
815 }
816
817 if (_libproc_debug) {
818 dprintf("uts.sysname = \"%s\"\n", utsp->sysname);
1213 #endif
1214 #ifdef __x86
1215 note_ldt, /* 9 NT_LDT */
1216 #else
1217 note_notsup, /* 9 NT_LDT */
1218 #endif
1219 note_pstatus, /* 10 NT_PSTATUS */
1220 note_notsup, /* 11 unassigned */
1221 note_notsup, /* 12 unassigned */
1222 note_psinfo, /* 13 NT_PSINFO */
1223 note_cred, /* 14 NT_PRCRED */
1224 note_utsname, /* 15 NT_UTSNAME */
1225 note_lwpstatus, /* 16 NT_LWPSTATUS */
1226 note_lwpsinfo, /* 17 NT_LWPSINFO */
1227 note_priv, /* 18 NT_PRPRIV */
1228 note_priv_info, /* 19 NT_PRPRIVINFO */
1229 note_content, /* 20 NT_CONTENT */
1230 note_zonename, /* 21 NT_ZONENAME */
1231 note_fdinfo, /* 22 NT_FDINFO */
1232 note_spymaster, /* 23 NT_SPYMASTER */
1233 note_secflags, /* 24 NT_SECFLAGS */
1234 };
1235
1236 static void
1237 core_report_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1238 {
1239 prkillinfo_t killinfo;
1240 siginfo_t *si = &killinfo.prk_info;
1241 char signame[SIG2STR_MAX], sig[64], info[64];
1242 void *addr = (void *)(uintptr_t)php->p_vaddr;
1243
1244 const char *errfmt = "core file data for mapping at %p not saved: %s\n";
1245 const char *incfmt = "core file incomplete due to %s%s\n";
1246 const char *msgfmt = "mappings at and above %p are missing\n";
1247
1248 if (!(php->p_flags & PF_SUNW_KILLED)) {
1249 int err = 0;
1250
1251 (void) pread64(P->asfd, &err,
1252 sizeof (err), (off64_t)php->p_offset);
1253
|