1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 *
22 * $FreeBSD$
23 */
24 /*
25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28 #include <sys/cdefs.h>
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/stack.h>
34 #include <sys/pcpu.h>
35
36 #include <machine/frame.h>
37 #include <machine/md_var.h>
38
39 #include <vm/vm.h>
40 #include <vm/vm_param.h>
41 #include <vm/pmap.h>
42
43 #include <machine/atomic.h>
44 #include <machine/db_machdep.h>
45 #include <machine/md_var.h>
46 #include <machine/stack.h>
47 #include <ddb/db_sym.h>
48 #include <ddb/ddb.h>
49 #include <sys/kdb.h>
50
51 #include "regset.h"
52
53 uint8_t dtrace_fuword8_nocheck(void *);
54 uint16_t dtrace_fuword16_nocheck(void *);
55 uint32_t dtrace_fuword32_nocheck(void *);
56 uint64_t dtrace_fuword64_nocheck(void *);
57
58 void
59 dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
60 uint32_t *intrpc)
61 {
62 struct unwind_state state;
63 register_t sp;
64 int scp_offset;
65 int depth = 0;
66
67 if (intrpc != 0)
68 pcstack[depth++] = (pc_t) intrpc;
69
70 aframes++;
71
72 __asm __volatile("mov %0, sp" : "=&r" (sp));
73
74 state.registers[FP] = (uint32_t)__builtin_frame_address(0);
75 state.registers[SP] = sp;
76 state.registers[LR] = (uint32_t)__builtin_return_address(0);
77 state.registers[PC] = (uint32_t)dtrace_getpcstack;
78
79 while (depth < pcstack_limit) {
80 int done;
81
82 done = unwind_stack_one(&state, 1);
83
84 /*
85 * NB: Unlike some other architectures, we don't need to
86 * explicitly insert cpu_dtrace_caller as it appears in the
87 * normal kernel stack trace rather than a special trap frame.
88 */
89 if (aframes > 0) {
90 aframes--;
91 } else {
92 pcstack[depth++] = state.registers[PC];
93 }
94
95 if (done)
96 break;
97 }
98
99 for (; depth < pcstack_limit; depth++) {
100 pcstack[depth] = 0;
101 }
102 }
103
104 void
105 dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
106 {
107 printf("IMPLEMENT ME: %s\n", __func__);
108 }
109
110 int
111 dtrace_getustackdepth(void)
112 {
113 printf("IMPLEMENT ME: %s\n", __func__);
114 return (0);
115 }
116
117 void
118 dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
119 {
120 printf("IMPLEMENT ME: %s\n", __func__);
121 }
122
123 /*ARGSUSED*/
124 uint64_t
125 dtrace_getarg(int arg, int aframes)
126 {
127 /* struct arm_frame *fp = (struct arm_frame *)dtrace_getfp();*/
128
129 return (0);
130 }
131
132 int
133 dtrace_getstackdepth(int aframes)
134 {
135 struct unwind_state state;
136 register_t sp;
137 int scp_offset;
138 int done = 0;
139 int depth = 1;
140
141 __asm __volatile("mov %0, sp" : "=&r" (sp));
142
143 state.registers[FP] = (uint32_t)__builtin_frame_address(0);
144 state.registers[SP] = sp;
145 state.registers[LR] = (uint32_t)__builtin_return_address(0);
146 state.registers[PC] = (uint32_t)dtrace_getstackdepth;
147
148 do {
149 done = unwind_stack_one(&state, 1);
150 depth++;
151 } while (!done);
152
153 if (depth < aframes)
154 return 0;
155 else
156 return depth - aframes;
157 }
158
159 ulong_t
160 dtrace_getreg(struct trapframe *rp, uint_t reg)
161 {
162 printf("IMPLEMENT ME: %s\n", __func__);
163
164 return (0);
165 }
166
167 static int
168 dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
169 {
170
171 if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) {
172 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
173 cpu_core[curcpu].cpuc_dtrace_illval = uaddr;
174 return (0);
175 }
176
177 return (1);
178 }
179
180 void
181 dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
182 volatile uint16_t *flags)
183 {
184 if (dtrace_copycheck(uaddr, kaddr, size))
185 dtrace_copy(uaddr, kaddr, size);
186 }
187
188 void
189 dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
190 volatile uint16_t *flags)
191 {
192 if (dtrace_copycheck(uaddr, kaddr, size))
193 dtrace_copy(kaddr, uaddr, size);
194 }
195
196 void
197 dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
198 volatile uint16_t *flags)
199 {
200 if (dtrace_copycheck(uaddr, kaddr, size))
201 dtrace_copystr(uaddr, kaddr, size, flags);
202 }
203
204 void
205 dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
206 volatile uint16_t *flags)
207 {
208 if (dtrace_copycheck(uaddr, kaddr, size))
209 dtrace_copystr(kaddr, uaddr, size, flags);
210 }
211
212 uint8_t
213 dtrace_fuword8(void *uaddr)
214 {
215 if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
216 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
217 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
218 return (0);
219 }
220 return (dtrace_fuword8_nocheck(uaddr));
221 }
222
223 uint16_t
224 dtrace_fuword16(void *uaddr)
225 {
226 if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
227 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
228 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
229 return (0);
230 }
231 return (dtrace_fuword16_nocheck(uaddr));
232 }
233
234 uint32_t
235 dtrace_fuword32(void *uaddr)
236 {
237 if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
238 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
239 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
240 return (0);
241 }
242 return (dtrace_fuword32_nocheck(uaddr));
243 }
244
245 uint64_t
246 dtrace_fuword64(void *uaddr)
247 {
248 if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
249 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
250 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
251 return (0);
252 }
253 return (dtrace_fuword64_nocheck(uaddr));
254 }
Cache object: 2b61f17dffddfe5eba6d191a32238b54
|