Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Jun 2018 20:28:58 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r334538 - in head: sys/powerpc/powerpc sys/sys usr.bin/gcore
Message-ID:  <201806022028.w52KSw8u070514@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201806022028.w52KSw8u070514>