elfcore.c (249704) | elfcore.c (269128) |
---|---|
1/*- 2 * Copyright (c) 2007 Sandvine Incorporated 3 * Copyright (c) 1998 John D. Polstra 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2007 Sandvine Incorporated 3 * Copyright (c) 1998 John D. Polstra 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/usr.bin/gcore/elfcore.c 249704 2013-04-20 15:37:33Z trociny $"); | 29__FBSDID("$FreeBSD: head/usr.bin/gcore/elfcore.c 269128 2014-07-26 16:45:11Z marcel $"); |
30 | 30 |
31#include <sys/endian.h> |
|
31#include <sys/param.h> 32#include <sys/procfs.h> 33#include <sys/ptrace.h> 34#include <sys/queue.h> 35#include <sys/linker_set.h> 36#include <sys/sbuf.h> 37#include <sys/sysctl.h> 38#include <sys/user.h> --- 29 unchanged lines hidden (view full) --- 68}; 69 70/* Closure for cb_size_segment(). */ 71struct sseg_closure { 72 int count; /* Count of writable segments. */ 73 size_t size; /* Total size of all writable segments. */ 74}; 75 | 32#include <sys/param.h> 33#include <sys/procfs.h> 34#include <sys/ptrace.h> 35#include <sys/queue.h> 36#include <sys/linker_set.h> 37#include <sys/sbuf.h> 38#include <sys/sysctl.h> 39#include <sys/user.h> --- 29 unchanged lines hidden (view full) --- 69}; 70 71/* Closure for cb_size_segment(). */ 72struct sseg_closure { 73 int count; /* Count of writable segments. */ 74 size_t size; /* Total size of all writable segments. */ 75}; 76 |
77#ifdef ELFCORE_COMPAT_32 78typedef struct fpreg32 elfcore_fpregset_t; 79typedef struct reg32 elfcore_gregset_t; 80typedef struct prpsinfo32 elfcore_prpsinfo_t; 81typedef struct prstatus32 elfcore_prstatus_t; 82static void elf_convert_gregset(elfcore_gregset_t *rd, struct reg *rs); 83static void elf_convert_fpregset(elfcore_fpregset_t *rd, struct fpreg *rs); 84#else 85typedef fpregset_t elfcore_fpregset_t; 86typedef gregset_t elfcore_gregset_t; 87typedef prpsinfo_t elfcore_prpsinfo_t; 88typedef prstatus_t elfcore_prstatus_t; 89#define elf_convert_gregset(d,s) *d = *s 90#define elf_convert_fpregset(d,s) *d = *s 91#endif 92 |
|
76typedef void* (*notefunc_t)(void *, size_t *); 77 78static void cb_put_phdr(vm_map_entry_t, void *); 79static void cb_size_segment(vm_map_entry_t, void *); 80static void each_writable_segment(vm_map_entry_t, segment_callback, 81 void *closure); 82static void elf_detach(void); /* atexit() handler. */ 83static void *elf_note_fpregset(void *, size_t *); --- 19 unchanged lines hidden (view full) --- 103 104static pid_t g_pid; /* Pid being dumped, global for elf_detach */ 105 106static int 107elf_ident(int efd, pid_t pid __unused, char *binfile __unused) 108{ 109 Elf_Ehdr hdr; 110 int cnt; | 93typedef void* (*notefunc_t)(void *, size_t *); 94 95static void cb_put_phdr(vm_map_entry_t, void *); 96static void cb_size_segment(vm_map_entry_t, void *); 97static void each_writable_segment(vm_map_entry_t, segment_callback, 98 void *closure); 99static void elf_detach(void); /* atexit() handler. */ 100static void *elf_note_fpregset(void *, size_t *); --- 19 unchanged lines hidden (view full) --- 120 121static pid_t g_pid; /* Pid being dumped, global for elf_detach */ 122 123static int 124elf_ident(int efd, pid_t pid __unused, char *binfile __unused) 125{ 126 Elf_Ehdr hdr; 127 int cnt; |
128 uint16_t machine; |
|
111 112 cnt = read(efd, &hdr, sizeof(hdr)); 113 if (cnt != sizeof(hdr)) 114 return (0); | 129 130 cnt = read(efd, &hdr, sizeof(hdr)); 131 if (cnt != sizeof(hdr)) 132 return (0); |
115 if (IS_ELF(hdr)) 116 return (1); 117 return (0); | 133 if (!IS_ELF(hdr)) 134 return (0); 135 switch (hdr.e_ident[EI_DATA]) { 136 case ELFDATA2LSB: 137 machine = le16toh(hdr.e_machine); 138 break; 139 case ELFDATA2MSB: 140 machine = be16toh(hdr.e_machine); 141 break; 142 default: 143 return (0); 144 } 145 if (!ELF_MACHINE_OK(machine)) 146 return (0); 147 148 /* Looks good. */ 149 return (1); |
118} 119 120static void 121elf_detach(void) 122{ 123 124 if (g_pid != 0) 125 ptrace(PT_DETACH, g_pid, (caddr_t)1, 0); --- 63 unchanged lines hidden (view full) --- 189 190 /* Write the contents of all of the writable segments. */ 191 php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; 192 for (i = 0; i < seginfo.count; i++) { 193 struct ptrace_io_desc iorequest; 194 uintmax_t nleft = php->p_filesz; 195 196 iorequest.piod_op = PIOD_READ_D; | 150} 151 152static void 153elf_detach(void) 154{ 155 156 if (g_pid != 0) 157 ptrace(PT_DETACH, g_pid, (caddr_t)1, 0); --- 63 unchanged lines hidden (view full) --- 221 222 /* Write the contents of all of the writable segments. */ 223 php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; 224 for (i = 0; i < seginfo.count; i++) { 225 struct ptrace_io_desc iorequest; 226 uintmax_t nleft = php->p_filesz; 227 228 iorequest.piod_op = PIOD_READ_D; |
197 iorequest.piod_offs = (caddr_t)php->p_vaddr; | 229 iorequest.piod_offs = (caddr_t)(uintptr_t)php->p_vaddr; |
198 while (nleft > 0) { 199 char buf[8*1024]; 200 size_t nwant; 201 ssize_t ngot; 202 203 if (nleft > sizeof(buf)) 204 nwant = sizeof buf; 205 else --- 100 unchanged lines hidden (view full) --- 306 elf_putnote(NT_PRPSINFO, elf_note_prpsinfo, &pid, sb); 307 308 for (i = 0; i < threads; ++i) { 309 elf_putnote(NT_PRSTATUS, elf_note_prstatus, tids + i, sb); 310 elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb); 311 elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb); 312 } 313 | 230 while (nleft > 0) { 231 char buf[8*1024]; 232 size_t nwant; 233 ssize_t ngot; 234 235 if (nleft > sizeof(buf)) 236 nwant = sizeof buf; 237 else --- 100 unchanged lines hidden (view full) --- 338 elf_putnote(NT_PRPSINFO, elf_note_prpsinfo, &pid, sb); 339 340 for (i = 0; i < threads; ++i) { 341 elf_putnote(NT_PRSTATUS, elf_note_prstatus, tids + i, sb); 342 elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb); 343 elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb); 344 } 345 |
346#ifndef ELFCORE_COMPAT_32 |
|
314 elf_putnote(NT_PROCSTAT_PROC, elf_note_procstat_proc, &pid, sb); 315 elf_putnote(NT_PROCSTAT_FILES, elf_note_procstat_files, &pid, sb); 316 elf_putnote(NT_PROCSTAT_VMMAP, elf_note_procstat_vmmap, &pid, sb); 317 elf_putnote(NT_PROCSTAT_GROUPS, elf_note_procstat_groups, &pid, sb); 318 elf_putnote(NT_PROCSTAT_UMASK, elf_note_procstat_umask, &pid, sb); 319 elf_putnote(NT_PROCSTAT_RLIMIT, elf_note_procstat_rlimit, &pid, sb); 320 elf_putnote(NT_PROCSTAT_OSREL, elf_note_procstat_osrel, &pid, sb); 321 elf_putnote(NT_PROCSTAT_PSSTRINGS, elf_note_procstat_psstrings, &pid, 322 sb); 323 elf_putnote(NT_PROCSTAT_AUXV, elf_note_procstat_auxv, &pid, sb); | 347 elf_putnote(NT_PROCSTAT_PROC, elf_note_procstat_proc, &pid, sb); 348 elf_putnote(NT_PROCSTAT_FILES, elf_note_procstat_files, &pid, sb); 349 elf_putnote(NT_PROCSTAT_VMMAP, elf_note_procstat_vmmap, &pid, sb); 350 elf_putnote(NT_PROCSTAT_GROUPS, elf_note_procstat_groups, &pid, sb); 351 elf_putnote(NT_PROCSTAT_UMASK, elf_note_procstat_umask, &pid, sb); 352 elf_putnote(NT_PROCSTAT_RLIMIT, elf_note_procstat_rlimit, &pid, sb); 353 elf_putnote(NT_PROCSTAT_OSREL, elf_note_procstat_osrel, &pid, sb); 354 elf_putnote(NT_PROCSTAT_PSSTRINGS, elf_note_procstat_psstrings, &pid, 355 sb); 356 elf_putnote(NT_PROCSTAT_AUXV, elf_note_procstat_auxv, &pid, sb); |
357#endif |
|
324 325 size = sbuf_end_section(sb, old_len, 1, 0); 326 if (size == -1) 327 err(1, "sbuf_end_section"); 328 free(tids); 329 *sizep = size; 330} 331 --- 154 unchanged lines hidden (view full) --- 486/* 487 * Miscellaneous note out functions. 488 */ 489 490static void * 491elf_note_prpsinfo(void *arg, size_t *sizep) 492{ 493 pid_t pid; | 358 359 size = sbuf_end_section(sb, old_len, 1, 0); 360 if (size == -1) 361 err(1, "sbuf_end_section"); 362 free(tids); 363 *sizep = size; 364} 365 --- 154 unchanged lines hidden (view full) --- 520/* 521 * Miscellaneous note out functions. 522 */ 523 524static void * 525elf_note_prpsinfo(void *arg, size_t *sizep) 526{ 527 pid_t pid; |
494 prpsinfo_t *psinfo; | 528 elfcore_prpsinfo_t *psinfo; |
495 struct kinfo_proc kip; 496 size_t len; 497 int name[4]; 498 499 pid = *(pid_t *)arg; 500 psinfo = calloc(1, sizeof(*psinfo)); 501 if (psinfo == NULL) 502 errx(1, "out of memory"); 503 psinfo->pr_version = PRPSINFO_VERSION; | 529 struct kinfo_proc kip; 530 size_t len; 531 int name[4]; 532 533 pid = *(pid_t *)arg; 534 psinfo = calloc(1, sizeof(*psinfo)); 535 if (psinfo == NULL) 536 errx(1, "out of memory"); 537 psinfo->pr_version = PRPSINFO_VERSION; |
504 psinfo->pr_psinfosz = sizeof(prpsinfo_t); | 538 psinfo->pr_psinfosz = sizeof(*psinfo); |
505 506 name[0] = CTL_KERN; 507 name[1] = KERN_PROC; 508 name[2] = KERN_PROC_PID; 509 name[3] = pid; 510 len = sizeof(kip); 511 if (sysctl(name, 4, &kip, &len, NULL, 0) == -1) 512 err(1, "kern.proc.pid.%u", pid); --- 5 unchanged lines hidden (view full) --- 518 *sizep = sizeof(*psinfo); 519 return (psinfo); 520} 521 522static void * 523elf_note_prstatus(void *arg, size_t *sizep) 524{ 525 lwpid_t tid; | 539 540 name[0] = CTL_KERN; 541 name[1] = KERN_PROC; 542 name[2] = KERN_PROC_PID; 543 name[3] = pid; 544 len = sizeof(kip); 545 if (sysctl(name, 4, &kip, &len, NULL, 0) == -1) 546 err(1, "kern.proc.pid.%u", pid); --- 5 unchanged lines hidden (view full) --- 552 *sizep = sizeof(*psinfo); 553 return (psinfo); 554} 555 556static void * 557elf_note_prstatus(void *arg, size_t *sizep) 558{ 559 lwpid_t tid; |
526 prstatus_t *status; | 560 elfcore_prstatus_t *status; 561 struct reg greg; |
527 528 tid = *(lwpid_t *)arg; 529 status = calloc(1, sizeof(*status)); 530 if (status == NULL) 531 errx(1, "out of memory"); 532 status->pr_version = PRSTATUS_VERSION; | 562 563 tid = *(lwpid_t *)arg; 564 status = calloc(1, sizeof(*status)); 565 if (status == NULL) 566 errx(1, "out of memory"); 567 status->pr_version = PRSTATUS_VERSION; |
533 status->pr_statussz = sizeof(prstatus_t); 534 status->pr_gregsetsz = sizeof(gregset_t); 535 status->pr_fpregsetsz = sizeof(fpregset_t); | 568 status->pr_statussz = sizeof(*status); 569 status->pr_gregsetsz = sizeof(elfcore_gregset_t); 570 status->pr_fpregsetsz = sizeof(elfcore_fpregset_t); |
536 status->pr_osreldate = __FreeBSD_version; 537 status->pr_pid = tid; | 571 status->pr_osreldate = __FreeBSD_version; 572 status->pr_pid = tid; |
538 ptrace(PT_GETREGS, tid, (void *)&status->pr_reg, 0); | 573 ptrace(PT_GETREGS, tid, (void *)&greg, 0); 574 elf_convert_gregset(&status->pr_reg, &greg); |
539 540 *sizep = sizeof(*status); 541 return (status); 542} 543 544static void * 545elf_note_fpregset(void *arg, size_t *sizep) 546{ 547 lwpid_t tid; | 575 576 *sizep = sizeof(*status); 577 return (status); 578} 579 580static void * 581elf_note_fpregset(void *arg, size_t *sizep) 582{ 583 lwpid_t tid; |
548 prfpregset_t *fpregset; | 584 elfcore_fpregset_t *fpregset; 585 fpregset_t fpreg; |
549 550 tid = *(lwpid_t *)arg; 551 fpregset = calloc(1, sizeof(*fpregset)); 552 if (fpregset == NULL) 553 errx(1, "out of memory"); | 586 587 tid = *(lwpid_t *)arg; 588 fpregset = calloc(1, sizeof(*fpregset)); 589 if (fpregset == NULL) 590 errx(1, "out of memory"); |
554 ptrace(PT_GETFPREGS, tid, (void *)fpregset, 0); | 591 ptrace(PT_GETFPREGS, tid, (void *)&fpreg, 0); 592 elf_convert_fpregset(fpregset, &fpreg); |
555 556 *sizep = sizeof(*fpregset); 557 return (fpregset); 558} 559 560static void * 561elf_note_thrmisc(void *arg, size_t *sizep) 562{ --- 132 unchanged lines hidden (view full) --- 695 errx(1, "kern.proc.rlimit.%u: short read", pid); 696 p += len; 697 } 698 699 *sizep = sizeof(structsize) + structsize; 700 return (buf); 701} 702 | 593 594 *sizep = sizeof(*fpregset); 595 return (fpregset); 596} 597 598static void * 599elf_note_thrmisc(void *arg, size_t *sizep) 600{ --- 132 unchanged lines hidden (view full) --- 733 errx(1, "kern.proc.rlimit.%u: short read", pid); 734 p += len; 735 } 736 737 *sizep = sizeof(structsize) + structsize; 738 return (buf); 739} 740 |
703struct dumpers elfdump = { elf_ident, elf_coredump }; 704TEXT_SET(dumpset, elfdump); | 741struct dumpers __elfN(dump) = { elf_ident, elf_coredump }; 742TEXT_SET(dumpset, __elfN(dump)); |