Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/dev/dtrace/aarch64/dtrace_isa.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
uint64_t dtrace_fuword64_nocheck(void *); | uint64_t dtrace_fuword64_nocheck(void *); | ||||
void | void | ||||
dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, | dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, | ||||
uint32_t *intrpc) | uint32_t *intrpc) | ||||
{ | { | ||||
struct unwind_state state; | struct unwind_state state; | ||||
int scp_offset; | int scp_offset; | ||||
register_t sp; | |||||
int depth; | int depth; | ||||
depth = 0; | depth = 0; | ||||
if (intrpc != 0) { | if (intrpc != 0) { | ||||
pcstack[depth++] = (pc_t) intrpc; | pcstack[depth++] = (pc_t) intrpc; | ||||
} | } | ||||
aframes++; | aframes++; | ||||
__asm __volatile("mov %0, sp" : "=&r" (sp)); | |||||
state.fp = (uintptr_t)__builtin_frame_address(0); | state.fp = (uintptr_t)__builtin_frame_address(0); | ||||
state.sp = sp; | |||||
state.pc = (uintptr_t)dtrace_getpcstack; | state.pc = (uintptr_t)dtrace_getpcstack; | ||||
while (depth < pcstack_limit) { | while (depth < pcstack_limit) { | ||||
if (!unwind_frame(curthread, &state)) | if (!unwind_frame(curthread, &state)) | ||||
break; | break; | ||||
if (!INKERNEL(state.pc)) | if (!INKERNEL(state.pc)) | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, | ||||
return (ret); | return (ret); | ||||
} | } | ||||
void | void | ||||
dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) | dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) | ||||
{ | { | ||||
proc_t *p = curproc; | proc_t *p = curproc; | ||||
struct trapframe *tf; | struct trapframe *tf; | ||||
uintptr_t pc, sp, fp; | uintptr_t pc, fp; | ||||
volatile uint16_t *flags = | volatile uint16_t *flags = | ||||
(volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; | (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; | ||||
int n; | int n; | ||||
if (*flags & CPU_DTRACE_FAULT) | if (*flags & CPU_DTRACE_FAULT) | ||||
return; | return; | ||||
if (pcstack_limit <= 0) | if (pcstack_limit <= 0) | ||||
return; | return; | ||||
/* | /* | ||||
* If there's no user context we still need to zero the stack. | * If there's no user context we still need to zero the stack. | ||||
*/ | */ | ||||
if (p == NULL || (tf = curthread->td_frame) == NULL) | if (p == NULL || (tf = curthread->td_frame) == NULL) | ||||
goto zero; | goto zero; | ||||
*pcstack++ = (uint64_t)p->p_pid; | *pcstack++ = (uint64_t)p->p_pid; | ||||
pcstack_limit--; | pcstack_limit--; | ||||
if (pcstack_limit <= 0) | if (pcstack_limit <= 0) | ||||
return; | return; | ||||
pc = tf->tf_elr; | pc = tf->tf_elr; | ||||
sp = tf->tf_sp; | |||||
fp = tf->tf_x[29]; | fp = tf->tf_x[29]; | ||||
if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { | if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { | ||||
/* | /* | ||||
* In an entry probe. The frame pointer has not yet been | * In an entry probe. The frame pointer has not yet been | ||||
* pushed (that happens in the function prologue). The | * pushed (that happens in the function prologue). The | ||||
* best approach is to add the current pc as a missing top | * best approach is to add the current pc as a missing top | ||||
* of stack and back the pc up to the caller, which is stored | * of stack and back the pc up to the caller, which is stored | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | dtrace_getarg(int arg, int aframes) | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
dtrace_getstackdepth(int aframes) | dtrace_getstackdepth(int aframes) | ||||
{ | { | ||||
struct unwind_state state; | struct unwind_state state; | ||||
int scp_offset; | int scp_offset; | ||||
register_t sp; | |||||
int depth; | int depth; | ||||
bool done; | bool done; | ||||
depth = 1; | depth = 1; | ||||
done = false; | done = false; | ||||
__asm __volatile("mov %0, sp" : "=&r" (sp)); | |||||
state.fp = (uintptr_t)__builtin_frame_address(0); | state.fp = (uintptr_t)__builtin_frame_address(0); | ||||
state.sp = sp; | |||||
state.pc = (uintptr_t)dtrace_getstackdepth; | state.pc = (uintptr_t)dtrace_getstackdepth; | ||||
do { | do { | ||||
done = !unwind_frame(curthread, &state); | done = !unwind_frame(curthread, &state); | ||||
if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) | if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) | ||||
break; | break; | ||||
depth++; | depth++; | ||||
} while (!done); | } while (!done); | ||||
▲ Show 20 Lines • Show All 116 Lines • Show Last 20 Lines |