Pull up following revision(s) (requested by rin in ticket #1172): sys/arch/aarch64/aarch64/trap.c: revision 1.30 sys/arch/aarch64/include/ptrace.h: revision 1.10 sys/arch/aarch64/include/netbsd32_machdep.h: revision 1.4 (patch) sys/arch/aarch64/aarch64/netbsd32_machdep.c: revision 1.14 sys/arch/aarch64/aarch64/netbsd32_machdep.c: revision 1.15 Add support of ptrace(2) for COMPAT_NETBSD32. Now, GDB for arm32 is usable for debugging 32bit applications. OK ryo@ For rev 1.14 and before, netbsd32_process_write_regs() returns EINVAL if non-modifiable bits are set in CPSR. Instead, mask out non-modifiable bits and make this function success regardless of value in CPSR. New behavior matches that of arm: https://nxr.netbsd.org/xref/src/sys/arch/arm/arm/process_machdep.c#187 This fixes lib/libc/sys/t_ptrace_wait*:access_regs6 tests, in which register contents retrieved by PT_GETREGS are set back by PT_SETREGS. No new regression is observed in full ATF run. OK ryodiff -r1.7.2.1 -r1.7.2.2 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c
(martin)
--- src/sys/arch/aarch64/aarch64/netbsd32_machdep.c 2020/05/02 16:26:04 1.7.2.1
+++ src/sys/arch/aarch64/aarch64/netbsd32_machdep.c 2021/01/01 12:58:35 1.7.2.2
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: netbsd32_machdep.c,v 1.7.2.1 2020/05/02 16:26:04 martin Exp $ */ | 1 | /* $NetBSD: netbsd32_machdep.c,v 1.7.2.2 2021/01/01 12:58:35 martin Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org> | 4 | * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -17,36 +17,37 @@ | @@ -17,36 +17,37 @@ | |||
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
19 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | 19 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | |
20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.7.2.1 2020/05/02 16:26:04 martin Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.7.2.2 2021/01/01 12:58:35 martin Exp $"); | |
31 | 31 | |||
32 | #if defined(_KERNEL_OPT) | 32 | #if defined(_KERNEL_OPT) | |
33 | #include "opt_compat_netbsd.h" | 33 | #include "opt_compat_netbsd.h" | |
34 | #endif | 34 | #endif | |
35 | 35 | |||
36 | #include <sys/param.h> | 36 | #include <sys/param.h> | |
37 | #include <sys/core.h> | 37 | #include <sys/core.h> | |
38 | #include <sys/exec.h> | 38 | #include <sys/exec.h> | |
39 | #include <sys/lwp.h> | 39 | #include <sys/lwp.h> | |
40 | #include <sys/ptrace.h> | |||
40 | #include <sys/ras.h> | 41 | #include <sys/ras.h> | |
41 | #include <sys/signalvar.h> | 42 | #include <sys/signalvar.h> | |
42 | #include <sys/syscallargs.h> | 43 | #include <sys/syscallargs.h> | |
43 | 44 | |||
44 | #include <uvm/uvm_extern.h> | 45 | #include <uvm/uvm_extern.h> | |
45 | 46 | |||
46 | #include <compat/netbsd32/netbsd32.h> | 47 | #include <compat/netbsd32/netbsd32.h> | |
47 | #include <compat/netbsd32/netbsd32_exec.h> | 48 | #include <compat/netbsd32/netbsd32_exec.h> | |
48 | #include <compat/netbsd32/netbsd32_syscallargs.h> | 49 | #include <compat/netbsd32/netbsd32_syscallargs.h> | |
49 | 50 | |||
50 | #include <aarch64/armreg.h> | 51 | #include <aarch64/armreg.h> | |
51 | #include <aarch64/cpufunc.h> | 52 | #include <aarch64/cpufunc.h> | |
52 | #include <aarch64/frame.h> | 53 | #include <aarch64/frame.h> | |
@@ -83,59 +84,83 @@ netbsd32_setregs(struct lwp *l, struct e | @@ -83,59 +84,83 @@ netbsd32_setregs(struct lwp *l, struct e | |||
83 | 84 | |||
84 | /* set 32bit mode, and same endian as 64bit's */ | 85 | /* set 32bit mode, and same endian as 64bit's */ | |
85 | #ifdef __AARCH64EB__ | 86 | #ifdef __AARCH64EB__ | |
86 | tf->tf_spsr = SPSR_M_USR32 | SPSR_A32_E; | 87 | tf->tf_spsr = SPSR_M_USR32 | SPSR_A32_E; | |
87 | #else | 88 | #else | |
88 | tf->tf_spsr = SPSR_M_USR32; | 89 | tf->tf_spsr = SPSR_M_USR32; | |
89 | #endif | 90 | #endif | |
90 | 91 | |||
91 | /* THUMB CODE? */ | 92 | /* THUMB CODE? */ | |
92 | if (pack->ep_entry & 1) | 93 | if (pack->ep_entry & 1) | |
93 | tf->tf_spsr |= SPSR_A32_T; | 94 | tf->tf_spsr |= SPSR_A32_T; | |
94 | } | 95 | } | |
95 | 96 | |||
97 | int | |||
98 | netbsd32_ptrace_translate_request(int req) | |||
99 | { | |||
100 | ||||
101 | switch (req) { | |||
102 | case 0 ... PT_FIRSTMACH - 1: | |||
103 | return req; | |||
104 | case PT32_GETREGS: | |||
105 | return PT_GETREGS; | |||
106 | case PT32_SETREGS: | |||
107 | return PT_SETREGS; | |||
108 | case PT32_GETFPREGS: | |||
109 | return PT_GETFPREGS; | |||
110 | case PT32_SETFPREGS: | |||
111 | return PT_SETFPREGS; | |||
112 | /* not implemented for arm32 */ | |||
113 | case PT32_STEP: | |||
114 | case PT32_SETSTEP: | |||
115 | case PT32_CLEARSTEP: | |||
116 | default: | |||
117 | return -1; | |||
118 | } | |||
119 | } | |||
120 | ||||
96 | /* aarch32 fpscr register is assigned to two registers fpsr/fpcr on aarch64 */ | 121 | /* aarch32 fpscr register is assigned to two registers fpsr/fpcr on aarch64 */ | |
97 | #define FPSR_BITS \ | 122 | #define FPSR_BITS \ | |
98 | (FPSR_N32|FPSR_Z32|FPSR_C32|FPSR_V32|FPSR_QC| \ | 123 | (FPSR_N32|FPSR_Z32|FPSR_C32|FPSR_V32|FPSR_QC| \ | |
99 | FPSR_IDC|FPSR_IXC|FPSR_UFC|FPSR_OFC|FPSR_DZC|FPSR_IOC) | 124 | FPSR_IDC|FPSR_IXC|FPSR_UFC|FPSR_OFC|FPSR_DZC|FPSR_IOC) | |
100 | #define FPCR_BITS \ | 125 | #define FPCR_BITS \ | |
101 | (FPCR_AHP|FPCR_DN|FPCR_FZ|FPCR_RMODE|FPCR_STRIDE|FPCR_LEN| \ | 126 | (FPCR_AHP|FPCR_DN|FPCR_FZ|FPCR_RMODE|FPCR_STRIDE|FPCR_LEN| \ | |
102 | FPCR_IDE|FPCR_IXE|FPCR_UFE|FPCR_OFE|FPCR_DZE|FPCR_IOE) | 127 | FPCR_IDE|FPCR_IXE|FPCR_UFE|FPCR_OFE|FPCR_DZE|FPCR_IOE) | |
103 | 128 | |||
104 | static int | 129 | int | |
105 | netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs) | 130 | netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs) | |
106 | { | 131 | { | |
107 | struct proc * const p = l->l_proc; | 132 | struct proc * const p = l->l_proc; | |
108 | struct trapframe *tf = l->l_md.md_utf; | 133 | struct trapframe *tf = l->l_md.md_utf; | |
109 | int i; | 134 | int i; | |
110 | 135 | |||
111 | if ((p->p_flag & PK_32) == 0) | 136 | if ((p->p_flag & PK_32) == 0) | |
112 | return EINVAL; | 137 | return EINVAL; | |
113 | 138 | |||
114 | for (i = 0; i < 13; i++) | 139 | for (i = 0; i < 13; i++) | |
115 | regs->r[i] = tf->tf_reg[i]; /* r0-r12 */ | 140 | regs->r[i] = tf->tf_reg[i]; /* r0-r12 */ | |
116 | regs->r_sp = tf->tf_reg[13]; /* r13 = sp */ | 141 | regs->r_sp = tf->tf_reg[13]; /* r13 = sp */ | |
117 | regs->r_lr = tf->tf_reg[14]; /* r14 = lr */ | 142 | regs->r_lr = tf->tf_reg[14]; /* r14 = lr */ | |
118 | regs->r_pc = tf->tf_pc; /* r15 = pc */ | 143 | regs->r_pc = tf->tf_pc; /* r15 = pc */ | |
119 | regs->r_cpsr = tf->tf_spsr; | 144 | regs->r_cpsr = tf->tf_spsr; | |
120 | 145 | |||
121 | /* THUMB CODE? */ | 146 | /* THUMB CODE? */ | |
122 | if (tf->tf_spsr & SPSR_A32_T) | 147 | if (tf->tf_spsr & SPSR_A32_T) | |
123 | regs->r_pc |= 1; | 148 | regs->r_pc |= 1; | |
124 | 149 | |||
125 | return 0; | 150 | return 0; | |
126 | } | 151 | } | |
127 | 152 | |||
128 | static int | 153 | int | |
129 | netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs, | 154 | netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs, | |
130 | size_t *lenp) | 155 | size_t *lenp) | |
131 | { | 156 | { | |
132 | struct proc * const p = l->l_proc; | 157 | struct proc * const p = l->l_proc; | |
133 | struct pcb * const pcb = lwp_getpcb(l); | 158 | struct pcb * const pcb = lwp_getpcb(l); | |
134 | int i; | 159 | int i; | |
135 | 160 | |||
136 | if ((p->p_flag & PK_32) == 0) | 161 | if ((p->p_flag & PK_32) == 0) | |
137 | return EINVAL; | 162 | return EINVAL; | |
138 | 163 | |||
139 | KASSERT(*lenp <= sizeof(*fpregs)); | 164 | KASSERT(*lenp <= sizeof(*fpregs)); | |
140 | fpu_save(l); | 165 | fpu_save(l); | |
141 | 166 | |||
@@ -155,26 +180,88 @@ netbsd32_process_read_fpregs(struct lwp | @@ -155,26 +180,88 @@ netbsd32_process_read_fpregs(struct lwp | |||
155 | 180 | |||
156 | for (i = 0; i < 32; i++) { | 181 | for (i = 0; i < 32; i++) { | |
157 | #ifdef __AARCH64EB__ | 182 | #ifdef __AARCH64EB__ | |
158 | fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[1]; | 183 | fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[1]; | |
159 | #else | 184 | #else | |
160 | fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[0]; | 185 | fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[0]; | |
161 | #endif | 186 | #endif | |
162 | } | 187 | } | |
163 | 188 | |||
164 | return 0; | 189 | return 0; | |
165 | } | 190 | } | |
166 | 191 | |||
167 | int | 192 | int | |
193 | netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs) | |||
194 | { | |||
195 | struct proc * const p = l->l_proc; | |||
196 | struct trapframe *tf = l->l_md.md_utf; | |||
197 | int i; | |||
198 | ||||
199 | if ((p->p_flag & PK_32) == 0) | |||
200 | return EINVAL; | |||
201 | ||||
202 | if (regs->r_pc >= VM_MAXUSER_ADDRESS32 || | |||
203 | regs->r_sp >= VM_MAXUSER_ADDRESS32) | |||
204 | return EINVAL; | |||
205 | ||||
206 | for (i = 0; i < 13; i++) | |||
207 | tf->tf_reg[i] = regs->r[i]; /* r0-r12 */ | |||
208 | tf->tf_reg[13] = regs->r_sp; /* r13 = sp */ | |||
209 | tf->tf_reg[14] = regs->r_lr; /* r14 = lr */ | |||
210 | tf->tf_pc = regs->r_pc; /* r15 = pc */ | |||
211 | tf->tf_spsr &= ~(SPSR_NZCV | SPSR_A32_T); | |||
212 | tf->tf_spsr |= regs->r_cpsr & (SPSR_NZCV | SPSR_A32_T); | |||
213 | ||||
214 | /* THUMB CODE? */ | |||
215 | if (regs->r_pc & 1) | |||
216 | tf->tf_spsr |= SPSR_A32_T; | |||
217 | ||||
218 | return 0; | |||
219 | } | |||
220 | ||||
221 | int | |||
222 | netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *fpregs, | |||
223 | size_t len) | |||
224 | { | |||
225 | struct proc * const p = l->l_proc; | |||
226 | struct pcb * const pcb = lwp_getpcb(l); | |||
227 | int i; | |||
228 | ||||
229 | if ((p->p_flag & PK_32) == 0) | |||
230 | return EINVAL; | |||
231 | ||||
232 | KASSERT(len <= sizeof(*fpregs)); | |||
233 | fpu_discard(l, true); // set used flag | |||
234 | ||||
235 | pcb->pcb_fpregs.fpsr = fpregs->fpr_vfp.vfp_fpscr & FPSR_BITS; | |||
236 | pcb->pcb_fpregs.fpcr = fpregs->fpr_vfp.vfp_fpscr & FPCR_BITS; | |||
237 | ||||
238 | CTASSERT(__arraycount(fpregs->fpr_vfp.vfp_regs) == | |||
239 | __arraycount(pcb->pcb_fpregs.fp_reg) + 1); | |||
240 | for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) { | |||
241 | #ifdef __AARCH64EB__ | |||
242 | pcb->pcb_fpregs.fp_reg[i].u64[0] = 0; | |||
243 | pcb->pcb_fpregs.fp_reg[i].u64[1] = | |||
244 | #else | |||
245 | pcb->pcb_fpregs.fp_reg[i].u64[1] = 0; | |||
246 | pcb->pcb_fpregs.fp_reg[i].u64[0] = | |||
247 | #endif | |||
248 | fpregs->fpr_vfp.vfp_regs[i]; | |||
249 | } | |||
250 | ||||
251 | return 0; | |||
252 | } | |||
253 | ||||
254 | int | |||
168 | cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie, | 255 | cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie, | |
169 | struct core32 *chdr) | 256 | struct core32 *chdr) | |
170 | { | 257 | { | |
171 | struct netbsd32_cpustate md_core32; | 258 | struct netbsd32_cpustate md_core32; | |
172 | struct coreseg32 cseg; | 259 | struct coreseg32 cseg; | |
173 | int error; | 260 | int error; | |
174 | 261 | |||
175 | if (iocookie == NULL) { | 262 | if (iocookie == NULL) { | |
176 | CORE_SETMAGIC(*chdr, COREMAGIC, MID_ARM6, 0); | 263 | CORE_SETMAGIC(*chdr, COREMAGIC, MID_ARM6, 0); | |
177 | chdr->c_hdrsize = ALIGN32(sizeof(*chdr)); | 264 | chdr->c_hdrsize = ALIGN32(sizeof(*chdr)); | |
178 | chdr->c_seghdrsize = ALIGN32(sizeof(cseg)); | 265 | chdr->c_seghdrsize = ALIGN32(sizeof(cseg)); | |
179 | chdr->c_cpusize = sizeof(md_core32); | 266 | chdr->c_cpusize = sizeof(md_core32); | |
180 | chdr->c_nseg++; | 267 | chdr->c_nseg++; |
--- src/sys/arch/aarch64/aarch64/trap.c 2021/01/01 12:31:19 1.17.4.3
+++ src/sys/arch/aarch64/aarch64/trap.c 2021/01/01 12:58:35 1.17.4.4
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: trap.c,v 1.17.4.3 2021/01/01 12:31:19 martin Exp $ */ | 1 | /* $NetBSD: trap.c,v 1.17.4.4 2021/01/01 12:58:35 martin Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Matt Thomas of 3am Software Foundry. | 8 | * by Matt Thomas of 3am Software Foundry. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -21,27 +21,27 @@ | @@ -21,27 +21,27 @@ | |||
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include <sys/cdefs.h> | 32 | #include <sys/cdefs.h> | |
33 | 33 | |||
34 | __KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17.4.3 2021/01/01 12:31:19 martin Exp $"); | 34 | __KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17.4.4 2021/01/01 12:58:35 martin Exp $"); | |
35 | 35 | |||
36 | #include "opt_arm_intr_impl.h" | 36 | #include "opt_arm_intr_impl.h" | |
37 | #include "opt_compat_netbsd32.h" | 37 | #include "opt_compat_netbsd32.h" | |
38 | #include "opt_dtrace.h" | 38 | #include "opt_dtrace.h" | |
39 | 39 | |||
40 | #include <sys/param.h> | 40 | #include <sys/param.h> | |
41 | #include <sys/kauth.h> | 41 | #include <sys/kauth.h> | |
42 | #include <sys/types.h> | 42 | #include <sys/types.h> | |
43 | #include <sys/atomic.h> | 43 | #include <sys/atomic.h> | |
44 | #include <sys/cpu.h> | 44 | #include <sys/cpu.h> | |
45 | #ifdef KDB | 45 | #ifdef KDB | |
46 | #include <sys/kdb.h> | 46 | #include <sys/kdb.h> | |
47 | #endif | 47 | #endif | |
@@ -386,41 +386,58 @@ fetch_arm_insn(struct trapframe *tf, uin | @@ -386,41 +386,58 @@ fetch_arm_insn(struct trapframe *tf, uin | |||
386 | 386 | |||
387 | return 4; | 387 | return 4; | |
388 | } | 388 | } | |
389 | 389 | |||
390 | enum emul_arm_result { | 390 | enum emul_arm_result { | |
391 | EMUL_ARM_SUCCESS = 0, | 391 | EMUL_ARM_SUCCESS = 0, | |
392 | EMUL_ARM_UNKNOWN, | 392 | EMUL_ARM_UNKNOWN, | |
393 | EMUL_ARM_FAULT, | 393 | EMUL_ARM_FAULT, | |
394 | }; | 394 | }; | |
395 | 395 | |||
396 | static enum emul_arm_result | 396 | static enum emul_arm_result | |
397 | emul_arm_insn(struct trapframe *tf) | 397 | emul_arm_insn(struct trapframe *tf) | |
398 | { | 398 | { | |
399 | struct lwp * const l = curlwp; | |||
399 | uint32_t insn; | 400 | uint32_t insn; | |
400 | int insn_size; | 401 | int insn_size; | |
401 | 402 | |||
402 | insn_size = fetch_arm_insn(tf, &insn); | 403 | insn_size = fetch_arm_insn(tf, &insn); | |
403 | 404 | |||
404 | switch (insn_size) { | 405 | switch (insn_size) { | |
405 | case 2: | 406 | case 2: | |
406 | /* T32-16bit instruction */ | 407 | /* T32-16bit instruction */ | |
407 | 408 | |||
409 | /* | |||
410 | * Breakpoint used by GDB. | |||
411 | */ | |||
412 | if (insn == 0xdefe) | |||
413 | goto trap; | |||
414 | ||||
408 | /* XXX: some T32 IT instruction deprecated should be emulated */ | 415 | /* XXX: some T32 IT instruction deprecated should be emulated */ | |
409 | break; | 416 | break; | |
410 | case 4: | 417 | case 4: | |
411 | /* T32-32bit instruction, or A32 instruction */ | 418 | /* T32-32bit instruction, or A32 instruction */ | |
412 | 419 | |||
413 | /* | 420 | /* | |
421 | * Breakpoint used by GDB. | |||
422 | */ | |||
423 | if (insn == 0xe6000011 || insn == 0xe7ffdefe) { | |||
424 | trap: | |||
425 | do_trapsignal(l, SIGTRAP, TRAP_BRKPT, | |||
426 | (void *)tf->tf_pc, 0); | |||
427 | return 0; | |||
428 | } | |||
429 | ||||
430 | /* | |||
414 | * Emulate ARMv6 instructions with cache operations | 431 | * Emulate ARMv6 instructions with cache operations | |
415 | * register (c7), that can be used in user mode. | 432 | * register (c7), that can be used in user mode. | |
416 | */ | 433 | */ | |
417 | switch (insn & 0x0fff0fff) { | 434 | switch (insn & 0x0fff0fff) { | |
418 | case 0x0e070f95: | 435 | case 0x0e070f95: | |
419 | /* | 436 | /* | |
420 | * mcr p15, 0, <Rd>, c7, c5, 4 | 437 | * mcr p15, 0, <Rd>, c7, c5, 4 | |
421 | * (flush prefetch buffer) | 438 | * (flush prefetch buffer) | |
422 | */ | 439 | */ | |
423 | __asm __volatile("isb sy" ::: "memory"); | 440 | __asm __volatile("isb sy" ::: "memory"); | |
424 | goto emulated; | 441 | goto emulated; | |
425 | case 0x0e070f9a: | 442 | case 0x0e070f9a: | |
426 | /* | 443 | /* |
--- src/sys/arch/aarch64/include/netbsd32_machdep.h 2018/10/12 01:28:58 1.2
+++ src/sys/arch/aarch64/include/netbsd32_machdep.h 2021/01/01 12:58:35 1.2.4.1
@@ -1,22 +1,34 @@ | @@ -1,22 +1,34 @@ | |||
1 | /* $NetBSD: netbsd32_machdep.h,v 1.2 2018/10/12 01:28:58 ryo Exp $ */ | 1 | /* $NetBSD: netbsd32_machdep.h,v 1.2.4.1 2021/01/01 12:58:35 martin Exp $ */ | |
2 | 2 | |||
3 | #ifndef _MACHINE_NETBSD32_H_ | 3 | #ifndef _MACHINE_NETBSD32_H_ | |
4 | #define _MACHINE_NETBSD32_H_ | 4 | #define _MACHINE_NETBSD32_H_ | |
5 | 5 | |||
6 | #include <sys/ucontext.h> | 6 | #include <sys/ucontext.h> | |
7 | #include <compat/sys/ucontext.h> | 7 | #include <compat/sys/ucontext.h> | |
8 | #include <compat/sys/siginfo.h> | 8 | #include <compat/sys/siginfo.h> | |
9 | 9 | |||
10 | /* | |||
11 | * arm ptrace constants | |||
12 | * Please keep in sync with sys/arch/arm/include/ptrace.h. | |||
13 | */ | |||
14 | #define PT32_STEP (PT_FIRSTMACH + 0) /* Not implemented */ | |||
15 | #define PT32_GETREGS (PT_FIRSTMACH + 1) | |||
16 | #define PT32_SETREGS (PT_FIRSTMACH + 2) | |||
17 | #define PT32_GETFPREGS (PT_FIRSTMACH + 5) | |||
18 | #define PT32_SETFPREGS (PT_FIRSTMACH + 6) | |||
19 | #define PT32_SETSTEP (PT_FIRSTMACH + 7) /* Not implemented */ | |||
20 | #define PT32_CLEARSTEP (PT_FIRSTMACH + 8) /* Not implemented */ | |||
21 | ||||
10 | #define NETBSD32_POINTER_TYPE uint32_t | 22 | #define NETBSD32_POINTER_TYPE uint32_t | |
11 | typedef struct { NETBSD32_POINTER_TYPE i32; } netbsd32_pointer_t; | 23 | typedef struct { NETBSD32_POINTER_TYPE i32; } netbsd32_pointer_t; | |
12 | 24 | |||
13 | /* earm has 64bit aligned 64bit integers */ | 25 | /* earm has 64bit aligned 64bit integers */ | |
14 | #define NETBSD32_INT64_ALIGN __attribute__((__aligned__(8))) | 26 | #define NETBSD32_INT64_ALIGN __attribute__((__aligned__(8))) | |
15 | 27 | |||
16 | typedef netbsd32_pointer_t netbsd32_sigcontextp_t; | 28 | typedef netbsd32_pointer_t netbsd32_sigcontextp_t; | |
17 | 29 | |||
18 | struct netbsd32_sigcontext13 { | 30 | struct netbsd32_sigcontext13 { | |
19 | int32_t sc_onstack; /* sigstack state to restore */ | 31 | int32_t sc_onstack; /* sigstack state to restore */ | |
20 | int32_t __sc_mask13; /* signal mask to restore (old style) */ | 32 | int32_t __sc_mask13; /* signal mask to restore (old style) */ | |
21 | 33 | |||
22 | uint32_t sc_spsr; | 34 | uint32_t sc_spsr; | |
@@ -93,18 +105,27 @@ struct fpreg32 { | @@ -93,18 +105,27 @@ struct fpreg32 { | |||
93 | /* same as cpustate in arm/arm/core_machdep.c */ | 105 | /* same as cpustate in arm/arm/core_machdep.c */ | |
94 | struct netbsd32_cpustate { | 106 | struct netbsd32_cpustate { | |
95 | struct reg32 regs; | 107 | struct reg32 regs; | |
96 | struct fpreg32 fpregs; | 108 | struct fpreg32 fpregs; | |
97 | }; | 109 | }; | |
98 | 110 | |||
99 | /* compat netbsd/arm sysarch(2) */ | 111 | /* compat netbsd/arm sysarch(2) */ | |
100 | #define ARM_SYNC_ICACHE 0 | 112 | #define ARM_SYNC_ICACHE 0 | |
101 | #define ARM_DRAIN_WRITEBUF 1 | 113 | #define ARM_DRAIN_WRITEBUF 1 | |
102 | #define ARM_VFP_FPSCR 2 | 114 | #define ARM_VFP_FPSCR 2 | |
103 | #define ARM_FPU_USED 3 | 115 | #define ARM_FPU_USED 3 | |
104 | 116 | |||
105 | struct netbsd32_arm_sync_icache_args { | 117 | struct netbsd32_arm_sync_icache_args { | |
106 | netbsd32_uintptr_t addr; /* Virtual start address */ | 118 | uint32_t addr; /* Virtual start address */ | |
107 | netbsd32_size_t len; /* Region size */ | 119 | uint32_t len; /* Region size */ | |
108 | }; | 120 | }; | |
109 | 121 | |||
122 | /* Translate ptrace() PT_* request from 32-bit userland to kernel. */ | |||
123 | int netbsd32_ptrace_translate_request(int); | |||
124 | ||||
125 | int netbsd32_process_read_regs(struct lwp *, struct reg32 *); | |||
126 | int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *); | |||
127 | ||||
128 | int netbsd32_process_write_regs(struct lwp *, const struct reg32 *); | |||
129 | int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t); | |||
130 | ||||
110 | #endif /* _MACHINE_NETBSD32_H_ */ | 131 | #endif /* _MACHINE_NETBSD32_H_ */ |
--- src/sys/arch/aarch64/include/ptrace.h 2019/06/18 21:18:11 1.9
+++ src/sys/arch/aarch64/include/ptrace.h 2021/01/01 12:58:35 1.9.2.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ptrace.h,v 1.9 2019/06/18 21:18:11 kamil Exp $ */ | 1 | /* $NetBSD: ptrace.h,v 1.9.2.1 2021/01/01 12:58:35 martin Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Matt Thomas of 3am Software Foundry. | 8 | * by Matt Thomas of 3am Software Foundry. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -56,20 +56,39 @@ | @@ -56,20 +56,39 @@ | |||
56 | 56 | |||
57 | 57 | |||
58 | #include <machine/reg.h> | 58 | #include <machine/reg.h> | |
59 | #define PTRACE_REG_PC(r) (r)->r_pc | 59 | #define PTRACE_REG_PC(r) (r)->r_pc | |
60 | #define PTRACE_REG_FP(r) (r)->r_reg[29] | 60 | #define PTRACE_REG_FP(r) (r)->r_reg[29] | |
61 | #define PTRACE_REG_SET_PC(r, v) (r)->r_pc = (v) | 61 | #define PTRACE_REG_SET_PC(r, v) (r)->r_pc = (v) | |
62 | #define PTRACE_REG_SP(r) (r)->r_sp | 62 | #define PTRACE_REG_SP(r) (r)->r_sp | |
63 | #define PTRACE_REG_INTRV(r) (r)->r_reg[0] | 63 | #define PTRACE_REG_INTRV(r) (r)->r_reg[0] | |
64 | 64 | |||
65 | #define PTRACE_BREAKPOINT ((const uint8_t[]) { 0xa0, 0x01, 0x20, 0xd4 }) | 65 | #define PTRACE_BREAKPOINT ((const uint8_t[]) { 0xa0, 0x01, 0x20, 0xd4 }) | |
66 | #define PTRACE_BREAKPOINT_ASM __asm __volatile("brk #13" ::: "memory") | 66 | #define PTRACE_BREAKPOINT_ASM __asm __volatile("brk #13" ::: "memory") | |
67 | #define PTRACE_BREAKPOINT_SIZE 4 | 67 | #define PTRACE_BREAKPOINT_SIZE 4 | |
68 | 68 | |||
69 | #ifdef _KERNEL_OPT | |||
70 | #include "opt_compat_netbsd32.h" | |||
71 | #endif | |||
72 | ||||
73 | #ifdef COMPAT_NETBSD32 | |||
74 | #include <machine/netbsd32_machdep.h> | |||
75 | ||||
76 | #define process_read_regs32 netbsd32_process_read_regs | |||
77 | #define process_read_fpregs32 netbsd32_process_read_fpregs | |||
78 | ||||
79 | #define process_write_regs32 netbsd32_process_write_regs | |||
80 | #define process_write_fpregs32 netbsd32_process_write_fpregs | |||
81 | ||||
82 | #define process_reg32 struct reg32 | |||
83 | #define process_fpreg32 struct fpreg32 | |||
84 | ||||
85 | #define PTRACE_TRANSLATE_REQUEST32(x) netbsd32_ptrace_translate_request(x) | |||
86 | #endif /* COMPAT_NETBSD32 */ | |||
87 | ||||
69 | #elif defined(__arm__) | 88 | #elif defined(__arm__) | |
70 | 89 | |||
71 | #include <arm/ptrace.h> | 90 | #include <arm/ptrace.h> | |
72 | 91 | |||
73 | #endif | 92 | #endif | |
74 | 93 | |||
75 | #endif /* _AARCH64_PTRACE_H_ */ | 94 | #endif /* _AARCH64_PTRACE_H_ */ |