diff options
Diffstat (limited to 'usr.bin/gcore/elfcore.c')
-rw-r--r-- | usr.bin/gcore/elfcore.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c index 20e801a..dbd0b30 100644 --- a/usr.bin/gcore/elfcore.c +++ b/usr.bin/gcore/elfcore.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> #include <fcntl.h> +#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -84,6 +85,9 @@ static void *elf_note_fpregset(void *, size_t *); static void *elf_note_prpsinfo(void *, size_t *); static void *elf_note_prstatus(void *, size_t *); static void *elf_note_thrmisc(void *, size_t *); +#if defined(__i386__) || defined(__amd64__) +static void *elf_note_x86_xstate(void *, size_t *); +#endif static void *elf_note_procstat_auxv(void *, size_t *); static void *elf_note_procstat_files(void *, size_t *); static void *elf_note_procstat_groups(void *, size_t *); @@ -309,6 +313,9 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep) elf_putnote(NT_PRSTATUS, elf_note_prstatus, tids + i, sb); elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb); elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb); +#if defined(__i386__) || defined(__amd64__) + elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb); +#endif } elf_putnote(NT_PROCSTAT_PROC, elf_note_procstat_proc, &pid, sb); @@ -577,6 +584,34 @@ elf_note_thrmisc(void *arg, size_t *sizep) return (thrmisc); } +#if defined(__i386__) || defined(__amd64__) +static void * +elf_note_x86_xstate(void *arg, size_t *sizep) +{ + lwpid_t tid; + char *xstate; + static bool xsave_checked = false; + static struct ptrace_xstate_info info; + + tid = *(lwpid_t *)arg; + if (!xsave_checked) { + if (ptrace(PT_GETXSTATE_INFO, tid, (void *)&info, + sizeof(info)) != 0) + info.xsave_len = 0; + xsave_checked = true; + } + if (info.xsave_len == 0) { + *sizep = 0; + return (NULL); + } + xstate = calloc(1, info.xsave_len); + ptrace(PT_GETXSTATE, tid, xstate, 0); + *(uint64_t *)(xstate + X86_XSTATE_XCR0_OFFSET) = info.xsave_mask; + *sizep = info.xsave_len; + return (xstate); +} +#endif + static void * procstat_sysctl(void *arg, int what, size_t structsz, size_t *sizep) { |