1 #ifndef _SRC_ASM_X86_KPROBES_H
2 #define _SRC_ASM_X86_KPROBES_H
5 * Kernel Probes (KProbes)
6 * include/linux/kprobes.h
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Copyright (C) IBM Corporation, 2002, 2004
26 * Dynamic Binary Instrumentation Module based on KProbes
27 * modules/kprobe/arch/asm-x86/dbi_kprobes.c
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43 * Copyright (C) Samsung Electronics, 2006-2010
45 * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
46 * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
47 * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
52 #include <linux/version.h>
53 #include <dbi_kprobes_deps.h>
55 typedef u8 kprobe_opcode_t;
57 #define BREAKPOINT_INSTRUCTION 0xcc
58 #define RELATIVEJUMP_INSTRUCTION 0xe9
60 #define MAX_INSN_SIZE 16
61 #define MAX_STACK_SIZE 64
63 #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \
64 (((unsigned long)current_thread_info()) \
65 + THREAD_SIZE - (ADDR))) \
67 : (((unsigned long)current_thread_info()) \
68 + THREAD_SIZE - (ADDR)))
70 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
72 #define EREG(rg) e##rg
73 #define XREG(rg) x##rg
74 #define ORIG_EAX_REG orig_eax
80 #define ORIG_EAX_REG orig_ax
82 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
84 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
85 #define TF_MASK X86_EFLAGS_TF
86 #define IF_MASK X86_EFLAGS_IF
88 #define UPROBES_TRAMP_LEN (MAX_INSN_SIZE+sizeof(kprobe_opcode_t))
89 #define UPROBES_TRAMP_INSN_IDX 0
90 #define UPROBES_TRAMP_RET_BREAK_IDX MAX_INSN_SIZE
91 #define KPROBES_TRAMP_LEN MAX_INSN_SIZE
92 #define KPROBES_TRAMP_INSN_IDX 0
94 static inline unsigned long *arch_get_patch_addr(struct task_struct *p,
97 return (unsigned long *)kernel_stack_pointer(regs);
100 static inline unsigned long arch_get_task_pc(struct task_struct *p)
102 /* FIXME: Not implemented yet */
106 static inline void arch_set_task_pc(struct task_struct *p, unsigned long val)
108 /* FIXME: Not implemented yet */
111 static inline struct pt_regs *dbi_get_syscall_uregs(unsigned long sp)
113 return NULL; //FIXME currently not implemented for x86
116 static inline unsigned long dbi_get_stack_ptr(struct pt_regs *regs)
118 return regs->EREG(sp);
121 static inline unsigned long dbi_get_instr_ptr(struct pt_regs *regs)
123 return regs->EREG(ip);
126 static inline void dbi_set_instr_ptr(struct pt_regs *regs, unsigned long val)
128 regs->EREG(ip) = val;
131 static inline unsigned long dbi_get_ret_addr(struct pt_regs *regs)
133 unsigned long addr = 0;
134 read_proc_vm_atomic(current, regs->EREG(sp), &addr, sizeof(addr));
138 static inline void dbi_set_ret_addr(struct pt_regs *regs, unsigned long val)
140 write_proc_vm_atomic(current, regs->EREG(sp), &val, sizeof(val));
143 static inline unsigned long dbi_get_arg(struct pt_regs *regs, int num)
145 unsigned long arg = 0;
146 read_proc_vm_atomic(current, regs->EREG(sp) + (1 + num) * 4,
151 static inline void dbi_set_arg(struct pt_regs *regs, int num, unsigned long val)
153 write_proc_vm_atomic(current, regs->EREG(sp) + (1 + num) * 4,
157 static inline int dbi_fp_backtrace(struct task_struct *task, unsigned long *buf,
161 struct pt_regs *regs;
169 regs = task_pt_regs(task);
170 frame.next = regs->EREG(bp);
171 frame.raddr = dbi_get_ret_addr(regs);
173 while (frame.next && i < max_cnt) {
174 if (read_proc_vm_atomic(task, frame.next, &frame, sizeof(frame))
176 buf[i++] = frame.raddr;
184 extern int kprobe_exceptions_notify (struct notifier_block *self, unsigned long val, void *data);
188 unsigned long status;
191 /* per-cpu kprobe control block */
192 struct kprobe_ctlblk {
193 unsigned long kprobe_status;
194 struct prev_kprobe prev_kprobe;
195 struct pt_regs jprobe_saved_regs;
196 unsigned long kprobe_old_eflags;
197 unsigned long kprobe_saved_eflags;
198 unsigned long *jprobe_saved_esp;
199 kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
203 int kprobe_fault_handler (struct pt_regs *regs, int trapnr);
205 /* Architecture specific copy of original instruction */
206 struct arch_specific_insn {
207 /* copy of the original instruction */
208 kprobe_opcode_t *insn;
210 * If this flag is not 0, this kprobe can be boost when its
211 * post_handler and break_handler is not set.
216 typedef kprobe_opcode_t (*entry_point_t) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
218 int arch_init_module_deps(void);
221 struct kretprobe_instance;
223 int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm);
224 void arch_arm_kprobe(struct kprobe *p);
225 void arch_disarm_kprobe(struct kprobe *p);
226 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs);
227 void kretprobe_trampoline(void);
229 void restore_previous_kprobe(struct kprobe_ctlblk *kcb);
230 int can_boost(kprobe_opcode_t *opcodes);
231 static inline int arch_check_insn(struct arch_specific_insn *ainsn)
236 int arch_init_kprobes(void);
237 void arch_exit_kprobes(void);
239 #endif /* _SRC_ASM_X86_KPROBES_H */