aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2010-08-25 09:10:32 +0000
committerRui Paulo <rpaulo@FreeBSD.org>2010-08-25 09:10:32 +0000
commit0bc1991a4a4d6186660fe09643d6bc486b70eeb6 (patch)
tree108e830df7eba3ce75f71cbb6e2a32c2d60ebb96
parent5cdefefaed82497ada795db6af8ae2bcf0137c94 (diff)
downloadsrc-0bc1991a4a4d6186660fe09643d6bc486b70eeb6.tar.gz
src-0bc1991a4a4d6186660fe09643d6bc486b70eeb6.zip
Call the necessary DTrace function pointers when we have different kinds
of traps. Sponsored by: The FreeBSD Foundation
Notes
Notes: svn path=/head/; revision=211804
-rw-r--r--sys/amd64/amd64/trap.c56
-rw-r--r--sys/i386/i386/trap.c35
2 files changed, 91 insertions, 0 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index f38dbf969e3b..69e94d95f903 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -109,6 +109,13 @@ dtrace_doubletrap_func_t dtrace_doubletrap_func;
* implementation opaque.
*/
systrace_probe_func_t systrace_probe_func;
+
+/*
+ * These hooks are necessary for the pid, usdt and fasttrap providers.
+ */
+dtrace_fasttrap_probe_ptr_t dtrace_fasttrap_probe_ptr;
+dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr;
+dtrace_return_probe_ptr_t dtrace_return_probe_ptr;
#endif
extern void trap(struct trapframe *frame);
@@ -239,6 +246,55 @@ trap(struct trapframe *frame)
if (dtrace_trap_func != NULL)
if ((*dtrace_trap_func)(frame, type))
goto out;
+ if (type == T_DTRACE_PROBE || type == T_DTRACE_RET ||
+ type == T_BPTFLT) {
+ struct reg regs;
+
+ regs.r_r15 = frame->tf_r15;
+ regs.r_r14 = frame->tf_r14;
+ regs.r_r13 = frame->tf_r13;
+ regs.r_r12 = frame->tf_r12;
+ regs.r_r11 = frame->tf_r11;
+ regs.r_r10 = frame->tf_r10;
+ regs.r_r9 = frame->tf_r9;
+ regs.r_r8 = frame->tf_r8;
+ regs.r_rdi = frame->tf_rdi;
+ regs.r_rsi = frame->tf_rsi;
+ regs.r_rbp = frame->tf_rbp;
+ regs.r_rbx = frame->tf_rbx;
+ regs.r_rdx = frame->tf_rdx;
+ regs.r_rcx = frame->tf_rcx;
+ regs.r_rax = frame->tf_rax;
+ regs.r_rip = frame->tf_rip;
+ regs.r_cs = frame->tf_cs;
+ regs.r_rflags = frame->tf_rflags;
+ regs.r_rsp = frame->tf_rsp;
+ regs.r_ss = frame->tf_ss;
+ if (frame->tf_flags & TF_HASSEGS) {
+ regs.r_ds = frame->tf_ds;
+ regs.r_es = frame->tf_es;
+ regs.r_fs = frame->tf_fs;
+ regs.r_gs = frame->tf_gs;
+ } else {
+ regs.r_ds = 0;
+ regs.r_es = 0;
+ regs.r_fs = 0;
+ regs.r_gs = 0;
+ }
+ if (type == T_DTRACE_PROBE &&
+ dtrace_fasttrap_probe_ptr != NULL &&
+ dtrace_fasttrap_probe_ptr(&regs) == 0)
+ goto out;
+ if (type == T_BPTFLT &&
+ dtrace_pid_probe_ptr != NULL &&
+ dtrace_pid_probe_ptr(&regs) == 0)
+ goto out;
+ if (type == T_DTRACE_RET &&
+ dtrace_return_probe_ptr != NULL &&
+ dtrace_return_probe_ptr(&regs) == 0)
+ goto out;
+
+ }
#endif
if ((frame->tf_rflags & PSL_I) == 0) {
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 561ce68fe0d1..9c580f74ac08 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -118,6 +118,9 @@ dtrace_doubletrap_func_t dtrace_doubletrap_func;
* implementation opaque.
*/
systrace_probe_func_t systrace_probe_func;
+
+dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr;
+dtrace_return_probe_ptr_t dtrace_return_probe_ptr;
#endif
extern void trap(struct trapframe *frame);
@@ -260,6 +263,38 @@ trap(struct trapframe *frame)
dtrace_trap_func != NULL)
if ((*dtrace_trap_func)(frame, type))
goto out;
+ if (type == T_DTRACE_PROBE || type == T_DTRACE_RET ||
+ type == T_BPTFLT) {
+ struct reg regs;
+
+ regs.r_fs = frame->tf_fs;
+ regs.r_es = frame->tf_es;
+ regs.r_ds = frame->tf_ds;
+ regs.r_edi = frame->tf_edi;
+ regs.r_esi = frame->tf_esi;
+ regs.r_ebp = frame->tf_ebp;
+ regs.r_ebx = frame->tf_ebx;
+ regs.r_edx = frame->tf_edx;
+ regs.r_ecx = frame->tf_ecx;
+ regs.r_eax = frame->tf_eax;
+ regs.r_eip = frame->tf_eip;
+ regs.r_cs = frame->tf_cs;
+ regs.r_eflags = frame->tf_eflags;
+ regs.r_esp = frame->tf_esp;
+ regs.r_ss = frame->tf_ss;
+ if (type == T_DTRACE_PROBE &&
+ dtrace_fasttrap_probe_ptr != NULL &&
+ dtrace_fasttrap_probe_ptr(&regs) == 0)
+ goto out;
+ if (type == T_BPTFLT &&
+ dtrace_pid_probe_ptr != NULL &&
+ dtrace_pid_probe_ptr(&regs) == 0)
+ goto out;
+ if (type == T_DTRACE_RET &&
+ dtrace_return_probe_ptr != NULL &&
+ dtrace_return_probe_ptr(&regs) == 0)
+ goto out;
+ }
#endif
if ((frame->tf_eflags & PSL_I) == 0) {