]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/ptrace_machdep.c
libfido2: update to 1.13.0
[FreeBSD/FreeBSD.git] / sys / arm / arm / ptrace_machdep.c
1 /*-
2  * Copyright (c) 2017 John Baldwin <jhb@FreeBSD.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  */
26
27 #include <sys/cdefs.h>
28 #include <sys/types.h>
29 #include <sys/elf.h>
30 #include <sys/proc.h>
31 #include <sys/ptrace.h>
32 #include <sys/reg.h>
33 #include <machine/pcb.h>
34 #ifdef VFP
35 #include <machine/vfp.h>
36 #endif
37
38 #ifdef VFP
39 static bool
40 get_arm_vfp(struct regset *rs, struct thread *td, void *buf, size_t *sizep)
41 {
42         if (buf != NULL) {
43                 KASSERT(*sizep == sizeof(mcontext_vfp_t),
44                     ("%s: invalid size", __func__));
45                 get_vfpcontext(td, buf);
46         }
47         *sizep = sizeof(mcontext_vfp_t);
48         return (true);
49 }
50
51 static bool
52 set_arm_vfp(struct regset *rs, struct thread *td, void *buf,
53     size_t size)
54 {
55         KASSERT(size == sizeof(mcontext_vfp_t), ("%s: invalid size", __func__));
56         set_vfpcontext(td, buf);
57         return (true);
58 }
59
60 static struct regset regset_arm_vfp = {
61         .note = NT_ARM_VFP,
62         .size = sizeof(mcontext_vfp_t),
63         .get = get_arm_vfp,
64         .set = set_arm_vfp,
65 };
66 ELF_REGSET(regset_arm_vfp);
67 #endif
68
69 static bool
70 get_arm_tls(struct regset *rs, struct thread *td, void *buf,
71     size_t *sizep)
72 {
73         if (buf != NULL) {
74                 KASSERT(*sizep == sizeof(td->td_pcb->pcb_regs.sf_tpidrurw),
75                     ("%s: invalid size", __func__));
76                 memcpy(buf, &td->td_pcb->pcb_regs.sf_tpidrurw,
77                     sizeof(td->td_pcb->pcb_regs.sf_tpidrurw));
78         }
79         *sizep = sizeof(td->td_pcb->pcb_regs.sf_tpidrurw);
80
81         return (true);
82 }
83
84 static struct regset regset_arm_tls = {
85         .note = NT_ARM_TLS,
86         .size = sizeof(uint32_t),
87         .get = get_arm_tls,
88 };
89 ELF_REGSET(regset_arm_tls);
90
91 int
92 cpu_ptrace(struct thread *td, int req, void *addr, int data)
93 {
94 #ifdef VFP
95         mcontext_vfp_t vfp;
96 #endif
97         int error;
98
99         switch (req) {
100 #ifdef VFP
101         case PT_GETVFPREGS:
102                 get_vfpcontext(td, &vfp);
103                 error = copyout(&vfp, addr, sizeof(vfp));
104                 break;
105         case PT_SETVFPREGS:
106                 error = copyin(addr, &vfp, sizeof(vfp));
107                 if (error == 0)
108                         set_vfpcontext(td, &vfp);
109                 break;
110 #endif
111         default:
112                 error = EINVAL;
113         }
114
115         return (error);
116 }