Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Nov 2017 02:03:38 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r325837 - in stable/11: sys/arm/arm sys/sys usr.bin/gcore
Message-ID:  <201711150203.vAF23c1F079743@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Nov 15 02:03:38 2017
New Revision: 325837
URL: https://svnweb.freebsd.org/changeset/base/325837

Log:
  MFC 323584: Add a NT_ARM_VFP ELF core note to hold VFP registers for each thread.
  
  The core note matches the format and layout of NT_ARM_VFP on Linux.
  Debuggers use the AT_HWCAP flags to determine how many VFP registers
  are actually used and their format.

Modified:
  stable/11/sys/arm/arm/elf_machdep.c
  stable/11/sys/sys/elf_common.h
  stable/11/usr.bin/gcore/elfcore.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/arm/elf_machdep.c
==============================================================================
--- stable/11/sys/arm/arm/elf_machdep.c	Wed Nov 15 00:06:18 2017	(r325836)
+++ stable/11/sys/arm/arm/elf_machdep.c	Wed Nov 15 02:03:38 2017	(r325837)
@@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/elf.h>
 #include <machine/md_var.h>
+#ifdef VFP
+#include <machine/vfp.h>
+#endif
 
 static boolean_t elf32_arm_abi_supported(struct image_params *);
 
@@ -129,9 +132,19 @@ elf32_arm_abi_supported(struct image_params *imgp)
 }
 
 void
-elf32_dump_thread(struct thread *td __unused, void *dst __unused,
-    size_t *off __unused)
+elf32_dump_thread(struct thread *td, void *dst, size_t *off)
 {
+#ifdef VFP
+	mcontext_vfp_t vfp;
+
+	if (dst != NULL) {
+		get_vfpcontext(td, &vfp);
+		*off = elf32_populate_note(NT_ARM_VFP, &vfp, dst, sizeof(vfp),
+		    NULL);
+	} else
+		*off = elf32_populate_note(NT_ARM_VFP, NULL, NULL, sizeof(vfp),
+		    NULL);
+#endif
 }
 
 /*

Modified: stable/11/sys/sys/elf_common.h
==============================================================================
--- stable/11/sys/sys/elf_common.h	Wed Nov 15 00:06:18 2017	(r325836)
+++ stable/11/sys/sys/elf_common.h	Wed Nov 15 02:03:38 2017	(r325837)
@@ -757,6 +757,7 @@ typedef struct {
 #define	NT_PTLWPINFO		17	/* Thread ptrace miscellaneous info. */
 #define	NT_PPC_VMX	0x100	/* PowerPC Altivec/VMX registers */
 #define	NT_X86_XSTATE	0x202	/* x86 XSAVE extended state. */
+#define	NT_ARM_VFP	0x400	/* ARM VFP registers */
 
 /* Symbol Binding - ELFNN_ST_BIND - st_info */
 #define	STB_LOCAL	0	/* Local symbol */

Modified: stable/11/usr.bin/gcore/elfcore.c
==============================================================================
--- stable/11/usr.bin/gcore/elfcore.c	Wed Nov 15 00:06:18 2017	(r325836)
+++ stable/11/usr.bin/gcore/elfcore.c	Wed Nov 15 02:03:38 2017	(r325837)
@@ -109,6 +109,9 @@ static void *elf_note_prpsinfo(void *, size_t *);
 static void *elf_note_prstatus(void *, size_t *);
 static void *elf_note_thrmisc(void *, size_t *);
 static void *elf_note_ptlwpinfo(void *, size_t *);
+#if defined(__arm__)
+static void *elf_note_arm_vfp(void *, size_t *);
+#endif
 #if defined(__i386__) || defined(__amd64__)
 static void *elf_note_x86_xstate(void *, size_t *);
 #endif
@@ -366,6 +369,9 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep
 		elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb);
 		elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb);
 		elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb);
+#if defined(__arm__)
+		elf_putnote(NT_ARM_VFP, elf_note_arm_vfp, tids + i, sb);
+#endif
 #if defined(__i386__) || defined(__amd64__)
 		elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb);
 #endif
@@ -689,6 +695,31 @@ elf_note_ptlwpinfo(void *arg, size_t *sizep)
 	*sizep = sizeof(int) + sizeof(struct ptrace_lwpinfo);
 	return (p);
 }
+
+#if defined(__arm__)
+static void *
+elf_note_arm_vfp(void *arg, size_t *sizep)
+{
+	lwpid_t tid;
+	struct vfpreg *vfp;
+	static bool has_vfp = true;
+	struct vfpreg info;
+
+	tid = *(lwpid_t *)arg;
+	if (has_vfp) {
+		if (ptrace(PT_GETVFPREGS, tid, (void *)&info, 0) != 0)
+			has_vfp = false;
+	}
+	if (!has_vfp) {
+		*sizep = 0;
+		return (NULL);
+	}
+	vfp = calloc(1, sizeof(*vfp));
+	memcpy(vfp, &info, sizeof(*vfp));
+	*sizep = sizeof(*vfp);
+	return (vfp);
+}
+#endif
 
 #if defined(__i386__) || defined(__amd64__)
 static void *



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