svn commit: r334538 - in head: sys/powerpc/powerpc sys/sys usr.bin/gcore
Justin Hibbits
jhibbits at FreeBSD.org
Sat Jun 2 20:29:00 UTC 2018
Author: jhibbits
Date: Sat Jun 2 20:28:58 2018
New Revision: 334538
URL: https://svnweb.freebsd.org/changeset/base/334538
Log:
Included VSX registers in powerpc core dumps
Summary: Included VSX registers in powerpc core dumps (both kernel and gcore)
Submitted by: Luis Pires
Differential Revision: https://reviews.freebsd.org/D15512
Modified:
head/sys/powerpc/powerpc/elf32_machdep.c
head/sys/powerpc/powerpc/elf64_machdep.c
head/sys/sys/elf_common.h
head/usr.bin/gcore/elfcore.c
Modified: head/sys/powerpc/powerpc/elf32_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf32_machdep.c Sat Jun 2 20:14:43 2018 (r334537)
+++ head/sys/powerpc/powerpc/elf32_machdep.c Sat Jun 2 20:28:58 2018 (r334538)
@@ -52,6 +52,7 @@
#include <machine/altivec.h>
#include <machine/cpu.h>
+#include <machine/fpu.h>
#include <machine/elf.h>
#include <machine/reg.h>
#include <machine/md_var.h>
@@ -171,19 +172,44 @@ elf32_dump_thread(struct thread *td, void *dst, size_t
{
size_t len;
struct pcb *pcb;
+ uint64_t vshr[32];
+ uint64_t *vsr_dw1;
+ int vsr_idx;
len = 0;
pcb = td->td_pcb;
+
if (pcb->pcb_flags & PCB_VEC) {
save_vec_nodrop(td);
if (dst != NULL) {
len += elf32_populate_note(NT_PPC_VMX,
- &pcb->pcb_vec, dst,
+ &pcb->pcb_vec, (char *)dst + len,
sizeof(pcb->pcb_vec), NULL);
} else
len += elf32_populate_note(NT_PPC_VMX, NULL, NULL,
sizeof(pcb->pcb_vec), NULL);
}
+
+ if (pcb->pcb_flags & PCB_VSX) {
+ save_fpu_nodrop(td);
+ if (dst != NULL) {
+ /*
+ * Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and
+ * VSR32-VSR63 overlap with VR0-VR31, so we only copy
+ * the non-overlapping data, which is doubleword 1 of VSR0-VSR31.
+ */
+ for (vsr_idx = 0; vsr_idx < nitems(vshr); vsr_idx++) {
+ vsr_dw1 = (uint64_t *)&pcb->pcb_fpu.fpr[vsr_idx].vsr[2];
+ vshr[vsr_idx] = *vsr_dw1;
+ }
+ len += elf32_populate_note(NT_PPC_VSX,
+ vshr, (char *)dst + len,
+ sizeof(vshr), NULL);
+ } else
+ len += elf32_populate_note(NT_PPC_VSX, NULL, NULL,
+ sizeof(vshr), NULL);
+ }
+
*off = len;
}
Modified: head/sys/powerpc/powerpc/elf64_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf64_machdep.c Sat Jun 2 20:14:43 2018 (r334537)
+++ head/sys/powerpc/powerpc/elf64_machdep.c Sat Jun 2 20:28:58 2018 (r334538)
@@ -48,6 +48,7 @@
#include <machine/altivec.h>
#include <machine/cpu.h>
+#include <machine/fpu.h>
#include <machine/elf.h>
#include <machine/md_var.h>
@@ -234,19 +235,44 @@ elf64_dump_thread(struct thread *td, void *dst, size_t
{
size_t len;
struct pcb *pcb;
+ uint64_t vshr[32];
+ uint64_t *vsr_dw1;
+ int vsr_idx;
len = 0;
pcb = td->td_pcb;
+
if (pcb->pcb_flags & PCB_VEC) {
save_vec_nodrop(td);
if (dst != NULL) {
len += elf64_populate_note(NT_PPC_VMX,
- &pcb->pcb_vec, dst,
+ &pcb->pcb_vec, (char *)dst + len,
sizeof(pcb->pcb_vec), NULL);
} else
len += elf64_populate_note(NT_PPC_VMX, NULL, NULL,
sizeof(pcb->pcb_vec), NULL);
}
+
+ if (pcb->pcb_flags & PCB_VSX) {
+ save_fpu_nodrop(td);
+ if (dst != NULL) {
+ /*
+ * Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and
+ * VSR32-VSR63 overlap with VR0-VR31, so we only copy
+ * the non-overlapping data, which is doubleword 1 of VSR0-VSR31.
+ */
+ for (vsr_idx = 0; vsr_idx < nitems(vshr); vsr_idx++) {
+ vsr_dw1 = (uint64_t *)&pcb->pcb_fpu.fpr[vsr_idx].vsr[2];
+ vshr[vsr_idx] = *vsr_dw1;
+ }
+ len += elf64_populate_note(NT_PPC_VSX,
+ vshr, (char *)dst + len,
+ sizeof(vshr), NULL);
+ } else
+ len += elf64_populate_note(NT_PPC_VSX, NULL, NULL,
+ sizeof(vshr), NULL);
+ }
+
*off = len;
}
Modified: head/sys/sys/elf_common.h
==============================================================================
--- head/sys/sys/elf_common.h Sat Jun 2 20:14:43 2018 (r334537)
+++ head/sys/sys/elf_common.h Sat Jun 2 20:28:58 2018 (r334538)
@@ -774,6 +774,7 @@ typedef struct {
#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */
#define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */
#define NT_ARM_VFP 0x400 /* ARM VFP registers */
Modified: head/usr.bin/gcore/elfcore.c
==============================================================================
--- head/usr.bin/gcore/elfcore.c Sat Jun 2 20:14:43 2018 (r334537)
+++ head/usr.bin/gcore/elfcore.c Sat Jun 2 20:28:58 2018 (r334538)
@@ -119,6 +119,7 @@ static void *elf_note_x86_xstate(void *, size_t *);
#endif
#if defined(__powerpc__)
static void *elf_note_powerpc_vmx(void *, size_t *);
+static void *elf_note_powerpc_vsx(void *, size_t *);
#endif
static void *elf_note_procstat_auxv(void *, size_t *);
static void *elf_note_procstat_files(void *, size_t *);
@@ -381,6 +382,7 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep
#endif
#if defined(__powerpc__)
elf_putnote(NT_PPC_VMX, elf_note_powerpc_vmx, tids + i, sb);
+ elf_putnote(NT_PPC_VSX, elf_note_powerpc_vsx, tids + i, sb);
#endif
}
@@ -802,6 +804,30 @@ elf_note_powerpc_vmx(void *arg, size_t *sizep)
memcpy(vmx, &info, sizeof(*vmx));
*sizep = sizeof(*vmx);
return (vmx);
+}
+
+static void *
+elf_note_powerpc_vsx(void *arg, size_t *sizep)
+{
+ lwpid_t tid;
+ char *vshr_data;
+ static bool has_vsx = true;
+ uint64_t vshr[32];
+
+ tid = *(lwpid_t *)arg;
+ if (has_vsx) {
+ if (ptrace(PT_GETVSRREGS, tid, (void *)vshr,
+ sizeof(vshr)) != 0)
+ has_vsx = false;
+ }
+ if (!has_vsx) {
+ *sizep = 0;
+ return (NULL);
+ }
+ vshr_data = calloc(1, sizeof(vshr));
+ memcpy(vshr_data, vshr, sizeof(vshr));
+ *sizep = sizeof(vshr);
+ return (vshr_data);
}
#endif
More information about the svn-src-head
mailing list