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:
parent
a47fd6929f
commit
add00c381e
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user