Deleted Added
full compact
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));