]> git.saurik.com Git - apple/xnu.git/blame - bsd/dev/arm64/fasttrap_isa.c
xnu-4903.241.1.tar.gz
[apple/xnu.git] / bsd / dev / arm64 / fasttrap_isa.c
CommitLineData
5ba3f43e
A
1/*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 */
4/*
5 * CDDL HEADER START
6 *
7 * The contents of this file are subject to the terms of the
8 * Common Development and Distribution License, Version 1.0 only
9 * (the "License"). You may not use this file except in compliance
10 * with the License.
11 *
12 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
13 * or http://www.opensolaris.org/os/licensing.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 *
17 * When distributing Covered Code, include this CDDL HEADER in each
18 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
19 * If applicable, add the following below this CDDL HEADER, with the
20 * fields enclosed by brackets "[]" replaced with your own identifying
21 * information: Portions Copyright [yyyy] [name of copyright owner]
22 *
23 * CDDL HEADER END
24 */
25/*
26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29
30/*
31 * #pragma ident "@(#)fasttrap_isa.c 1.19 05/09/14 SMI"
32 */
33
34#ifdef KERNEL
35#ifndef _KERNEL
36#define _KERNEL /* Solaris vs. Darwin */
37#endif
38#endif
5ba3f43e
A
39#include <sys/fasttrap_isa.h>
40#include <sys/fasttrap_impl.h>
41#include <sys/dtrace.h>
42#include <sys/dtrace_impl.h>
43#include <kern/task.h>
44#include <vm/pmap.h>
45#include <vm/vm_map.h>
46#include <mach/mach_vm.h>
47#include <arm/proc_reg.h>
48#include <arm/thread.h>
49#include <arm/caches_internal.h>
50
51#include <sys/dtrace_ptss.h>
52#include <kern/debug.h>
53
54#include <pexpert/pexpert.h>
55
d9a64523
A
56#if __has_include(<ptrauth.h>)
57#include <ptrauth.h>
58#endif
59
60
5ba3f43e
A
61extern dtrace_id_t dtrace_probeid_error;
62
63/* Solaris proc_t is the struct. Darwin's proc_t is a pointer to it. */
64#define proc_t struct proc /* Steer clear of the Darwin typedef for proc_t */
65
66extern int dtrace_decode_arm64(uint32_t instr);
67extern int dtrace_decode_arm(uint32_t instr);
68extern int dtrace_decode_thumb(uint32_t instr);
69
70/*
71 * Lossless User-Land Tracing on ARM
72 * ---------------------------------
73 *
74 * The details here will be fleshed out as more of this is implemented. The
75 * basic design will be the same way as tracing works in x86.
76 *
77 * Some ARM specific issues:
78 *
79 * We need to patch differently for ARM instructions and Thumb instructions.
80 * When we hit a probe, we check to see if the mode we're currently in is the
81 * same as the mode we're patching for. If not, we remove the tracepoint and
82 * abort. This ARM/Thumb information is pulled in from the arch specific
83 * information in the fasttrap probe.
84 *
85 * On ARM, any instruction that uses registers can also use the pc as a
86 * register. This presents problems during emulation because we have copied
87 * the instruction and thus the pc can be different. Currently we've emulated
88 * any instructions that use the pc if they can be used in a return probe.
89 * Eventually we will want to support all instructions that use the pc, but
90 * to do so requires disassembling the instruction and reconstituting it by
91 * substituting a different register.
92 *
93 */
94
95#define THUMB_INSTR(x) (*(uint16_t*) &(x))
96
97#define SIGNEXTEND(x,v) ((((int) (x)) << (32-(v))) >> (32-(v)))
98#define ALIGNADDR(x,v) (((x) >> (v)) << (v))
99#define GETITSTATE(x) ((((x) >> 8) & 0xFC) | (((x) >> 25) & 0x3))
100#define ISLASTINIT(x) (((x) & 0xF) == 8)
101
102#define SET16(x,w) *((uint16_t*) (x)) = (w)
103#define SET32(x,w) *((uint32_t*) (x)) = (w)
104
105#define IS_ARM32_NOP(x) ((x) == 0xE1A00000)
106/* Marker for is-enabled probes */
107#define IS_ARM32_IS_ENABLED(x) ((x) == 0xE0200000)
108
109#define IS_ARM64_NOP(x) ((x) == 0xD503201F)
110/* Marker for is-enabled probes */
111#define IS_ARM64_IS_ENABLED(x) ((x) == 0xD2800000)
112
113#define IS_THUMB32_NOP(x) ((x) == 0x46C0)
114/* Marker for is-enabled probes */
115#define IS_THUMB32_IS_ENABLED(x) ((x) == 0x4040)
116
117#define ARM_LDM_UF (1 << 23)
118#define ARM_LDM_PF (1 << 24)
119#define ARM_LDM_WF (1 << 21)
120
121#define ARM_LDR_UF (1 << 23)
122#define ARM_LDR_BF (1 << 22)
123
5ba3f43e
A
124static int fasttrap_tracepoint_init32 (proc_t *, fasttrap_tracepoint_t *, user_addr_t, fasttrap_probe_type_t);
125static int fasttrap_tracepoint_init64 (proc_t *, fasttrap_tracepoint_t *, user_addr_t, fasttrap_probe_type_t);
126
127int
128fasttrap_tracepoint_init(proc_t *p, fasttrap_tracepoint_t *tp,
129 user_addr_t pc, fasttrap_probe_type_t type)
130{
d9a64523 131 if (proc_is64bit_data(p)) {
5ba3f43e
A
132 return fasttrap_tracepoint_init64(p, tp, pc, type);
133 } else {
134 return fasttrap_tracepoint_init32(p, tp, pc, type);
135 }
136}
137
138static int
139fasttrap_tracepoint_init32(proc_t *p, fasttrap_tracepoint_t *tp,
140 user_addr_t pc, fasttrap_probe_type_t type)
141{
142#pragma unused(type)
143 uint32_t instr;
144
145 /*
146 * Read the instruction at the given address out of the process's
147 * address space. We don't have to worry about a debugger
148 * changing this instruction before we overwrite it with our trap
149 * instruction since P_PR_LOCK is set. Since instructions can span
150 * pages, we potentially read the instruction in two parts. If the
151 * second part fails, we just zero out that part of the instruction.
152 */
153 /*
154 * APPLE NOTE: Of course, we do not have a P_PR_LOCK, so this is racey...
155 */
156
157 if (uread(p, &instr, 4, pc) != 0)
158 return (-1);
159
160 /* We want &instr to always point to the saved instruction, so just copy the
161 * whole thing When cast to a pointer to a uint16_t, that will give us a
162 * pointer to the first two bytes, which is the thumb instruction.
163 */
164 tp->ftt_instr = instr;
165
166 if (tp->ftt_fntype != FASTTRAP_FN_DONE_INIT) {
167 switch(tp->ftt_fntype) {
168 case FASTTRAP_FN_UNKNOWN:
169 /* Can't instrument without any information. We can add some heuristics later if necessary. */
170 return (-1);
171
172 case FASTTRAP_FN_USDT:
173 if (IS_ARM32_NOP(instr) || IS_ARM32_IS_ENABLED(instr)) {
174 tp->ftt_thumb = 0;
175 } else if (IS_THUMB32_NOP(THUMB_INSTR(instr)) || IS_THUMB32_IS_ENABLED(THUMB_INSTR(instr))) {
176 tp->ftt_thumb = 1;
177 } else {
178 /* Shouldn't reach here - this means we don't recognize
179 * the instruction at one of the USDT probe locations
180 */
181 return (-1);
182 }
183 tp->ftt_fntype = FASTTRAP_FN_DONE_INIT;
184 break;
185
186 case FASTTRAP_FN_ARM:
187 tp->ftt_thumb = 0;
188 tp->ftt_fntype = FASTTRAP_FN_DONE_INIT;
189 break;
190
191 case FASTTRAP_FN_THUMB:
192 tp->ftt_thumb = 1;
193 tp->ftt_fntype = FASTTRAP_FN_DONE_INIT;
194 break;
195
196 default:
197 return (-1);
198 }
199 }
200
201 if (tp->ftt_thumb) {
202 tp->ftt_type = dtrace_decode_thumb(instr);
203 } else {
204 tp->ftt_type = dtrace_decode_arm(instr);
205 }
206
207 if (tp->ftt_type == FASTTRAP_T_INV) {
208 /* This is an instruction we either don't recognize or can't instrument */
209 printf("dtrace: fasttrap init32: Unrecognized instruction: %08x at %08llx\n",
210 (tp->ftt_thumb && dtrace_instr_size(tp->ftt_instr,tp->ftt_thumb) == 2) ? tp->ftt_instr1 : instr, pc);
211 return (-1);
212 }
213
214 return (0);
215}
216
217
218static int
219fasttrap_tracepoint_init64(proc_t *p, fasttrap_tracepoint_t *tp,
220 user_addr_t pc, fasttrap_probe_type_t type)
221{
222#pragma unused(type)
223 uint32_t instr = 0;
224
225 /*
226 * Read the instruction at the given address out of the process's
227 * address space. We don't have to worry about a debugger
228 * changing this instruction before we overwrite it with our trap
229 * instruction since P_PR_LOCK is set. Since instructions can span
230 * pages, we potentially read the instruction in two parts. If the
231 * second part fails, we just zero out that part of the instruction.
232 */
233 /*
234 * APPLE NOTE: Of course, we do not have a P_PR_LOCK, so this is racey...
235 */
236
237 if (uread(p, &instr, 4, pc) != 0)
238 return (-1);
239
240 tp->ftt_instr = instr;
241 tp->ftt_thumb = 0; /* Always zero on 64bit */
242
243 if (tp->ftt_fntype != FASTTRAP_FN_DONE_INIT) {
244 switch(tp->ftt_fntype) {
245 case FASTTRAP_FN_UNKNOWN:
d9a64523
A
246 case FASTTRAP_FN_ARM64:
247 case FASTTRAP_FN_ARM64_32:
5ba3f43e
A
248 /*
249 * On arm64 there is no distinction between
250 * arm vs. thumb mode instruction types.
251 */
252 tp->ftt_fntype = FASTTRAP_FN_DONE_INIT;
253 break;
254
255 case FASTTRAP_FN_USDT:
256 if (IS_ARM64_NOP(instr) || IS_ARM64_IS_ENABLED(instr)) {
257 tp->ftt_fntype = FASTTRAP_FN_DONE_INIT;
258 } else {
259 /*
260 * Shouldn't reach here - this means we don't
261 * recognize the instruction at one of the
262 * USDT probe locations
263 */
264 return (-1);
265 }
266
267 break;
268
269 case FASTTRAP_FN_ARM:
270 case FASTTRAP_FN_THUMB:
271 default:
272 /*
273 * If we get an arm or thumb mode type
274 * then we are clearly in the wrong path.
275 */
276 return (-1);
277 }
278 }
279
280 tp->ftt_type = dtrace_decode_arm64(instr);
281
282 if (tp->ftt_type == FASTTRAP_T_ARM64_EXCLUSIVE_MEM) {
283 kprintf("Detected attempt to place DTrace probe on exclusive memory instruction (pc = 0x%llx); refusing to trace (or exclusive operation could never succeed).\n", pc);
284 tp->ftt_type = FASTTRAP_T_INV;
285 return (-1);
286 }
287
288 if (tp->ftt_type == FASTTRAP_T_INV) {
289 /* This is an instruction we either don't recognize or can't instrument */
290 printf("dtrace: fasttrap init64: Unrecognized instruction: %08x at %08llx\n", instr, pc);
291 return (-1);
292 }
293
294 return (0);
295}
296
5ba3f43e
A
297int
298fasttrap_tracepoint_install(proc_t *p, fasttrap_tracepoint_t *tp)
299{
300 /* The thumb patch is a 2 byte instruction regardless of the size of the original instruction */
301 uint32_t instr;
302 int size;
303
d9a64523 304 if (proc_is64bit_data(p)) {
5ba3f43e
A
305 size = 4;
306 instr = FASTTRAP_ARM64_INSTR;
307 }
308 else {
309 size = tp->ftt_thumb ? 2 : 4;
310 if (tp->ftt_thumb) {
311 *((uint16_t*) &instr) = FASTTRAP_THUMB32_INSTR;
312 } else {
313 instr = FASTTRAP_ARM32_INSTR;
314 }
315 }
316
d9a64523 317 if (uwrite(p, &instr, size, tp->ftt_pc) != 0)
5ba3f43e
A
318 return (-1);
319
320 tp->ftt_installed = 1;
321
322 return (0);
323}
324
325int
326fasttrap_tracepoint_remove(proc_t *p, fasttrap_tracepoint_t *tp)
327{
328 /* The thumb patch is a 2 byte instruction regardless of the size of the original instruction */
329 uint32_t instr;
330 int size;
331
d9a64523 332 if (proc_is64bit_data(p)) {
5ba3f43e
A
333 /*
334 * Distinguish between read or write failures and a changed
335 * instruction.
336 */
337 size = 4;
338 if (uread(p, &instr, size, tp->ftt_pc) != 0)
339 goto end;
340
341 if (instr != FASTTRAP_ARM64_INSTR)
342 goto end;
343 } else {
344 /*
345 * Distinguish between read or write failures and a changed
346 * instruction.
347 */
348 size = tp->ftt_thumb ? 2 : 4;
349 if (uread(p, &instr, size, tp->ftt_pc) != 0)
350 goto end;
351
352 if (tp->ftt_thumb) {
353 if (*((uint16_t*) &instr) != FASTTRAP_THUMB32_INSTR)
354 goto end;
355 } else {
356 if (instr != FASTTRAP_ARM32_INSTR)
357 goto end;
358 }
359 }
360
d9a64523 361 if (uwrite(p, &tp->ftt_instr, size, tp->ftt_pc) != 0)
5ba3f43e
A
362 return (-1);
363
364end:
365 tp->ftt_installed = 0;
366
367 return (0);
368}
369
370static void
371fasttrap_return_common(proc_t *p, arm_saved_state_t *regs, user_addr_t pc, user_addr_t new_pc)
372{
373 pid_t pid = p->p_pid;
374 fasttrap_tracepoint_t *tp;
375 fasttrap_bucket_t *bucket;
376 fasttrap_id_t *id;
377 lck_mtx_t *pid_mtx;
378 int retire_tp = 1;
379 pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
380 lck_mtx_lock(pid_mtx);
381 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
382
383 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
384 if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
385 tp->ftt_proc->ftpc_acount != 0)
386 break;
387 }
388
389 /*
390 * Don't sweat it if we can't find the tracepoint again; unlike
391 * when we're in fasttrap_pid_probe(), finding the tracepoint here
392 * is not essential to the correct execution of the process.
393 */
394 if (tp == NULL) {
395 lck_mtx_unlock(pid_mtx);
396 return;
397 }
398
399 for (id = tp->ftt_retids; id != NULL; id = id->fti_next) {
400 fasttrap_probe_t *probe = id->fti_probe;
401 /*
402 * If there's a branch that could act as a return site, we
403 * need to trace it, and check here if the program counter is
404 * external to the function.
405 */
406 if (is_saved_state32(regs))
407 {
408 if (tp->ftt_type != FASTTRAP_T_LDM_PC &&
409 tp->ftt_type != FASTTRAP_T_POP_PC &&
410 new_pc - probe->ftp_faddr < probe->ftp_fsize)
411 continue;
412 }
413 else {
414 /* ARM64_TODO - check for FASTTRAP_T_RET */
d9a64523 415 if ((tp->ftt_type != FASTTRAP_T_ARM64_RET || tp->ftt_type != FASTTRAP_T_ARM64_RETAB) &&
5ba3f43e
A
416 new_pc - probe->ftp_faddr < probe->ftp_fsize)
417 continue;
418 }
419 if (probe->ftp_prov->ftp_provider_type == DTFTP_PROVIDER_ONESHOT) {
420 uint8_t already_triggered = atomic_or_8(&probe->ftp_triggered, 1);
421 if (already_triggered) {
422 continue;
423 }
424 }
425 /*
426 * If we have at least one probe associated that
427 * is not a oneshot probe, don't remove the
428 * tracepoint
429 */
430 else {
431 retire_tp = 0;
432 }
433
434#ifndef CONFIG_EMBEDDED
435 if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
436 dtrace_probe(dtrace_probeid_error, 0 /* state */, id->fti_probe->ftp_id,
437 1 /* ndx */, -1 /* offset */, DTRACEFLT_UPRIV);
438#else
439 if (FALSE) {
440#endif
441 } else {
442 if (is_saved_state32(regs)) {
443 dtrace_probe(probe->ftp_id,
444 pc - id->fti_probe->ftp_faddr,
445 saved_state32(regs)->r[0], 0, 0, 0);
446 } else {
447 dtrace_probe(probe->ftp_id,
448 pc - id->fti_probe->ftp_faddr,
449 saved_state64(regs)->x[0], 0, 0, 0);
450 }
451 }
452 }
453 if (retire_tp) {
454 fasttrap_tracepoint_retire(p, tp);
455 }
456
457 lck_mtx_unlock(pid_mtx);
458}
459
460static void
461fasttrap_sigsegv(proc_t *p, uthread_t t, user_addr_t addr, arm_saved_state_t *regs)
462{
463 /* TODO: This function isn't implemented yet. In debug mode, panic the system to
464 * find out why we're hitting this point. In other modes, kill the process.
465 */
466#if DEBUG
467#pragma unused(p,t,addr,arm_saved_state)
468 panic("fasttrap: sigsegv not yet implemented");
469#else
470#pragma unused(p,t,addr)
471 /* Kill the process */
472 set_saved_state_pc(regs, 0);
473#endif
474
475#if 0
476 proc_lock(p);
477
478 /* Set fault address and mark signal */
479 t->uu_code = addr;
480 t->uu_siglist |= sigmask(SIGSEGV);
481
482 /*
483 * XXX These two line may be redundant; if not, then we need
484 * XXX to potentially set the data address in the machine
485 * XXX specific thread state structure to indicate the address.
486 */
487 t->uu_exception = KERN_INVALID_ADDRESS; /* SIGSEGV */
488 t->uu_subcode = 0; /* XXX pad */
489
490 proc_unlock(p);
491
492 /* raise signal */
493 signal_setast(t->uu_context.vc_thread);
494#endif
495}
496
497static void
498fasttrap_usdt_args32(fasttrap_probe_t *probe, arm_saved_state32_t *regs32, int argc,
499 uint64_t *argv)
500{
501 int i, x, cap = MIN(argc, probe->ftp_nargs);
502
503 for (i = 0; i < cap; i++) {
504 x = probe->ftp_argmap[i];
505
506 /* Up to 4 args are passed in registers on arm */
507 if (x < 4) {
508 argv[i] = regs32->r[x];
509 } else {
510 uint32_t arg;
511 fasttrap_fuword32_noerr(regs32->sp + (x - 4) * sizeof(uint32_t), &arg);
512
513 argv[i] = arg;
514 }
515 }
516
517 for (; i < argc; i++) {
518 argv[i] = 0;
519 }
520}
521
522static void
523fasttrap_usdt_args64(fasttrap_probe_t *probe, arm_saved_state64_t *regs64, int argc,
524 uint64_t *argv)
525{
526 int i, x, cap = MIN(argc, probe->ftp_nargs);
527
528 for (i = 0; i < cap; i++) {
529 x = probe->ftp_argmap[i];
530
531 /* Up to 8 args are passed in registers on arm64 */
532 if (x < 8) {
533 argv[i] = regs64->x[x];
534 } else {
535 fasttrap_fuword64_noerr(regs64->sp + (x - 8) * sizeof(uint64_t), &argv[i]);
536 }
537 }
538
539 for (; i < argc; i++) {
540 argv[i] = 0;
541 }
542}
543
544static int condition_true(int cond, int cpsr)
545{
546 int taken = 0;
547 int zf = (cpsr & PSR_ZF) ? 1 : 0,
548 nf = (cpsr & PSR_NF) ? 1 : 0,
549 cf = (cpsr & PSR_CF) ? 1 : 0,
550 vf = (cpsr & PSR_VF) ? 1 : 0;
551
552 switch(cond) {
553 case 0: taken = zf; break;
554 case 1: taken = !zf; break;
555 case 2: taken = cf; break;
556 case 3: taken = !cf; break;
557 case 4: taken = nf; break;
558 case 5: taken = !nf; break;
559 case 6: taken = vf; break;
560 case 7: taken = !vf; break;
561 case 8: taken = (cf && !zf); break;
562 case 9: taken = (!cf || zf); break;
563 case 10: taken = (nf == vf); break;
564 case 11: taken = (nf != vf); break;
565 case 12: taken = (!zf && (nf == vf)); break;
566 case 13: taken = (zf || (nf != vf)); break;
567 case 14: taken = 1; break;
568 case 15: taken = 1; break; /* always "true" for ARM, unpredictable for THUMB. */
569 }
570
571 return taken;
572}
573
574static void set_thumb_flag(arm_saved_state32_t *regs32, user_addr_t pc)
575{
576 if (pc & 1) {
577 regs32->cpsr |= PSR_TF;
578 } else {
579 regs32->cpsr &= ~PSR_TF;
580 }
581}
582
583static int
584fasttrap_pid_probe_thumb_state_valid(arm_saved_state32_t *state32, fasttrap_tracepoint_t *tp)
585{
586 uint32_t cpsr = state32->cpsr;
587 uint32_t itstate = GETITSTATE(cpsr);
588
589 /* If in IT block, make sure it's the last statement in the block */
590 if ((itstate != 0) && !ISLASTINIT(itstate)) {
591 printf("dtrace: fasttrap: Tried to trace instruction %08x at %08x but not at end of IT block\n",
592 (tp->ftt_thumb && dtrace_instr_size(tp->ftt_instr,tp->ftt_thumb) == 2) ? tp->ftt_instr1 : tp->ftt_instr, state32->pc);
593 return 0;
594 }
595
596 if (!(cpsr & PSR_TF)) {
597 return 0;
598 }
599
600 return 1;
601}
602
603static int
604fasttrap_get_condition_code(arm_saved_state32_t *regs32, fasttrap_tracepoint_t *tp)
605{
606 /* Default to always execute */
607 int condition_code = 0xE;
608 if (tp->ftt_thumb) {
609 uint32_t itstate = GETITSTATE(regs32->cpsr);
610 if (itstate != 0) {
611 /* In IT block, make sure it's the last statement in the block */
612 assert(ISLASTINIT(itstate));
613 condition_code = itstate >> 4;
614 }
615 } else {
616 condition_code = ARM_CONDCODE(tp->ftt_instr);
617 }
618
619 return condition_code;
620}
621
622static void
623fasttrap_pid_probe_handle_patched_instr32(arm_saved_state_t *state, fasttrap_tracepoint_t *tp, uthread_t uthread,
624 proc_t *p, uint_t is_enabled, int *was_simulated)
625{
626 arm_saved_state32_t *regs32 = saved_state32(state);
627 uint32_t new_pc = 0;
628 uint32_t pc = regs32->pc;
629 int instr_size;
630 int condition_code;
631
632 *was_simulated = 1;
633
634 /*
635 * If there's an is-enabled probe connected to this tracepoint it
636 * means that there was a 'eor r0,r0,r0'
637 * instruction that was placed there by DTrace when the binary was
638 * linked. As this probe is, in fact, enabled, we need to stuff 1
639 * into R0. Accordingly, we can bypass all the instruction
640 * emulation logic since we know the inevitable result. It's possible
641 * that a user could construct a scenario where the 'is-enabled'
642 * probe was on some other instruction, but that would be a rather
643 * exotic way to shoot oneself in the foot.
644 */
645
646 if (is_enabled) {
647 regs32->r[0] = 1;
648 new_pc = regs32->pc + (tp->ftt_thumb ? 2 : 4);
649 goto done;
650 }
651
652 /* For USDT probes, bypass all the emulation logic for the nop instruction */
653 if ((tp->ftt_thumb && IS_THUMB32_NOP(THUMB_INSTR(tp->ftt_instr))) ||
654 (!tp->ftt_thumb && IS_ARM32_NOP(tp->ftt_instr))) {
655 new_pc = regs32->pc + (tp->ftt_thumb ? 2 : 4);
656 goto done;
657 }
658
659 condition_code = fasttrap_get_condition_code(regs32, tp);
660 instr_size = dtrace_instr_size(tp->ftt_instr,tp->ftt_thumb);
661
662 switch (tp->ftt_type) {
663 case FASTTRAP_T_MOV_PC_REG:
664 case FASTTRAP_T_CPY_PC:
665 {
666 if (!condition_true(condition_code, regs32->cpsr)) {
667 new_pc = pc + instr_size;
668 break;
669 }
670
671 int rm;
672 if (tp->ftt_thumb) {
673 rm = THUMB16_HRM(tp->ftt_instr1);
674 } else {
675 rm = tp->ftt_instr & 0xF;
676 }
677 new_pc = regs32->r[rm];
678
679 /* This instruction does not change the Thumb state */
680
681 break;
682 }
683
684 case FASTTRAP_T_STM_LR:
685 case FASTTRAP_T_PUSH_LR:
686 {
687 /*
688 * This is a very common case, so we want to emulate this instruction if
689 * possible. However, on a push, it is possible that we might reach the end
690 * of a page and have to allocate a new page. Most of the time this will not
691 * happen, and we know that the push instruction can store at most 16 words,
692 * so check to see if we are far from the boundary, and if so, emulate. This
693 * can be made more aggressive by checking the actual number of words being
694 * pushed, but we won't do that for now.
695 *
696 * Some of the same issues that apply to POP_PC probably apply here also.
697 */
698
699 int reglist;
700 int ret;
701 uint32_t base;
702
703 if (!condition_true(condition_code, regs32->cpsr)) {
704 new_pc = pc + instr_size;
705 break;
706 }
707
708 base = regs32->sp;
709 if (((base-16*4) >> PAGE_SHIFT) != (base >> PAGE_SHIFT)) {
710 /* Crosses the page boundary, go to emulation */
711 goto instr_emulate;
712 }
713
714 if (tp->ftt_thumb) {
715 if (instr_size == 4) {
716 /* We know we have to push lr, never push sp or pc */
717 reglist = tp->ftt_instr2 & 0x1FFF;
718 } else {
719 reglist = tp->ftt_instr1 & 0xFF;
720 }
721 } else {
722 /* We know we have to push lr, never push sp or pc */
723 reglist = tp->ftt_instr & 0x1FFF;
724 }
725
726 /* Push the link register */
727 base -= 4;
728 ret = fasttrap_suword32(base, regs32->lr);
729 if (ret == -1) {
730 fasttrap_sigsegv(p, uthread, (user_addr_t) base, state);
731 new_pc = regs32->pc;
732 break;
733 }
734
735 /* Start pushing from $r12 */
736 int regmask = 1 << 12;
737 int regnum = 12;
738
739 while (regmask) {
740 if (reglist & regmask) {
741 base -= 4;
742 ret = fasttrap_suword32(base, regs32->r[regnum]);
743 if (ret == -1) {
744 fasttrap_sigsegv(p, uthread, (user_addr_t) base, state);
745 new_pc = regs32->pc;
746 break;
747 }
748 }
749 regmask >>= 1;
750 regnum--;
751 }
752
753 regs32->sp = base;
754
755 new_pc = pc + instr_size;
756
757 break;
758 }
759
760
761 case FASTTRAP_T_LDM_PC:
762 case FASTTRAP_T_POP_PC:
763 {
764 /* TODO Two issues that will eventually need to be resolved:
765 *
766 * 1. Understand what the hardware does if we have to segfault (data abort) in
767 * the middle of a load multiple. We currently don't have a working segfault
768 * handler anyway, and with no swapfile we should never segfault on this load.
769 * If we do, we'll just kill the process by setting the pc to 0.
770 *
771 * 2. The emulation is no longer atomic. We currently only emulate pop for
772 * function epilogues, and so we should never have a race here because one
773 * thread should never be trying to manipulate another thread's stack frames.
774 * That is almost certainly a bug in the program.
775 *
776 * This will need to be fixed if we ever:
777 * a. Ship dtrace externally, as this could be a potential attack vector
778 * b. Support instruction level tracing, as we might then pop/ldm non epilogues.
779 *
780 */
781
782 /* Assume ldmia! sp/pop ... pc */
783
784 int regnum = 0, reglist;
785 int ret;
786 uint32_t base;
787
788 if (!condition_true(condition_code, regs32->cpsr)) {
789 new_pc = pc + instr_size;
790 break;
791 }
792
793 if (tp->ftt_thumb) {
794 if (instr_size == 4) {
795 /* We know we have to load the pc, don't do it twice */
796 reglist = tp->ftt_instr2 & 0x7FFF;
797 } else {
798 reglist = tp->ftt_instr1 & 0xFF;
799 }
800 } else {
801 /* We know we have to load the pc, don't do it twice */
802 reglist = tp->ftt_instr & 0x7FFF;
803 }
804
805 base = regs32->sp;
806 while (reglist) {
807 if (reglist & 1) {
808 ret = fasttrap_fuword32((user_addr_t)base, &regs32->r[regnum]);
809 if (ret == -1) {
810 fasttrap_sigsegv(p, uthread, (user_addr_t) base, state);
811 new_pc = regs32->pc;
812 break;
813 }
814 base += 4;
815 }
816 reglist >>= 1;
817 regnum++;
818 }
819
820 ret = fasttrap_fuword32((user_addr_t)base, &new_pc);
821 if (ret == -1) {
822 fasttrap_sigsegv(p, uthread, (user_addr_t) base, state);
823 new_pc = regs32->pc;
824 break;
825 }
826 base += 4;
827
828 regs32->sp = base;
829
830 set_thumb_flag(regs32, new_pc);
831
832 break;
833 }
834
835 case FASTTRAP_T_CB_N_Z:
836 {
837 /* Thumb mode instruction, and not permitted in IT block, so skip the condition code check */
838 int rn = tp->ftt_instr1 & 0x7;
839 int offset = (((tp->ftt_instr1 & 0x00F8) >> 2) | ((tp->ftt_instr1 & 0x0200) >> 3)) + 4;
840 int nonzero = tp->ftt_instr1 & 0x0800;
841 if (!nonzero != !(regs32->r[rn] == 0)) {
842 new_pc = pc + offset;
843 } else {
844 new_pc = pc + instr_size;
845 }
846 break;
847 }
848
849 case FASTTRAP_T_B_COND:
850 {
851 /* Use the condition code in the instruction and ignore the ITSTATE */
852
853 int code, offset;
854 if (tp->ftt_thumb) {
855 if (instr_size == 4) {
856 code = (tp->ftt_instr1 >> 6) & 0xF;
857 if (code == 14 || code == 15) {
858 panic("fasttrap: Emulation of invalid branch");
859 }
860 int S = (tp->ftt_instr1 >> 10) & 1,
861 J1 = (tp->ftt_instr2 >> 13) & 1,
862 J2 = (tp->ftt_instr2 >> 11) & 1;
863 offset = 4 + SIGNEXTEND(
864 (S << 20) | (J2 << 19) | (J1 << 18) |
865 ((tp->ftt_instr1 & 0x003F) << 12) |
866 ((tp->ftt_instr2 & 0x07FF) << 1),
867 21);
868 } else {
869 code = (tp->ftt_instr1 >> 8) & 0xF;
870 if (code == 14 || code == 15) {
871 panic("fasttrap: Emulation of invalid branch");
872 }
873 offset = 4 + (SIGNEXTEND(tp->ftt_instr1 & 0xFF, 8) << 1);
874 }
875 } else {
876 code = ARM_CONDCODE(tp->ftt_instr);
877 if (code == 15) {
878 panic("fasttrap: Emulation of invalid branch");
879 }
880 offset = 8 + (SIGNEXTEND(tp->ftt_instr & 0x00FFFFFF, 24) << 2);
881 }
882
883 if (condition_true(code, regs32->cpsr)) {
884 new_pc = pc + offset;
885 } else {
886 new_pc = pc + instr_size;
887 }
888
889 break;
890 }
891
892 case FASTTRAP_T_B_UNCOND:
893 {
894 int offset;
895
896 /* Unconditional branches can only be taken from Thumb mode */
897 /* (This is different from an ARM branch with condition code "always") */
898 ASSERT(tp->ftt_thumb == 1);
899
900 if (!condition_true(condition_code, regs32->cpsr)) {
901 new_pc = pc + instr_size;
902 break;
903 }
904
905 if (instr_size == 4) {
906 int S = (tp->ftt_instr1 >> 10) & 1,
907 J1 = (tp->ftt_instr2 >> 13) & 1,
908 J2 = (tp->ftt_instr2 >> 11) & 1;
909 int I1 = (J1 != S) ? 0 : 1, I2 = (J2 != S) ? 0 : 1;
910 offset = 4 + SIGNEXTEND(
911 (S << 24) | (I1 << 23) | (I2 << 22) |
912 ((tp->ftt_instr1 & 0x03FF) << 12) |
913 ((tp->ftt_instr2 & 0x07FF) << 1),
914 25);
915 } else {
916 uint32_t instr1 = tp->ftt_instr1;
917 offset = 4 + (SIGNEXTEND(instr1 & 0x7FF, 11) << 1);
918 }
919
920 new_pc = pc + offset;
921
922 break;
923 }
924
925 case FASTTRAP_T_BX_REG:
926 {
927 int reg;
928
929 if (!condition_true(condition_code, regs32->cpsr)) {
930 new_pc = pc + instr_size;
931 break;
932 }
933
934 if (tp->ftt_thumb) {
935 reg = THUMB16_HRM(tp->ftt_instr1);
936 } else {
937 reg = ARM_RM(tp->ftt_instr);
938 }
939 new_pc = regs32->r[reg];
940 set_thumb_flag(regs32, new_pc);
941
942 break;
943 }
944
945 case FASTTRAP_T_LDR_PC_IMMED:
946 case FASTTRAP_T_VLDR_PC_IMMED:
947 /* Handle these instructions by replacing the PC in the instruction with another
948 * register. They are common, so we'd like to support them, and this way we do so
949 * without any risk of having to simulate a segfault.
950 */
951
952 /* Fall through */
953
954 instr_emulate:
955 case FASTTRAP_T_COMMON:
956 {
957 user_addr_t addr;
958 uint8_t scratch[32];
959 uint_t i = 0;
960 fasttrap_instr_t emul_instr;
961 emul_instr.instr32 = tp->ftt_instr;
962 int emul_instr_size;
963
964 /*
965 * Unfortunately sometimes when we emulate the instruction and have to replace the
966 * PC, there is no longer a thumb mode equivalent. We end up having to run the
967 * modified instruction in ARM mode. We use this variable to keep track of which
968 * mode we should emulate in. We still use the original variable to determine
969 * what mode to return to.
970 */
971 uint8_t emul_thumb = tp->ftt_thumb;
972 int save_reg = -1;
973 uint32_t save_val = 0;
974
975 /*
976 * Dealing with condition codes and emulation:
977 * We can't just uniformly do a condition code check here because not all instructions
978 * have condition codes. We currently do not support an instruction by instruction trace,
979 * so we can assume that either: 1. We are executing a Thumb instruction, in which case
980 * we either are not in an IT block and should execute always, or we are last in an IT
981 * block. Either way, the traced instruction will run correctly, and we won't have any
982 * problems when we return to the original code, because we will no longer be in the IT
983 * block. 2. We are executing an ARM instruction, in which case we are ok as long as
984 * we don't attempt to change the condition code.
985 */
986 if (tp->ftt_type == FASTTRAP_T_LDR_PC_IMMED) {
987 /* We know we always have a free register (the one we plan to write the
988 * result value to!). So we'll replace the pc with that one.
989 */
990 int new_reg;
991 if (tp->ftt_thumb) {
992 /* Check to see if thumb or thumb2 */
993 if (instr_size == 2) {
994 /*
995 * Sadness. We need to emulate this instruction in ARM mode
996 * because it has an 8 bit immediate offset. Instead of having
997 * to deal with condition codes in the ARM instruction, we'll
998 * just check the condition and abort if the condition is false.
999 */
1000 if (!condition_true(condition_code, regs32->cpsr)) {
1001 new_pc = pc + instr_size;
1002 break;
1003 }
1004
1005 new_reg = (tp->ftt_instr1 >> 8) & 0x7;
1006 regs32->r[new_reg] = ALIGNADDR(regs32->pc + 4, 2);
1007 emul_thumb = 0;
1008 emul_instr.instr32 = 0xE5900000 | (new_reg << 16) | (new_reg << 12) | ((tp->ftt_instr1 & 0xFF) << 2);
1009 } else {
1010 /* Thumb2. Just replace the register. */
1011 new_reg = (tp->ftt_instr2 >> 12) & 0xF;
1012 regs32->r[new_reg] = ALIGNADDR(regs32->pc + 4, 2);
1013 emul_instr.instr16.instr1 &= ~0x000F;
1014 emul_instr.instr16.instr1 |= new_reg;
1015 }
1016 } else {
1017 /* ARM. Just replace the register. */
1018 new_reg = (tp->ftt_instr >> 12) & 0xF;
1019 regs32->r[new_reg] = ALIGNADDR(regs32->pc + 8,2);
1020 emul_instr.instr32 &= ~0x000F0000;
1021 emul_instr.instr32 |= new_reg << 16;
1022 }
1023 } else if (tp->ftt_type == FASTTRAP_T_VLDR_PC_IMMED) {
1024 /* This instruction only uses one register, and if we're here, we know
1025 * it must be the pc. So we'll just replace it with R0.
1026 */
1027 save_reg = 0;
1028 save_val = regs32->r[0];
1029 regs32->r[save_reg] = ALIGNADDR(regs32->pc + (tp->ftt_thumb ? 4 : 8), 2);
1030 if (tp->ftt_thumb) {
1031 emul_instr.instr16.instr1 &= ~0x000F;
1032 } else {
1033 emul_instr.instr32 &= ~0x000F0000;
1034 }
1035 }
1036
1037 emul_instr_size = dtrace_instr_size(emul_instr.instr32, emul_thumb);
1038
1039 /*
1040 * At this point:
1041 * tp->ftt_thumb = thumb mode of original instruction
1042 * emul_thumb = thumb mode for emulation
1043 * emul_instr = instruction we are using to emulate original instruction
1044 * emul_instr_size = size of emulating instruction
1045 */
1046
1047 addr = uthread->t_dtrace_scratch->addr;
1048
1049 if (addr == 0LL) {
1050 fasttrap_sigtrap(p, uthread, pc); // Should be killing target proc
1051 new_pc = pc;
1052 break;
1053 }
1054
1055 uthread->t_dtrace_scrpc = addr;
1056 if (emul_thumb) {
1057 /*
1058 * No way to do an unconditional branch in Thumb mode, shove the address
1059 * onto the user stack and go to the next location with a pop. This can
1060 * segfault if this push happens to cross a stack page, but that's ok, since
1061 * we are running in userland, and the kernel knows how to handle userland
1062 * stack expansions correctly.
1063 *
1064 * Layout of scratch space for Thumb mode:
1065 * Emulated instruction
1066 * ldr save_reg, [pc, #16] (if necessary, restore any register we clobbered)
1067 * push { r0, r1 }
1068 * ldr r0, [pc, #4]
1069 * str r0, [sp, #4]
1070 * pop { r0, pc }
1071 * Location we should return to in original program
1072 * Saved value of clobbered register (if necessary)
1073 */
1074
1075 bcopy(&emul_instr, &scratch[i], emul_instr_size); i += emul_instr_size;
1076
1077 if (save_reg != -1) {
1078 uint16_t restore_inst = 0x4803;
1079 restore_inst |= (save_reg & 0x7) << 8;
1080 SET16(scratch+i, restore_inst); i += 2; // ldr reg, [pc , #16]
1081 }
1082
1083 SET16(scratch+i, 0xB403); i += 2; // push { r0, r1 }
1084 SET16(scratch+i, 0x4801); i += 2; // ldr r0, [pc, #4]
1085 SET16(scratch+i, 0x9001); i += 2; // str r0, [sp, #4]
1086 SET16(scratch+i, 0xBD01); i += 2; // pop { r0, pc }
1087
1088 if (i % 4) {
1089 SET16(scratch+i, 0); i += 2; // padding - saved 32 bit words must be aligned
1090 }
1091 SET32(scratch+i, pc + instr_size + (tp->ftt_thumb ? 1 : 0)); i += 4; // Return address
1092 if (save_reg != -1) {
1093 SET32(scratch+i, save_val); i += 4; // saved value of clobbered register
1094 }
1095
1096 uthread->t_dtrace_astpc = addr + i;
1097 bcopy(&emul_instr, &scratch[i], emul_instr_size); i += emul_instr_size;
1098 SET16(scratch+i, FASTTRAP_THUMB32_RET_INSTR); i += 2;
1099 } else {
1100 /*
1101 * Layout of scratch space for ARM mode:
1102 * Emulated instruction
1103 * ldr save_reg, [pc, #12] (if necessary, restore any register we clobbered)
1104 * ldr pc, [pc, #4]
1105 * Location we should return to in original program
1106 * Saved value of clobbered register (if necessary)
1107 */
1108
1109 bcopy(&emul_instr, &scratch[i], emul_instr_size); i += emul_instr_size;
1110
1111 if (save_reg != -1) {
1112 uint32_t restore_inst = 0xE59F0004;
1113 restore_inst |= save_reg << 12;
1114 SET32(scratch+i, restore_inst); i += 4; // ldr reg, [pc, #12]
1115 }
1116 SET32(scratch+i, 0xE51FF004); i += 4; // ldr pc, [pc, #4]
1117
1118 SET32(scratch+i, pc + instr_size + (tp->ftt_thumb ? 1 : 0)); i += 4; // Return address
1119 if (save_reg != -1) {
1120 SET32(scratch+i, save_val); i += 4; // Saved value of clobbered register
1121 }
1122
1123 uthread->t_dtrace_astpc = addr + i;
1124 bcopy(&emul_instr, &scratch[i], emul_instr_size); i += emul_instr_size;
1125 SET32(scratch+i, FASTTRAP_ARM32_RET_INSTR); i += 4;
1126 }
1127
d9a64523 1128 if (uwrite(p, scratch, i, uthread->t_dtrace_scratch->write_addr) != KERN_SUCCESS) {
5ba3f43e
A
1129 fasttrap_sigtrap(p, uthread, pc);
1130 new_pc = pc;
1131 break;
1132 }
1133
1134 if (tp->ftt_retids != NULL) {
1135 uthread->t_dtrace_step = 1;
1136 uthread->t_dtrace_ret = 1;
1137 new_pc = uthread->t_dtrace_astpc + (emul_thumb ? 1 : 0);
1138 } else {
1139 new_pc = uthread->t_dtrace_scrpc + (emul_thumb ? 1 : 0);
1140 }
1141
1142 uthread->t_dtrace_pc = pc;
1143 uthread->t_dtrace_npc = pc + instr_size;
1144 uthread->t_dtrace_on = 1;
1145 *was_simulated = 0;
1146 set_thumb_flag(regs32, new_pc);
1147 break;
1148 }
1149
1150 default:
1151 panic("fasttrap: mishandled an instruction");
1152 }
1153done:
1154 set_saved_state_pc(state, new_pc);
1155 return;
1156}
1157
1158/*
1159 * Copy out an instruction for execution in userland.
1160 * Trap back to kernel to handle return to original flow of execution, because
1161 * direct branches don't have sufficient range (+/- 128MB) and we
1162 * cannot clobber a GPR. Note that we have to specially handle PC-rel loads/stores
1163 * as well, which have range +/- 1MB (convert to an indirect load). Instruction buffer
1164 * layout:
1165 *
1166 * [ Thunked instruction sequence ]
1167 * [ Trap for return to original code and return probe handling ]
1168 *
1169 * This *does* make it impossible for an ldxr/stxr pair to succeed if we trace on or between
1170 * them... may need to get fancy at some point.
1171 */
1172static void
1173fasttrap_pid_probe_thunk_instr64(arm_saved_state_t *state, fasttrap_tracepoint_t *tp, proc_t *p, uthread_t uthread,
1174 const uint32_t *instructions, uint32_t num_instrs, user_addr_t *pc_out)
1175{
1176 uint32_t local_scratch[8];
1177 user_addr_t pc = get_saved_state_pc(state);
1178 user_addr_t user_scratch_area;
1179
1180 assert(num_instrs < 8);
1181
1182 bcopy(instructions, local_scratch, num_instrs * sizeof(uint32_t));
1183 local_scratch[num_instrs] = FASTTRAP_ARM64_RET_INSTR;
1184
1185 uthread->t_dtrace_astpc = uthread->t_dtrace_scrpc = uthread->t_dtrace_scratch->addr;
1186 user_scratch_area = uthread->t_dtrace_scratch->write_addr;
1187
1188 if (user_scratch_area == (user_addr_t)0) {
1189 fasttrap_sigtrap(p, uthread, pc); // Should be killing target proc
1190 *pc_out = pc;
1191 return;
1192 }
1193
d9a64523 1194 if (uwrite(p, local_scratch, (num_instrs + 1) * sizeof(uint32_t), user_scratch_area) != KERN_SUCCESS) {
5ba3f43e
A
1195 fasttrap_sigtrap(p, uthread, pc);
1196 *pc_out = pc;
1197 return;
1198 }
1199
1200 /* We're stepping (come back to kernel to adjust PC for return to regular code). */
1201 uthread->t_dtrace_step = 1;
1202
1203 /* We may or may not be about to run a return probe (but we wouldn't thunk ret lr)*/
1204 uthread->t_dtrace_ret = (tp->ftt_retids != NULL);
1205 assert(tp->ftt_type != FASTTRAP_T_ARM64_RET);
d9a64523 1206 assert(tp->ftt_type != FASTTRAP_T_ARM64_RETAB);
5ba3f43e
A
1207
1208 /* Set address of instruction we've patched */
1209 uthread->t_dtrace_pc = pc;
1210
1211 /* Any branch would be emulated, next instruction should be one ahead */
1212 uthread->t_dtrace_npc = pc + 4;
1213
1214 /* We are certainly handling a probe */
1215 uthread->t_dtrace_on = 1;
1216
1217 /* Let's jump to the scratch area */
1218 *pc_out = uthread->t_dtrace_scratch->addr;
1219}
1220
1221/*
1222 * Sign-extend bit "sign_bit_index" out to bit 64.
1223 */
1224static int64_t
1225sign_extend(int64_t input, uint32_t sign_bit_index)
1226{
1227 assert(sign_bit_index < 63);
1228 if (input & (1ULL << sign_bit_index)) {
1229 /* All 1's & ~[1's from 0 to sign bit] */
1230 input |= ((~0ULL) & ~((1ULL << (sign_bit_index + 1)) - 1ULL));
1231 }
1232
1233 return input;
1234}
1235
1236/*
1237 * Handle xzr vs. sp, fp, lr, etc. Will *not* read the SP.
1238 */
1239static uint64_t
1240get_saved_state64_regno(arm_saved_state64_t *regs64, uint32_t regno, int use_xzr)
1241{
1242 /* Set PC to register value */
1243 switch (regno) {
1244 case 29:
1245 return regs64->fp;
1246 case 30:
1247 return regs64->lr;
1248 case 31:
1249 /* xzr */
1250 if (use_xzr) {
1251 return 0;
1252 } else {
1253 return regs64->sp;
1254 }
1255 default:
1256 return regs64->x[regno];
1257 }
1258}
1259
1260static void
1261set_saved_state64_regno(arm_saved_state64_t *regs64, uint32_t regno, int use_xzr, register_t value)
1262{
1263 /* Set PC to register value */
1264 switch (regno) {
1265 case 29:
1266 regs64->fp = value;
1267 break;
1268 case 30:
1269 regs64->lr = value;
1270 break;
1271 case 31:
1272 if (!use_xzr) {
1273 regs64->sp = value;
1274 }
1275 break;
1276 default:
1277 regs64->x[regno] = value;
1278 break;
1279 }
1280}
1281
1282/*
1283 * Common operation: extract sign-extended PC offset from instruction
1284 * Left-shifts result by two bits.
1285 */
1286static uint64_t
1287extract_address_literal_sign_extended(uint32_t instr, uint32_t base, uint32_t numbits)
1288{
1289 uint64_t offset;
1290
1291 offset = (instr >> base) & ((1 << numbits) - 1);
1292 offset = sign_extend(offset, numbits - 1);
1293 offset = offset << 2;
1294
1295 return offset;
1296}
1297
1298static void
1299do_cbz_cnbz(arm_saved_state64_t *regs64, uint32_t regwidth, uint32_t instr, int is_cbz, user_addr_t *pc_out)
1300{
1301 uint32_t regno;
1302 uint64_t regval;
1303 uint64_t offset;
1304
1305 /* Extract register */
1306 regno = (instr & 0x1f);
1307 assert(regno <= 31);
1308 regval = get_saved_state64_regno(regs64, regno, 1);
1309
1310 /* Control for size */
1311 if (regwidth == 32) {
1312 regval &= 0xFFFFFFFFULL;
1313 }
1314
1315 /* Extract offset */
1316 offset = extract_address_literal_sign_extended(instr, 5, 19);
1317
1318 /* Do test */
1319 if ((is_cbz && regval == 0) || ((!is_cbz) && regval != 0)) {
1320 /* Set PC from label */
1321 *pc_out = regs64->pc + offset;
1322 } else {
1323 /* Advance PC */
1324 *pc_out = regs64->pc + 4;
1325 }
1326}
1327
1328static void
1329do_tbz_tbnz(arm_saved_state64_t *regs64, uint32_t instr, int is_tbz, user_addr_t *pc_out)
1330{
1331 uint64_t offset, regval;
1332 uint32_t bit_index, b5, b40, regno, bit_set;
1333
1334 /* Compute offset */
1335 offset = extract_address_literal_sign_extended(instr, 5, 14);
1336
1337 /* Extract bit index */
1338 b5 = (instr >> 31);
1339 b40 = ((instr >> 19) & 0x1f);
1340 bit_index = (b5 << 5) | b40;
1341 assert(bit_index <= 63);
1342
1343 /* Extract register */
1344 regno = (instr & 0x1f);
1345 assert(regno <= 31);
1346 regval = get_saved_state64_regno(regs64, regno, 1);
1347
1348 /* Test bit */
1349 bit_set = ((regval & (1 << bit_index)) != 0);
1350
1351 if ((is_tbz && (!bit_set)) || ((!is_tbz) && bit_set)) {
1352 /* Branch: unsigned addition so overflow defined */
1353 *pc_out = regs64->pc + offset;
1354 } else {
1355 /* Advance PC */
1356 *pc_out = regs64->pc + 4;
1357 }
1358}
1359
1360
1361static void
1362fasttrap_pid_probe_handle_patched_instr64(arm_saved_state_t *state, fasttrap_tracepoint_t *tp __unused, uthread_t uthread,
1363 proc_t *p, uint_t is_enabled, int *was_simulated)
1364{
1365 int res1, res2;
1366 arm_saved_state64_t *regs64 = saved_state64(state);
1367 uint32_t instr = tp->ftt_instr;
1368 user_addr_t new_pc = 0;
1369
1370 /* Neon state should be threaded throw, but hack it until we have better arm/arm64 integration */
1371 arm_neon_saved_state64_t *ns64 = &(get_user_neon_regs(uthread->uu_thread)->ns_64);
1372
1373 /* is-enabled probe: set x0 to 1 and step forwards */
1374 if (is_enabled) {
1375 regs64->x[0] = 1;
1376 set_saved_state_pc(state, regs64->pc + 4);
1377 return;
1378 }
1379
1380 /* For USDT probes, bypass all the emulation logic for the nop instruction */
1381 if (IS_ARM64_NOP(tp->ftt_instr)) {
1382 set_saved_state_pc(state, regs64->pc + 4);
1383 return;
1384 }
1385
1386
1387 /* Only one of many cases in the switch doesn't simulate */
1388 switch(tp->ftt_type) {
1389 /*
1390 * Function entry: emulate for speed.
1391 * stp fp, lr, [sp, #-16]!
1392 */
1393 case FASTTRAP_T_ARM64_STANDARD_FUNCTION_ENTRY:
1394 {
1395 /* Store values to stack */
1396 res1 = fasttrap_suword64(regs64->sp - 16, regs64->fp);
1397 res2 = fasttrap_suword64(regs64->sp - 8, regs64->lr);
1398 if (res1 != 0 || res2 != 0) {
1399 fasttrap_sigsegv(p, uthread, regs64->sp - (res1 ? 16 : 8), state);
1400 new_pc = regs64->pc; /* Bit of a hack */
1401 break;
1402 }
1403
1404 /* Move stack pointer */
1405 regs64->sp -= 16;
1406
1407 /* Move PC forward */
1408 new_pc = regs64->pc + 4;
1409 *was_simulated = 1;
1410 break;
1411 }
1412
1413 /*
1414 * PC-relative loads/stores: emulate for correctness.
1415 * All loads are 32bits or greater (no need to handle byte or halfword accesses).
1416 * LDR Wt, addr
1417 * LDR Xt, addr
1418 * LDRSW Xt, addr
1419 *
1420 * LDR St, addr
1421 * LDR Dt, addr
1422 * LDR Qt, addr
1423 * PRFM label -> becomes a NOP
1424 */
1425 case FASTTRAP_T_ARM64_LDR_S_PC_REL:
1426 case FASTTRAP_T_ARM64_LDR_W_PC_REL:
1427 case FASTTRAP_T_ARM64_LDR_D_PC_REL:
1428 case FASTTRAP_T_ARM64_LDR_X_PC_REL:
1429 case FASTTRAP_T_ARM64_LDR_Q_PC_REL:
1430 case FASTTRAP_T_ARM64_LDRSW_PC_REL:
1431 {
1432 uint64_t offset;
1433 uint32_t valsize, regno;
1434 user_addr_t address;
1435 union {
1436 uint32_t val32;
1437 uint64_t val64;
1438 uint128_t val128;
1439 } value;
1440
1441 /* Extract 19-bit offset, add to pc */
1442 offset = extract_address_literal_sign_extended(instr, 5, 19);
1443 address = regs64->pc + offset;
1444
1445 /* Extract destination register */
1446 regno = (instr & 0x1f);
1447 assert(regno <= 31);
1448
1449 /* Read value of desired size from memory */
1450 switch (tp->ftt_type) {
1451 case FASTTRAP_T_ARM64_LDR_S_PC_REL:
1452 case FASTTRAP_T_ARM64_LDR_W_PC_REL:
1453 case FASTTRAP_T_ARM64_LDRSW_PC_REL:
1454 valsize = 4;
1455 break;
1456 case FASTTRAP_T_ARM64_LDR_D_PC_REL:
1457 case FASTTRAP_T_ARM64_LDR_X_PC_REL:
1458 valsize = 8;
1459 break;
1460 case FASTTRAP_T_ARM64_LDR_Q_PC_REL:
1461 valsize = 16;
1462 break;
1463 default:
1464 panic("Should never get here!");
1465 valsize = -1;
1466 break;
1467 }
1468
1469 if (copyin(address, &value, valsize) != 0) {
1470 fasttrap_sigsegv(p, uthread, address, state);
1471 new_pc = regs64->pc; /* Bit of a hack, we know about update in fasttrap_sigsegv() */
1472 break;
1473 }
1474
1475 /* Stash in correct register slot */
1476 switch (tp->ftt_type) {
1477 case FASTTRAP_T_ARM64_LDR_W_PC_REL:
1478 set_saved_state64_regno(regs64, regno, 1, value.val32);
1479 break;
1480 case FASTTRAP_T_ARM64_LDRSW_PC_REL:
1481 set_saved_state64_regno(regs64, regno, 1, sign_extend(value.val32, 31));
1482 break;
1483 case FASTTRAP_T_ARM64_LDR_X_PC_REL:
1484 set_saved_state64_regno(regs64, regno, 1, value.val64);
1485 break;
1486 case FASTTRAP_T_ARM64_LDR_S_PC_REL:
1487 ns64->v.s[regno][0] = value.val32;
1488 break;
1489 case FASTTRAP_T_ARM64_LDR_D_PC_REL:
1490 ns64->v.d[regno][0] = value.val64;
1491 break;
1492 case FASTTRAP_T_ARM64_LDR_Q_PC_REL:
1493 ns64->v.q[regno] = value.val128;
1494 break;
1495 default:
1496 panic("Should never get here!");
1497 }
1498
1499
1500 /* Move PC forward */
1501 new_pc = regs64->pc + 4;
1502 *was_simulated = 1;
1503 break;
1504
1505 }
1506
1507 case FASTTRAP_T_ARM64_PRFM:
1508 {
1509 /* Becomes a NOP (architecturally permitted). Just move PC forward */
1510 new_pc = regs64->pc + 4;
1511 *was_simulated = 1;
1512 break;
1513 }
1514
1515 /*
1516 * End explicit memory accesses.
1517 */
1518
1519 /*
1520 * Branches: parse condition codes if needed, emulate for correctness and
1521 * in the case of the indirect branches, convenience
1522 * B.cond
1523 * CBNZ Wn, label
1524 * CBNZ Xn, label
1525 * CBZ Wn, label
1526 * CBZ Xn, label
1527 * TBNZ, Xn|Wn, #uimm16, label
1528 * TBZ, Xn|Wn, #uimm16, label
1529 *
1530 * B label
1531 * BL label
1532 *
1533 * BLR Xm
1534 * BR Xm
1535 * RET Xm
1536 */
1537 case FASTTRAP_T_ARM64_B_COND:
1538 {
1539 int cond;
1540
1541 /* Extract condition code */
1542 cond = (instr & 0xf);
1543
1544 /* Determine if it passes */
1545 if (condition_true(cond, regs64->cpsr)) {
1546 uint64_t offset;
1547
1548 /* Extract 19-bit target offset, add to PC */
1549 offset = extract_address_literal_sign_extended(instr, 5, 19);
1550 new_pc = regs64->pc + offset;
1551 } else {
1552 /* Move forwards */
1553 new_pc = regs64->pc + 4;
1554 }
1555
1556 *was_simulated = 1;
1557 break;
1558 }
1559
1560 case FASTTRAP_T_ARM64_CBNZ_W:
1561 {
1562 do_cbz_cnbz(regs64, 32, instr, 0, &new_pc);
1563 *was_simulated = 1;
1564 break;
1565 }
1566 case FASTTRAP_T_ARM64_CBNZ_X:
1567 {
1568 do_cbz_cnbz(regs64, 64, instr, 0, &new_pc);
1569 *was_simulated = 1;
1570 break;
1571 }
1572 case FASTTRAP_T_ARM64_CBZ_W:
1573 {
1574 do_cbz_cnbz(regs64, 32, instr, 1, &new_pc);
1575 *was_simulated = 1;
1576 break;
1577 }
1578 case FASTTRAP_T_ARM64_CBZ_X:
1579 {
1580 do_cbz_cnbz(regs64, 64, instr, 1, &new_pc);
1581 *was_simulated = 1;
1582 break;
1583 }
1584
1585 case FASTTRAP_T_ARM64_TBNZ:
1586 {
1587 do_tbz_tbnz(regs64, instr, 0, &new_pc);
1588 *was_simulated = 1;
1589 break;
1590 }
1591 case FASTTRAP_T_ARM64_TBZ:
1592 {
1593 do_tbz_tbnz(regs64, instr, 1, &new_pc);
1594 *was_simulated = 1;
1595 break;
1596 }
1597 case FASTTRAP_T_ARM64_B:
1598 case FASTTRAP_T_ARM64_BL:
1599 {
1600 uint64_t offset;
1601
1602 /* Extract offset from instruction */
1603 offset = extract_address_literal_sign_extended(instr, 0, 26);
1604
1605 /* Update LR if appropriate */
1606 if (tp->ftt_type == FASTTRAP_T_ARM64_BL) {
1607 regs64->lr = regs64->pc + 4;
1608 }
1609
1610 /* Compute PC (unsigned addition for defined overflow) */
1611 new_pc = regs64->pc + offset;
1612 *was_simulated = 1;
1613 break;
1614 }
1615
1616 case FASTTRAP_T_ARM64_BLR:
1617 case FASTTRAP_T_ARM64_BR:
1618 {
1619 uint32_t regno;
1620
1621 /* Extract register from instruction */
1622 regno = ((instr >> 5) & 0x1f);
1623 assert(regno <= 31);
1624
1625 /* Update LR if appropriate */
1626 if (tp->ftt_type == FASTTRAP_T_ARM64_BLR) {
1627 regs64->lr = regs64->pc + 4;
1628 }
1629
1630 /* Update PC in saved state */
1631 new_pc = get_saved_state64_regno(regs64, regno, 1);
1632 *was_simulated = 1;
1633 break;
1634 }
1635
1636 case FASTTRAP_T_ARM64_RET:
1637 {
1638 /* Extract register */
1639 unsigned regno = ((instr >> 5) & 0x1f);
1640 assert(regno <= 31);
1641
1642 /* Set PC to register value (xzr, not sp) */
1643 new_pc = get_saved_state64_regno(regs64, regno, 1);
d9a64523 1644
5ba3f43e
A
1645 *was_simulated = 1;
1646 break;
1647 }
d9a64523
A
1648 case FASTTRAP_T_ARM64_RETAB:
1649 {
1650 /* Set PC to register value (xzr, not sp) */
1651 new_pc = get_saved_state64_regno(regs64, 30, 1);
1652#if __has_feature(ptrauth_calls)
1653 new_pc = (user_addr_t) ptrauth_strip((void *)new_pc, ptrauth_key_return_address);
1654#endif
5ba3f43e 1655
d9a64523
A
1656 *was_simulated = 1;
1657 break;
1658
1659 }
5ba3f43e
A
1660 /*
1661 * End branches.
1662 */
1663
1664 /*
1665 * Address calculations: emulate for correctness.
1666 *
1667 * ADRP Xd, label
1668 * ADR Xd, label
1669 */
1670 case FASTTRAP_T_ARM64_ADRP:
1671 case FASTTRAP_T_ARM64_ADR:
1672 {
1673 uint64_t immhi, immlo, offset, result;
1674 uint32_t regno;
1675
1676 /* Extract destination register */
1677 regno = (instr & 0x1f);
1678 assert(regno <= 31);
1679
1680 /* Extract offset */
1681 immhi = ((instr & 0x00ffffe0) >> 5); /* bits [23,5]: 19 bits */
1682 immlo = ((instr & 0x60000000) >> 29); /* bits [30,29]: 2 bits */
1683
1684 /* Add to PC. Use unsigned addition so that overflow wraps (rather than being undefined). */
1685 if (tp->ftt_type == FASTTRAP_T_ARM64_ADRP) {
1686 offset = (immhi << 14) | (immlo << 12); /* Concatenate bits into [32,12]*/
1687 offset = sign_extend(offset, 32); /* Sign extend from bit 32 */
1688 result = (regs64->pc & ~0xfffULL) + offset; /* And add to page of current pc */
1689 } else {
1690 assert(tp->ftt_type == FASTTRAP_T_ARM64_ADR);
1691 offset = (immhi << 2) | immlo; /* Concatenate bits into [20,0] */
1692 offset = sign_extend(offset, 20); /* Sign-extend */
1693 result = regs64->pc + offset; /* And add to page of current pc */
1694 }
1695
1696 /* xzr, not sp */
1697 set_saved_state64_regno(regs64, regno, 1, result);
1698
1699 /* Move PC forward */
1700 new_pc = regs64->pc + 4;
1701 *was_simulated = 1;
1702 break;
1703 }
1704
1705 /*
1706 * End address calculations.
1707 */
1708
1709 /*
1710 * Everything else: thunk to userland
1711 */
1712 case FASTTRAP_T_COMMON:
1713 {
1714 fasttrap_pid_probe_thunk_instr64(state, tp, p, uthread, &tp->ftt_instr, 1, &new_pc);
1715 *was_simulated = 0;
1716 break;
1717 }
1718 default:
1719 {
1720 panic("An instruction DTrace doesn't expect: %d\n", tp->ftt_type);
1721 break;
1722 }
1723 }
1724
1725 set_saved_state_pc(state, new_pc);
1726 return;
1727}
1728
1729int
1730fasttrap_pid_probe(arm_saved_state_t *state)
1731{
1732 proc_t *p = current_proc();
1733 fasttrap_bucket_t *bucket;
1734 lck_mtx_t *pid_mtx;
1735 fasttrap_tracepoint_t *tp, tp_local;
1736 pid_t pid;
1737 dtrace_icookie_t cookie;
1738 uint_t is_enabled = 0;
1739 int was_simulated, retire_tp = 1;
1740 int is_64_bit = is_saved_state64(state);
1741
1742 uint64_t pc = get_saved_state_pc(state);
1743
1744 assert(is_64_bit || (pc <= UINT32_MAX));
1745
1746 uthread_t uthread = (uthread_t) get_bsdthread_info(current_thread());
1747
1748 /*
1749 * It's possible that a user (in a veritable orgy of bad planning)
1750 * could redirect this thread's flow of control before it reached the
1751 * return probe fasttrap. In this case we need to kill the process
1752 * since it's in a unrecoverable state.
1753 */
1754 if (uthread->t_dtrace_step) {
1755 ASSERT(uthread->t_dtrace_on);
1756 fasttrap_sigtrap(p, uthread, (user_addr_t)pc);
1757 return (0);
1758 }
1759
1760 /*
1761 * Clear all user tracing flags.
1762 */
1763 uthread->t_dtrace_ft = 0;
1764 uthread->t_dtrace_pc = 0;
1765 uthread->t_dtrace_npc = 0;
1766 uthread->t_dtrace_scrpc = 0;
1767 uthread->t_dtrace_astpc = 0;
1768 uthread->t_dtrace_reg = 0;
1769
1770 /*
1771 * Treat a child created by a call to vfork(2) as if it were its
1772 * parent. We know that there's only one thread of control in such a
1773 * process: this one.
1774 */
1775 if (p->p_lflag & P_LINVFORK) {
1776 proc_list_lock();
1777 while (p->p_lflag & P_LINVFORK)
1778 p = p->p_pptr;
1779 proc_list_unlock();
1780 }
1781
1782 pid = p->p_pid;
1783 pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
1784 lck_mtx_lock(pid_mtx);
1785 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid,pc)];
1786
1787 /*
1788 * Lookup the tracepoint that the process just hit.
1789 */
1790 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
1791 if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
1792 tp->ftt_proc->ftpc_acount != 0)
1793 break;
1794 }
1795
1796 /*
1797 * If we couldn't find a matching tracepoint, either a tracepoint has
1798 * been inserted without using the pid<pid> ioctl interface (see
1799 * fasttrap_ioctl), or somehow we have mislaid this tracepoint.
1800 */
1801 if (tp == NULL) {
1802 lck_mtx_unlock(pid_mtx);
1803 return (-1);
1804 }
1805
1806 /* Validation of THUMB-related state */
1807 if (tp->ftt_thumb) {
1808 if (!fasttrap_pid_probe_thumb_state_valid(saved_state32(state), tp)) {
1809 fasttrap_tracepoint_remove(p, tp);
1810 lck_mtx_unlock(pid_mtx);
1811 return (-1);
1812 }
1813 }
1814
1815 /* Execute the actual probe */
1816 if (tp->ftt_ids != NULL) {
1817 fasttrap_id_t *id;
1818 uint64_t arg4;
1819
1820 if (is_saved_state64(state)) {
1821 arg4 = get_saved_state_reg(state, 4);
1822 } else {
1823 uint32_t arg;
1824 user_addr_t stack = (user_addr_t)get_saved_state_sp(state);
1825
1826 fasttrap_fuword32_noerr(stack, &arg);
1827 arg4 = arg;
1828 }
1829
1830
1831 /* First four parameters are passed in registers */
1832
1833 for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
1834 fasttrap_probe_t *probe = id->fti_probe;
1835
1836#ifndef CONFIG_EMBEDDED
1837 if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
1838 dtrace_probe(dtrace_probeid_error, 0 /* state */, probe->ftp_id,
1839 1 /* ndx */, -1 /* offset */, DTRACEFLT_UPRIV);
1840#else
1841 if (FALSE) {
1842#endif
1843 } else {
1844 if (probe->ftp_prov->ftp_provider_type == DTFTP_PROVIDER_ONESHOT) {
1845 uint8_t already_triggered = atomic_or_8(&probe->ftp_triggered, 1);
1846 if (already_triggered) {
1847 continue;
1848 }
1849 }
1850 /*
1851 * If we have at least one probe associated that
1852 * is not a oneshot probe, don't remove the
1853 * tracepoint
1854 */
1855 else {
1856 retire_tp = 0;
1857 }
1858 if (id->fti_ptype == DTFTP_ENTRY) {
1859 /*
1860 * We note that this was an entry
1861 * probe to help ustack() find the
1862 * first caller.
1863 */
1864 cookie = dtrace_interrupt_disable();
1865 DTRACE_CPUFLAG_SET(CPU_DTRACE_ENTRY);
1866 dtrace_probe(probe->ftp_id,
1867 get_saved_state_reg(state, 0),
1868 get_saved_state_reg(state, 1),
1869 get_saved_state_reg(state, 2),
1870 get_saved_state_reg(state, 3),
1871 arg4);
1872 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_ENTRY);
1873 dtrace_interrupt_enable(cookie);
1874 } else if (id->fti_ptype == DTFTP_IS_ENABLED) {
1875 /*
1876 * Note that in this case, we don't
1877 * call dtrace_probe() since it's only
1878 * an artificial probe meant to change
1879 * the flow of control so that it
1880 * encounters the true probe.
1881 */
1882 is_enabled = 1;
1883 } else if (probe->ftp_argmap == NULL) {
1884 dtrace_probe(probe->ftp_id,
1885 get_saved_state_reg(state, 0),
1886 get_saved_state_reg(state, 1),
1887 get_saved_state_reg(state, 2),
1888 get_saved_state_reg(state, 3),
1889 arg4);
1890
1891 } else {
1892 uint64_t t[5];
1893
1894 if (is_64_bit) {
1895 fasttrap_usdt_args64(probe, saved_state64(state), 5, t);
1896 } else {
1897 fasttrap_usdt_args32(probe, saved_state32(state), 5, t);
1898 }
1899 dtrace_probe(probe->ftp_id, t[0], t[1], t[2], t[3], t[4]);
1900 }
1901 }
1902 }
1903 if (retire_tp) {
1904 fasttrap_tracepoint_retire(p, tp);
1905 }
1906 }
1907 /*
1908 * We're about to do a bunch of work so we cache a local copy of
1909 * the tracepoint to emulate the instruction, and then find the
1910 * tracepoint again later if we need to light up any return probes.
1911 */
1912 tp_local = *tp;
1913 lck_mtx_unlock(pid_mtx);
1914 tp = &tp_local;
1915
1916 /*
1917 * APPLE NOTE:
1918 *
1919 * Subroutines should update PC.
1920 * We're setting this earlier than Solaris does, to get a "correct"
1921 * ustack() output. In the Sun code, a() -> b() -> c() -> d() is
1922 * reported at: d, b, a. The new way gives c, b, a, which is closer
1923 * to correct, as the return instruction has already exectued.
1924 */
1925 if (is_64_bit) {
1926 fasttrap_pid_probe_handle_patched_instr64(state, tp, uthread, p, is_enabled, &was_simulated);
1927 } else {
1928 fasttrap_pid_probe_handle_patched_instr32(state, tp, uthread, p, is_enabled, &was_simulated);
1929 }
1930
1931 /*
1932 * If there were no return probes when we first found the tracepoint,
1933 * we should feel no obligation to honor any return probes that were
1934 * subsequently enabled -- they'll just have to wait until the next
1935 * time around.
1936 */
1937 if (tp->ftt_retids != NULL) {
1938 /*
1939 * We need to wait until the results of the instruction are
1940 * apparent before invoking any return probes. If this
1941 * instruction was emulated we can just call
1942 * fasttrap_return_common(); if it needs to be executed, we
1943 * need to wait until the user thread returns to the kernel.
1944 */
1945 /*
1946 * It used to be that only common instructions were simulated.
1947 * For performance reasons, we now simulate some instructions
1948 * when safe and go back to userland otherwise. The was_simulated
1949 * flag means we don't need to go back to userland.
1950 */
1951 if (was_simulated) {
1952 fasttrap_return_common(p, state, (user_addr_t)pc, (user_addr_t)get_saved_state_pc(state));
1953 } else {
1954 ASSERT(uthread->t_dtrace_ret != 0);
1955 ASSERT(uthread->t_dtrace_pc == pc);
1956 ASSERT(uthread->t_dtrace_scrpc != 0);
1957 ASSERT(((user_addr_t)get_saved_state_pc(state)) == uthread->t_dtrace_astpc);
1958 }
1959 }
1960
1961 return (0);
1962}
1963
1964int
1965fasttrap_return_probe(arm_saved_state_t *regs)
1966{
1967 proc_t *p = current_proc();
1968 uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
1969 user_addr_t pc = uthread->t_dtrace_pc;
1970 user_addr_t npc = uthread->t_dtrace_npc;
1971
1972 uthread->t_dtrace_pc = 0;
1973 uthread->t_dtrace_npc = 0;
1974 uthread->t_dtrace_scrpc = 0;
1975 uthread->t_dtrace_astpc = 0;
1976
1977 /*
1978 * Treat a child created by a call to vfork(2) as if it were its
1979 * parent. We know that there's only one thread of control in such a
1980 * process: this one.
1981 */
1982 if (p->p_lflag & P_LINVFORK) {
1983 proc_list_lock();
1984 while (p->p_lflag & P_LINVFORK)
1985 p = p->p_pptr;
1986 proc_list_unlock();
1987 }
1988
1989 /*
1990 * We set rp->r_pc to the address of the traced instruction so
1991 * that it appears to dtrace_probe() that we're on the original
1992 * instruction, and so that the user can't easily detect our
1993 * complex web of lies. dtrace_return_probe() (our caller)
1994 * will correctly set %pc after we return.
1995 */
1996 set_saved_state_pc(regs, pc);
1997
1998 fasttrap_return_common(p, regs, pc, npc);
1999
2000 return (0);
2001}
2002
2003uint64_t
2004fasttrap_pid_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
2005 int aframes)
2006{
2007#pragma unused(arg, id, parg, aframes)
2008 arm_saved_state_t* regs = find_user_regs(current_thread());
2009
2010 if (is_saved_state32(regs)) {
2011 /* First four arguments are in registers */
2012 if (argno < 4)
2013 return saved_state32(regs)->r[argno];
2014
2015 /* Look on the stack for the rest */
2016 uint32_t value;
2017 uint32_t* sp = (uint32_t*)(uintptr_t) saved_state32(regs)->sp;
2018 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
2019 value = dtrace_fuword32((user_addr_t) (sp+argno-4));
2020 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
2021
2022 return value;
2023 }
2024 else {
2025 /* First eight arguments are in registers */
2026 if (argno < 8)
2027 return saved_state64(regs)->x[argno];
2028
2029 /* Look on the stack for the rest */
2030 uint64_t value;
2031 uint64_t* sp = (uint64_t*) saved_state64(regs)->sp;
2032 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
2033 value = dtrace_fuword64((user_addr_t) (sp+argno-8));
2034 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
2035
2036 return value;
2037 }
2038
2039}
2040
2041uint64_t
2042fasttrap_usdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno, int aframes)
2043{
2044#pragma unused(arg, id, parg, argno, aframes)
2045#if 0
2046 return (fasttrap_anarg(ttolwp(curthread)->lwp_regs, 0, argno));
2047#endif
2048
2049 return 0;
2050}
2051