Use a regset for NT_ARM_VFP.

This includes adding support for NT_ARM_VFP for 32-bit binaries
running under aarch64 kernels both for ptrace(), and coredumps via the
kernel and gcore.

Reviewed by:	andrew, markj
Sponsored by:	University of Cambridge, Google, Inc.
Differential Revision:	https://reviews.freebsd.org/D34448
This commit is contained in:
John Baldwin 2022-03-23 13:33:06 -07:00
parent a47fd6929f
commit add00c381e
7 changed files with 78 additions and 24 deletions

View File

@ -145,19 +145,9 @@ elf32_arm_abi_supported(struct image_params *imgp, int32_t *osrel __unused,
}
void
elf32_dump_thread(struct thread *td, void *dst, size_t *off)
elf32_dump_thread(struct thread *td __unused, void *dst __unused,
size_t *off __unused)
{
#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
}
bool

View File

@ -28,12 +28,45 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/elf.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#ifdef VFP
#include <machine/vfp.h>
#endif
#ifdef VFP
static bool
get_arm_vfp(struct regset *rs, struct thread *td, void *buf, size_t *sizep)
{
if (buf != NULL) {
KASSERT(*sizep == sizeof(mcontext_vfp_t),
("%s: invalid size", __func__));
get_vfpcontext(td, buf);
}
*sizep = sizeof(mcontext_vfp_t);
return (true);
}
static bool
set_arm_vfp(struct regset *rs, struct thread *td, void *buf,
size_t size)
{
KASSERT(size == sizeof(mcontext_vfp_t), ("%s: invalid size", __func__));
set_vfpcontext(td, buf);
return (true);
}
static struct regset regset_arm_vfp = {
.note = NT_ARM_VFP,
.size = sizeof(mcontext_vfp_t),
.get = get_arm_vfp,
.set = set_arm_vfp,
};
ELF_REGSET(regset_arm_vfp);
#endif
int
cpu_ptrace(struct thread *td, int req, void *addr, int data)
{

View File

@ -288,5 +288,4 @@ freebsd32_setregs(struct thread *td, struct image_params *imgp,
void
elf32_dump_thread(struct thread *td, void *dst, size_t *off)
{
/* XXX: VFP */
}

View File

@ -61,10 +61,6 @@ extern void freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
*/
#define UC32_COPY_SIZE offsetof(ucontext32_t, uc_link)
#ifdef VFP
static void get_fpcontext32(struct thread *td, mcontext32_vfp_t *);
#endif
/*
* Stubs for machine dependent 32-bits system calls.
*/
@ -127,7 +123,7 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap)
}
#ifdef VFP
static void
void
get_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
{
struct pcb *pcb;
@ -159,7 +155,7 @@ get_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
}
}
static void
void
set_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
{
struct pcb *pcb;
@ -176,6 +172,7 @@ set_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
critical_exit();
}
#endif
static void
get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
{

View File

@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/elf.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/kernel.h>
@ -48,6 +49,38 @@ __FBSDID("$FreeBSD$");
#include <machine/armreg.h>
#if defined(VFP) && defined(COMPAT_FREEBSD32)
static bool
get_arm_vfp(struct regset *rs, struct thread *td, void *buf, size_t *sizep)
{
if (buf != NULL) {
KASSERT(*sizep == sizeof(mcontext32_vfp_t),
("%s: invalid size", __func__));
get_fpcontext32(td, buf);
}
*sizep = sizeof(mcontext32_vfp_t);
return (true);
}
static bool
set_arm_vfp(struct regset *rs, struct thread *td, void *buf,
size_t size)
{
KASSERT(size == sizeof(mcontext32_vfp_t), ("%s: invalid size",
__func__));
set_fpcontext32(td, buf);
return (true);
}
static struct regset regset_arm_vfp = {
.note = NT_ARM_VFP,
.size = sizeof(mcontext32_vfp_t),
.get = get_arm_vfp,
.set = set_arm_vfp,
};
ELF32_REGSET(regset_arm_vfp);
#endif
int
ptrace_set_pc(struct thread *td, u_long addr)
{

View File

@ -94,6 +94,11 @@ int is_fpu_kern_thread(u_int);
#define VFP_FPSR_FROM_FPSCR(vpscr) ((vpscr) &~ 0x7c00000)
#define VFP_FPCR_FROM_FPSCR(vpsrc) ((vpsrc) & 0x7c00000)
#ifdef COMPAT_FREEBSD32
void get_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp);
void set_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp);
#endif
#endif
#endif

View File

@ -110,9 +110,6 @@ static void elf_detach(void); /* atexit() handler. */
static void *elf_note_prpsinfo(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
@ -375,8 +372,8 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep)
elf_putregnote(NT_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);
#if (defined(ELFCORE_COMPAT_32) && defined(__aarch64__)) || defined(__arm__)
elf_putregnote(NT_ARM_VFP, tids[i], sb);
#endif
#if defined(__i386__) || defined(__amd64__)
elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb);