Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libproc/common/Pcore.c
+++ new/usr/src/lib/libproc/common/Pcore.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25 /*
26 26 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
27 - * Copyright (c) 2014, Joyent, Inc. All rights reserved.
27 + * Copyright (c) 2018, Joyent, Inc. All rights reserved.
28 28 * Copyright (c) 2013 by Delphix. All rights reserved.
29 29 * Copyright 2015 Gary Mills
30 30 */
31 31
32 32 #include <sys/types.h>
33 33 #include <sys/utsname.h>
34 34 #include <sys/sysmacros.h>
35 35 #include <sys/proc.h>
36 36
37 37 #include <alloca.h>
38 38 #include <rtld_db.h>
39 39 #include <libgen.h>
40 40 #include <limits.h>
41 41 #include <string.h>
42 42 #include <stdlib.h>
43 43 #include <unistd.h>
44 44 #include <errno.h>
45 45 #include <gelf.h>
46 46 #include <stddef.h>
47 47 #include <signal.h>
48 48
49 49 #include "libproc.h"
50 50 #include "Pcontrol.h"
51 51 #include "P32ton.h"
52 52 #include "Putil.h"
53 53 #ifdef __x86
54 54 #include "Pcore_linux.h"
55 55 #endif
56 56
57 57 /*
58 58 * Pcore.c - Code to initialize a ps_prochandle from a core dump. We
59 59 * allocate an additional structure to hold information from the core
60 60 * file, and attach this to the standard ps_prochandle in place of the
61 61 * ability to examine /proc/<pid>/ files.
62 62 */
63 63
64 64 /*
65 65 * Basic i/o function for reading and writing from the process address space
66 66 * stored in the core file and associated shared libraries. We compute the
67 67 * appropriate fd and offsets, and let the provided prw function do the rest.
68 68 */
69 69 static ssize_t
70 70 core_rw(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
71 71 ssize_t (*prw)(int, void *, size_t, off64_t))
72 72 {
73 73 ssize_t resid = n;
74 74
75 75 while (resid != 0) {
76 76 map_info_t *mp = Paddr2mptr(P, addr);
77 77
78 78 uintptr_t mapoff;
79 79 ssize_t len;
80 80 off64_t off;
81 81 int fd;
82 82
83 83 if (mp == NULL)
84 84 break; /* No mapping for this address */
85 85
86 86 if (mp->map_pmap.pr_mflags & MA_RESERVED1) {
87 87 if (mp->map_file == NULL || mp->map_file->file_fd < 0)
88 88 break; /* No file or file not open */
89 89
90 90 fd = mp->map_file->file_fd;
91 91 } else
92 92 fd = P->asfd;
93 93
94 94 mapoff = addr - mp->map_pmap.pr_vaddr;
95 95 len = MIN(resid, mp->map_pmap.pr_size - mapoff);
96 96 off = mp->map_offset + mapoff;
97 97
98 98 if ((len = prw(fd, buf, len, off)) <= 0)
99 99 break;
100 100
101 101 resid -= len;
102 102 addr += len;
103 103 buf = (char *)buf + len;
104 104 }
105 105
106 106 /*
107 107 * Important: Be consistent with the behavior of i/o on the as file:
108 108 * writing to an invalid address yields EIO; reading from an invalid
109 109 * address falls through to returning success and zero bytes.
110 110 */
111 111 if (resid == n && n != 0 && prw != pread64) {
112 112 errno = EIO;
113 113 return (-1);
114 114 }
115 115
116 116 return (n - resid);
117 117 }
118 118
119 119 /*ARGSUSED*/
120 120 static ssize_t
121 121 Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
122 122 void *data)
123 123 {
124 124 return (core_rw(P, buf, n, addr, pread64));
125 125 }
126 126
127 127 /*ARGSUSED*/
128 128 static ssize_t
129 129 Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
130 130 void *data)
131 131 {
132 132 return (core_rw(P, (void *)buf, n, addr,
133 133 (ssize_t (*)(int, void *, size_t, off64_t)) pwrite64));
134 134 }
135 135
136 136 /*ARGSUSED*/
137 137 static int
138 138 Pcred_core(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
139 139 {
140 140 core_info_t *core = data;
141 141
142 142 if (core->core_cred != NULL) {
143 143 /*
144 144 * Avoid returning more supplementary group data than the
145 145 * caller has allocated in their buffer. We expect them to
146 146 * check pr_ngroups afterward and potentially call us again.
147 147 */
148 148 ngroups = MIN(ngroups, core->core_cred->pr_ngroups);
149 149
150 150 (void) memcpy(pcrp, core->core_cred,
151 151 sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t));
152 152
153 153 return (0);
154 154 }
155 155
156 156 errno = ENODATA;
157 157 return (-1);
158 158 }
159 159
160 160 /*ARGSUSED*/
161 161 static int
162 162 Psecflags_core(struct ps_prochandle *P, prsecflags_t **psf, void *data)
163 163 {
164 164 core_info_t *core = data;
165 165
166 166 if (core->core_secflags == NULL) {
167 167 errno = ENODATA;
168 168 return (-1);
169 169 }
170 170
171 171 if ((*psf = calloc(1, sizeof (prsecflags_t))) == NULL)
172 172 return (-1);
173 173
174 174 (void) memcpy(*psf, core->core_secflags, sizeof (prsecflags_t));
175 175
176 176 return (0);
177 177 }
178 178
179 179 /*ARGSUSED*/
180 180 static int
181 181 Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data)
182 182 {
183 183 core_info_t *core = data;
184 184
185 185 if (core->core_priv == NULL) {
186 186 errno = ENODATA;
187 187 return (-1);
188 188 }
189 189
190 190 *pprv = malloc(core->core_priv_size);
191 191 if (*pprv == NULL) {
192 192 return (-1);
193 193 }
194 194
195 195 (void) memcpy(*pprv, core->core_priv, core->core_priv_size);
196 196 return (0);
197 197 }
198 198
199 199 /*ARGSUSED*/
200 200 static const psinfo_t *
201 201 Ppsinfo_core(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
202 202 {
203 203 return (&P->psinfo);
204 204 }
205 205
206 206 /*ARGSUSED*/
207 207 static void
208 208 Pfini_core(struct ps_prochandle *P, void *data)
209 209 {
210 210 core_info_t *core = data;
211 211
212 212 if (core != NULL) {
213 213 extern void __priv_free_info(void *);
214 214 lwp_info_t *nlwp, *lwp = list_next(&core->core_lwp_head);
215 215 int i;
216 216
217 217 for (i = 0; i < core->core_nlwp; i++, lwp = nlwp) {
218 218 nlwp = list_next(lwp);
219 219 #ifdef __sparc
220 220 if (lwp->lwp_gwins != NULL)
221 221 free(lwp->lwp_gwins);
222 222 if (lwp->lwp_xregs != NULL)
223 223 free(lwp->lwp_xregs);
224 224 if (lwp->lwp_asrs != NULL)
225 225 free(lwp->lwp_asrs);
226 226 #endif
227 227 free(lwp);
228 228 }
229 229
230 230 if (core->core_platform != NULL)
231 231 free(core->core_platform);
232 232 if (core->core_uts != NULL)
233 233 free(core->core_uts);
234 234 if (core->core_cred != NULL)
235 235 free(core->core_cred);
236 236 if (core->core_priv != NULL)
237 237 free(core->core_priv);
238 238 if (core->core_privinfo != NULL)
239 239 __priv_free_info(core->core_privinfo);
240 240 if (core->core_ppii != NULL)
241 241 free(core->core_ppii);
242 242 if (core->core_zonename != NULL)
243 243 free(core->core_zonename);
244 244 if (core->core_secflags != NULL)
245 245 free(core->core_secflags);
246 246 #ifdef __x86
247 247 if (core->core_ldt != NULL)
248 248 free(core->core_ldt);
249 249 #endif
250 250
251 251 free(core);
252 252 }
253 253 }
254 254
255 255 /*ARGSUSED*/
256 256 static char *
257 257 Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data)
258 258 {
259 259 core_info_t *core = data;
260 260
261 261 if (core->core_platform == NULL) {
262 262 errno = ENODATA;
263 263 return (NULL);
264 264 }
265 265 (void) strncpy(s, core->core_platform, n - 1);
266 266 s[n - 1] = '\0';
267 267 return (s);
268 268 }
269 269
270 270 /*ARGSUSED*/
271 271 static int
272 272 Puname_core(struct ps_prochandle *P, struct utsname *u, void *data)
273 273 {
274 274 core_info_t *core = data;
275 275
276 276 if (core->core_uts == NULL) {
277 277 errno = ENODATA;
278 278 return (-1);
279 279 }
280 280 (void) memcpy(u, core->core_uts, sizeof (struct utsname));
281 281 return (0);
282 282 }
283 283
284 284 /*ARGSUSED*/
285 285 static char *
286 286 Pzonename_core(struct ps_prochandle *P, char *s, size_t n, void *data)
287 287 {
288 288 core_info_t *core = data;
289 289
290 290 if (core->core_zonename == NULL) {
291 291 errno = ENODATA;
292 292 return (NULL);
293 293 }
294 294 (void) strlcpy(s, core->core_zonename, n);
295 295 return (s);
296 296 }
297 297
298 298 #ifdef __x86
299 299 /*ARGSUSED*/
300 300 static int
301 301 Pldt_core(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
302 302 {
303 303 core_info_t *core = data;
304 304
305 305 if (pldt == NULL || nldt == 0)
306 306 return (core->core_nldt);
307 307
308 308 if (core->core_ldt != NULL) {
309 309 nldt = MIN(nldt, core->core_nldt);
310 310
311 311 (void) memcpy(pldt, core->core_ldt,
312 312 nldt * sizeof (struct ssd));
313 313
314 314 return (nldt);
315 315 }
316 316
317 317 errno = ENODATA;
318 318 return (-1);
319 319 }
320 320 #endif
321 321
322 322 static const ps_ops_t P_core_ops = {
323 323 .pop_pread = Pread_core,
324 324 .pop_pwrite = Pwrite_core,
325 325 .pop_cred = Pcred_core,
326 326 .pop_priv = Ppriv_core,
327 327 .pop_psinfo = Ppsinfo_core,
328 328 .pop_fini = Pfini_core,
329 329 .pop_platform = Pplatform_core,
330 330 .pop_uname = Puname_core,
331 331 .pop_zonename = Pzonename_core,
332 332 .pop_secflags = Psecflags_core,
333 333 #ifdef __x86
334 334 .pop_ldt = Pldt_core
335 335 #endif
336 336 };
337 337
338 338 /*
339 339 * Return the lwp_info_t for the given lwpid. If no such lwpid has been
340 340 * encountered yet, allocate a new structure and return a pointer to it.
341 341 * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
342 342 */
343 343 static lwp_info_t *
344 344 lwpid2info(struct ps_prochandle *P, lwpid_t id)
345 345 {
346 346 core_info_t *core = P->data;
347 347 lwp_info_t *lwp = list_next(&core->core_lwp_head);
348 348 lwp_info_t *next;
349 349 uint_t i;
350 350
351 351 for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
352 352 if (lwp->lwp_id == id) {
353 353 core->core_lwp = lwp;
354 354 return (lwp);
355 355 }
356 356 if (lwp->lwp_id < id) {
357 357 break;
358 358 }
359 359 }
360 360
361 361 next = lwp;
362 362 if ((lwp = calloc(1, sizeof (lwp_info_t))) == NULL)
363 363 return (NULL);
364 364
365 365 list_link(lwp, next);
366 366 lwp->lwp_id = id;
367 367
368 368 core->core_lwp = lwp;
369 369 core->core_nlwp++;
370 370
371 371 return (lwp);
372 372 }
373 373
374 374 /*
375 375 * The core file itself contains a series of NOTE segments containing saved
376 376 * structures from /proc at the time the process died. For each note we
377 377 * comprehend, we define a function to read it in from the core file,
378 378 * convert it to our native data model if necessary, and store it inside
379 379 * the ps_prochandle. Each function is invoked by Pfgrab_core() with the
380 380 * seek pointer on P->asfd positioned appropriately. We populate a table
381 381 * of pointers to these note functions below.
382 382 */
383 383
384 384 static int
385 385 note_pstatus(struct ps_prochandle *P, size_t nbytes)
386 386 {
387 387 #ifdef _LP64
388 388 core_info_t *core = P->data;
389 389
390 390 if (core->core_dmodel == PR_MODEL_ILP32) {
391 391 pstatus32_t ps32;
392 392
393 393 if (nbytes < sizeof (pstatus32_t) ||
394 394 read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
395 395 goto err;
396 396
397 397 pstatus_32_to_n(&ps32, &P->status);
398 398
399 399 } else
400 400 #endif
401 401 if (nbytes < sizeof (pstatus_t) ||
402 402 read(P->asfd, &P->status, sizeof (pstatus_t)) != sizeof (pstatus_t))
403 403 goto err;
404 404
405 405 P->orig_status = P->status;
406 406 P->pid = P->status.pr_pid;
407 407
408 408 return (0);
409 409
410 410 err:
411 411 dprintf("Pgrab_core: failed to read NT_PSTATUS\n");
412 412 return (-1);
413 413 }
414 414
415 415 static int
416 416 note_lwpstatus(struct ps_prochandle *P, size_t nbytes)
417 417 {
418 418 lwp_info_t *lwp;
419 419 lwpstatus_t lps;
420 420
421 421 #ifdef _LP64
422 422 core_info_t *core = P->data;
423 423
424 424 if (core->core_dmodel == PR_MODEL_ILP32) {
425 425 lwpstatus32_t l32;
426 426
427 427 if (nbytes < sizeof (lwpstatus32_t) ||
428 428 read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
429 429 goto err;
430 430
431 431 lwpstatus_32_to_n(&l32, &lps);
432 432 } else
433 433 #endif
434 434 if (nbytes < sizeof (lwpstatus_t) ||
435 435 read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
436 436 goto err;
437 437
438 438 if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
439 439 dprintf("Pgrab_core: failed to add NT_LWPSTATUS\n");
440 440 return (-1);
441 441 }
442 442
443 443 /*
444 444 * Erase a useless and confusing artifact of the kernel implementation:
445 445 * the lwps which did *not* create the core will show SIGKILL. We can
446 446 * be assured this is bogus because SIGKILL can't produce core files.
447 447 */
448 448 if (lps.pr_cursig == SIGKILL)
449 449 lps.pr_cursig = 0;
450 450
451 451 (void) memcpy(&lwp->lwp_status, &lps, sizeof (lps));
452 452 return (0);
453 453
454 454 err:
455 455 dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
456 456 return (-1);
457 457 }
458 458
459 459 #ifdef __x86
460 460
461 461 static void
462 462 lx_prpsinfo32_to_psinfo(lx_prpsinfo32_t *p32, psinfo_t *psinfo)
463 463 {
464 464 psinfo->pr_flag = p32->pr_flag;
465 465 psinfo->pr_pid = p32->pr_pid;
466 466 psinfo->pr_ppid = p32->pr_ppid;
467 467 psinfo->pr_uid = p32->pr_uid;
468 468 psinfo->pr_gid = p32->pr_gid;
469 469 psinfo->pr_sid = p32->pr_sid;
470 470 psinfo->pr_pgid = p32->pr_pgrp;
471 471
472 472 (void) memcpy(psinfo->pr_fname, p32->pr_fname,
473 473 sizeof (psinfo->pr_fname));
474 474 (void) memcpy(psinfo->pr_psargs, p32->pr_psargs,
475 475 sizeof (psinfo->pr_psargs));
476 476 }
477 477
478 478 static void
479 479 lx_prpsinfo64_to_psinfo(lx_prpsinfo64_t *p64, psinfo_t *psinfo)
480 480 {
481 481 psinfo->pr_flag = p64->pr_flag;
482 482 psinfo->pr_pid = p64->pr_pid;
483 483 psinfo->pr_ppid = p64->pr_ppid;
484 484 psinfo->pr_uid = p64->pr_uid;
485 485 psinfo->pr_gid = p64->pr_gid;
486 486 psinfo->pr_sid = p64->pr_sid;
487 487 psinfo->pr_pgid = p64->pr_pgrp;
488 488 psinfo->pr_pgid = p64->pr_pgrp;
489 489
490 490 (void) memcpy(psinfo->pr_fname, p64->pr_fname,
491 491 sizeof (psinfo->pr_fname));
492 492 (void) memcpy(psinfo->pr_psargs, p64->pr_psargs,
493 493 sizeof (psinfo->pr_psargs));
494 494 }
495 495
496 496 static int
497 497 note_linux_psinfo(struct ps_prochandle *P, size_t nbytes)
498 498 {
499 499 core_info_t *core = P->data;
500 500 lx_prpsinfo32_t p32;
501 501 lx_prpsinfo64_t p64;
502 502
503 503 if (core->core_dmodel == PR_MODEL_ILP32) {
504 504 if (nbytes < sizeof (p32) ||
505 505 read(P->asfd, &p32, sizeof (p32)) != sizeof (p32))
506 506 goto err;
507 507
508 508 lx_prpsinfo32_to_psinfo(&p32, &P->psinfo);
509 509 } else {
510 510 if (nbytes < sizeof (p64) ||
511 511 read(P->asfd, &p64, sizeof (p64)) != sizeof (p64))
512 512 goto err;
513 513
514 514 lx_prpsinfo64_to_psinfo(&p64, &P->psinfo);
515 515 }
516 516
517 517
518 518 P->status.pr_pid = P->psinfo.pr_pid;
519 519 P->status.pr_ppid = P->psinfo.pr_ppid;
520 520 P->status.pr_pgid = P->psinfo.pr_pgid;
521 521 P->status.pr_sid = P->psinfo.pr_sid;
522 522
523 523 P->psinfo.pr_nlwp = 0;
524 524 P->status.pr_nlwp = 0;
525 525
526 526 return (0);
527 527 err:
528 528 dprintf("Pgrab_core: failed to read NT_PSINFO\n");
529 529 return (-1);
530 530 }
531 531
532 532 static void
533 533 lx_prstatus64_to_lwp(lx_prstatus64_t *prs64, lwp_info_t *lwp)
534 534 {
535 535 LTIME_TO_TIMESPEC(lwp->lwp_status.pr_utime, prs64->pr_utime);
536 536 LTIME_TO_TIMESPEC(lwp->lwp_status.pr_stime, prs64->pr_stime);
537 537
538 538 lwp->lwp_status.pr_reg[REG_R15] = prs64->pr_reg.lxr_r15;
539 539 lwp->lwp_status.pr_reg[REG_R14] = prs64->pr_reg.lxr_r14;
540 540 lwp->lwp_status.pr_reg[REG_R13] = prs64->pr_reg.lxr_r13;
541 541 lwp->lwp_status.pr_reg[REG_R12] = prs64->pr_reg.lxr_r12;
542 542 lwp->lwp_status.pr_reg[REG_R11] = prs64->pr_reg.lxr_r11;
543 543 lwp->lwp_status.pr_reg[REG_R10] = prs64->pr_reg.lxr_r10;
544 544 lwp->lwp_status.pr_reg[REG_R9] = prs64->pr_reg.lxr_r9;
545 545 lwp->lwp_status.pr_reg[REG_R8] = prs64->pr_reg.lxr_r8;
546 546
547 547 lwp->lwp_status.pr_reg[REG_RDI] = prs64->pr_reg.lxr_rdi;
548 548 lwp->lwp_status.pr_reg[REG_RSI] = prs64->pr_reg.lxr_rsi;
549 549 lwp->lwp_status.pr_reg[REG_RBP] = prs64->pr_reg.lxr_rbp;
550 550 lwp->lwp_status.pr_reg[REG_RBX] = prs64->pr_reg.lxr_rbx;
551 551 lwp->lwp_status.pr_reg[REG_RDX] = prs64->pr_reg.lxr_rdx;
552 552 lwp->lwp_status.pr_reg[REG_RCX] = prs64->pr_reg.lxr_rcx;
553 553 lwp->lwp_status.pr_reg[REG_RAX] = prs64->pr_reg.lxr_rax;
554 554
555 555 lwp->lwp_status.pr_reg[REG_RIP] = prs64->pr_reg.lxr_rip;
556 556 lwp->lwp_status.pr_reg[REG_CS] = prs64->pr_reg.lxr_cs;
557 557 lwp->lwp_status.pr_reg[REG_RSP] = prs64->pr_reg.lxr_rsp;
558 558 lwp->lwp_status.pr_reg[REG_FS] = prs64->pr_reg.lxr_fs;
559 559 lwp->lwp_status.pr_reg[REG_SS] = prs64->pr_reg.lxr_ss;
560 560 lwp->lwp_status.pr_reg[REG_GS] = prs64->pr_reg.lxr_gs;
561 561 lwp->lwp_status.pr_reg[REG_ES] = prs64->pr_reg.lxr_es;
562 562 lwp->lwp_status.pr_reg[REG_DS] = prs64->pr_reg.lxr_ds;
563 563
564 564 lwp->lwp_status.pr_reg[REG_GSBASE] = prs64->pr_reg.lxr_gs_base;
565 565 lwp->lwp_status.pr_reg[REG_FSBASE] = prs64->pr_reg.lxr_fs_base;
566 566 }
567 567
568 568 static void
569 569 lx_prstatus32_to_lwp(lx_prstatus32_t *prs32, lwp_info_t *lwp)
570 570 {
571 571 LTIME_TO_TIMESPEC(lwp->lwp_status.pr_utime, prs32->pr_utime);
572 572 LTIME_TO_TIMESPEC(lwp->lwp_status.pr_stime, prs32->pr_stime);
573 573
574 574 #ifdef __amd64
575 575 lwp->lwp_status.pr_reg[REG_GS] = prs32->pr_reg.lxr_gs;
576 576 lwp->lwp_status.pr_reg[REG_FS] = prs32->pr_reg.lxr_fs;
577 577 lwp->lwp_status.pr_reg[REG_DS] = prs32->pr_reg.lxr_ds;
578 578 lwp->lwp_status.pr_reg[REG_ES] = prs32->pr_reg.lxr_es;
579 579 lwp->lwp_status.pr_reg[REG_RDI] = prs32->pr_reg.lxr_di;
580 580 lwp->lwp_status.pr_reg[REG_RSI] = prs32->pr_reg.lxr_si;
581 581 lwp->lwp_status.pr_reg[REG_RBP] = prs32->pr_reg.lxr_bp;
582 582 lwp->lwp_status.pr_reg[REG_RBX] = prs32->pr_reg.lxr_bx;
583 583 lwp->lwp_status.pr_reg[REG_RDX] = prs32->pr_reg.lxr_dx;
584 584 lwp->lwp_status.pr_reg[REG_RCX] = prs32->pr_reg.lxr_cx;
585 585 lwp->lwp_status.pr_reg[REG_RAX] = prs32->pr_reg.lxr_ax;
586 586 lwp->lwp_status.pr_reg[REG_RIP] = prs32->pr_reg.lxr_ip;
587 587 lwp->lwp_status.pr_reg[REG_CS] = prs32->pr_reg.lxr_cs;
588 588 lwp->lwp_status.pr_reg[REG_RFL] = prs32->pr_reg.lxr_flags;
589 589 lwp->lwp_status.pr_reg[REG_RSP] = prs32->pr_reg.lxr_sp;
590 590 lwp->lwp_status.pr_reg[REG_SS] = prs32->pr_reg.lxr_ss;
591 591 #else /* __amd64 */
592 592 lwp->lwp_status.pr_reg[EBX] = prs32->pr_reg.lxr_bx;
593 593 lwp->lwp_status.pr_reg[ECX] = prs32->pr_reg.lxr_cx;
594 594 lwp->lwp_status.pr_reg[EDX] = prs32->pr_reg.lxr_dx;
595 595 lwp->lwp_status.pr_reg[ESI] = prs32->pr_reg.lxr_si;
596 596 lwp->lwp_status.pr_reg[EDI] = prs32->pr_reg.lxr_di;
597 597 lwp->lwp_status.pr_reg[EBP] = prs32->pr_reg.lxr_bp;
598 598 lwp->lwp_status.pr_reg[EAX] = prs32->pr_reg.lxr_ax;
599 599 lwp->lwp_status.pr_reg[EIP] = prs32->pr_reg.lxr_ip;
600 600 lwp->lwp_status.pr_reg[UESP] = prs32->pr_reg.lxr_sp;
601 601
602 602 lwp->lwp_status.pr_reg[DS] = prs32->pr_reg.lxr_ds;
603 603 lwp->lwp_status.pr_reg[ES] = prs32->pr_reg.lxr_es;
604 604 lwp->lwp_status.pr_reg[FS] = prs32->pr_reg.lxr_fs;
605 605 lwp->lwp_status.pr_reg[GS] = prs32->pr_reg.lxr_gs;
606 606 lwp->lwp_status.pr_reg[CS] = prs32->pr_reg.lxr_cs;
607 607 lwp->lwp_status.pr_reg[SS] = prs32->pr_reg.lxr_ss;
608 608
609 609 lwp->lwp_status.pr_reg[EFL] = prs32->pr_reg.lxr_flags;
610 610 #endif /* !__amd64 */
611 611 }
612 612
613 613 static int
614 614 note_linux_prstatus(struct ps_prochandle *P, size_t nbytes)
615 615 {
616 616 core_info_t *core = P->data;
617 617
618 618 lx_prstatus64_t prs64;
619 619 lx_prstatus32_t prs32;
620 620 lwp_info_t *lwp;
621 621 lwpid_t tid;
622 622
623 623 dprintf("looking for model %d, %ld/%ld\n", core->core_dmodel,
624 624 (ulong_t)nbytes, (ulong_t)sizeof (prs32));
625 625 if (core->core_dmodel == PR_MODEL_ILP32) {
626 626 if (nbytes < sizeof (prs32) ||
627 627 read(P->asfd, &prs32, sizeof (prs32)) != nbytes)
628 628 goto err;
629 629 tid = prs32.pr_pid;
630 630 } else {
631 631 if (nbytes < sizeof (prs64) ||
632 632 read(P->asfd, &prs64, sizeof (prs64)) != nbytes)
633 633 goto err;
634 634 tid = prs64.pr_pid;
635 635 }
636 636
637 637 if ((lwp = lwpid2info(P, tid)) == NULL) {
638 638 dprintf("Pgrab_core: failed to add lwpid2info "
639 639 "linux_prstatus\n");
640 640 return (-1);
641 641 }
642 642
643 643 P->psinfo.pr_nlwp++;
644 644 P->status.pr_nlwp++;
645 645
646 646 lwp->lwp_status.pr_lwpid = tid;
647 647
648 648 if (core->core_dmodel == PR_MODEL_ILP32)
649 649 lx_prstatus32_to_lwp(&prs32, lwp);
650 650 else
651 651 lx_prstatus64_to_lwp(&prs64, lwp);
652 652
653 653 return (0);
654 654 err:
655 655 dprintf("Pgrab_core: failed to read NT_PRSTATUS\n");
656 656 return (-1);
657 657 }
658 658
659 659 #endif /* __x86 */
660 660
661 661 static int
662 662 note_psinfo(struct ps_prochandle *P, size_t nbytes)
663 663 {
664 664 #ifdef _LP64
665 665 core_info_t *core = P->data;
666 666
667 667 if (core->core_dmodel == PR_MODEL_ILP32) {
668 668 psinfo32_t ps32;
669 669
670 670 if (nbytes < sizeof (psinfo32_t) ||
671 671 read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
672 672 goto err;
673 673
674 674 psinfo_32_to_n(&ps32, &P->psinfo);
675 675 } else
676 676 #endif
677 677 if (nbytes < sizeof (psinfo_t) ||
678 678 read(P->asfd, &P->psinfo, sizeof (psinfo_t)) != sizeof (psinfo_t))
679 679 goto err;
680 680
681 681 dprintf("pr_fname = <%s>\n", P->psinfo.pr_fname);
682 682 dprintf("pr_psargs = <%s>\n", P->psinfo.pr_psargs);
683 683 dprintf("pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
684 684
685 685 return (0);
686 686
687 687 err:
688 688 dprintf("Pgrab_core: failed to read NT_PSINFO\n");
689 689 return (-1);
690 690 }
691 691
692 692 static int
693 693 note_lwpsinfo(struct ps_prochandle *P, size_t nbytes)
694 694 {
695 695 lwp_info_t *lwp;
696 696 lwpsinfo_t lps;
697 697
698 698 #ifdef _LP64
699 699 core_info_t *core = P->data;
700 700
701 701 if (core->core_dmodel == PR_MODEL_ILP32) {
702 702 lwpsinfo32_t l32;
703 703
704 704 if (nbytes < sizeof (lwpsinfo32_t) ||
705 705 read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
706 706 goto err;
707 707
708 708 lwpsinfo_32_to_n(&l32, &lps);
709 709 } else
710 710 #endif
711 711 if (nbytes < sizeof (lwpsinfo_t) ||
712 712 read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
713 713 goto err;
714 714
715 715 if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
716 716 dprintf("Pgrab_core: failed to add NT_LWPSINFO\n");
717 717 return (-1);
718 718 }
↓ open down ↓ |
681 lines elided |
↑ open up ↑ |
719 719
720 720 (void) memcpy(&lwp->lwp_psinfo, &lps, sizeof (lps));
721 721 return (0);
722 722
723 723 err:
724 724 dprintf("Pgrab_core: failed to read NT_LWPSINFO\n");
725 725 return (-1);
726 726 }
727 727
728 728 static int
729 +note_lwpname(struct ps_prochandle *P, size_t nbytes)
730 +{
731 + prlwpname_t name;
732 + lwp_info_t *lwp;
733 +
734 + if (nbytes != sizeof (name) ||
735 + read(P->asfd, &name, sizeof (name)) != sizeof (name))
736 + goto err;
737 +
738 + if ((lwp = lwpid2info(P, name.pr_lwpid)) == NULL)
739 + goto err;
740 +
741 + if (strlcpy(lwp->lwp_name, name.pr_lwpname,
742 + sizeof (lwp->lwp_name)) >= sizeof (lwp->lwp_name)) {
743 + errno = ENAMETOOLONG;
744 + goto err;
745 + }
746 +
747 + return (0);
748 +
749 +err:
750 + dprintf("Pgrab_core: failed to read NT_LWPNAME\n");
751 + return (-1);
752 +}
753 +
754 +static int
729 755 note_fdinfo(struct ps_prochandle *P, size_t nbytes)
730 756 {
731 757 prfdinfo_t prfd;
732 758 fd_info_t *fip;
733 759
734 760 if ((nbytes < sizeof (prfd)) ||
735 761 (read(P->asfd, &prfd, sizeof (prfd)) != sizeof (prfd))) {
736 762 dprintf("Pgrab_core: failed to read NT_FDINFO\n");
737 763 return (-1);
738 764 }
739 765
740 766 if ((fip = Pfd2info(P, prfd.pr_fd)) == NULL) {
741 767 dprintf("Pgrab_core: failed to add NT_FDINFO\n");
742 768 return (-1);
743 769 }
744 770 (void) memcpy(&fip->fd_info, &prfd, sizeof (prfd));
745 771 return (0);
746 772 }
747 773
748 774 static int
749 775 note_platform(struct ps_prochandle *P, size_t nbytes)
750 776 {
751 777 core_info_t *core = P->data;
752 778 char *plat;
753 779
754 780 if (core->core_platform != NULL)
755 781 return (0); /* Already seen */
756 782
757 783 if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
758 784 if (read(P->asfd, plat, nbytes) != nbytes) {
759 785 dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
760 786 free(plat);
761 787 return (-1);
762 788 }
763 789 plat[nbytes - 1] = '\0';
764 790 core->core_platform = plat;
765 791 }
766 792
767 793 return (0);
768 794 }
769 795
770 796 static int
771 797 note_secflags(struct ps_prochandle *P, size_t nbytes)
772 798 {
773 799 core_info_t *core = P->data;
774 800 prsecflags_t *psf;
775 801
776 802 if (core->core_secflags != NULL)
777 803 return (0); /* Already seen */
778 804
779 805 if (sizeof (*psf) != nbytes) {
780 806 dprintf("Pgrab_core: NT_SECFLAGS changed size."
781 807 " Need to handle a version change?\n");
782 808 return (-1);
783 809 }
784 810
785 811 if (nbytes != 0 && ((psf = malloc(nbytes)) != NULL)) {
786 812 if (read(P->asfd, psf, nbytes) != nbytes) {
787 813 dprintf("Pgrab_core: failed to read NT_SECFLAGS\n");
788 814 free(psf);
789 815 return (-1);
790 816 }
791 817
792 818 core->core_secflags = psf;
793 819 }
794 820
795 821 return (0);
796 822 }
797 823
798 824 static int
799 825 note_utsname(struct ps_prochandle *P, size_t nbytes)
800 826 {
801 827 core_info_t *core = P->data;
802 828 size_t ubytes = sizeof (struct utsname);
803 829 struct utsname *utsp;
804 830
805 831 if (core->core_uts != NULL || nbytes < ubytes)
806 832 return (0); /* Already seen or bad size */
807 833
808 834 if ((utsp = malloc(ubytes)) == NULL)
809 835 return (-1);
810 836
811 837 if (read(P->asfd, utsp, ubytes) != ubytes) {
812 838 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
813 839 free(utsp);
814 840 return (-1);
815 841 }
816 842
817 843 if (_libproc_debug) {
818 844 dprintf("uts.sysname = \"%s\"\n", utsp->sysname);
819 845 dprintf("uts.nodename = \"%s\"\n", utsp->nodename);
820 846 dprintf("uts.release = \"%s\"\n", utsp->release);
821 847 dprintf("uts.version = \"%s\"\n", utsp->version);
822 848 dprintf("uts.machine = \"%s\"\n", utsp->machine);
823 849 }
824 850
825 851 core->core_uts = utsp;
826 852 return (0);
827 853 }
828 854
829 855 static int
830 856 note_content(struct ps_prochandle *P, size_t nbytes)
831 857 {
832 858 core_info_t *core = P->data;
833 859 core_content_t content;
834 860
835 861 if (sizeof (core->core_content) != nbytes)
836 862 return (-1);
837 863
838 864 if (read(P->asfd, &content, sizeof (content)) != sizeof (content))
839 865 return (-1);
840 866
841 867 core->core_content = content;
842 868
843 869 dprintf("core content = %llx\n", content);
844 870
845 871 return (0);
846 872 }
847 873
848 874 static int
849 875 note_cred(struct ps_prochandle *P, size_t nbytes)
850 876 {
851 877 core_info_t *core = P->data;
852 878 prcred_t *pcrp;
853 879 int ngroups;
854 880 const size_t min_size = sizeof (prcred_t) - sizeof (gid_t);
855 881
856 882 /*
857 883 * We allow for prcred_t notes that are actually smaller than a
858 884 * prcred_t since the last member isn't essential if there are
859 885 * no group memberships. This allows for more flexibility when it
860 886 * comes to slightly malformed -- but still valid -- notes.
861 887 */
862 888 if (core->core_cred != NULL || nbytes < min_size)
863 889 return (0); /* Already seen or bad size */
864 890
865 891 ngroups = (nbytes - min_size) / sizeof (gid_t);
866 892 nbytes = sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t);
867 893
868 894 if ((pcrp = malloc(nbytes)) == NULL)
869 895 return (-1);
870 896
871 897 if (read(P->asfd, pcrp, nbytes) != nbytes) {
872 898 dprintf("Pgrab_core: failed to read NT_PRCRED\n");
873 899 free(pcrp);
874 900 return (-1);
875 901 }
876 902
877 903 if (pcrp->pr_ngroups > ngroups) {
878 904 dprintf("pr_ngroups = %d; resetting to %d based on note size\n",
879 905 pcrp->pr_ngroups, ngroups);
880 906 pcrp->pr_ngroups = ngroups;
881 907 }
882 908
883 909 core->core_cred = pcrp;
884 910 return (0);
885 911 }
886 912
887 913 #ifdef __x86
888 914 static int
889 915 note_ldt(struct ps_prochandle *P, size_t nbytes)
890 916 {
891 917 core_info_t *core = P->data;
892 918 struct ssd *pldt;
893 919 uint_t nldt;
894 920
895 921 if (core->core_ldt != NULL || nbytes < sizeof (struct ssd))
896 922 return (0); /* Already seen or bad size */
897 923
898 924 nldt = nbytes / sizeof (struct ssd);
899 925 nbytes = nldt * sizeof (struct ssd);
900 926
901 927 if ((pldt = malloc(nbytes)) == NULL)
902 928 return (-1);
903 929
904 930 if (read(P->asfd, pldt, nbytes) != nbytes) {
905 931 dprintf("Pgrab_core: failed to read NT_LDT\n");
906 932 free(pldt);
907 933 return (-1);
908 934 }
909 935
910 936 core->core_ldt = pldt;
911 937 core->core_nldt = nldt;
912 938 return (0);
913 939 }
914 940 #endif /* __i386 */
915 941
916 942 static int
917 943 note_priv(struct ps_prochandle *P, size_t nbytes)
918 944 {
919 945 core_info_t *core = P->data;
920 946 prpriv_t *pprvp;
921 947
922 948 if (core->core_priv != NULL || nbytes < sizeof (prpriv_t))
923 949 return (0); /* Already seen or bad size */
924 950
925 951 if ((pprvp = malloc(nbytes)) == NULL)
926 952 return (-1);
927 953
928 954 if (read(P->asfd, pprvp, nbytes) != nbytes) {
929 955 dprintf("Pgrab_core: failed to read NT_PRPRIV\n");
930 956 free(pprvp);
931 957 return (-1);
932 958 }
933 959
934 960 core->core_priv = pprvp;
935 961 core->core_priv_size = nbytes;
936 962 return (0);
937 963 }
938 964
939 965 static int
940 966 note_priv_info(struct ps_prochandle *P, size_t nbytes)
941 967 {
942 968 core_info_t *core = P->data;
943 969 extern void *__priv_parse_info();
944 970 priv_impl_info_t *ppii;
945 971
946 972 if (core->core_privinfo != NULL ||
947 973 nbytes < sizeof (priv_impl_info_t))
948 974 return (0); /* Already seen or bad size */
949 975
950 976 if ((ppii = malloc(nbytes)) == NULL)
951 977 return (-1);
952 978
953 979 if (read(P->asfd, ppii, nbytes) != nbytes ||
954 980 PRIV_IMPL_INFO_SIZE(ppii) != nbytes) {
955 981 dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n");
956 982 free(ppii);
957 983 return (-1);
958 984 }
959 985
960 986 core->core_privinfo = __priv_parse_info(ppii);
961 987 core->core_ppii = ppii;
962 988 return (0);
963 989 }
964 990
965 991 static int
966 992 note_zonename(struct ps_prochandle *P, size_t nbytes)
967 993 {
968 994 core_info_t *core = P->data;
969 995 char *zonename;
970 996
971 997 if (core->core_zonename != NULL)
972 998 return (0); /* Already seen */
973 999
974 1000 if (nbytes != 0) {
975 1001 if ((zonename = malloc(nbytes)) == NULL)
976 1002 return (-1);
977 1003 if (read(P->asfd, zonename, nbytes) != nbytes) {
978 1004 dprintf("Pgrab_core: failed to read NT_ZONENAME\n");
979 1005 free(zonename);
980 1006 return (-1);
981 1007 }
982 1008 zonename[nbytes - 1] = '\0';
983 1009 core->core_zonename = zonename;
984 1010 }
985 1011
986 1012 return (0);
987 1013 }
988 1014
989 1015 static int
990 1016 note_auxv(struct ps_prochandle *P, size_t nbytes)
991 1017 {
992 1018 size_t n, i;
993 1019
994 1020 #ifdef _LP64
995 1021 core_info_t *core = P->data;
996 1022
997 1023 if (core->core_dmodel == PR_MODEL_ILP32) {
998 1024 auxv32_t *a32;
999 1025
1000 1026 n = nbytes / sizeof (auxv32_t);
1001 1027 nbytes = n * sizeof (auxv32_t);
1002 1028 a32 = alloca(nbytes);
1003 1029
1004 1030 if (read(P->asfd, a32, nbytes) != nbytes) {
1005 1031 dprintf("Pgrab_core: failed to read NT_AUXV\n");
1006 1032 return (-1);
1007 1033 }
1008 1034
1009 1035 if ((P->auxv = malloc(sizeof (auxv_t) * (n + 1))) == NULL)
1010 1036 return (-1);
1011 1037
1012 1038 for (i = 0; i < n; i++)
1013 1039 auxv_32_to_n(&a32[i], &P->auxv[i]);
1014 1040
1015 1041 } else {
1016 1042 #endif
1017 1043 n = nbytes / sizeof (auxv_t);
1018 1044 nbytes = n * sizeof (auxv_t);
1019 1045
1020 1046 if ((P->auxv = malloc(nbytes + sizeof (auxv_t))) == NULL)
1021 1047 return (-1);
1022 1048
1023 1049 if (read(P->asfd, P->auxv, nbytes) != nbytes) {
1024 1050 free(P->auxv);
1025 1051 P->auxv = NULL;
1026 1052 return (-1);
1027 1053 }
1028 1054 #ifdef _LP64
1029 1055 }
1030 1056 #endif
1031 1057
1032 1058 if (_libproc_debug) {
1033 1059 for (i = 0; i < n; i++) {
1034 1060 dprintf("P->auxv[%lu] = ( %d, 0x%lx )\n", (ulong_t)i,
1035 1061 P->auxv[i].a_type, P->auxv[i].a_un.a_val);
1036 1062 }
1037 1063 }
1038 1064
1039 1065 /*
1040 1066 * Defensive coding for loops which depend upon the auxv array being
1041 1067 * terminated by an AT_NULL element; in each case, we've allocated
1042 1068 * P->auxv to have an additional element which we force to be AT_NULL.
1043 1069 */
1044 1070 P->auxv[n].a_type = AT_NULL;
1045 1071 P->auxv[n].a_un.a_val = 0L;
1046 1072 P->nauxv = (int)n;
1047 1073
1048 1074 return (0);
1049 1075 }
1050 1076
1051 1077 #ifdef __sparc
1052 1078 static int
1053 1079 note_xreg(struct ps_prochandle *P, size_t nbytes)
1054 1080 {
1055 1081 core_info_t *core = P->data;
1056 1082 lwp_info_t *lwp = core->core_lwp;
1057 1083 size_t xbytes = sizeof (prxregset_t);
1058 1084 prxregset_t *xregs;
1059 1085
1060 1086 if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)
1061 1087 return (0); /* No lwp yet, already seen, or bad size */
1062 1088
1063 1089 if ((xregs = malloc(xbytes)) == NULL)
1064 1090 return (-1);
1065 1091
1066 1092 if (read(P->asfd, xregs, xbytes) != xbytes) {
1067 1093 dprintf("Pgrab_core: failed to read NT_PRXREG\n");
1068 1094 free(xregs);
1069 1095 return (-1);
1070 1096 }
1071 1097
1072 1098 lwp->lwp_xregs = xregs;
1073 1099 return (0);
1074 1100 }
1075 1101
1076 1102 static int
1077 1103 note_gwindows(struct ps_prochandle *P, size_t nbytes)
1078 1104 {
1079 1105 core_info_t *core = P->data;
1080 1106 lwp_info_t *lwp = core->core_lwp;
1081 1107
1082 1108 if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)
1083 1109 return (0); /* No lwp yet or already seen or no data */
1084 1110
1085 1111 if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
1086 1112 return (-1);
1087 1113
1088 1114 /*
1089 1115 * Since the amount of gwindows data varies with how many windows were
1090 1116 * actually saved, we just read up to the minimum of the note size
1091 1117 * and the size of the gwindows_t type. It doesn't matter if the read
1092 1118 * fails since we have to zero out gwindows first anyway.
1093 1119 */
1094 1120 #ifdef _LP64
1095 1121 if (core->core_dmodel == PR_MODEL_ILP32) {
1096 1122 gwindows32_t g32;
1097 1123
1098 1124 (void) memset(&g32, 0, sizeof (g32));
1099 1125 (void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32)));
1100 1126 gwindows_32_to_n(&g32, lwp->lwp_gwins);
1101 1127
1102 1128 } else {
1103 1129 #endif
1104 1130 (void) memset(lwp->lwp_gwins, 0, sizeof (gwindows_t));
1105 1131 (void) read(P->asfd, lwp->lwp_gwins,
1106 1132 MIN(nbytes, sizeof (gwindows_t)));
1107 1133 #ifdef _LP64
1108 1134 }
1109 1135 #endif
1110 1136 return (0);
1111 1137 }
1112 1138
1113 1139 #ifdef __sparcv9
1114 1140 static int
1115 1141 note_asrs(struct ps_prochandle *P, size_t nbytes)
1116 1142 {
1117 1143 core_info_t *core = P->data;
1118 1144 lwp_info_t *lwp = core->core_lwp;
1119 1145 int64_t *asrs;
1120 1146
1121 1147 if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t))
1122 1148 return (0); /* No lwp yet, already seen, or bad size */
1123 1149
1124 1150 if ((asrs = malloc(sizeof (asrset_t))) == NULL)
1125 1151 return (-1);
1126 1152
1127 1153 if (read(P->asfd, asrs, sizeof (asrset_t)) != sizeof (asrset_t)) {
1128 1154 dprintf("Pgrab_core: failed to read NT_ASRS\n");
1129 1155 free(asrs);
1130 1156 return (-1);
1131 1157 }
1132 1158
1133 1159 lwp->lwp_asrs = asrs;
1134 1160 return (0);
1135 1161 }
1136 1162 #endif /* __sparcv9 */
1137 1163 #endif /* __sparc */
1138 1164
1139 1165 static int
1140 1166 note_spymaster(struct ps_prochandle *P, size_t nbytes)
1141 1167 {
1142 1168 #ifdef _LP64
1143 1169 core_info_t *core = P->data;
1144 1170
1145 1171 if (core->core_dmodel == PR_MODEL_ILP32) {
1146 1172 psinfo32_t ps32;
1147 1173
1148 1174 if (nbytes < sizeof (psinfo32_t) ||
1149 1175 read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
1150 1176 goto err;
1151 1177
1152 1178 psinfo_32_to_n(&ps32, &P->spymaster);
1153 1179 } else
1154 1180 #endif
1155 1181 if (nbytes < sizeof (psinfo_t) || read(P->asfd,
1156 1182 &P->spymaster, sizeof (psinfo_t)) != sizeof (psinfo_t))
1157 1183 goto err;
1158 1184
1159 1185 dprintf("spymaster pr_fname = <%s>\n", P->psinfo.pr_fname);
1160 1186 dprintf("spymaster pr_psargs = <%s>\n", P->psinfo.pr_psargs);
1161 1187 dprintf("spymaster pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
1162 1188
1163 1189 return (0);
1164 1190
1165 1191 err:
1166 1192 dprintf("Pgrab_core: failed to read NT_SPYMASTER\n");
1167 1193 return (-1);
1168 1194 }
1169 1195
1170 1196 /*ARGSUSED*/
1171 1197 static int
1172 1198 note_notsup(struct ps_prochandle *P, size_t nbytes)
1173 1199 {
1174 1200 dprintf("skipping unsupported note type of size %ld bytes\n",
1175 1201 (ulong_t)nbytes);
1176 1202 return (0);
1177 1203 }
1178 1204
1179 1205 /*
1180 1206 * Populate a table of function pointers indexed by Note type with our
1181 1207 * functions to process each type of core file note:
1182 1208 */
1183 1209 static int (*nhdlrs[])(struct ps_prochandle *, size_t) = {
1184 1210 note_notsup, /* 0 unassigned */
1185 1211 #ifdef __x86
1186 1212 note_linux_prstatus, /* 1 NT_PRSTATUS (old) */
1187 1213 #else
1188 1214 note_notsup, /* 1 NT_PRSTATUS (old) */
1189 1215 #endif
1190 1216 note_notsup, /* 2 NT_PRFPREG (old) */
1191 1217 #ifdef __x86
1192 1218 note_linux_psinfo, /* 3 NT_PRPSINFO (old) */
1193 1219 #else
1194 1220 note_notsup, /* 3 NT_PRPSINFO (old) */
1195 1221 #endif
1196 1222 #ifdef __sparc
1197 1223 note_xreg, /* 4 NT_PRXREG */
1198 1224 #else
1199 1225 note_notsup, /* 4 NT_PRXREG */
1200 1226 #endif
1201 1227 note_platform, /* 5 NT_PLATFORM */
1202 1228 note_auxv, /* 6 NT_AUXV */
1203 1229 #ifdef __sparc
1204 1230 note_gwindows, /* 7 NT_GWINDOWS */
1205 1231 #ifdef __sparcv9
1206 1232 note_asrs, /* 8 NT_ASRS */
1207 1233 #else
1208 1234 note_notsup, /* 8 NT_ASRS */
1209 1235 #endif
1210 1236 #else
1211 1237 note_notsup, /* 7 NT_GWINDOWS */
1212 1238 note_notsup, /* 8 NT_ASRS */
1213 1239 #endif
1214 1240 #ifdef __x86
1215 1241 note_ldt, /* 9 NT_LDT */
1216 1242 #else
1217 1243 note_notsup, /* 9 NT_LDT */
1218 1244 #endif
1219 1245 note_pstatus, /* 10 NT_PSTATUS */
1220 1246 note_notsup, /* 11 unassigned */
1221 1247 note_notsup, /* 12 unassigned */
1222 1248 note_psinfo, /* 13 NT_PSINFO */
1223 1249 note_cred, /* 14 NT_PRCRED */
↓ open down ↓ |
485 lines elided |
↑ open up ↑ |
1224 1250 note_utsname, /* 15 NT_UTSNAME */
1225 1251 note_lwpstatus, /* 16 NT_LWPSTATUS */
1226 1252 note_lwpsinfo, /* 17 NT_LWPSINFO */
1227 1253 note_priv, /* 18 NT_PRPRIV */
1228 1254 note_priv_info, /* 19 NT_PRPRIVINFO */
1229 1255 note_content, /* 20 NT_CONTENT */
1230 1256 note_zonename, /* 21 NT_ZONENAME */
1231 1257 note_fdinfo, /* 22 NT_FDINFO */
1232 1258 note_spymaster, /* 23 NT_SPYMASTER */
1233 1259 note_secflags, /* 24 NT_SECFLAGS */
1260 + note_lwpname, /* 25 NT_LWPNAME */
1234 1261 };
1235 1262
1236 1263 static void
1237 1264 core_report_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1238 1265 {
1239 1266 prkillinfo_t killinfo;
1240 1267 siginfo_t *si = &killinfo.prk_info;
1241 1268 char signame[SIG2STR_MAX], sig[64], info[64];
1242 1269 void *addr = (void *)(uintptr_t)php->p_vaddr;
1243 1270
1244 1271 const char *errfmt = "core file data for mapping at %p not saved: %s\n";
1245 1272 const char *incfmt = "core file incomplete due to %s%s\n";
1246 1273 const char *msgfmt = "mappings at and above %p are missing\n";
1247 1274
1248 1275 if (!(php->p_flags & PF_SUNW_KILLED)) {
1249 1276 int err = 0;
1250 1277
1251 1278 (void) pread64(P->asfd, &err,
1252 1279 sizeof (err), (off64_t)php->p_offset);
1253 1280
1254 1281 Perror_printf(P, errfmt, addr, strerror(err));
1255 1282 dprintf(errfmt, addr, strerror(err));
1256 1283 return;
1257 1284 }
1258 1285
1259 1286 if (!(php->p_flags & PF_SUNW_SIGINFO))
1260 1287 return;
1261 1288
1262 1289 (void) memset(&killinfo, 0, sizeof (killinfo));
1263 1290
1264 1291 (void) pread64(P->asfd, &killinfo,
1265 1292 sizeof (killinfo), (off64_t)php->p_offset);
1266 1293
1267 1294 /*
1268 1295 * While there is (or at least should be) only one segment that has
1269 1296 * PF_SUNW_SIGINFO set, the signal information there is globally
1270 1297 * useful (even if only to those debugging libproc consumers); we hang
1271 1298 * the signal information gleaned here off of the ps_prochandle.
1272 1299 */
1273 1300 P->map_missing = php->p_vaddr;
1274 1301 P->killinfo = killinfo.prk_info;
1275 1302
1276 1303 if (sig2str(si->si_signo, signame) == -1) {
1277 1304 (void) snprintf(sig, sizeof (sig),
1278 1305 "<Unknown signal: 0x%x>, ", si->si_signo);
1279 1306 } else {
1280 1307 (void) snprintf(sig, sizeof (sig), "SIG%s, ", signame);
1281 1308 }
1282 1309
1283 1310 if (si->si_code == SI_USER || si->si_code == SI_QUEUE) {
1284 1311 (void) snprintf(info, sizeof (info),
1285 1312 "pid=%d uid=%d zone=%d ctid=%d",
1286 1313 si->si_pid, si->si_uid, si->si_zoneid, si->si_ctid);
1287 1314 } else {
1288 1315 (void) snprintf(info, sizeof (info),
1289 1316 "code=%d", si->si_code);
1290 1317 }
1291 1318
1292 1319 Perror_printf(P, incfmt, sig, info);
1293 1320 Perror_printf(P, msgfmt, addr);
1294 1321
1295 1322 dprintf(incfmt, sig, info);
1296 1323 dprintf(msgfmt, addr);
1297 1324 }
1298 1325
1299 1326 /*
1300 1327 * Add information on the address space mapping described by the given
1301 1328 * PT_LOAD program header. We fill in more information on the mapping later.
1302 1329 */
1303 1330 static int
1304 1331 core_add_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1305 1332 {
1306 1333 core_info_t *core = P->data;
1307 1334 prmap_t pmap;
1308 1335
1309 1336 dprintf("mapping base %llx filesz %llx memsz %llx offset %llx\n",
1310 1337 (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,
1311 1338 (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
1312 1339
1313 1340 pmap.pr_vaddr = (uintptr_t)php->p_vaddr;
1314 1341 pmap.pr_size = php->p_memsz;
1315 1342
1316 1343 /*
1317 1344 * If Pgcore() or elfcore() fail to write a mapping, they will set
1318 1345 * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us.
1319 1346 */
1320 1347 if (php->p_flags & PF_SUNW_FAILURE) {
1321 1348 core_report_mapping(P, php);
1322 1349 } else if (php->p_filesz != 0 && php->p_offset >= core->core_size) {
1323 1350 Perror_printf(P, "core file may be corrupt -- data for mapping "
1324 1351 "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
1325 1352 dprintf("core file may be corrupt -- data for mapping "
1326 1353 "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
1327 1354 }
1328 1355
1329 1356 /*
1330 1357 * The mapping name and offset will hopefully be filled in
1331 1358 * by the librtld_db agent. Unfortunately, if it isn't a
1332 1359 * shared library mapping, this information is gone forever.
1333 1360 */
1334 1361 pmap.pr_mapname[0] = '\0';
1335 1362 pmap.pr_offset = 0;
1336 1363
1337 1364 pmap.pr_mflags = 0;
1338 1365 if (php->p_flags & PF_R)
1339 1366 pmap.pr_mflags |= MA_READ;
1340 1367 if (php->p_flags & PF_W)
1341 1368 pmap.pr_mflags |= MA_WRITE;
1342 1369 if (php->p_flags & PF_X)
1343 1370 pmap.pr_mflags |= MA_EXEC;
1344 1371
1345 1372 if (php->p_filesz == 0)
1346 1373 pmap.pr_mflags |= MA_RESERVED1;
1347 1374
1348 1375 /*
1349 1376 * At the time of adding this mapping, we just zero the pagesize.
1350 1377 * Once we've processed more of the core file, we'll have the
1351 1378 * pagesize from the auxv's AT_PAGESZ element and we can fill this in.
1352 1379 */
1353 1380 pmap.pr_pagesize = 0;
1354 1381
1355 1382 /*
1356 1383 * Unfortunately whether or not the mapping was a System V
1357 1384 * shared memory segment is lost. We use -1 to mark it as not shm.
1358 1385 */
1359 1386 pmap.pr_shmid = -1;
1360 1387
1361 1388 return (Padd_mapping(P, php->p_offset, NULL, &pmap));
1362 1389 }
1363 1390
1364 1391 /*
1365 1392 * Given a virtual address, name the mapping at that address using the
1366 1393 * specified name, and return the map_info_t pointer.
1367 1394 */
1368 1395 static map_info_t *
1369 1396 core_name_mapping(struct ps_prochandle *P, uintptr_t addr, const char *name)
1370 1397 {
1371 1398 map_info_t *mp = Paddr2mptr(P, addr);
1372 1399
1373 1400 if (mp != NULL) {
1374 1401 (void) strncpy(mp->map_pmap.pr_mapname, name, PRMAPSZ);
1375 1402 mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
1376 1403 }
1377 1404
1378 1405 return (mp);
1379 1406 }
1380 1407
1381 1408 /*
1382 1409 * libproc uses libelf for all of its symbol table manipulation. This function
1383 1410 * takes a symbol table and string table from a core file and places them
1384 1411 * in a memory backed elf file.
1385 1412 */
1386 1413 static void
1387 1414 fake_up_symtab(struct ps_prochandle *P, const elf_file_header_t *ehdr,
1388 1415 GElf_Shdr *symtab, GElf_Shdr *strtab)
1389 1416 {
1390 1417 size_t size;
1391 1418 off64_t off, base;
1392 1419 map_info_t *mp;
1393 1420 file_info_t *fp;
1394 1421 Elf_Scn *scn;
1395 1422 Elf_Data *data;
1396 1423
1397 1424 if (symtab->sh_addr == 0 ||
1398 1425 (mp = Paddr2mptr(P, symtab->sh_addr)) == NULL ||
1399 1426 (fp = mp->map_file) == NULL) {
1400 1427 dprintf("fake_up_symtab: invalid section\n");
1401 1428 return;
1402 1429 }
1403 1430
1404 1431 if (fp->file_symtab.sym_data_pri != NULL) {
1405 1432 dprintf("Symbol table already loaded (sh_addr 0x%lx)\n",
1406 1433 (long)symtab->sh_addr);
1407 1434 return;
1408 1435 }
1409 1436
1410 1437 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1411 1438 struct {
1412 1439 Elf32_Ehdr ehdr;
1413 1440 Elf32_Shdr shdr[3];
1414 1441 char data[1];
1415 1442 } *b;
1416 1443
1417 1444 base = sizeof (b->ehdr) + sizeof (b->shdr);
1418 1445 size = base + symtab->sh_size + strtab->sh_size;
1419 1446
1420 1447 if ((b = calloc(1, size)) == NULL)
1421 1448 return;
1422 1449
1423 1450 (void) memcpy(b->ehdr.e_ident, ehdr->e_ident,
1424 1451 sizeof (ehdr->e_ident));
1425 1452 b->ehdr.e_type = ehdr->e_type;
1426 1453 b->ehdr.e_machine = ehdr->e_machine;
1427 1454 b->ehdr.e_version = ehdr->e_version;
1428 1455 b->ehdr.e_flags = ehdr->e_flags;
1429 1456 b->ehdr.e_ehsize = sizeof (b->ehdr);
1430 1457 b->ehdr.e_shoff = sizeof (b->ehdr);
1431 1458 b->ehdr.e_shentsize = sizeof (b->shdr[0]);
1432 1459 b->ehdr.e_shnum = 3;
1433 1460 off = 0;
1434 1461
1435 1462 b->shdr[1].sh_size = symtab->sh_size;
1436 1463 b->shdr[1].sh_type = SHT_SYMTAB;
1437 1464 b->shdr[1].sh_offset = off + base;
1438 1465 b->shdr[1].sh_entsize = sizeof (Elf32_Sym);
1439 1466 b->shdr[1].sh_link = 2;
1440 1467 b->shdr[1].sh_info = symtab->sh_info;
1441 1468 b->shdr[1].sh_addralign = symtab->sh_addralign;
1442 1469
1443 1470 if (pread64(P->asfd, &b->data[off], b->shdr[1].sh_size,
1444 1471 symtab->sh_offset) != b->shdr[1].sh_size) {
1445 1472 dprintf("fake_up_symtab: pread of symtab[1] failed\n");
1446 1473 free(b);
1447 1474 return;
1448 1475 }
1449 1476
1450 1477 off += b->shdr[1].sh_size;
1451 1478
1452 1479 b->shdr[2].sh_flags = SHF_STRINGS;
1453 1480 b->shdr[2].sh_size = strtab->sh_size;
1454 1481 b->shdr[2].sh_type = SHT_STRTAB;
1455 1482 b->shdr[2].sh_offset = off + base;
1456 1483 b->shdr[2].sh_info = strtab->sh_info;
1457 1484 b->shdr[2].sh_addralign = 1;
1458 1485
1459 1486 if (pread64(P->asfd, &b->data[off], b->shdr[2].sh_size,
1460 1487 strtab->sh_offset) != b->shdr[2].sh_size) {
1461 1488 dprintf("fake_up_symtab: pread of symtab[2] failed\n");
1462 1489 free(b);
1463 1490 return;
1464 1491 }
1465 1492
1466 1493 off += b->shdr[2].sh_size;
1467 1494
1468 1495 fp->file_symtab.sym_elf = elf_memory((char *)b, size);
1469 1496 if (fp->file_symtab.sym_elf == NULL) {
1470 1497 free(b);
1471 1498 return;
1472 1499 }
1473 1500
1474 1501 fp->file_symtab.sym_elfmem = b;
1475 1502 #ifdef _LP64
1476 1503 } else {
1477 1504 struct {
1478 1505 Elf64_Ehdr ehdr;
1479 1506 Elf64_Shdr shdr[3];
1480 1507 char data[1];
1481 1508 } *b;
1482 1509
1483 1510 base = sizeof (b->ehdr) + sizeof (b->shdr);
1484 1511 size = base + symtab->sh_size + strtab->sh_size;
1485 1512
1486 1513 if ((b = calloc(1, size)) == NULL)
1487 1514 return;
1488 1515
1489 1516 (void) memcpy(b->ehdr.e_ident, ehdr->e_ident,
1490 1517 sizeof (ehdr->e_ident));
1491 1518 b->ehdr.e_type = ehdr->e_type;
1492 1519 b->ehdr.e_machine = ehdr->e_machine;
1493 1520 b->ehdr.e_version = ehdr->e_version;
1494 1521 b->ehdr.e_flags = ehdr->e_flags;
1495 1522 b->ehdr.e_ehsize = sizeof (b->ehdr);
1496 1523 b->ehdr.e_shoff = sizeof (b->ehdr);
1497 1524 b->ehdr.e_shentsize = sizeof (b->shdr[0]);
1498 1525 b->ehdr.e_shnum = 3;
1499 1526 off = 0;
1500 1527
1501 1528 b->shdr[1].sh_size = symtab->sh_size;
1502 1529 b->shdr[1].sh_type = SHT_SYMTAB;
1503 1530 b->shdr[1].sh_offset = off + base;
1504 1531 b->shdr[1].sh_entsize = sizeof (Elf64_Sym);
1505 1532 b->shdr[1].sh_link = 2;
1506 1533 b->shdr[1].sh_info = symtab->sh_info;
1507 1534 b->shdr[1].sh_addralign = symtab->sh_addralign;
1508 1535
1509 1536 if (pread64(P->asfd, &b->data[off], b->shdr[1].sh_size,
1510 1537 symtab->sh_offset) != b->shdr[1].sh_size) {
1511 1538 free(b);
1512 1539 return;
1513 1540 }
1514 1541
1515 1542 off += b->shdr[1].sh_size;
1516 1543
1517 1544 b->shdr[2].sh_flags = SHF_STRINGS;
1518 1545 b->shdr[2].sh_size = strtab->sh_size;
1519 1546 b->shdr[2].sh_type = SHT_STRTAB;
1520 1547 b->shdr[2].sh_offset = off + base;
1521 1548 b->shdr[2].sh_info = strtab->sh_info;
1522 1549 b->shdr[2].sh_addralign = 1;
1523 1550
1524 1551 if (pread64(P->asfd, &b->data[off], b->shdr[2].sh_size,
1525 1552 strtab->sh_offset) != b->shdr[2].sh_size) {
1526 1553 free(b);
1527 1554 return;
1528 1555 }
1529 1556
1530 1557 off += b->shdr[2].sh_size;
1531 1558
1532 1559 fp->file_symtab.sym_elf = elf_memory((char *)b, size);
1533 1560 if (fp->file_symtab.sym_elf == NULL) {
1534 1561 free(b);
1535 1562 return;
1536 1563 }
1537 1564
1538 1565 fp->file_symtab.sym_elfmem = b;
1539 1566 #endif
1540 1567 }
1541 1568
1542 1569 if ((scn = elf_getscn(fp->file_symtab.sym_elf, 1)) == NULL ||
1543 1570 (fp->file_symtab.sym_data_pri = elf_getdata(scn, NULL)) == NULL ||
1544 1571 (scn = elf_getscn(fp->file_symtab.sym_elf, 2)) == NULL ||
1545 1572 (data = elf_getdata(scn, NULL)) == NULL) {
1546 1573 dprintf("fake_up_symtab: failed to get section data at %p\n",
1547 1574 (void *)scn);
1548 1575 goto err;
1549 1576 }
1550 1577
1551 1578 fp->file_symtab.sym_strs = data->d_buf;
1552 1579 fp->file_symtab.sym_strsz = data->d_size;
1553 1580 fp->file_symtab.sym_symn = symtab->sh_size / symtab->sh_entsize;
1554 1581 fp->file_symtab.sym_hdr_pri = *symtab;
1555 1582 fp->file_symtab.sym_strhdr = *strtab;
1556 1583
1557 1584 optimize_symtab(&fp->file_symtab);
1558 1585
1559 1586 return;
1560 1587 err:
1561 1588 (void) elf_end(fp->file_symtab.sym_elf);
1562 1589 free(fp->file_symtab.sym_elfmem);
1563 1590 fp->file_symtab.sym_elf = NULL;
1564 1591 fp->file_symtab.sym_elfmem = NULL;
1565 1592 }
1566 1593
1567 1594 static void
1568 1595 core_phdr_to_gelf(const Elf32_Phdr *src, GElf_Phdr *dst)
1569 1596 {
1570 1597 dst->p_type = src->p_type;
1571 1598 dst->p_flags = src->p_flags;
1572 1599 dst->p_offset = (Elf64_Off)src->p_offset;
1573 1600 dst->p_vaddr = (Elf64_Addr)src->p_vaddr;
1574 1601 dst->p_paddr = (Elf64_Addr)src->p_paddr;
1575 1602 dst->p_filesz = (Elf64_Xword)src->p_filesz;
1576 1603 dst->p_memsz = (Elf64_Xword)src->p_memsz;
1577 1604 dst->p_align = (Elf64_Xword)src->p_align;
1578 1605 }
1579 1606
1580 1607 static void
1581 1608 core_shdr_to_gelf(const Elf32_Shdr *src, GElf_Shdr *dst)
1582 1609 {
1583 1610 dst->sh_name = src->sh_name;
1584 1611 dst->sh_type = src->sh_type;
1585 1612 dst->sh_flags = (Elf64_Xword)src->sh_flags;
1586 1613 dst->sh_addr = (Elf64_Addr)src->sh_addr;
1587 1614 dst->sh_offset = (Elf64_Off)src->sh_offset;
1588 1615 dst->sh_size = (Elf64_Xword)src->sh_size;
1589 1616 dst->sh_link = src->sh_link;
1590 1617 dst->sh_info = src->sh_info;
1591 1618 dst->sh_addralign = (Elf64_Xword)src->sh_addralign;
1592 1619 dst->sh_entsize = (Elf64_Xword)src->sh_entsize;
1593 1620 }
1594 1621
1595 1622 /*
1596 1623 * Perform elf_begin on efp->e_fd and verify the ELF file's type and class.
1597 1624 */
1598 1625 static int
1599 1626 core_elf_fdopen(elf_file_t *efp, GElf_Half type, int *perr)
1600 1627 {
1601 1628 #ifdef _BIG_ENDIAN
1602 1629 uchar_t order = ELFDATA2MSB;
1603 1630 #else
1604 1631 uchar_t order = ELFDATA2LSB;
1605 1632 #endif
1606 1633 Elf32_Ehdr e32;
1607 1634 int is_noelf = -1;
1608 1635 int isa_err = 0;
1609 1636
1610 1637 /*
1611 1638 * Because 32-bit libelf cannot deal with large files, we need to read,
1612 1639 * check, and convert the file header manually in case type == ET_CORE.
1613 1640 */
1614 1641 if (pread64(efp->e_fd, &e32, sizeof (e32), 0) != sizeof (e32)) {
1615 1642 if (perr != NULL)
1616 1643 *perr = G_FORMAT;
1617 1644 goto err;
1618 1645 }
1619 1646 if ((is_noelf = memcmp(&e32.e_ident[EI_MAG0], ELFMAG, SELFMAG)) != 0 ||
1620 1647 e32.e_type != type || (isa_err = (e32.e_ident[EI_DATA] != order)) ||
1621 1648 e32.e_version != EV_CURRENT) {
1622 1649 if (perr != NULL) {
1623 1650 if (is_noelf == 0 && isa_err) {
1624 1651 *perr = G_ISAINVAL;
1625 1652 } else {
1626 1653 *perr = G_FORMAT;
1627 1654 }
1628 1655 }
1629 1656 goto err;
1630 1657 }
1631 1658
1632 1659 /*
1633 1660 * If the file is 64-bit and we are 32-bit, fail with G_LP64. If the
1634 1661 * file is 64-bit and we are 64-bit, re-read the header as a Elf64_Ehdr,
1635 1662 * and convert it to a elf_file_header_t. Otherwise, the file is
1636 1663 * 32-bit, so convert e32 to a elf_file_header_t.
1637 1664 */
1638 1665 if (e32.e_ident[EI_CLASS] == ELFCLASS64) {
1639 1666 #ifdef _LP64
1640 1667 Elf64_Ehdr e64;
1641 1668
1642 1669 if (pread64(efp->e_fd, &e64, sizeof (e64), 0) != sizeof (e64)) {
1643 1670 if (perr != NULL)
1644 1671 *perr = G_FORMAT;
1645 1672 goto err;
1646 1673 }
1647 1674
1648 1675 (void) memcpy(efp->e_hdr.e_ident, e64.e_ident, EI_NIDENT);
1649 1676 efp->e_hdr.e_type = e64.e_type;
1650 1677 efp->e_hdr.e_machine = e64.e_machine;
1651 1678 efp->e_hdr.e_version = e64.e_version;
1652 1679 efp->e_hdr.e_entry = e64.e_entry;
1653 1680 efp->e_hdr.e_phoff = e64.e_phoff;
1654 1681 efp->e_hdr.e_shoff = e64.e_shoff;
1655 1682 efp->e_hdr.e_flags = e64.e_flags;
1656 1683 efp->e_hdr.e_ehsize = e64.e_ehsize;
1657 1684 efp->e_hdr.e_phentsize = e64.e_phentsize;
1658 1685 efp->e_hdr.e_phnum = (Elf64_Word)e64.e_phnum;
1659 1686 efp->e_hdr.e_shentsize = e64.e_shentsize;
1660 1687 efp->e_hdr.e_shnum = (Elf64_Word)e64.e_shnum;
1661 1688 efp->e_hdr.e_shstrndx = (Elf64_Word)e64.e_shstrndx;
1662 1689 #else /* _LP64 */
1663 1690 if (perr != NULL)
1664 1691 *perr = G_LP64;
1665 1692 goto err;
1666 1693 #endif /* _LP64 */
1667 1694 } else {
1668 1695 (void) memcpy(efp->e_hdr.e_ident, e32.e_ident, EI_NIDENT);
1669 1696 efp->e_hdr.e_type = e32.e_type;
1670 1697 efp->e_hdr.e_machine = e32.e_machine;
1671 1698 efp->e_hdr.e_version = e32.e_version;
1672 1699 efp->e_hdr.e_entry = (Elf64_Addr)e32.e_entry;
1673 1700 efp->e_hdr.e_phoff = (Elf64_Off)e32.e_phoff;
1674 1701 efp->e_hdr.e_shoff = (Elf64_Off)e32.e_shoff;
1675 1702 efp->e_hdr.e_flags = e32.e_flags;
1676 1703 efp->e_hdr.e_ehsize = e32.e_ehsize;
1677 1704 efp->e_hdr.e_phentsize = e32.e_phentsize;
1678 1705 efp->e_hdr.e_phnum = (Elf64_Word)e32.e_phnum;
1679 1706 efp->e_hdr.e_shentsize = e32.e_shentsize;
1680 1707 efp->e_hdr.e_shnum = (Elf64_Word)e32.e_shnum;
1681 1708 efp->e_hdr.e_shstrndx = (Elf64_Word)e32.e_shstrndx;
1682 1709 }
1683 1710
1684 1711 /*
1685 1712 * If the number of section headers or program headers or the section
1686 1713 * header string table index would overflow their respective fields
1687 1714 * in the ELF header, they're stored in the section header at index
1688 1715 * zero. To simplify use elsewhere, we look for those sentinel values
1689 1716 * here.
1690 1717 */
1691 1718 if ((efp->e_hdr.e_shnum == 0 && efp->e_hdr.e_shoff != 0) ||
1692 1719 efp->e_hdr.e_shstrndx == SHN_XINDEX ||
1693 1720 efp->e_hdr.e_phnum == PN_XNUM) {
1694 1721 GElf_Shdr shdr;
1695 1722
1696 1723 dprintf("extended ELF header\n");
1697 1724
1698 1725 if (efp->e_hdr.e_shoff == 0) {
1699 1726 if (perr != NULL)
1700 1727 *perr = G_FORMAT;
1701 1728 goto err;
1702 1729 }
1703 1730
1704 1731 if (efp->e_hdr.e_ident[EI_CLASS] == ELFCLASS32) {
1705 1732 Elf32_Shdr shdr32;
1706 1733
1707 1734 if (pread64(efp->e_fd, &shdr32, sizeof (shdr32),
1708 1735 efp->e_hdr.e_shoff) != sizeof (shdr32)) {
1709 1736 if (perr != NULL)
1710 1737 *perr = G_FORMAT;
1711 1738 goto err;
1712 1739 }
1713 1740
1714 1741 core_shdr_to_gelf(&shdr32, &shdr);
1715 1742 } else {
1716 1743 if (pread64(efp->e_fd, &shdr, sizeof (shdr),
1717 1744 efp->e_hdr.e_shoff) != sizeof (shdr)) {
1718 1745 if (perr != NULL)
1719 1746 *perr = G_FORMAT;
1720 1747 goto err;
1721 1748 }
1722 1749 }
1723 1750
1724 1751 if (efp->e_hdr.e_shnum == 0) {
1725 1752 efp->e_hdr.e_shnum = shdr.sh_size;
1726 1753 dprintf("section header count %lu\n",
1727 1754 (ulong_t)shdr.sh_size);
1728 1755 }
1729 1756
1730 1757 if (efp->e_hdr.e_shstrndx == SHN_XINDEX) {
1731 1758 efp->e_hdr.e_shstrndx = shdr.sh_link;
1732 1759 dprintf("section string index %u\n", shdr.sh_link);
1733 1760 }
1734 1761
1735 1762 if (efp->e_hdr.e_phnum == PN_XNUM && shdr.sh_info != 0) {
1736 1763 efp->e_hdr.e_phnum = shdr.sh_info;
1737 1764 dprintf("program header count %u\n", shdr.sh_info);
1738 1765 }
1739 1766
1740 1767 } else if (efp->e_hdr.e_phoff != 0) {
1741 1768 GElf_Phdr phdr;
1742 1769 uint64_t phnum;
1743 1770
1744 1771 /*
1745 1772 * It's possible this core file came from a system that
1746 1773 * accidentally truncated the e_phnum field without correctly
1747 1774 * using the extended format in the section header at index
1748 1775 * zero. We try to detect and correct that specific type of
1749 1776 * corruption by using the knowledge that the core dump
1750 1777 * routines usually place the data referenced by the first
1751 1778 * program header immediately after the last header element.
1752 1779 */
1753 1780 if (efp->e_hdr.e_ident[EI_CLASS] == ELFCLASS32) {
1754 1781 Elf32_Phdr phdr32;
1755 1782
1756 1783 if (pread64(efp->e_fd, &phdr32, sizeof (phdr32),
1757 1784 efp->e_hdr.e_phoff) != sizeof (phdr32)) {
1758 1785 if (perr != NULL)
1759 1786 *perr = G_FORMAT;
1760 1787 goto err;
1761 1788 }
1762 1789
1763 1790 core_phdr_to_gelf(&phdr32, &phdr);
1764 1791 } else {
1765 1792 if (pread64(efp->e_fd, &phdr, sizeof (phdr),
1766 1793 efp->e_hdr.e_phoff) != sizeof (phdr)) {
1767 1794 if (perr != NULL)
1768 1795 *perr = G_FORMAT;
1769 1796 goto err;
1770 1797 }
1771 1798 }
1772 1799
1773 1800 phnum = phdr.p_offset - efp->e_hdr.e_ehsize -
1774 1801 (uint64_t)efp->e_hdr.e_shnum * efp->e_hdr.e_shentsize;
1775 1802 phnum /= efp->e_hdr.e_phentsize;
1776 1803
1777 1804 if (phdr.p_offset != 0 && phnum != efp->e_hdr.e_phnum) {
1778 1805 dprintf("suspicious program header count %u %u\n",
1779 1806 (uint_t)phnum, efp->e_hdr.e_phnum);
1780 1807
1781 1808 /*
1782 1809 * If the new program header count we computed doesn't
1783 1810 * jive with count in the ELF header, we'll use the
1784 1811 * data that's there and hope for the best.
1785 1812 *
1786 1813 * If it does, it's also possible that the section
1787 1814 * header offset is incorrect; we'll check that and
1788 1815 * possibly try to fix it.
1789 1816 */
1790 1817 if (phnum <= INT_MAX &&
1791 1818 (uint16_t)phnum == efp->e_hdr.e_phnum) {
1792 1819
1793 1820 if (efp->e_hdr.e_shoff == efp->e_hdr.e_phoff +
1794 1821 efp->e_hdr.e_phentsize *
1795 1822 (uint_t)efp->e_hdr.e_phnum) {
1796 1823 efp->e_hdr.e_shoff =
1797 1824 efp->e_hdr.e_phoff +
1798 1825 efp->e_hdr.e_phentsize * phnum;
1799 1826 }
1800 1827
1801 1828 efp->e_hdr.e_phnum = (Elf64_Word)phnum;
1802 1829 dprintf("using new program header count\n");
1803 1830 } else {
1804 1831 dprintf("inconsistent program header count\n");
1805 1832 }
1806 1833 }
1807 1834 }
1808 1835
1809 1836 /*
1810 1837 * The libelf implementation was never ported to be large-file aware.
1811 1838 * This is typically not a problem for your average executable or
1812 1839 * shared library, but a large 32-bit core file can exceed 2GB in size.
1813 1840 * So if type is ET_CORE, we don't bother doing elf_begin; the code
1814 1841 * in Pfgrab_core() below will do its own i/o and struct conversion.
1815 1842 */
1816 1843
1817 1844 if (type == ET_CORE) {
1818 1845 efp->e_elf = NULL;
1819 1846 return (0);
1820 1847 }
1821 1848
1822 1849 if ((efp->e_elf = elf_begin(efp->e_fd, ELF_C_READ, NULL)) == NULL) {
1823 1850 if (perr != NULL)
1824 1851 *perr = G_ELF;
1825 1852 goto err;
1826 1853 }
1827 1854
1828 1855 return (0);
1829 1856
1830 1857 err:
1831 1858 efp->e_elf = NULL;
1832 1859 return (-1);
1833 1860 }
1834 1861
1835 1862 /*
1836 1863 * Open the specified file and then do a core_elf_fdopen on it.
1837 1864 */
1838 1865 static int
1839 1866 core_elf_open(elf_file_t *efp, const char *path, GElf_Half type, int *perr)
1840 1867 {
1841 1868 (void) memset(efp, 0, sizeof (elf_file_t));
1842 1869
1843 1870 if ((efp->e_fd = open64(path, O_RDONLY)) >= 0) {
1844 1871 if (core_elf_fdopen(efp, type, perr) == 0)
1845 1872 return (0);
1846 1873
1847 1874 (void) close(efp->e_fd);
1848 1875 efp->e_fd = -1;
1849 1876 }
1850 1877
1851 1878 return (-1);
1852 1879 }
1853 1880
1854 1881 /*
1855 1882 * Close the ELF handle and file descriptor.
1856 1883 */
1857 1884 static void
1858 1885 core_elf_close(elf_file_t *efp)
1859 1886 {
1860 1887 if (efp->e_elf != NULL) {
1861 1888 (void) elf_end(efp->e_elf);
1862 1889 efp->e_elf = NULL;
1863 1890 }
1864 1891
1865 1892 if (efp->e_fd != -1) {
1866 1893 (void) close(efp->e_fd);
1867 1894 efp->e_fd = -1;
1868 1895 }
1869 1896 }
1870 1897
1871 1898 /*
1872 1899 * Given an ELF file for a statically linked executable, locate the likely
1873 1900 * primary text section and fill in rl_base with its virtual address.
1874 1901 */
1875 1902 static map_info_t *
1876 1903 core_find_text(struct ps_prochandle *P, Elf *elf, rd_loadobj_t *rlp)
1877 1904 {
1878 1905 GElf_Phdr phdr;
1879 1906 uint_t i;
1880 1907 size_t nphdrs;
1881 1908
1882 1909 if (elf_getphdrnum(elf, &nphdrs) == -1)
1883 1910 return (NULL);
1884 1911
1885 1912 for (i = 0; i < nphdrs; i++) {
1886 1913 if (gelf_getphdr(elf, i, &phdr) != NULL &&
1887 1914 phdr.p_type == PT_LOAD && (phdr.p_flags & PF_X)) {
1888 1915 rlp->rl_base = phdr.p_vaddr;
1889 1916 return (Paddr2mptr(P, rlp->rl_base));
1890 1917 }
1891 1918 }
1892 1919
1893 1920 return (NULL);
1894 1921 }
1895 1922
1896 1923 /*
1897 1924 * Given an ELF file and the librtld_db structure corresponding to its primary
1898 1925 * text mapping, deduce where its data segment was loaded and fill in
1899 1926 * rl_data_base and prmap_t.pr_offset accordingly.
1900 1927 */
1901 1928 static map_info_t *
1902 1929 core_find_data(struct ps_prochandle *P, Elf *elf, rd_loadobj_t *rlp)
1903 1930 {
1904 1931 GElf_Ehdr ehdr;
1905 1932 GElf_Phdr phdr;
1906 1933 map_info_t *mp;
1907 1934 uint_t i, pagemask;
1908 1935 size_t nphdrs;
1909 1936
1910 1937 rlp->rl_data_base = NULL;
1911 1938
1912 1939 /*
1913 1940 * Find the first loadable, writeable Phdr and compute rl_data_base
1914 1941 * as the virtual address at which is was loaded.
1915 1942 */
1916 1943 if (gelf_getehdr(elf, &ehdr) == NULL ||
1917 1944 elf_getphdrnum(elf, &nphdrs) == -1)
1918 1945 return (NULL);
1919 1946
1920 1947 for (i = 0; i < nphdrs; i++) {
1921 1948 if (gelf_getphdr(elf, i, &phdr) != NULL &&
1922 1949 phdr.p_type == PT_LOAD && (phdr.p_flags & PF_W)) {
1923 1950 rlp->rl_data_base = phdr.p_vaddr;
1924 1951 if (ehdr.e_type == ET_DYN)
1925 1952 rlp->rl_data_base += rlp->rl_base;
1926 1953 break;
1927 1954 }
1928 1955 }
1929 1956
1930 1957 /*
1931 1958 * If we didn't find an appropriate phdr or if the address we
1932 1959 * computed has no mapping, return NULL.
1933 1960 */
1934 1961 if (rlp->rl_data_base == NULL ||
1935 1962 (mp = Paddr2mptr(P, rlp->rl_data_base)) == NULL)
1936 1963 return (NULL);
1937 1964
1938 1965 /*
1939 1966 * It wouldn't be procfs-related code if we didn't make use of
1940 1967 * unclean knowledge of segvn, even in userland ... the prmap_t's
1941 1968 * pr_offset field will be the segvn offset from mmap(2)ing the
1942 1969 * data section, which will be the file offset & PAGEMASK.
1943 1970 */
1944 1971 pagemask = ~(mp->map_pmap.pr_pagesize - 1);
1945 1972 mp->map_pmap.pr_offset = phdr.p_offset & pagemask;
1946 1973
1947 1974 return (mp);
1948 1975 }
1949 1976
1950 1977 /*
1951 1978 * Librtld_db agent callback for iterating over load object mappings.
1952 1979 * For each load object, we allocate a new file_info_t, perform naming,
1953 1980 * and attempt to construct a symbol table for the load object.
1954 1981 */
1955 1982 static int
1956 1983 core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P)
1957 1984 {
1958 1985 core_info_t *core = P->data;
1959 1986 char lname[PATH_MAX], buf[PATH_MAX];
1960 1987 file_info_t *fp;
1961 1988 map_info_t *mp;
1962 1989
1963 1990 if (Pread_string(P, lname, PATH_MAX, (off_t)rlp->rl_nameaddr) <= 0) {
1964 1991 dprintf("failed to read name %p\n", (void *)rlp->rl_nameaddr);
1965 1992 return (1); /* Keep going; forget this if we can't get a name */
1966 1993 }
1967 1994
1968 1995 dprintf("rd_loadobj name = \"%s\" rl_base = %p\n",
1969 1996 lname, (void *)rlp->rl_base);
1970 1997
1971 1998 if ((mp = Paddr2mptr(P, rlp->rl_base)) == NULL) {
1972 1999 dprintf("no mapping for %p\n", (void *)rlp->rl_base);
1973 2000 return (1); /* No mapping; advance to next mapping */
1974 2001 }
1975 2002
1976 2003 /*
1977 2004 * Create a new file_info_t for this mapping, and therefore for
1978 2005 * this load object.
1979 2006 *
1980 2007 * If there's an ELF header at the beginning of this mapping,
1981 2008 * file_info_new() will try to use its section headers to
1982 2009 * identify any other mappings that belong to this load object.
1983 2010 */
1984 2011 if ((fp = mp->map_file) == NULL &&
1985 2012 (fp = file_info_new(P, mp)) == NULL) {
1986 2013 core->core_errno = errno;
1987 2014 dprintf("failed to malloc mapping data\n");
1988 2015 return (0); /* Abort */
1989 2016 }
1990 2017 fp->file_map = mp;
1991 2018
1992 2019 /* Create a local copy of the load object representation */
1993 2020 if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
1994 2021 core->core_errno = errno;
1995 2022 dprintf("failed to malloc mapping data\n");
1996 2023 return (0); /* Abort */
1997 2024 }
1998 2025 *fp->file_lo = *rlp;
1999 2026
2000 2027 if (lname[0] != '\0') {
2001 2028 /*
2002 2029 * Naming dance part 1: if we got a name from librtld_db, then
2003 2030 * copy this name to the prmap_t if it is unnamed. If the
2004 2031 * file_info_t is unnamed, name it after the lname.
2005 2032 */
2006 2033 if (mp->map_pmap.pr_mapname[0] == '\0') {
2007 2034 (void) strncpy(mp->map_pmap.pr_mapname, lname, PRMAPSZ);
2008 2035 mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2009 2036 }
2010 2037
2011 2038 if (fp->file_lname == NULL)
2012 2039 fp->file_lname = strdup(lname);
2013 2040
2014 2041 } else if (fp->file_lname == NULL &&
2015 2042 mp->map_pmap.pr_mapname[0] != '\0') {
2016 2043 /*
2017 2044 * Naming dance part 2: if the mapping is named and the
2018 2045 * file_info_t is not, name the file after the mapping.
2019 2046 */
2020 2047 fp->file_lname = strdup(mp->map_pmap.pr_mapname);
2021 2048 }
2022 2049
2023 2050 if ((fp->file_rname == NULL) &&
2024 2051 (Pfindmap(P, mp, buf, sizeof (buf)) != NULL))
2025 2052 fp->file_rname = strdup(buf);
2026 2053
2027 2054 if (fp->file_lname != NULL)
2028 2055 fp->file_lbase = basename(fp->file_lname);
2029 2056 if (fp->file_rname != NULL)
2030 2057 fp->file_rbase = basename(fp->file_rname);
2031 2058
2032 2059 /* Associate the file and the mapping. */
2033 2060 (void) strncpy(fp->file_pname, mp->map_pmap.pr_mapname, PRMAPSZ);
2034 2061 fp->file_pname[PRMAPSZ - 1] = '\0';
2035 2062
2036 2063 /*
2037 2064 * If no section headers were available then we'll have to
2038 2065 * identify this load object's other mappings with what we've
2039 2066 * got: the start and end of the object's corresponding
2040 2067 * address space.
2041 2068 */
2042 2069 if (fp->file_saddrs == NULL) {
2043 2070 for (mp = fp->file_map + 1; mp < P->mappings + P->map_count &&
2044 2071 mp->map_pmap.pr_vaddr < rlp->rl_bend; mp++) {
2045 2072
2046 2073 if (mp->map_file == NULL) {
2047 2074 dprintf("core_iter_mapping %s: associating "
2048 2075 "segment at %p\n",
2049 2076 fp->file_pname,
2050 2077 (void *)mp->map_pmap.pr_vaddr);
2051 2078 mp->map_file = fp;
2052 2079 fp->file_ref++;
2053 2080 } else {
2054 2081 dprintf("core_iter_mapping %s: segment at "
2055 2082 "%p already associated with %s\n",
2056 2083 fp->file_pname,
2057 2084 (void *)mp->map_pmap.pr_vaddr,
2058 2085 (mp == fp->file_map ? "this file" :
2059 2086 mp->map_file->file_pname));
2060 2087 }
2061 2088 }
2062 2089 }
2063 2090
2064 2091 /* Ensure that all this file's mappings are named. */
2065 2092 for (mp = fp->file_map; mp < P->mappings + P->map_count &&
2066 2093 mp->map_file == fp; mp++) {
2067 2094 if (mp->map_pmap.pr_mapname[0] == '\0' &&
2068 2095 !(mp->map_pmap.pr_mflags & MA_BREAK)) {
2069 2096 (void) strncpy(mp->map_pmap.pr_mapname, fp->file_pname,
2070 2097 PRMAPSZ);
2071 2098 mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2072 2099 }
2073 2100 }
2074 2101
2075 2102 /* Attempt to build a symbol table for this file. */
2076 2103 Pbuild_file_symtab(P, fp);
2077 2104 if (fp->file_elf == NULL)
2078 2105 dprintf("core_iter_mapping: no symtab for %s\n",
2079 2106 fp->file_pname);
2080 2107
2081 2108 /* Locate the start of a data segment associated with this file. */
2082 2109 if ((mp = core_find_data(P, fp->file_elf, fp->file_lo)) != NULL) {
2083 2110 dprintf("found data for %s at %p (pr_offset 0x%llx)\n",
2084 2111 fp->file_pname, (void *)fp->file_lo->rl_data_base,
2085 2112 mp->map_pmap.pr_offset);
2086 2113 } else {
2087 2114 dprintf("core_iter_mapping: no data found for %s\n",
2088 2115 fp->file_pname);
2089 2116 }
2090 2117
2091 2118 return (1); /* Advance to next mapping */
2092 2119 }
2093 2120
2094 2121 /*
2095 2122 * Callback function for Pfindexec(). In order to confirm a given pathname,
2096 2123 * we verify that we can open it as an ELF file of type ET_EXEC or ET_DYN.
2097 2124 */
2098 2125 static int
2099 2126 core_exec_open(const char *path, void *efp)
2100 2127 {
2101 2128 if (core_elf_open(efp, path, ET_EXEC, NULL) == 0)
2102 2129 return (1);
2103 2130 if (core_elf_open(efp, path, ET_DYN, NULL) == 0)
2104 2131 return (1);
2105 2132 return (0);
2106 2133 }
2107 2134
2108 2135 /*
2109 2136 * Attempt to load any section headers found in the core file. If present,
2110 2137 * this will refer to non-loadable data added to the core file by the kernel
2111 2138 * based on coreadm(1M) settings, including CTF data and the symbol table.
2112 2139 */
2113 2140 static void
2114 2141 core_load_shdrs(struct ps_prochandle *P, elf_file_t *efp)
2115 2142 {
2116 2143 GElf_Shdr *shp, *shdrs = NULL;
2117 2144 char *shstrtab = NULL;
2118 2145 ulong_t shstrtabsz;
2119 2146 const char *name;
2120 2147 map_info_t *mp;
2121 2148
2122 2149 size_t nbytes;
2123 2150 void *buf;
2124 2151 int i;
2125 2152
2126 2153 if (efp->e_hdr.e_shstrndx >= efp->e_hdr.e_shnum) {
2127 2154 dprintf("corrupt shstrndx (%u) exceeds shnum (%u)\n",
2128 2155 efp->e_hdr.e_shstrndx, efp->e_hdr.e_shnum);
2129 2156 return;
2130 2157 }
2131 2158
2132 2159 /*
2133 2160 * Read the section header table from the core file and then iterate
2134 2161 * over the section headers, converting each to a GElf_Shdr.
2135 2162 */
2136 2163 if ((shdrs = malloc(efp->e_hdr.e_shnum * sizeof (GElf_Shdr))) == NULL) {
2137 2164 dprintf("failed to malloc %u section headers: %s\n",
2138 2165 (uint_t)efp->e_hdr.e_shnum, strerror(errno));
2139 2166 return;
2140 2167 }
2141 2168
2142 2169 nbytes = efp->e_hdr.e_shnum * efp->e_hdr.e_shentsize;
2143 2170 if ((buf = malloc(nbytes)) == NULL) {
2144 2171 dprintf("failed to malloc %d bytes: %s\n", (int)nbytes,
2145 2172 strerror(errno));
2146 2173 free(shdrs);
2147 2174 goto out;
2148 2175 }
2149 2176
2150 2177 if (pread64(efp->e_fd, buf, nbytes, efp->e_hdr.e_shoff) != nbytes) {
2151 2178 dprintf("failed to read section headers at off %lld: %s\n",
2152 2179 (longlong_t)efp->e_hdr.e_shoff, strerror(errno));
2153 2180 free(buf);
2154 2181 goto out;
2155 2182 }
2156 2183
2157 2184 for (i = 0; i < efp->e_hdr.e_shnum; i++) {
2158 2185 void *p = (uchar_t *)buf + efp->e_hdr.e_shentsize * i;
2159 2186
2160 2187 if (efp->e_hdr.e_ident[EI_CLASS] == ELFCLASS32)
2161 2188 core_shdr_to_gelf(p, &shdrs[i]);
2162 2189 else
2163 2190 (void) memcpy(&shdrs[i], p, sizeof (GElf_Shdr));
2164 2191 }
2165 2192
2166 2193 free(buf);
2167 2194 buf = NULL;
2168 2195
2169 2196 /*
2170 2197 * Read the .shstrtab section from the core file, terminating it with
2171 2198 * an extra \0 so that a corrupt section will not cause us to die.
2172 2199 */
2173 2200 shp = &shdrs[efp->e_hdr.e_shstrndx];
2174 2201 shstrtabsz = shp->sh_size;
2175 2202
2176 2203 if ((shstrtab = malloc(shstrtabsz + 1)) == NULL) {
2177 2204 dprintf("failed to allocate %lu bytes for shstrtab\n",
2178 2205 (ulong_t)shstrtabsz);
2179 2206 goto out;
2180 2207 }
2181 2208
2182 2209 if (pread64(efp->e_fd, shstrtab, shstrtabsz,
2183 2210 shp->sh_offset) != shstrtabsz) {
2184 2211 dprintf("failed to read %lu bytes of shstrs at off %lld: %s\n",
2185 2212 shstrtabsz, (longlong_t)shp->sh_offset, strerror(errno));
2186 2213 goto out;
2187 2214 }
2188 2215
2189 2216 shstrtab[shstrtabsz] = '\0';
2190 2217
2191 2218 /*
2192 2219 * Now iterate over each section in the section header table, locating
2193 2220 * sections of interest and initializing more of the ps_prochandle.
2194 2221 */
2195 2222 for (i = 0; i < efp->e_hdr.e_shnum; i++) {
2196 2223 shp = &shdrs[i];
2197 2224 name = shstrtab + shp->sh_name;
2198 2225
2199 2226 if (shp->sh_name >= shstrtabsz) {
2200 2227 dprintf("skipping section [%d]: corrupt sh_name\n", i);
2201 2228 continue;
2202 2229 }
2203 2230
2204 2231 if (shp->sh_link >= efp->e_hdr.e_shnum) {
2205 2232 dprintf("skipping section [%d]: corrupt sh_link\n", i);
2206 2233 continue;
2207 2234 }
2208 2235
2209 2236 dprintf("found section header %s (sh_addr 0x%llx)\n",
2210 2237 name, (u_longlong_t)shp->sh_addr);
2211 2238
2212 2239 if (strcmp(name, ".SUNW_ctf") == 0) {
2213 2240 if ((mp = Paddr2mptr(P, shp->sh_addr)) == NULL) {
2214 2241 dprintf("no map at addr 0x%llx for %s [%d]\n",
2215 2242 (u_longlong_t)shp->sh_addr, name, i);
2216 2243 continue;
2217 2244 }
2218 2245
2219 2246 if (mp->map_file == NULL ||
2220 2247 mp->map_file->file_ctf_buf != NULL) {
2221 2248 dprintf("no mapping file or duplicate buffer "
2222 2249 "for %s [%d]\n", name, i);
2223 2250 continue;
2224 2251 }
2225 2252
2226 2253 if ((buf = malloc(shp->sh_size)) == NULL ||
2227 2254 pread64(efp->e_fd, buf, shp->sh_size,
2228 2255 shp->sh_offset) != shp->sh_size) {
2229 2256 dprintf("skipping section %s [%d]: %s\n",
2230 2257 name, i, strerror(errno));
2231 2258 free(buf);
2232 2259 continue;
2233 2260 }
2234 2261
2235 2262 mp->map_file->file_ctf_size = shp->sh_size;
2236 2263 mp->map_file->file_ctf_buf = buf;
2237 2264
2238 2265 if (shdrs[shp->sh_link].sh_type == SHT_DYNSYM)
2239 2266 mp->map_file->file_ctf_dyn = 1;
2240 2267
2241 2268 } else if (strcmp(name, ".symtab") == 0) {
2242 2269 fake_up_symtab(P, &efp->e_hdr,
2243 2270 shp, &shdrs[shp->sh_link]);
2244 2271 }
2245 2272 }
2246 2273 out:
2247 2274 free(shstrtab);
2248 2275 free(shdrs);
2249 2276 }
2250 2277
2251 2278 /*
2252 2279 * Main engine for core file initialization: given an fd for the core file
2253 2280 * and an optional pathname, construct the ps_prochandle. The aout_path can
2254 2281 * either be a suggested executable pathname, or a suggested directory to
2255 2282 * use as a possible current working directory.
2256 2283 */
2257 2284 struct ps_prochandle *
2258 2285 Pfgrab_core(int core_fd, const char *aout_path, int *perr)
2259 2286 {
2260 2287 struct ps_prochandle *P;
2261 2288 core_info_t *core_info;
2262 2289 map_info_t *stk_mp, *brk_mp;
2263 2290 const char *execname;
2264 2291 char *interp;
2265 2292 int i, notes, pagesize;
2266 2293 uintptr_t addr, base_addr;
2267 2294 struct stat64 stbuf;
2268 2295 void *phbuf, *php;
2269 2296 size_t nbytes;
2270 2297 #ifdef __x86
2271 2298 boolean_t from_linux = B_FALSE;
2272 2299 #endif
2273 2300
2274 2301 elf_file_t aout;
2275 2302 elf_file_t core;
2276 2303
2277 2304 Elf_Scn *scn, *intp_scn = NULL;
2278 2305 Elf_Data *dp;
2279 2306
2280 2307 GElf_Phdr phdr, note_phdr;
2281 2308 GElf_Shdr shdr;
2282 2309 GElf_Xword nleft;
2283 2310
2284 2311 if (elf_version(EV_CURRENT) == EV_NONE) {
2285 2312 dprintf("libproc ELF version is more recent than libelf\n");
2286 2313 *perr = G_ELF;
2287 2314 return (NULL);
2288 2315 }
2289 2316
2290 2317 aout.e_elf = NULL;
2291 2318 aout.e_fd = -1;
2292 2319
2293 2320 core.e_elf = NULL;
2294 2321 core.e_fd = core_fd;
2295 2322
2296 2323 /*
2297 2324 * Allocate and initialize a ps_prochandle structure for the core.
2298 2325 * There are several key pieces of initialization here:
2299 2326 *
2300 2327 * 1. The PS_DEAD state flag marks this prochandle as a core file.
2301 2328 * PS_DEAD also thus prevents all operations which require state
2302 2329 * to be PS_STOP from operating on this handle.
2303 2330 *
2304 2331 * 2. We keep the core file fd in P->asfd since the core file contains
2305 2332 * the remnants of the process address space.
2306 2333 *
2307 2334 * 3. We set the P->info_valid bit because all information about the
2308 2335 * core is determined by the end of this function; there is no need
2309 2336 * for proc_update_maps() to reload mappings at any later point.
2310 2337 *
2311 2338 * 4. The read/write ops vector uses our core_rw() function defined
2312 2339 * above to handle i/o requests.
2313 2340 */
2314 2341 if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
2315 2342 *perr = G_STRANGE;
2316 2343 return (NULL);
2317 2344 }
2318 2345
2319 2346 (void) memset(P, 0, sizeof (struct ps_prochandle));
2320 2347 (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
2321 2348 P->state = PS_DEAD;
2322 2349 P->pid = (pid_t)-1;
2323 2350 P->asfd = core.e_fd;
2324 2351 P->ctlfd = -1;
2325 2352 P->statfd = -1;
2326 2353 P->agentctlfd = -1;
2327 2354 P->agentstatfd = -1;
2328 2355 P->zoneroot = NULL;
2329 2356 P->info_valid = 1;
2330 2357 Pinit_ops(&P->ops, &P_core_ops);
2331 2358
2332 2359 Pinitsym(P);
2333 2360
2334 2361 /*
2335 2362 * Fstat and open the core file and make sure it is a valid ELF core.
2336 2363 */
2337 2364 if (fstat64(P->asfd, &stbuf) == -1) {
2338 2365 *perr = G_STRANGE;
2339 2366 goto err;
2340 2367 }
2341 2368
2342 2369 if (core_elf_fdopen(&core, ET_CORE, perr) == -1)
2343 2370 goto err;
2344 2371
2345 2372 /*
2346 2373 * Allocate and initialize a core_info_t to hang off the ps_prochandle
2347 2374 * structure. We keep all core-specific information in this structure.
2348 2375 */
2349 2376 if ((core_info = calloc(1, sizeof (core_info_t))) == NULL) {
2350 2377 *perr = G_STRANGE;
2351 2378 goto err;
2352 2379 }
2353 2380
2354 2381 P->data = core_info;
2355 2382 list_link(&core_info->core_lwp_head, NULL);
2356 2383 core_info->core_size = stbuf.st_size;
2357 2384 /*
2358 2385 * In the days before adjustable core file content, this was the
2359 2386 * default core file content. For new core files, this value will
2360 2387 * be overwritten by the NT_CONTENT note section.
2361 2388 */
2362 2389 core_info->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP |
2363 2390 CC_CONTENT_DATA | CC_CONTENT_RODATA | CC_CONTENT_ANON |
2364 2391 CC_CONTENT_SHANON;
2365 2392
2366 2393 switch (core.e_hdr.e_ident[EI_CLASS]) {
2367 2394 case ELFCLASS32:
2368 2395 core_info->core_dmodel = PR_MODEL_ILP32;
2369 2396 break;
2370 2397 case ELFCLASS64:
2371 2398 core_info->core_dmodel = PR_MODEL_LP64;
2372 2399 break;
2373 2400 default:
2374 2401 *perr = G_FORMAT;
2375 2402 goto err;
2376 2403 }
2377 2404 core_info->core_osabi = core.e_hdr.e_ident[EI_OSABI];
2378 2405
2379 2406 /*
2380 2407 * Because the core file may be a large file, we can't use libelf to
2381 2408 * read the Phdrs. We use e_phnum and e_phentsize to simplify things.
2382 2409 */
2383 2410 nbytes = core.e_hdr.e_phnum * core.e_hdr.e_phentsize;
2384 2411
2385 2412 if ((phbuf = malloc(nbytes)) == NULL) {
2386 2413 *perr = G_STRANGE;
2387 2414 goto err;
2388 2415 }
2389 2416
2390 2417 if (pread64(core_fd, phbuf, nbytes, core.e_hdr.e_phoff) != nbytes) {
2391 2418 *perr = G_STRANGE;
2392 2419 free(phbuf);
2393 2420 goto err;
2394 2421 }
2395 2422
2396 2423 /*
2397 2424 * Iterate through the program headers in the core file.
2398 2425 * We're interested in two types of Phdrs: PT_NOTE (which
2399 2426 * contains a set of saved /proc structures), and PT_LOAD (which
2400 2427 * represents a memory mapping from the process's address space).
2401 2428 * In the case of PT_NOTE, we're interested in the last PT_NOTE
2402 2429 * in the core file; currently the first PT_NOTE (if present)
2403 2430 * contains /proc structs in the pre-2.6 unstructured /proc format.
2404 2431 */
2405 2432 for (php = phbuf, notes = 0, i = 0; i < core.e_hdr.e_phnum; i++) {
2406 2433 if (core.e_hdr.e_ident[EI_CLASS] == ELFCLASS64)
2407 2434 (void) memcpy(&phdr, php, sizeof (GElf_Phdr));
2408 2435 else
2409 2436 core_phdr_to_gelf(php, &phdr);
2410 2437
2411 2438 switch (phdr.p_type) {
2412 2439 case PT_NOTE:
2413 2440 note_phdr = phdr;
2414 2441 notes++;
2415 2442 break;
2416 2443
2417 2444 case PT_LOAD:
2418 2445 if (core_add_mapping(P, &phdr) == -1) {
2419 2446 *perr = G_STRANGE;
2420 2447 free(phbuf);
2421 2448 goto err;
2422 2449 }
2423 2450 break;
2424 2451 default:
2425 2452 dprintf("Pgrab_core: unknown phdr %d\n", phdr.p_type);
2426 2453 break;
2427 2454 }
2428 2455
2429 2456 php = (char *)php + core.e_hdr.e_phentsize;
2430 2457 }
2431 2458
2432 2459 free(phbuf);
2433 2460
2434 2461 Psort_mappings(P);
2435 2462
2436 2463 /*
2437 2464 * If we couldn't find anything of type PT_NOTE, or only one PT_NOTE
2438 2465 * was present, abort. The core file is either corrupt or too old.
2439 2466 */
2440 2467 if (notes == 0 || (notes == 1 && core_info->core_osabi ==
2441 2468 ELFOSABI_SOLARIS)) {
2442 2469 *perr = G_NOTE;
2443 2470 goto err;
2444 2471 }
2445 2472
2446 2473 /*
2447 2474 * Advance the seek pointer to the start of the PT_NOTE data
2448 2475 */
2449 2476 if (lseek64(P->asfd, note_phdr.p_offset, SEEK_SET) == (off64_t)-1) {
2450 2477 dprintf("Pgrab_core: failed to lseek to PT_NOTE data\n");
2451 2478 *perr = G_STRANGE;
2452 2479 goto err;
2453 2480 }
2454 2481
2455 2482 /*
2456 2483 * Now process the PT_NOTE structures. Each one is preceded by
2457 2484 * an Elf{32/64}_Nhdr structure describing its type and size.
2458 2485 *
2459 2486 * +--------+
2460 2487 * | header |
2461 2488 * +--------+
2462 2489 * | name |
2463 2490 * | ... |
2464 2491 * +--------+
2465 2492 * | desc |
2466 2493 * | ... |
2467 2494 * +--------+
2468 2495 */
2469 2496 for (nleft = note_phdr.p_filesz; nleft > 0; ) {
2470 2497 Elf64_Nhdr nhdr;
2471 2498 off64_t off, namesz, descsz;
2472 2499
2473 2500 /*
2474 2501 * Although <sys/elf.h> defines both Elf32_Nhdr and Elf64_Nhdr
2475 2502 * as different types, they are both of the same content and
2476 2503 * size, so we don't need to worry about 32/64 conversion here.
2477 2504 */
2478 2505 if (read(P->asfd, &nhdr, sizeof (nhdr)) != sizeof (nhdr)) {
2479 2506 dprintf("Pgrab_core: failed to read ELF note header\n");
2480 2507 *perr = G_NOTE;
2481 2508 goto err;
2482 2509 }
2483 2510
2484 2511 /*
2485 2512 * According to the System V ABI, the amount of padding
2486 2513 * following the name field should align the description
2487 2514 * field on a 4 byte boundary for 32-bit binaries or on an 8
2488 2515 * byte boundary for 64-bit binaries. However, this change
2489 2516 * was not made correctly during the 64-bit port so all
2490 2517 * descriptions can assume only 4-byte alignment. We ignore
2491 2518 * the name field and the padding to 4-byte alignment.
2492 2519 */
2493 2520 namesz = P2ROUNDUP((off64_t)nhdr.n_namesz, (off64_t)4);
2494 2521
2495 2522 if (lseek64(P->asfd, namesz, SEEK_CUR) == (off64_t)-1) {
2496 2523 dprintf("failed to seek past name and padding\n");
2497 2524 *perr = G_STRANGE;
2498 2525 goto err;
2499 2526 }
2500 2527
2501 2528 dprintf("Note hdr n_type=%u n_namesz=%u n_descsz=%u\n",
2502 2529 nhdr.n_type, nhdr.n_namesz, nhdr.n_descsz);
2503 2530
2504 2531 off = lseek64(P->asfd, (off64_t)0L, SEEK_CUR);
2505 2532
2506 2533 /*
2507 2534 * Invoke the note handler function from our table
2508 2535 */
2509 2536 if (nhdr.n_type < sizeof (nhdlrs) / sizeof (nhdlrs[0])) {
2510 2537 if (nhdlrs[nhdr.n_type](P, nhdr.n_descsz) < 0) {
2511 2538 dprintf("handler for type %d returned < 0",
2512 2539 nhdr.n_type);
2513 2540 *perr = G_NOTE;
2514 2541 goto err;
2515 2542 }
2516 2543 /*
2517 2544 * The presence of either of these notes indicates that
2518 2545 * the dump was generated on Linux.
2519 2546 */
2520 2547 #ifdef __x86
2521 2548 if (nhdr.n_type == NT_PRSTATUS ||
2522 2549 nhdr.n_type == NT_PRPSINFO)
2523 2550 from_linux = B_TRUE;
2524 2551 #endif
2525 2552 } else {
2526 2553 (void) note_notsup(P, nhdr.n_descsz);
2527 2554 }
2528 2555
2529 2556 /*
2530 2557 * Seek past the current note data to the next Elf_Nhdr
2531 2558 */
2532 2559 descsz = P2ROUNDUP((off64_t)nhdr.n_descsz, (off64_t)4);
2533 2560 if (lseek64(P->asfd, off + descsz, SEEK_SET) == (off64_t)-1) {
2534 2561 dprintf("Pgrab_core: failed to seek to next nhdr\n");
2535 2562 *perr = G_STRANGE;
2536 2563 goto err;
2537 2564 }
2538 2565
2539 2566 /*
2540 2567 * Subtract the size of the header and its data from what
2541 2568 * we have left to process.
2542 2569 */
2543 2570 nleft -= sizeof (nhdr) + namesz + descsz;
2544 2571 }
2545 2572
2546 2573 #ifdef __x86
2547 2574 if (from_linux) {
2548 2575 size_t tcount, pid;
2549 2576 lwp_info_t *lwp;
2550 2577
2551 2578 P->status.pr_dmodel = core_info->core_dmodel;
2552 2579
2553 2580 lwp = list_next(&core_info->core_lwp_head);
2554 2581
2555 2582 pid = P->status.pr_pid;
2556 2583
2557 2584 for (tcount = 0; tcount < core_info->core_nlwp;
2558 2585 tcount++, lwp = list_next(lwp)) {
2559 2586 dprintf("Linux thread with id %d\n", lwp->lwp_id);
2560 2587
2561 2588 /*
2562 2589 * In the case we don't have a valid psinfo (i.e. pid is
2563 2590 * 0, probably because of gdb creating the core) assume
2564 2591 * lowest pid count is the first thread (what if the
2565 2592 * next thread wraps the pid around?)
2566 2593 */
2567 2594 if (P->status.pr_pid == 0 &&
2568 2595 ((pid == 0 && lwp->lwp_id > 0) ||
2569 2596 (lwp->lwp_id < pid))) {
2570 2597 pid = lwp->lwp_id;
2571 2598 }
2572 2599 }
2573 2600
2574 2601 if (P->status.pr_pid != pid) {
2575 2602 dprintf("No valid pid, setting to %ld\n", (ulong_t)pid);
2576 2603 P->status.pr_pid = pid;
2577 2604 P->psinfo.pr_pid = pid;
2578 2605 }
2579 2606
2580 2607 /*
2581 2608 * Consumers like mdb expect the first thread to actually have
2582 2609 * an id of 1, on linux that is actually the pid. Find the the
2583 2610 * thread with our process id, and set the id to 1
2584 2611 */
2585 2612 if ((lwp = lwpid2info(P, pid)) == NULL) {
2586 2613 dprintf("Couldn't find first thread\n");
2587 2614 *perr = G_STRANGE;
2588 2615 goto err;
2589 2616 }
2590 2617
2591 2618 dprintf("setting representative thread: %d\n", lwp->lwp_id);
2592 2619
2593 2620 lwp->lwp_id = 1;
2594 2621 lwp->lwp_status.pr_lwpid = 1;
2595 2622
2596 2623 /* set representative thread */
2597 2624 (void) memcpy(&P->status.pr_lwp, &lwp->lwp_status,
2598 2625 sizeof (P->status.pr_lwp));
2599 2626 }
2600 2627 #endif /* __x86 */
2601 2628
2602 2629 if (nleft != 0) {
2603 2630 dprintf("Pgrab_core: note section malformed\n");
2604 2631 *perr = G_STRANGE;
2605 2632 goto err;
2606 2633 }
2607 2634
2608 2635 if ((pagesize = Pgetauxval(P, AT_PAGESZ)) == -1) {
2609 2636 pagesize = getpagesize();
2610 2637 dprintf("AT_PAGESZ missing; defaulting to %d\n", pagesize);
2611 2638 }
2612 2639
2613 2640 /*
2614 2641 * Locate and label the mappings corresponding to the end of the
2615 2642 * heap (MA_BREAK) and the base of the stack (MA_STACK).
2616 2643 */
2617 2644 if ((P->status.pr_brkbase != 0 || P->status.pr_brksize != 0) &&
2618 2645 (brk_mp = Paddr2mptr(P, P->status.pr_brkbase +
2619 2646 P->status.pr_brksize - 1)) != NULL)
2620 2647 brk_mp->map_pmap.pr_mflags |= MA_BREAK;
2621 2648 else
2622 2649 brk_mp = NULL;
2623 2650
2624 2651 if ((stk_mp = Paddr2mptr(P, P->status.pr_stkbase)) != NULL)
2625 2652 stk_mp->map_pmap.pr_mflags |= MA_STACK;
2626 2653
2627 2654 /*
2628 2655 * At this point, we have enough information to look for the
2629 2656 * executable and open it: we have access to the auxv, a psinfo_t,
2630 2657 * and the ability to read from mappings provided by the core file.
2631 2658 */
2632 2659 (void) Pfindexec(P, aout_path, core_exec_open, &aout);
2633 2660 dprintf("P->execname = \"%s\"\n", P->execname ? P->execname : "NULL");
2634 2661 execname = P->execname ? P->execname : "a.out";
2635 2662
2636 2663 /*
2637 2664 * Iterate through the sections, looking for the .dynamic and .interp
2638 2665 * sections. If we encounter them, remember their section pointers.
2639 2666 */
2640 2667 for (scn = NULL; (scn = elf_nextscn(aout.e_elf, scn)) != NULL; ) {
2641 2668 char *sname;
2642 2669
2643 2670 if ((gelf_getshdr(scn, &shdr) == NULL) ||
2644 2671 (sname = elf_strptr(aout.e_elf, aout.e_hdr.e_shstrndx,
2645 2672 (size_t)shdr.sh_name)) == NULL)
2646 2673 continue;
2647 2674
2648 2675 if (strcmp(sname, ".interp") == 0)
2649 2676 intp_scn = scn;
2650 2677 }
2651 2678
2652 2679 /*
2653 2680 * Get the AT_BASE auxv element. If this is missing (-1), then
2654 2681 * we assume this is a statically-linked executable.
2655 2682 */
2656 2683 base_addr = Pgetauxval(P, AT_BASE);
2657 2684
2658 2685 /*
2659 2686 * In order to get librtld_db initialized, we'll need to identify
2660 2687 * and name the mapping corresponding to the run-time linker. The
2661 2688 * AT_BASE auxv element tells us the address where it was mapped,
2662 2689 * and the .interp section of the executable tells us its path.
2663 2690 * If for some reason that doesn't pan out, just use ld.so.1.
2664 2691 */
2665 2692 if (intp_scn != NULL && (dp = elf_getdata(intp_scn, NULL)) != NULL &&
2666 2693 dp->d_size != 0) {
2667 2694 dprintf(".interp = <%s>\n", (char *)dp->d_buf);
2668 2695 interp = dp->d_buf;
2669 2696
2670 2697 } else if (base_addr != (uintptr_t)-1L) {
2671 2698 if (core_info->core_dmodel == PR_MODEL_LP64)
2672 2699 interp = "/usr/lib/64/ld.so.1";
2673 2700 else
2674 2701 interp = "/usr/lib/ld.so.1";
2675 2702
2676 2703 dprintf(".interp section is missing or could not be read; "
2677 2704 "defaulting to %s\n", interp);
2678 2705 } else
2679 2706 dprintf("detected statically linked executable\n");
2680 2707
2681 2708 /*
2682 2709 * If we have an AT_BASE element, name the mapping at that address
2683 2710 * using the interpreter pathname. Name the corresponding data
2684 2711 * mapping after the interpreter as well.
2685 2712 */
2686 2713 if (base_addr != (uintptr_t)-1L) {
2687 2714 elf_file_t intf;
2688 2715
2689 2716 P->map_ldso = core_name_mapping(P, base_addr, interp);
2690 2717
2691 2718 if (core_elf_open(&intf, interp, ET_DYN, NULL) == 0) {
2692 2719 rd_loadobj_t rl;
2693 2720 map_info_t *dmp;
2694 2721
2695 2722 rl.rl_base = base_addr;
2696 2723 dmp = core_find_data(P, intf.e_elf, &rl);
2697 2724
2698 2725 if (dmp != NULL) {
2699 2726 dprintf("renamed data at %p to %s\n",
2700 2727 (void *)rl.rl_data_base, interp);
2701 2728 (void) strncpy(dmp->map_pmap.pr_mapname,
2702 2729 interp, PRMAPSZ);
2703 2730 dmp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2704 2731 }
2705 2732 }
2706 2733
2707 2734 core_elf_close(&intf);
2708 2735 }
2709 2736
2710 2737 /*
2711 2738 * If we have an AT_ENTRY element, name the mapping at that address
2712 2739 * using the special name "a.out" just like /proc does.
2713 2740 */
2714 2741 if ((addr = Pgetauxval(P, AT_ENTRY)) != (uintptr_t)-1L)
2715 2742 P->map_exec = core_name_mapping(P, addr, "a.out");
2716 2743
2717 2744 /*
2718 2745 * If we're a statically linked executable (or we're on x86 and looking
2719 2746 * at a Linux core dump), then just locate the executable's text and
2720 2747 * data and name them after the executable.
2721 2748 */
2722 2749 #ifndef __x86
2723 2750 if (base_addr == (uintptr_t)-1L) {
2724 2751 #else
2725 2752 if (base_addr == (uintptr_t)-1L || from_linux) {
2726 2753 #endif
2727 2754 dprintf("looking for text and data: %s\n", execname);
2728 2755 map_info_t *tmp, *dmp;
2729 2756 file_info_t *fp;
2730 2757 rd_loadobj_t rl;
2731 2758
2732 2759 if ((tmp = core_find_text(P, aout.e_elf, &rl)) != NULL &&
2733 2760 (dmp = core_find_data(P, aout.e_elf, &rl)) != NULL) {
2734 2761 (void) strncpy(tmp->map_pmap.pr_mapname,
2735 2762 execname, PRMAPSZ);
2736 2763 tmp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2737 2764 (void) strncpy(dmp->map_pmap.pr_mapname,
2738 2765 execname, PRMAPSZ);
2739 2766 dmp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2740 2767 }
2741 2768
2742 2769 if ((P->map_exec = tmp) != NULL &&
2743 2770 (fp = malloc(sizeof (file_info_t))) != NULL) {
2744 2771
2745 2772 (void) memset(fp, 0, sizeof (file_info_t));
2746 2773
2747 2774 list_link(fp, &P->file_head);
2748 2775 tmp->map_file = fp;
2749 2776 P->num_files++;
2750 2777
2751 2778 fp->file_ref = 1;
2752 2779 fp->file_fd = -1;
2753 2780
2754 2781 fp->file_lo = malloc(sizeof (rd_loadobj_t));
2755 2782 fp->file_lname = strdup(execname);
2756 2783
2757 2784 if (fp->file_lo)
2758 2785 *fp->file_lo = rl;
2759 2786 if (fp->file_lname)
2760 2787 fp->file_lbase = basename(fp->file_lname);
2761 2788 if (fp->file_rname)
2762 2789 fp->file_rbase = basename(fp->file_rname);
2763 2790
2764 2791 (void) strcpy(fp->file_pname,
2765 2792 P->mappings[0].map_pmap.pr_mapname);
2766 2793 fp->file_map = tmp;
2767 2794
2768 2795 Pbuild_file_symtab(P, fp);
2769 2796
2770 2797 if (dmp != NULL) {
2771 2798 dmp->map_file = fp;
2772 2799 fp->file_ref++;
2773 2800 }
2774 2801 }
2775 2802 }
2776 2803
2777 2804 core_elf_close(&aout);
2778 2805
2779 2806 /*
2780 2807 * We now have enough information to initialize librtld_db.
2781 2808 * After it warms up, we can iterate through the load object chain
2782 2809 * in the core, which will allow us to construct the file info
2783 2810 * we need to provide symbol information for the other shared
2784 2811 * libraries, and also to fill in the missing mapping names.
2785 2812 */
2786 2813 rd_log(_libproc_debug);
2787 2814
2788 2815 if ((P->rap = rd_new(P)) != NULL) {
2789 2816 (void) rd_loadobj_iter(P->rap, (rl_iter_f *)
2790 2817 core_iter_mapping, P);
2791 2818
2792 2819 if (core_info->core_errno != 0) {
2793 2820 errno = core_info->core_errno;
2794 2821 *perr = G_STRANGE;
2795 2822 goto err;
2796 2823 }
2797 2824 } else
2798 2825 dprintf("failed to initialize rtld_db agent\n");
2799 2826
2800 2827 /*
2801 2828 * If there are sections, load them and process the data from any
2802 2829 * sections that we can use to annotate the file_info_t's.
2803 2830 */
2804 2831 core_load_shdrs(P, &core);
2805 2832
2806 2833 /*
2807 2834 * If we previously located a stack or break mapping, and they are
2808 2835 * still anonymous, we now assume that they were MAP_ANON mappings.
2809 2836 * If brk_mp turns out to now have a name, then the heap is still
2810 2837 * sitting at the end of the executable's data+bss mapping: remove
2811 2838 * the previous MA_BREAK setting to be consistent with /proc.
2812 2839 */
2813 2840 if (stk_mp != NULL && stk_mp->map_pmap.pr_mapname[0] == '\0')
2814 2841 stk_mp->map_pmap.pr_mflags |= MA_ANON;
2815 2842 if (brk_mp != NULL && brk_mp->map_pmap.pr_mapname[0] == '\0')
2816 2843 brk_mp->map_pmap.pr_mflags |= MA_ANON;
2817 2844 else if (brk_mp != NULL)
2818 2845 brk_mp->map_pmap.pr_mflags &= ~MA_BREAK;
2819 2846
2820 2847 *perr = 0;
2821 2848 return (P);
2822 2849
2823 2850 err:
2824 2851 Pfree(P);
2825 2852 core_elf_close(&aout);
2826 2853 return (NULL);
2827 2854 }
2828 2855
2829 2856 /*
2830 2857 * Grab a core file using a pathname. We just open it and call Pfgrab_core().
2831 2858 */
2832 2859 struct ps_prochandle *
2833 2860 Pgrab_core(const char *core, const char *aout, int gflag, int *perr)
2834 2861 {
2835 2862 int fd, oflag = (gflag & PGRAB_RDONLY) ? O_RDONLY : O_RDWR;
2836 2863
2837 2864 if ((fd = open64(core, oflag)) >= 0)
2838 2865 return (Pfgrab_core(fd, aout, perr));
2839 2866
2840 2867 if (errno != ENOENT)
2841 2868 *perr = G_STRANGE;
2842 2869 else
2843 2870 *perr = G_NOCORE;
2844 2871
2845 2872 return (NULL);
2846 2873 }
↓ open down ↓ |
1603 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX