summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorJasper Lievisse Adriaanse <jasper@cvs.openbsd.org>2021-09-03 16:45:46 +0000
committerJasper Lievisse Adriaanse <jasper@cvs.openbsd.org>2021-09-03 16:45:46 +0000
commitfce04b0e80489062d30507672c4c064fbab3538c (patch)
treed6f516ec863b671ee396c63daaaae1bfcfff5a8a /sys/arch/i386
parent562bd13c16f2bafe89c42489d0ec06b2b02c5e32 (diff)
add kprobes provider for dt
this allows us to dynamically trace function boundaries with btrace by patching prologues and epilogues with a breakpoint upon which the handler records the data, sends it back to userland for btrace to consume. currently it's hidden behind DDBPROF, and there is still a lot to cleanup and improve, but basic scripts that observe return codes from a probed function work. from Tom Rollet, with various changes by me feedback and ok mpi@
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/locore.s60
1 files changed, 49 insertions, 11 deletions
diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s
index c51416aacd8..c7c04dc8c7b 100644
--- a/sys/arch/i386/i386/locore.s
+++ b/sys/arch/i386/i386/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.192 2021/09/02 12:32:22 jasper Exp $ */
+/* $OpenBSD: locore.s,v 1.193 2021/09/03 16:45:44 jasper Exp $ */
/* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */
/*-
@@ -205,7 +205,8 @@ INTRENTRY_LABEL(label): /* from kernel */ ; \
#define INTRFASTEXIT \
jmp intr_fast_exit
-#define INTR_FAKE_TRAP 0xbadabada
+#define INTR_FAKE_TRAP_PUSH_RPB 0xbadabada
+#define INTR_FAKE_TRAP_POP_RBP 0xbcbcbcbc
/*
* PTmap is recursive pagemap at top of virtual address space.
@@ -1259,17 +1260,32 @@ calltrap:
jne .Lreal_trap
pushl %esp
- call _C_LABEL(db_prof_hook)
- addl $4,%esp
- cmpl $1,%eax
- jne .Lreal_trap
+ subl $4, %esp
+ pushl %eax
+ leal _C_LABEL(dt_prov_kprobe), %eax
+ movl %eax, 4(%esp)
+ popl %eax
+ call _C_LABEL(dt_prov_kprobe_hook)
+ addl $8, %esp
+ cmpl $0, %eax
+ je .Lreal_trap
/*
* Abuse the error field to indicate that INTRFASTEXIT needs
* to emulate the patched instruction.
*/
- movl $INTR_FAKE_TRAP, TF_ERR(%esp)
- jz .Lalltraps_check_asts
+ cmpl $1, %eax
+ je .Lset_emulate_push_rbp
+
+ cmpl $2, %eax
+ je .Lset_emulate_ret
+
+.Lset_emulate_push_rbp:
+ movl $INTR_FAKE_TRAP_PUSH_RPB, TF_ERR(%esp)
+ jmp .Lalltraps_check_asts
+.Lset_emulate_ret:
+ movl $INTR_FAKE_TRAP_POP_RBP, TF_ERR(%esp)
+ jmp .Lalltraps_check_asts
.Lreal_trap:
#endif /* !defined(GPROF) && defined(DDBPROF) */
pushl %esp
@@ -1298,8 +1314,10 @@ calltrap:
* The code below does that by trashing %eax, so it MUST be
* restored afterward.
*/
- cmpl $INTR_FAKE_TRAP, TF_ERR(%esp)
- je .Lprobe_fixup
+ cmpl $INTR_FAKE_TRAP_PUSH_RPB, TF_ERR(%esp)
+ je .Lprobe_fixup_push_rbp
+ cmpl $INTR_FAKE_TRAP_POP_RBP, TF_ERR(%esp)
+ je .Lprobe_fixup_pop_rbp
#endif /* !defined(GPROF) && defined(DDBPROF) */
#ifndef DIAGNOSTIC
INTRFASTEXIT
@@ -1327,7 +1345,7 @@ spl_lowered:
.text
#if !defined(GPROF) && defined(DDBPROF)
-.Lprobe_fixup:
+.Lprobe_fixup_push_rbp:
/* Restore all register unwinding the stack. */
INTR_RESTORE_ALL
@@ -1352,6 +1370,26 @@ spl_lowered:
popl %eax
iret
+.Lprobe_fixup_pop_rbp:
+ /* Restore all register unwinding the stack. */
+ INTR_RESTORE_ALL
+
+ movl %eax, 0(%esp)
+
+ /* pop %ebp */
+ movl 20(%esp), %ebp
+ /* Shift hardware-saved registers: eflags, cs, eip */
+ movl 16(%esp), %eax
+ movl %eax, 20(%esp)
+ movl 12(%esp), %eax
+ movl %eax, 16(%esp)
+ movl 8(%esp), %eax
+ movl %eax, 12(%esp)
+
+ /* Pop eax and restore the stack pointer */
+ popl %eax
+ addl $8, %esp
+ iret
#endif /* !defined(GPROF) && defined(DDBPROF) */
.text