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:
parent
ca2b367f5c
commit
27efb0a242
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=323584
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user