1#ifndef __X86_KERNEL_KPROBES_COMMON_H
2#define __X86_KERNEL_KPROBES_COMMON_H
3
4/* Kprobes and Optprobes common header */
5
6#ifdef CONFIG_X86_64
7#define SAVE_REGS_STRING			\
8	/* Skip cs, ip, orig_ax. */		\
9	"	subq $24, %rsp\n"		\
10	"	pushq %rdi\n"			\
11	"	pushq %rsi\n"			\
12	"	pushq %rdx\n"			\
13	"	pushq %rcx\n"			\
14	"	pushq %rax\n"			\
15	"	pushq %r8\n"			\
16	"	pushq %r9\n"			\
17	"	pushq %r10\n"			\
18	"	pushq %r11\n"			\
19	"	pushq %rbx\n"			\
20	"	pushq %rbp\n"			\
21	"	pushq %r12\n"			\
22	"	pushq %r13\n"			\
23	"	pushq %r14\n"			\
24	"	pushq %r15\n"
25#define RESTORE_REGS_STRING			\
26	"	popq %r15\n"			\
27	"	popq %r14\n"			\
28	"	popq %r13\n"			\
29	"	popq %r12\n"			\
30	"	popq %rbp\n"			\
31	"	popq %rbx\n"			\
32	"	popq %r11\n"			\
33	"	popq %r10\n"			\
34	"	popq %r9\n"			\
35	"	popq %r8\n"			\
36	"	popq %rax\n"			\
37	"	popq %rcx\n"			\
38	"	popq %rdx\n"			\
39	"	popq %rsi\n"			\
40	"	popq %rdi\n"			\
41	/* Skip orig_ax, ip, cs */		\
42	"	addq $24, %rsp\n"
43#else
44#define SAVE_REGS_STRING			\
45	/* Skip cs, ip, orig_ax and gs. */	\
46	"	subl $16, %esp\n"		\
47	"	pushl %fs\n"			\
48	"	pushl %es\n"			\
49	"	pushl %ds\n"			\
50	"	pushl %eax\n"			\
51	"	pushl %ebp\n"			\
52	"	pushl %edi\n"			\
53	"	pushl %esi\n"			\
54	"	pushl %edx\n"			\
55	"	pushl %ecx\n"			\
56	"	pushl %ebx\n"
57#define RESTORE_REGS_STRING			\
58	"	popl %ebx\n"			\
59	"	popl %ecx\n"			\
60	"	popl %edx\n"			\
61	"	popl %esi\n"			\
62	"	popl %edi\n"			\
63	"	popl %ebp\n"			\
64	"	popl %eax\n"			\
65	/* Skip ds, es, fs, gs, orig_ax, and ip. Note: don't pop cs here*/\
66	"	addl $24, %esp\n"
67#endif
68
69/* Ensure if the instruction can be boostable */
70extern int can_boost(kprobe_opcode_t *instruction);
71/* Recover instruction if given address is probed */
72extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
73					 unsigned long addr);
74/*
75 * Copy an instruction and adjust the displacement if the instruction
76 * uses the %rip-relative addressing mode.
77 */
78extern int __copy_instruction(u8 *dest, u8 *src);
79
80/* Generate a relative-jump/call instruction */
81extern void synthesize_reljump(void *from, void *to);
82extern void synthesize_relcall(void *from, void *to);
83
84#ifdef	CONFIG_OPTPROBES
85extern int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter);
86extern unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr);
87#else	/* !CONFIG_OPTPROBES */
88static inline int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter)
89{
90	return 0;
91}
92static inline unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr)
93{
94	return addr;
95}
96#endif
97
98#ifdef CONFIG_KPROBES_ON_FTRACE
99extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
100			   struct kprobe_ctlblk *kcb);
101#else
102static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
103				  struct kprobe_ctlblk *kcb)
104{
105	return 0;
106}
107#endif
108#endif
109