|
@@ -554,6 +554,69 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+#define SAVE_REGS_STRING \
|
|
|
+ /* Skip cs, ip, orig_ax. */ \
|
|
|
+ " subq $24, %rsp\n" \
|
|
|
+ " pushq %rdi\n" \
|
|
|
+ " pushq %rsi\n" \
|
|
|
+ " pushq %rdx\n" \
|
|
|
+ " pushq %rcx\n" \
|
|
|
+ " pushq %rax\n" \
|
|
|
+ " pushq %r8\n" \
|
|
|
+ " pushq %r9\n" \
|
|
|
+ " pushq %r10\n" \
|
|
|
+ " pushq %r11\n" \
|
|
|
+ " pushq %rbx\n" \
|
|
|
+ " pushq %rbp\n" \
|
|
|
+ " pushq %r12\n" \
|
|
|
+ " pushq %r13\n" \
|
|
|
+ " pushq %r14\n" \
|
|
|
+ " pushq %r15\n"
|
|
|
+#define RESTORE_REGS_STRING \
|
|
|
+ " popq %r15\n" \
|
|
|
+ " popq %r14\n" \
|
|
|
+ " popq %r13\n" \
|
|
|
+ " popq %r12\n" \
|
|
|
+ " popq %rbp\n" \
|
|
|
+ " popq %rbx\n" \
|
|
|
+ " popq %r11\n" \
|
|
|
+ " popq %r10\n" \
|
|
|
+ " popq %r9\n" \
|
|
|
+ " popq %r8\n" \
|
|
|
+ " popq %rax\n" \
|
|
|
+ " popq %rcx\n" \
|
|
|
+ " popq %rdx\n" \
|
|
|
+ " popq %rsi\n" \
|
|
|
+ " popq %rdi\n" \
|
|
|
+ /* Skip orig_ax, ip, cs */ \
|
|
|
+ " addq $24, %rsp\n"
|
|
|
+#else
|
|
|
+#define SAVE_REGS_STRING \
|
|
|
+ /* Skip cs, ip, orig_ax and gs. */ \
|
|
|
+ " subl $16, %esp\n" \
|
|
|
+ " pushl %fs\n" \
|
|
|
+ " pushl %ds\n" \
|
|
|
+ " pushl %es\n" \
|
|
|
+ " pushl %eax\n" \
|
|
|
+ " pushl %ebp\n" \
|
|
|
+ " pushl %edi\n" \
|
|
|
+ " pushl %esi\n" \
|
|
|
+ " pushl %edx\n" \
|
|
|
+ " pushl %ecx\n" \
|
|
|
+ " pushl %ebx\n"
|
|
|
+#define RESTORE_REGS_STRING \
|
|
|
+ " popl %ebx\n" \
|
|
|
+ " popl %ecx\n" \
|
|
|
+ " popl %edx\n" \
|
|
|
+ " popl %esi\n" \
|
|
|
+ " popl %edi\n" \
|
|
|
+ " popl %ebp\n" \
|
|
|
+ " popl %eax\n" \
|
|
|
+ /* Skip ds, es, fs, gs, orig_ax, and ip. Note: don't pop cs here*/\
|
|
|
+ " addl $24, %esp\n"
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* When a retprobed function returns, this code saves registers and
|
|
|
* calls trampoline_handler() runs, which calls the kretprobe's handler.
|
|
@@ -567,65 +630,16 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
|
|
|
/* We don't bother saving the ss register */
|
|
|
" pushq %rsp\n"
|
|
|
" pushfq\n"
|
|
|
- /*
|
|
|
- * Skip cs, ip, orig_ax.
|
|
|
- * trampoline_handler() will plug in these values
|
|
|
- */
|
|
|
- " subq $24, %rsp\n"
|
|
|
- " pushq %rdi\n"
|
|
|
- " pushq %rsi\n"
|
|
|
- " pushq %rdx\n"
|
|
|
- " pushq %rcx\n"
|
|
|
- " pushq %rax\n"
|
|
|
- " pushq %r8\n"
|
|
|
- " pushq %r9\n"
|
|
|
- " pushq %r10\n"
|
|
|
- " pushq %r11\n"
|
|
|
- " pushq %rbx\n"
|
|
|
- " pushq %rbp\n"
|
|
|
- " pushq %r12\n"
|
|
|
- " pushq %r13\n"
|
|
|
- " pushq %r14\n"
|
|
|
- " pushq %r15\n"
|
|
|
+ SAVE_REGS_STRING
|
|
|
" movq %rsp, %rdi\n"
|
|
|
" call trampoline_handler\n"
|
|
|
/* Replace saved sp with true return address. */
|
|
|
" movq %rax, 152(%rsp)\n"
|
|
|
- " popq %r15\n"
|
|
|
- " popq %r14\n"
|
|
|
- " popq %r13\n"
|
|
|
- " popq %r12\n"
|
|
|
- " popq %rbp\n"
|
|
|
- " popq %rbx\n"
|
|
|
- " popq %r11\n"
|
|
|
- " popq %r10\n"
|
|
|
- " popq %r9\n"
|
|
|
- " popq %r8\n"
|
|
|
- " popq %rax\n"
|
|
|
- " popq %rcx\n"
|
|
|
- " popq %rdx\n"
|
|
|
- " popq %rsi\n"
|
|
|
- " popq %rdi\n"
|
|
|
- /* Skip orig_ax, ip, cs */
|
|
|
- " addq $24, %rsp\n"
|
|
|
+ RESTORE_REGS_STRING
|
|
|
" popfq\n"
|
|
|
#else
|
|
|
" pushf\n"
|
|
|
- /*
|
|
|
- * Skip cs, ip, orig_ax and gs.
|
|
|
- * trampoline_handler() will plug in these values
|
|
|
- */
|
|
|
- " subl $16, %esp\n"
|
|
|
- " pushl %fs\n"
|
|
|
- " pushl %es\n"
|
|
|
- " pushl %ds\n"
|
|
|
- " pushl %eax\n"
|
|
|
- " pushl %ebp\n"
|
|
|
- " pushl %edi\n"
|
|
|
- " pushl %esi\n"
|
|
|
- " pushl %edx\n"
|
|
|
- " pushl %ecx\n"
|
|
|
- " pushl %ebx\n"
|
|
|
+ SAVE_REGS_STRING
|
|
|
" movl %esp, %eax\n"
|
|
|
" call trampoline_handler\n"
|
|
|
/* Move flags to cs */
|
|
@@ -633,15 +647,7 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
|
|
|
" movl %edx, 52(%esp)\n"
|
|
|
/* Replace saved flags with true return address. */
|
|
|
" movl %eax, 56(%esp)\n"
|
|
|
- " popl %ebx\n"
|
|
|
- " popl %ecx\n"
|
|
|
- " popl %edx\n"
|
|
|
- " popl %esi\n"
|
|
|
- " popl %edi\n"
|
|
|
- " popl %ebp\n"
|
|
|
- " popl %eax\n"
|
|
|
- /* Skip ds, es, fs, gs, orig_ax and ip */
|
|
|
- " addl $24, %esp\n"
|
|
|
+ RESTORE_REGS_STRING
|
|
|
" popf\n"
|
|
|
#endif
|
|
|
" ret\n");
|