2 * Copyright (c) 2007 Apple Inc. All rights reserved.
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
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.
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]
26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
31 * #pragma ident "@(#)fasttrap_isa.c 1.19 05/09/14 SMI"
36 #define _KERNEL /* Solaris vs. Darwin */
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>
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>
51 #include <sys/dtrace_ptss.h>
52 #include <kern/debug.h>
54 #include <pexpert/pexpert.h>
56 #if __has_include(<ptrauth.h>)
61 extern dtrace_id_t dtrace_probeid_error
;
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 */
66 extern int dtrace_decode_arm64(uint32_t instr
);
67 extern int dtrace_decode_arm(uint32_t instr
);
68 extern int dtrace_decode_thumb(uint32_t instr
);
71 * Lossless User-Land Tracing on ARM
72 * ---------------------------------
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.
77 * Some ARM specific issues:
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.
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.
95 #define THUMB_INSTR(x) (*(uint16_t*) &(x))
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)
102 #define SET16(x,w) *((uint16_t*) (x)) = (w)
103 #define SET32(x,w) *((uint32_t*) (x)) = (w)
105 #define IS_ARM32_NOP(x) ((x) == 0xE1A00000)
106 /* Marker for is-enabled probes */
107 #define IS_ARM32_IS_ENABLED(x) ((x) == 0xE0200000)
109 #define IS_ARM64_NOP(x) ((x) == 0xD503201F)
110 /* Marker for is-enabled probes */
111 #define IS_ARM64_IS_ENABLED(x) ((x) == 0xD2800000)
113 #define IS_THUMB32_NOP(x) ((x) == 0x46C0)
114 /* Marker for is-enabled probes */
115 #define IS_THUMB32_IS_ENABLED(x) ((x) == 0x4040)
117 #define ARM_LDM_UF (1 << 23)
118 #define ARM_LDM_PF (1 << 24)
119 #define ARM_LDM_WF (1 << 21)
121 #define ARM_LDR_UF (1 << 23)
122 #define ARM_LDR_BF (1 << 22)
124 static int fasttrap_tracepoint_init32 (proc_t
*, fasttrap_tracepoint_t
*, user_addr_t
, fasttrap_probe_type_t
);
125 static int fasttrap_tracepoint_init64 (proc_t
*, fasttrap_tracepoint_t
*, user_addr_t
, fasttrap_probe_type_t
);
128 fasttrap_tracepoint_init(proc_t
*p
, fasttrap_tracepoint_t
*tp
,
129 user_addr_t pc
, fasttrap_probe_type_t type
)
131 if (proc_is64bit_data(p
)) {
132 return fasttrap_tracepoint_init64(p
, tp
, pc
, type
);
134 return fasttrap_tracepoint_init32(p
, tp
, pc
, type
);
139 fasttrap_tracepoint_init32(proc_t
*p
, fasttrap_tracepoint_t
*tp
,
140 user_addr_t pc
, fasttrap_probe_type_t type
)
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.
154 * APPLE NOTE: Of course, we do not have a P_PR_LOCK, so this is racey...
157 if (uread(p
, &instr
, 4, pc
) != 0)
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.
164 tp
->ftt_instr
= instr
;
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. */
172 case FASTTRAP_FN_USDT
:
173 if (IS_ARM32_NOP(instr
) || IS_ARM32_IS_ENABLED(instr
)) {
175 } else if (IS_THUMB32_NOP(THUMB_INSTR(instr
)) || IS_THUMB32_IS_ENABLED(THUMB_INSTR(instr
))) {
178 /* Shouldn't reach here - this means we don't recognize
179 * the instruction at one of the USDT probe locations
183 tp
->ftt_fntype
= FASTTRAP_FN_DONE_INIT
;
186 case FASTTRAP_FN_ARM
:
188 tp
->ftt_fntype
= FASTTRAP_FN_DONE_INIT
;
191 case FASTTRAP_FN_THUMB
:
193 tp
->ftt_fntype
= FASTTRAP_FN_DONE_INIT
;
202 tp
->ftt_type
= dtrace_decode_thumb(instr
);
204 tp
->ftt_type
= dtrace_decode_arm(instr
);
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
);
219 fasttrap_tracepoint_init64(proc_t
*p
, fasttrap_tracepoint_t
*tp
,
220 user_addr_t pc
, fasttrap_probe_type_t type
)
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.
234 * APPLE NOTE: Of course, we do not have a P_PR_LOCK, so this is racey...
237 if (uread(p
, &instr
, 4, pc
) != 0)
240 tp
->ftt_instr
= instr
;
241 tp
->ftt_thumb
= 0; /* Always zero on 64bit */
243 if (tp
->ftt_fntype
!= FASTTRAP_FN_DONE_INIT
) {
244 switch(tp
->ftt_fntype
) {
245 case FASTTRAP_FN_UNKNOWN
:
246 case FASTTRAP_FN_ARM64
:
247 case FASTTRAP_FN_ARM64_32
:
249 * On arm64 there is no distinction between
250 * arm vs. thumb mode instruction types.
252 tp
->ftt_fntype
= FASTTRAP_FN_DONE_INIT
;
255 case FASTTRAP_FN_USDT
:
256 if (IS_ARM64_NOP(instr
) || IS_ARM64_IS_ENABLED(instr
)) {
257 tp
->ftt_fntype
= FASTTRAP_FN_DONE_INIT
;
260 * Shouldn't reach here - this means we don't
261 * recognize the instruction at one of the
262 * USDT probe locations
269 case FASTTRAP_FN_ARM
:
270 case FASTTRAP_FN_THUMB
:
273 * If we get an arm or thumb mode type
274 * then we are clearly in the wrong path.
280 tp
->ftt_type
= dtrace_decode_arm64(instr
);
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
;
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
);
298 fasttrap_tracepoint_install(proc_t
*p
, fasttrap_tracepoint_t
*tp
)
300 /* The thumb patch is a 2 byte instruction regardless of the size of the original instruction */
304 if (proc_is64bit_data(p
)) {
306 instr
= FASTTRAP_ARM64_INSTR
;
309 size
= tp
->ftt_thumb
? 2 : 4;
311 *((uint16_t*) &instr
) = FASTTRAP_THUMB32_INSTR
;
313 instr
= FASTTRAP_ARM32_INSTR
;
317 if (uwrite(p
, &instr
, size
, tp
->ftt_pc
) != 0)
320 tp
->ftt_installed
= 1;
326 fasttrap_tracepoint_remove(proc_t
*p
, fasttrap_tracepoint_t
*tp
)
328 /* The thumb patch is a 2 byte instruction regardless of the size of the original instruction */
332 if (proc_is64bit_data(p
)) {
334 * Distinguish between read or write failures and a changed
338 if (uread(p
, &instr
, size
, tp
->ftt_pc
) != 0)
341 if (instr
!= FASTTRAP_ARM64_INSTR
)
345 * Distinguish between read or write failures and a changed
348 size
= tp
->ftt_thumb
? 2 : 4;
349 if (uread(p
, &instr
, size
, tp
->ftt_pc
) != 0)
353 if (*((uint16_t*) &instr
) != FASTTRAP_THUMB32_INSTR
)
356 if (instr
!= FASTTRAP_ARM32_INSTR
)
361 if (uwrite(p
, &tp
->ftt_instr
, size
, tp
->ftt_pc
) != 0)
365 tp
->ftt_installed
= 0;
371 fasttrap_return_common(proc_t
*p
, arm_saved_state_t
*regs
, user_addr_t pc
, user_addr_t new_pc
)
373 pid_t pid
= p
->p_pid
;
374 fasttrap_tracepoint_t
*tp
;
375 fasttrap_bucket_t
*bucket
;
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
)];
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)
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.
395 lck_mtx_unlock(pid_mtx
);
399 for (id
= tp
->ftt_retids
; id
!= NULL
; id
= id
->fti_next
) {
400 fasttrap_probe_t
*probe
= id
->fti_probe
;
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.
406 if (is_saved_state32(regs
))
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
)
414 /* ARM64_TODO - check for FASTTRAP_T_RET */
415 if ((tp
->ftt_type
!= FASTTRAP_T_ARM64_RET
|| tp
->ftt_type
!= FASTTRAP_T_ARM64_RETAB
) &&
416 new_pc
- probe
->ftp_faddr
< probe
->ftp_fsize
)
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
) {
426 * If we have at least one probe associated that
427 * is not a oneshot probe, don't remove the
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
);
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);
447 dtrace_probe(probe
->ftp_id
,
448 pc
- id
->fti_probe
->ftp_faddr
,
449 saved_state64(regs
)->x
[0], 0, 0, 0);
454 fasttrap_tracepoint_retire(p
, tp
);
457 lck_mtx_unlock(pid_mtx
);
461 fasttrap_sigsegv(proc_t
*p
, uthread_t t
, user_addr_t addr
, arm_saved_state_t
*regs
)
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.
467 #pragma unused(p,t,addr,arm_saved_state)
468 panic("fasttrap: sigsegv not yet implemented");
470 #pragma unused(p,t,addr)
471 /* Kill the process */
472 set_saved_state_pc(regs
, 0);
478 /* Set fault address and mark signal */
480 t
->uu_siglist
|= sigmask(SIGSEGV
);
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.
487 t
->uu_exception
= KERN_INVALID_ADDRESS
; /* SIGSEGV */
488 t
->uu_subcode
= 0; /* XXX pad */
493 signal_setast(t
->uu_context
.vc_thread
);
498 fasttrap_usdt_args32(fasttrap_probe_t
*probe
, arm_saved_state32_t
*regs32
, int argc
,
501 int i
, x
, cap
= MIN(argc
, probe
->ftp_nargs
);
503 for (i
= 0; i
< cap
; i
++) {
504 x
= probe
->ftp_argmap
[i
];
506 /* Up to 4 args are passed in registers on arm */
508 argv
[i
] = regs32
->r
[x
];
511 fasttrap_fuword32_noerr(regs32
->sp
+ (x
- 4) * sizeof(uint32_t), &arg
);
517 for (; i
< argc
; i
++) {
523 fasttrap_usdt_args64(fasttrap_probe_t
*probe
, arm_saved_state64_t
*regs64
, int argc
,
526 int i
, x
, cap
= MIN(argc
, probe
->ftp_nargs
);
528 for (i
= 0; i
< cap
; i
++) {
529 x
= probe
->ftp_argmap
[i
];
531 /* Up to 8 args are passed in registers on arm64 */
533 argv
[i
] = regs64
->x
[x
];
535 fasttrap_fuword64_noerr(regs64
->sp
+ (x
- 8) * sizeof(uint64_t), &argv
[i
]);
539 for (; i
< argc
; i
++) {
544 static int condition_true(int cond
, int cpsr
)
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;
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. */
574 static void set_thumb_flag(arm_saved_state32_t
*regs32
, user_addr_t pc
)
577 regs32
->cpsr
|= PSR_TF
;
579 regs32
->cpsr
&= ~PSR_TF
;
584 fasttrap_pid_probe_thumb_state_valid(arm_saved_state32_t
*state32
, fasttrap_tracepoint_t
*tp
)
586 uint32_t cpsr
= state32
->cpsr
;
587 uint32_t itstate
= GETITSTATE(cpsr
);
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
);
596 if (!(cpsr
& PSR_TF
)) {
604 fasttrap_get_condition_code(arm_saved_state32_t
*regs32
, fasttrap_tracepoint_t
*tp
)
606 /* Default to always execute */
607 int condition_code
= 0xE;
609 uint32_t itstate
= GETITSTATE(regs32
->cpsr
);
611 /* In IT block, make sure it's the last statement in the block */
612 assert(ISLASTINIT(itstate
));
613 condition_code
= itstate
>> 4;
616 condition_code
= ARM_CONDCODE(tp
->ftt_instr
);
619 return condition_code
;
623 fasttrap_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
)
626 arm_saved_state32_t
*regs32
= saved_state32(state
);
628 uint32_t pc
= regs32
->pc
;
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.
648 new_pc
= regs32
->pc
+ (tp
->ftt_thumb
? 2 : 4);
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);
659 condition_code
= fasttrap_get_condition_code(regs32
, tp
);
660 instr_size
= dtrace_instr_size(tp
->ftt_instr
,tp
->ftt_thumb
);
662 switch (tp
->ftt_type
) {
663 case FASTTRAP_T_MOV_PC_REG
:
664 case FASTTRAP_T_CPY_PC
:
666 if (!condition_true(condition_code
, regs32
->cpsr
)) {
667 new_pc
= pc
+ instr_size
;
673 rm
= THUMB16_HRM(tp
->ftt_instr1
);
675 rm
= tp
->ftt_instr
& 0xF;
677 new_pc
= regs32
->r
[rm
];
679 /* This instruction does not change the Thumb state */
684 case FASTTRAP_T_STM_LR
:
685 case FASTTRAP_T_PUSH_LR
:
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.
696 * Some of the same issues that apply to POP_PC probably apply here also.
703 if (!condition_true(condition_code
, regs32
->cpsr
)) {
704 new_pc
= pc
+ instr_size
;
709 if (((base
-16*4) >> PAGE_SHIFT
) != (base
>> PAGE_SHIFT
)) {
710 /* Crosses the page boundary, go to emulation */
715 if (instr_size
== 4) {
716 /* We know we have to push lr, never push sp or pc */
717 reglist
= tp
->ftt_instr2
& 0x1FFF;
719 reglist
= tp
->ftt_instr1
& 0xFF;
722 /* We know we have to push lr, never push sp or pc */
723 reglist
= tp
->ftt_instr
& 0x1FFF;
726 /* Push the link register */
728 ret
= fasttrap_suword32(base
, regs32
->lr
);
730 fasttrap_sigsegv(p
, uthread
, (user_addr_t
) base
, state
);
735 /* Start pushing from $r12 */
736 int regmask
= 1 << 12;
740 if (reglist
& regmask
) {
742 ret
= fasttrap_suword32(base
, regs32
->r
[regnum
]);
744 fasttrap_sigsegv(p
, uthread
, (user_addr_t
) base
, state
);
755 new_pc
= pc
+ instr_size
;
761 case FASTTRAP_T_LDM_PC
:
762 case FASTTRAP_T_POP_PC
:
764 /* TODO Two issues that will eventually need to be resolved:
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.
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.
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.
782 /* Assume ldmia! sp/pop ... pc */
784 int regnum
= 0, reglist
;
788 if (!condition_true(condition_code
, regs32
->cpsr
)) {
789 new_pc
= pc
+ instr_size
;
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;
798 reglist
= tp
->ftt_instr1
& 0xFF;
801 /* We know we have to load the pc, don't do it twice */
802 reglist
= tp
->ftt_instr
& 0x7FFF;
808 ret
= fasttrap_fuword32((user_addr_t
)base
, ®s32
->r
[regnum
]);
810 fasttrap_sigsegv(p
, uthread
, (user_addr_t
) base
, state
);
820 ret
= fasttrap_fuword32((user_addr_t
)base
, &new_pc
);
822 fasttrap_sigsegv(p
, uthread
, (user_addr_t
) base
, state
);
830 set_thumb_flag(regs32
, new_pc
);
835 case FASTTRAP_T_CB_N_Z
:
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
;
844 new_pc
= pc
+ instr_size
;
849 case FASTTRAP_T_B_COND
:
851 /* Use the condition code in the instruction and ignore the ITSTATE */
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");
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),
869 code
= (tp
->ftt_instr1
>> 8) & 0xF;
870 if (code
== 14 || code
== 15) {
871 panic("fasttrap: Emulation of invalid branch");
873 offset
= 4 + (SIGNEXTEND(tp
->ftt_instr1
& 0xFF, 8) << 1);
876 code
= ARM_CONDCODE(tp
->ftt_instr
);
878 panic("fasttrap: Emulation of invalid branch");
880 offset
= 8 + (SIGNEXTEND(tp
->ftt_instr
& 0x00FFFFFF, 24) << 2);
883 if (condition_true(code
, regs32
->cpsr
)) {
884 new_pc
= pc
+ offset
;
886 new_pc
= pc
+ instr_size
;
892 case FASTTRAP_T_B_UNCOND
:
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);
900 if (!condition_true(condition_code
, regs32
->cpsr
)) {
901 new_pc
= pc
+ instr_size
;
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),
916 uint32_t instr1
= tp
->ftt_instr1
;
917 offset
= 4 + (SIGNEXTEND(instr1
& 0x7FF, 11) << 1);
920 new_pc
= pc
+ offset
;
925 case FASTTRAP_T_BX_REG
:
929 if (!condition_true(condition_code
, regs32
->cpsr
)) {
930 new_pc
= pc
+ instr_size
;
935 reg
= THUMB16_HRM(tp
->ftt_instr1
);
937 reg
= ARM_RM(tp
->ftt_instr
);
939 new_pc
= regs32
->r
[reg
];
940 set_thumb_flag(regs32
, new_pc
);
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.
955 case FASTTRAP_T_COMMON
:
960 fasttrap_instr_t emul_instr
;
961 emul_instr
.instr32
= tp
->ftt_instr
;
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.
971 uint8_t emul_thumb
= tp
->ftt_thumb
;
973 uint32_t save_val
= 0;
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.
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.
992 /* Check to see if thumb or thumb2 */
993 if (instr_size
== 2) {
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.
1000 if (!condition_true(condition_code
, regs32
->cpsr
)) {
1001 new_pc
= pc
+ instr_size
;
1005 new_reg
= (tp
->ftt_instr1
>> 8) & 0x7;
1006 regs32
->r
[new_reg
] = ALIGNADDR(regs32
->pc
+ 4, 2);
1008 emul_instr
.instr32
= 0xE5900000 | (new_reg
<< 16) | (new_reg
<< 12) | ((tp
->ftt_instr1
& 0xFF) << 2);
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
;
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;
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.
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;
1033 emul_instr
.instr32
&= ~0x000F0000;
1037 emul_instr_size
= dtrace_instr_size(emul_instr
.instr32
, emul_thumb
);
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
1047 addr
= uthread
->t_dtrace_scratch
->addr
;
1050 fasttrap_sigtrap(p
, uthread
, pc
); // Should be killing target proc
1055 uthread
->t_dtrace_scrpc
= addr
;
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.
1064 * Layout of scratch space for Thumb mode:
1065 * Emulated instruction
1066 * ldr save_reg, [pc, #16] (if necessary, restore any register we clobbered)
1071 * Location we should return to in original program
1072 * Saved value of clobbered register (if necessary)
1075 bcopy(&emul_instr
, &scratch
[i
], emul_instr_size
); i
+= emul_instr_size
;
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]
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 }
1089 SET16(scratch
+i
, 0); i
+= 2; // padding - saved 32 bit words must be aligned
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
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;
1101 * Layout of scratch space for ARM mode:
1102 * Emulated instruction
1103 * ldr save_reg, [pc, #12] (if necessary, restore any register we clobbered)
1105 * Location we should return to in original program
1106 * Saved value of clobbered register (if necessary)
1109 bcopy(&emul_instr
, &scratch
[i
], emul_instr_size
); i
+= emul_instr_size
;
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]
1116 SET32(scratch
+i
, 0xE51FF004); i
+= 4; // ldr pc, [pc, #4]
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
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;
1128 if (uwrite(p
, scratch
, i
, uthread
->t_dtrace_scratch
->write_addr
) != KERN_SUCCESS
) {
1129 fasttrap_sigtrap(p
, uthread
, pc
);
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);
1139 new_pc
= uthread
->t_dtrace_scrpc
+ (emul_thumb
? 1 : 0);
1142 uthread
->t_dtrace_pc
= pc
;
1143 uthread
->t_dtrace_npc
= pc
+ instr_size
;
1144 uthread
->t_dtrace_on
= 1;
1146 set_thumb_flag(regs32
, new_pc
);
1151 panic("fasttrap: mishandled an instruction");
1154 set_saved_state_pc(state
, new_pc
);
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
1166 * [ Thunked instruction sequence ]
1167 * [ Trap for return to original code and return probe handling ]
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.
1173 fasttrap_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
)
1176 uint32_t local_scratch
[8];
1177 user_addr_t pc
= get_saved_state_pc(state
);
1178 user_addr_t user_scratch_area
;
1180 assert(num_instrs
< 8);
1182 bcopy(instructions
, local_scratch
, num_instrs
* sizeof(uint32_t));
1183 local_scratch
[num_instrs
] = FASTTRAP_ARM64_RET_INSTR
;
1185 uthread
->t_dtrace_astpc
= uthread
->t_dtrace_scrpc
= uthread
->t_dtrace_scratch
->addr
;
1186 user_scratch_area
= uthread
->t_dtrace_scratch
->write_addr
;
1188 if (user_scratch_area
== (user_addr_t
)0) {
1189 fasttrap_sigtrap(p
, uthread
, pc
); // Should be killing target proc
1194 if (uwrite(p
, local_scratch
, (num_instrs
+ 1) * sizeof(uint32_t), user_scratch_area
) != KERN_SUCCESS
) {
1195 fasttrap_sigtrap(p
, uthread
, pc
);
1200 /* We're stepping (come back to kernel to adjust PC for return to regular code). */
1201 uthread
->t_dtrace_step
= 1;
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
);
1206 assert(tp
->ftt_type
!= FASTTRAP_T_ARM64_RETAB
);
1208 /* Set address of instruction we've patched */
1209 uthread
->t_dtrace_pc
= pc
;
1211 /* Any branch would be emulated, next instruction should be one ahead */
1212 uthread
->t_dtrace_npc
= pc
+ 4;
1214 /* We are certainly handling a probe */
1215 uthread
->t_dtrace_on
= 1;
1217 /* Let's jump to the scratch area */
1218 *pc_out
= uthread
->t_dtrace_scratch
->addr
;
1222 * Sign-extend bit "sign_bit_index" out to bit 64.
1225 sign_extend(int64_t input
, uint32_t sign_bit_index
)
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));
1237 * Handle xzr vs. sp, fp, lr, etc. Will *not* read the SP.
1240 get_saved_state64_regno(arm_saved_state64_t
*regs64
, uint32_t regno
, int use_xzr
)
1242 /* Set PC to register value */
1256 return regs64
->x
[regno
];
1261 set_saved_state64_regno(arm_saved_state64_t
*regs64
, uint32_t regno
, int use_xzr
, register_t value
)
1263 /* Set PC to register value */
1277 regs64
->x
[regno
] = value
;
1283 * Common operation: extract sign-extended PC offset from instruction
1284 * Left-shifts result by two bits.
1287 extract_address_literal_sign_extended(uint32_t instr
, uint32_t base
, uint32_t numbits
)
1291 offset
= (instr
>> base
) & ((1 << numbits
) - 1);
1292 offset
= sign_extend(offset
, numbits
- 1);
1293 offset
= offset
<< 2;
1299 do_cbz_cnbz(arm_saved_state64_t
*regs64
, uint32_t regwidth
, uint32_t instr
, int is_cbz
, user_addr_t
*pc_out
)
1305 /* Extract register */
1306 regno
= (instr
& 0x1f);
1307 assert(regno
<= 31);
1308 regval
= get_saved_state64_regno(regs64
, regno
, 1);
1310 /* Control for size */
1311 if (regwidth
== 32) {
1312 regval
&= 0xFFFFFFFFULL
;
1315 /* Extract offset */
1316 offset
= extract_address_literal_sign_extended(instr
, 5, 19);
1319 if ((is_cbz
&& regval
== 0) || ((!is_cbz
) && regval
!= 0)) {
1320 /* Set PC from label */
1321 *pc_out
= regs64
->pc
+ offset
;
1324 *pc_out
= regs64
->pc
+ 4;
1329 do_tbz_tbnz(arm_saved_state64_t
*regs64
, uint32_t instr
, int is_tbz
, user_addr_t
*pc_out
)
1331 uint64_t offset
, regval
;
1332 uint32_t bit_index
, b5
, b40
, regno
, bit_set
;
1334 /* Compute offset */
1335 offset
= extract_address_literal_sign_extended(instr
, 5, 14);
1337 /* Extract bit index */
1339 b40
= ((instr
>> 19) & 0x1f);
1340 bit_index
= (b5
<< 5) | b40
;
1341 assert(bit_index
<= 63);
1343 /* Extract register */
1344 regno
= (instr
& 0x1f);
1345 assert(regno
<= 31);
1346 regval
= get_saved_state64_regno(regs64
, regno
, 1);
1349 bit_set
= ((regval
& (1 << bit_index
)) != 0);
1351 if ((is_tbz
&& (!bit_set
)) || ((!is_tbz
) && bit_set
)) {
1352 /* Branch: unsigned addition so overflow defined */
1353 *pc_out
= regs64
->pc
+ offset
;
1356 *pc_out
= regs64
->pc
+ 4;
1362 fasttrap_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
)
1366 arm_saved_state64_t
*regs64
= saved_state64(state
);
1367 uint32_t instr
= tp
->ftt_instr
;
1368 user_addr_t new_pc
= 0;
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
);
1373 /* is-enabled probe: set x0 to 1 and step forwards */
1376 set_saved_state_pc(state
, regs64
->pc
+ 4);
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);
1387 /* Only one of many cases in the switch doesn't simulate */
1388 switch(tp
->ftt_type
) {
1390 * Function entry: emulate for speed.
1391 * stp fp, lr, [sp, #-16]!
1393 case FASTTRAP_T_ARM64_STANDARD_FUNCTION_ENTRY
:
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 */
1404 /* Move stack pointer */
1407 /* Move PC forward */
1408 new_pc
= regs64
->pc
+ 4;
1414 * PC-relative loads/stores: emulate for correctness.
1415 * All loads are 32bits or greater (no need to handle byte or halfword accesses).
1423 * PRFM label -> becomes a NOP
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
:
1433 uint32_t valsize
, regno
;
1434 user_addr_t address
;
1441 /* Extract 19-bit offset, add to pc */
1442 offset
= extract_address_literal_sign_extended(instr
, 5, 19);
1443 address
= regs64
->pc
+ offset
;
1445 /* Extract destination register */
1446 regno
= (instr
& 0x1f);
1447 assert(regno
<= 31);
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
:
1456 case FASTTRAP_T_ARM64_LDR_D_PC_REL
:
1457 case FASTTRAP_T_ARM64_LDR_X_PC_REL
:
1460 case FASTTRAP_T_ARM64_LDR_Q_PC_REL
:
1464 panic("Should never get here!");
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() */
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
);
1480 case FASTTRAP_T_ARM64_LDRSW_PC_REL
:
1481 set_saved_state64_regno(regs64
, regno
, 1, sign_extend(value
.val32
, 31));
1483 case FASTTRAP_T_ARM64_LDR_X_PC_REL
:
1484 set_saved_state64_regno(regs64
, regno
, 1, value
.val64
);
1486 case FASTTRAP_T_ARM64_LDR_S_PC_REL
:
1487 ns64
->v
.s
[regno
][0] = value
.val32
;
1489 case FASTTRAP_T_ARM64_LDR_D_PC_REL
:
1490 ns64
->v
.d
[regno
][0] = value
.val64
;
1492 case FASTTRAP_T_ARM64_LDR_Q_PC_REL
:
1493 ns64
->v
.q
[regno
] = value
.val128
;
1496 panic("Should never get here!");
1500 /* Move PC forward */
1501 new_pc
= regs64
->pc
+ 4;
1507 case FASTTRAP_T_ARM64_PRFM
:
1509 /* Becomes a NOP (architecturally permitted). Just move PC forward */
1510 new_pc
= regs64
->pc
+ 4;
1516 * End explicit memory accesses.
1520 * Branches: parse condition codes if needed, emulate for correctness and
1521 * in the case of the indirect branches, convenience
1527 * TBNZ, Xn|Wn, #uimm16, label
1528 * TBZ, Xn|Wn, #uimm16, label
1537 case FASTTRAP_T_ARM64_B_COND
:
1541 /* Extract condition code */
1542 cond
= (instr
& 0xf);
1544 /* Determine if it passes */
1545 if (condition_true(cond
, regs64
->cpsr
)) {
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
;
1553 new_pc
= regs64
->pc
+ 4;
1560 case FASTTRAP_T_ARM64_CBNZ_W
:
1562 do_cbz_cnbz(regs64
, 32, instr
, 0, &new_pc
);
1566 case FASTTRAP_T_ARM64_CBNZ_X
:
1568 do_cbz_cnbz(regs64
, 64, instr
, 0, &new_pc
);
1572 case FASTTRAP_T_ARM64_CBZ_W
:
1574 do_cbz_cnbz(regs64
, 32, instr
, 1, &new_pc
);
1578 case FASTTRAP_T_ARM64_CBZ_X
:
1580 do_cbz_cnbz(regs64
, 64, instr
, 1, &new_pc
);
1585 case FASTTRAP_T_ARM64_TBNZ
:
1587 do_tbz_tbnz(regs64
, instr
, 0, &new_pc
);
1591 case FASTTRAP_T_ARM64_TBZ
:
1593 do_tbz_tbnz(regs64
, instr
, 1, &new_pc
);
1597 case FASTTRAP_T_ARM64_B
:
1598 case FASTTRAP_T_ARM64_BL
:
1602 /* Extract offset from instruction */
1603 offset
= extract_address_literal_sign_extended(instr
, 0, 26);
1605 /* Update LR if appropriate */
1606 if (tp
->ftt_type
== FASTTRAP_T_ARM64_BL
) {
1607 regs64
->lr
= regs64
->pc
+ 4;
1610 /* Compute PC (unsigned addition for defined overflow) */
1611 new_pc
= regs64
->pc
+ offset
;
1616 case FASTTRAP_T_ARM64_BLR
:
1617 case FASTTRAP_T_ARM64_BR
:
1621 /* Extract register from instruction */
1622 regno
= ((instr
>> 5) & 0x1f);
1623 assert(regno
<= 31);
1625 /* Update LR if appropriate */
1626 if (tp
->ftt_type
== FASTTRAP_T_ARM64_BLR
) {
1627 regs64
->lr
= regs64
->pc
+ 4;
1630 /* Update PC in saved state */
1631 new_pc
= get_saved_state64_regno(regs64
, regno
, 1);
1636 case FASTTRAP_T_ARM64_RET
:
1638 /* Extract register */
1639 unsigned regno
= ((instr
>> 5) & 0x1f);
1640 assert(regno
<= 31);
1642 /* Set PC to register value (xzr, not sp) */
1643 new_pc
= get_saved_state64_regno(regs64
, regno
, 1);
1648 case FASTTRAP_T_ARM64_RETAB
:
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
);
1665 * Address calculations: emulate for correctness.
1670 case FASTTRAP_T_ARM64_ADRP
:
1671 case FASTTRAP_T_ARM64_ADR
:
1673 uint64_t immhi
, immlo
, offset
, result
;
1676 /* Extract destination register */
1677 regno
= (instr
& 0x1f);
1678 assert(regno
<= 31);
1680 /* Extract offset */
1681 immhi
= ((instr
& 0x00ffffe0) >> 5); /* bits [23,5]: 19 bits */
1682 immlo
= ((instr
& 0x60000000) >> 29); /* bits [30,29]: 2 bits */
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 */
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 */
1697 set_saved_state64_regno(regs64
, regno
, 1, result
);
1699 /* Move PC forward */
1700 new_pc
= regs64
->pc
+ 4;
1706 * End address calculations.
1710 * Everything else: thunk to userland
1712 case FASTTRAP_T_COMMON
:
1714 fasttrap_pid_probe_thunk_instr64(state
, tp
, p
, uthread
, &tp
->ftt_instr
, 1, &new_pc
);
1720 panic("An instruction DTrace doesn't expect: %d\n", tp
->ftt_type
);
1725 set_saved_state_pc(state
, new_pc
);
1730 fasttrap_pid_probe(arm_saved_state_t
*state
)
1732 proc_t
*p
= current_proc();
1733 fasttrap_bucket_t
*bucket
;
1735 fasttrap_tracepoint_t
*tp
, tp_local
;
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
);
1742 uint64_t pc
= get_saved_state_pc(state
);
1744 assert(is_64_bit
|| (pc
<= UINT32_MAX
));
1746 uthread_t uthread
= (uthread_t
) get_bsdthread_info(current_thread());
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.
1754 if (uthread
->t_dtrace_step
) {
1755 ASSERT(uthread
->t_dtrace_on
);
1756 fasttrap_sigtrap(p
, uthread
, (user_addr_t
)pc
);
1761 * Clear all user tracing flags.
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;
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.
1775 if (p
->p_lflag
& P_LINVFORK
) {
1777 while (p
->p_lflag
& P_LINVFORK
)
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
)];
1788 * Lookup the tracepoint that the process just hit.
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)
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.
1802 lck_mtx_unlock(pid_mtx
);
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
);
1815 /* Execute the actual probe */
1816 if (tp
->ftt_ids
!= NULL
) {
1820 if (is_saved_state64(state
)) {
1821 arg4
= get_saved_state_reg(state
, 4);
1824 user_addr_t stack
= (user_addr_t
)get_saved_state_sp(state
);
1826 fasttrap_fuword32_noerr(stack
, &arg
);
1831 /* First four parameters are passed in registers */
1833 for (id
= tp
->ftt_ids
; id
!= NULL
; id
= id
->fti_next
) {
1834 fasttrap_probe_t
*probe
= id
->fti_probe
;
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
);
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
) {
1851 * If we have at least one probe associated that
1852 * is not a oneshot probe, don't remove the
1858 if (id
->fti_ptype
== DTFTP_ENTRY
) {
1860 * We note that this was an entry
1861 * probe to help ustack() find the
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),
1872 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_ENTRY
);
1873 dtrace_interrupt_enable(cookie
);
1874 } else if (id
->fti_ptype
== DTFTP_IS_ENABLED
) {
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.
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),
1895 fasttrap_usdt_args64(probe
, saved_state64(state
), 5, t
);
1897 fasttrap_usdt_args32(probe
, saved_state32(state
), 5, t
);
1899 dtrace_probe(probe
->ftp_id
, t
[0], t
[1], t
[2], t
[3], t
[4]);
1904 fasttrap_tracepoint_retire(p
, tp
);
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.
1913 lck_mtx_unlock(pid_mtx
);
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.
1926 fasttrap_pid_probe_handle_patched_instr64(state
, tp
, uthread
, p
, is_enabled
, &was_simulated
);
1928 fasttrap_pid_probe_handle_patched_instr32(state
, tp
, uthread
, p
, is_enabled
, &was_simulated
);
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
1937 if (tp
->ftt_retids
!= NULL
) {
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.
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.
1951 if (was_simulated
) {
1952 fasttrap_return_common(p
, state
, (user_addr_t
)pc
, (user_addr_t
)get_saved_state_pc(state
));
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
);
1965 fasttrap_return_probe(arm_saved_state_t
*regs
)
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
;
1972 uthread
->t_dtrace_pc
= 0;
1973 uthread
->t_dtrace_npc
= 0;
1974 uthread
->t_dtrace_scrpc
= 0;
1975 uthread
->t_dtrace_astpc
= 0;
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.
1982 if (p
->p_lflag
& P_LINVFORK
) {
1984 while (p
->p_lflag
& P_LINVFORK
)
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.
1996 set_saved_state_pc(regs
, pc
);
1998 fasttrap_return_common(p
, regs
, pc
, npc
);
2004 fasttrap_pid_getarg(void *arg
, dtrace_id_t id
, void *parg
, int argno
,
2007 #pragma unused(arg, id, parg, aframes)
2008 arm_saved_state_t
* regs
= find_user_regs(current_thread());
2010 if (is_saved_state32(regs
)) {
2011 /* First four arguments are in registers */
2013 return saved_state32(regs
)->r
[argno
];
2015 /* Look on the stack for the rest */
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
);
2025 /* First eight arguments are in registers */
2027 return saved_state64(regs
)->x
[argno
];
2029 /* Look on the stack for the rest */
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
);
2042 fasttrap_usdt_getarg(void *arg
, dtrace_id_t id
, void *parg
, int argno
, int aframes
)
2044 #pragma unused(arg, id, parg, argno, aframes)
2046 return (fasttrap_anarg(ttolwp(curthread
)->lwp_regs
, 0, argno
));