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.

Reviewed by:	mmel (earlier version w/o gcore)
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D12293
This commit is contained in:
John Baldwin 2017-09-14 15:07:48 +00:00
parent ca2b367f5c
commit 27efb0a242
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=323584
3 changed files with 47 additions and 2 deletions

View File

@ -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 *);
@ -127,9 +130,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
}
/*

View File

@ -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 */

View File

@ -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
@ -368,6 +371,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
@ -718,6 +724,31 @@ elf_note_ptlwpinfo(void *arg, size_t *sizep)
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 *
elf_note_x86_xstate(void *arg, size_t *sizep)