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:
@@ -145,19 +145,9 @@ elf32_arm_abi_supported(struct image_params *imgp, int32_t *osrel __unused,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
bool
|
||||||
|
|||||||
@@ -28,12 +28,45 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/elf.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/ptrace.h>
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/reg.h>
|
||||||
#ifdef VFP
|
#ifdef VFP
|
||||||
#include <machine/vfp.h>
|
#include <machine/vfp.h>
|
||||||
#endif
|
#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
|
int
|
||||||
cpu_ptrace(struct thread *td, int req, void *addr, int data)
|
cpu_ptrace(struct thread *td, int req, void *addr, int data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -288,5 +288,4 @@ freebsd32_setregs(struct thread *td, struct image_params *imgp,
|
|||||||
void
|
void
|
||||||
elf32_dump_thread(struct thread *td, void *dst, size_t *off)
|
elf32_dump_thread(struct thread *td, void *dst, size_t *off)
|
||||||
{
|
{
|
||||||
/* XXX: VFP */
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
#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.
|
* Stubs for machine dependent 32-bits system calls.
|
||||||
*/
|
*/
|
||||||
@@ -127,7 +123,7 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VFP
|
#ifdef VFP
|
||||||
static void
|
void
|
||||||
get_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
|
get_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
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)
|
set_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
@@ -176,6 +172,7 @@ set_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
|
|||||||
critical_exit();
|
critical_exit();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
|
get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
#include <sys/elf.h>
|
||||||
#include <sys/exec.h>
|
#include <sys/exec.h>
|
||||||
#include <sys/imgact.h>
|
#include <sys/imgact.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
@@ -48,6 +49,38 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <machine/armreg.h>
|
#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
|
int
|
||||||
ptrace_set_pc(struct thread *td, u_long addr)
|
ptrace_set_pc(struct thread *td, u_long addr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ int is_fpu_kern_thread(u_int);
|
|||||||
#define VFP_FPSR_FROM_FPSCR(vpscr) ((vpscr) &~ 0x7c00000)
|
#define VFP_FPSR_FROM_FPSCR(vpscr) ((vpscr) &~ 0x7c00000)
|
||||||
#define VFP_FPCR_FROM_FPSCR(vpsrc) ((vpsrc) & 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
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -110,9 +110,6 @@ static void elf_detach(void); /* atexit() handler. */
|
|||||||
static void *elf_note_prpsinfo(void *, size_t *);
|
static void *elf_note_prpsinfo(void *, size_t *);
|
||||||
static void *elf_note_thrmisc(void *, size_t *);
|
static void *elf_note_thrmisc(void *, size_t *);
|
||||||
static void *elf_note_ptlwpinfo(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__)
|
#if defined(__i386__) || defined(__amd64__)
|
||||||
static void *elf_note_x86_xstate(void *, size_t *);
|
static void *elf_note_x86_xstate(void *, size_t *);
|
||||||
#endif
|
#endif
|
||||||
@@ -375,8 +372,8 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep)
|
|||||||
elf_putregnote(NT_FPREGSET, tids[i], sb);
|
elf_putregnote(NT_FPREGSET, tids[i], sb);
|
||||||
elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb);
|
elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb);
|
||||||
elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb);
|
elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb);
|
||||||
#if defined(__arm__)
|
#if (defined(ELFCORE_COMPAT_32) && defined(__aarch64__)) || defined(__arm__)
|
||||||
elf_putnote(NT_ARM_VFP, elf_note_arm_vfp, tids + i, sb);
|
elf_putregnote(NT_ARM_VFP, tids[i], sb);
|
||||||
#endif
|
#endif
|
||||||
#if defined(__i386__) || defined(__amd64__)
|
#if defined(__i386__) || defined(__amd64__)
|
||||||
elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb);
|
elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb);
|
||||||
|
|||||||
Reference in New Issue
Block a user