Root/
1 | #ifndef _LINUX_KPROBES_H |
2 | #define _LINUX_KPROBES_H |
3 | /* |
4 | * Kernel Probes (KProbes) |
5 | * include/linux/kprobes.h |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. |
11 | * |
12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
20 | * |
21 | * Copyright (C) IBM Corporation, 2002, 2004 |
22 | * |
23 | * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel |
24 | * Probes initial implementation ( includes suggestions from |
25 | * Rusty Russell). |
26 | * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes |
27 | * interface to access function arguments. |
28 | * 2005-May Hien Nguyen <hien@us.ibm.com> and Jim Keniston |
29 | * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi |
30 | * <prasanna@in.ibm.com> added function-return probes. |
31 | */ |
32 | #include <linux/linkage.h> |
33 | #include <linux/list.h> |
34 | #include <linux/notifier.h> |
35 | #include <linux/smp.h> |
36 | #include <linux/percpu.h> |
37 | #include <linux/spinlock.h> |
38 | #include <linux/rcupdate.h> |
39 | #include <linux/mutex.h> |
40 | |
41 | #ifdef CONFIG_KPROBES |
42 | #include <asm/kprobes.h> |
43 | |
44 | /* kprobe_status settings */ |
45 | #define KPROBE_HIT_ACTIVE 0x00000001 |
46 | #define KPROBE_HIT_SS 0x00000002 |
47 | #define KPROBE_REENTER 0x00000004 |
48 | #define KPROBE_HIT_SSDONE 0x00000008 |
49 | |
50 | /* Attach to insert probes on any functions which should be ignored*/ |
51 | #define __kprobes __attribute__((__section__(".kprobes.text"))) |
52 | #else /* CONFIG_KPROBES */ |
53 | typedef int kprobe_opcode_t; |
54 | struct arch_specific_insn { |
55 | int dummy; |
56 | }; |
57 | #define __kprobes |
58 | #endif /* CONFIG_KPROBES */ |
59 | |
60 | struct kprobe; |
61 | struct pt_regs; |
62 | struct kretprobe; |
63 | struct kretprobe_instance; |
64 | typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *); |
65 | typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *); |
66 | typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *, |
67 | unsigned long flags); |
68 | typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *, |
69 | int trapnr); |
70 | typedef int (*kretprobe_handler_t) (struct kretprobe_instance *, |
71 | struct pt_regs *); |
72 | |
73 | struct kprobe { |
74 | struct hlist_node hlist; |
75 | |
76 | /* list of kprobes for multi-handler support */ |
77 | struct list_head list; |
78 | |
79 | /*count the number of times this probe was temporarily disarmed */ |
80 | unsigned long nmissed; |
81 | |
82 | /* location of the probe point */ |
83 | kprobe_opcode_t *addr; |
84 | |
85 | /* Allow user to indicate symbol name of the probe point */ |
86 | const char *symbol_name; |
87 | |
88 | /* Offset into the symbol */ |
89 | unsigned int offset; |
90 | |
91 | /* Called before addr is executed. */ |
92 | kprobe_pre_handler_t pre_handler; |
93 | |
94 | /* Called after addr is executed, unless... */ |
95 | kprobe_post_handler_t post_handler; |
96 | |
97 | /* |
98 | * ... called if executing addr causes a fault (eg. page fault). |
99 | * Return 1 if it handled fault, otherwise kernel will see it. |
100 | */ |
101 | kprobe_fault_handler_t fault_handler; |
102 | |
103 | /* |
104 | * ... called if breakpoint trap occurs in probe handler. |
105 | * Return 1 if it handled break, otherwise kernel will see it. |
106 | */ |
107 | kprobe_break_handler_t break_handler; |
108 | |
109 | /* Saved opcode (which has been replaced with breakpoint) */ |
110 | kprobe_opcode_t opcode; |
111 | |
112 | /* copy of the original instruction */ |
113 | struct arch_specific_insn ainsn; |
114 | |
115 | /* |
116 | * Indicates various status flags. |
117 | * Protected by kprobe_mutex after this kprobe is registered. |
118 | */ |
119 | u32 flags; |
120 | }; |
121 | |
122 | /* Kprobe status flags */ |
123 | #define KPROBE_FLAG_GONE 1 /* breakpoint has already gone */ |
124 | #define KPROBE_FLAG_DISABLED 2 /* probe is temporarily disabled */ |
125 | #define KPROBE_FLAG_OPTIMIZED 4 /* |
126 | * probe is really optimized. |
127 | * NOTE: |
128 | * this flag is only for optimized_kprobe. |
129 | */ |
130 | |
131 | /* Has this kprobe gone ? */ |
132 | static inline int kprobe_gone(struct kprobe *p) |
133 | { |
134 | return p->flags & KPROBE_FLAG_GONE; |
135 | } |
136 | |
137 | /* Is this kprobe disabled ? */ |
138 | static inline int kprobe_disabled(struct kprobe *p) |
139 | { |
140 | return p->flags & (KPROBE_FLAG_DISABLED | KPROBE_FLAG_GONE); |
141 | } |
142 | |
143 | /* Is this kprobe really running optimized path ? */ |
144 | static inline int kprobe_optimized(struct kprobe *p) |
145 | { |
146 | return p->flags & KPROBE_FLAG_OPTIMIZED; |
147 | } |
148 | /* |
149 | * Special probe type that uses setjmp-longjmp type tricks to resume |
150 | * execution at a specified entry with a matching prototype corresponding |
151 | * to the probed function - a trick to enable arguments to become |
152 | * accessible seamlessly by probe handling logic. |
153 | * Note: |
154 | * Because of the way compilers allocate stack space for local variables |
155 | * etc upfront, regardless of sub-scopes within a function, this mirroring |
156 | * principle currently works only for probes placed on function entry points. |
157 | */ |
158 | struct jprobe { |
159 | struct kprobe kp; |
160 | void *entry; /* probe handling code to jump to */ |
161 | }; |
162 | |
163 | /* For backward compatibility with old code using JPROBE_ENTRY() */ |
164 | #define JPROBE_ENTRY(handler) (handler) |
165 | |
166 | /* |
167 | * Function-return probe - |
168 | * Note: |
169 | * User needs to provide a handler function, and initialize maxactive. |
170 | * maxactive - The maximum number of instances of the probed function that |
171 | * can be active concurrently. |
172 | * nmissed - tracks the number of times the probed function's return was |
173 | * ignored, due to maxactive being too low. |
174 | * |
175 | */ |
176 | struct kretprobe { |
177 | struct kprobe kp; |
178 | kretprobe_handler_t handler; |
179 | kretprobe_handler_t entry_handler; |
180 | int maxactive; |
181 | int nmissed; |
182 | size_t data_size; |
183 | struct hlist_head free_instances; |
184 | spinlock_t lock; |
185 | }; |
186 | |
187 | struct kretprobe_instance { |
188 | struct hlist_node hlist; |
189 | struct kretprobe *rp; |
190 | kprobe_opcode_t *ret_addr; |
191 | struct task_struct *task; |
192 | char data[0]; |
193 | }; |
194 | |
195 | struct kretprobe_blackpoint { |
196 | const char *name; |
197 | void *addr; |
198 | }; |
199 | |
200 | struct kprobe_blackpoint { |
201 | const char *name; |
202 | unsigned long start_addr; |
203 | unsigned long range; |
204 | }; |
205 | |
206 | #ifdef CONFIG_KPROBES |
207 | DECLARE_PER_CPU(struct kprobe *, current_kprobe); |
208 | DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
209 | |
210 | /* |
211 | * For #ifdef avoidance: |
212 | */ |
213 | static inline int kprobes_built_in(void) |
214 | { |
215 | return 1; |
216 | } |
217 | |
218 | #ifdef CONFIG_KRETPROBES |
219 | extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, |
220 | struct pt_regs *regs); |
221 | extern int arch_trampoline_kprobe(struct kprobe *p); |
222 | #else /* CONFIG_KRETPROBES */ |
223 | static inline void arch_prepare_kretprobe(struct kretprobe *rp, |
224 | struct pt_regs *regs) |
225 | { |
226 | } |
227 | static inline int arch_trampoline_kprobe(struct kprobe *p) |
228 | { |
229 | return 0; |
230 | } |
231 | #endif /* CONFIG_KRETPROBES */ |
232 | |
233 | extern struct kretprobe_blackpoint kretprobe_blacklist[]; |
234 | |
235 | static inline void kretprobe_assert(struct kretprobe_instance *ri, |
236 | unsigned long orig_ret_address, unsigned long trampoline_address) |
237 | { |
238 | if (!orig_ret_address || (orig_ret_address == trampoline_address)) { |
239 | printk("kretprobe BUG!: Processing kretprobe %p @ %p\n", |
240 | ri->rp, ri->rp->kp.addr); |
241 | BUG(); |
242 | } |
243 | } |
244 | |
245 | #ifdef CONFIG_KPROBES_SANITY_TEST |
246 | extern int init_test_probes(void); |
247 | #else |
248 | static inline int init_test_probes(void) |
249 | { |
250 | return 0; |
251 | } |
252 | #endif /* CONFIG_KPROBES_SANITY_TEST */ |
253 | |
254 | extern int arch_prepare_kprobe(struct kprobe *p); |
255 | extern void arch_arm_kprobe(struct kprobe *p); |
256 | extern void arch_disarm_kprobe(struct kprobe *p); |
257 | extern int arch_init_kprobes(void); |
258 | extern void show_registers(struct pt_regs *regs); |
259 | extern kprobe_opcode_t *get_insn_slot(void); |
260 | extern void free_insn_slot(kprobe_opcode_t *slot, int dirty); |
261 | extern void kprobes_inc_nmissed_count(struct kprobe *p); |
262 | |
263 | #ifdef CONFIG_OPTPROBES |
264 | /* |
265 | * Internal structure for direct jump optimized probe |
266 | */ |
267 | struct optimized_kprobe { |
268 | struct kprobe kp; |
269 | struct list_head list; /* list for optimizing queue */ |
270 | struct arch_optimized_insn optinsn; |
271 | }; |
272 | |
273 | /* Architecture dependent functions for direct jump optimization */ |
274 | extern int arch_prepared_optinsn(struct arch_optimized_insn *optinsn); |
275 | extern int arch_check_optimized_kprobe(struct optimized_kprobe *op); |
276 | extern int arch_prepare_optimized_kprobe(struct optimized_kprobe *op); |
277 | extern void arch_remove_optimized_kprobe(struct optimized_kprobe *op); |
278 | extern int arch_optimize_kprobe(struct optimized_kprobe *op); |
279 | extern void arch_unoptimize_kprobe(struct optimized_kprobe *op); |
280 | extern kprobe_opcode_t *get_optinsn_slot(void); |
281 | extern void free_optinsn_slot(kprobe_opcode_t *slot, int dirty); |
282 | extern int arch_within_optimized_kprobe(struct optimized_kprobe *op, |
283 | unsigned long addr); |
284 | |
285 | extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs); |
286 | |
287 | #ifdef CONFIG_SYSCTL |
288 | extern int sysctl_kprobes_optimization; |
289 | extern int proc_kprobes_optimization_handler(struct ctl_table *table, |
290 | int write, void __user *buffer, |
291 | size_t *length, loff_t *ppos); |
292 | #endif |
293 | |
294 | #endif /* CONFIG_OPTPROBES */ |
295 | |
296 | /* Get the kprobe at this addr (if any) - called with preemption disabled */ |
297 | struct kprobe *get_kprobe(void *addr); |
298 | void kretprobe_hash_lock(struct task_struct *tsk, |
299 | struct hlist_head **head, unsigned long *flags); |
300 | void kretprobe_hash_unlock(struct task_struct *tsk, unsigned long *flags); |
301 | struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk); |
302 | |
303 | /* kprobe_running() will just return the current_kprobe on this CPU */ |
304 | static inline struct kprobe *kprobe_running(void) |
305 | { |
306 | return (__get_cpu_var(current_kprobe)); |
307 | } |
308 | |
309 | static inline void reset_current_kprobe(void) |
310 | { |
311 | __get_cpu_var(current_kprobe) = NULL; |
312 | } |
313 | |
314 | static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void) |
315 | { |
316 | return (&__get_cpu_var(kprobe_ctlblk)); |
317 | } |
318 | |
319 | int register_kprobe(struct kprobe *p); |
320 | void unregister_kprobe(struct kprobe *p); |
321 | int register_kprobes(struct kprobe **kps, int num); |
322 | void unregister_kprobes(struct kprobe **kps, int num); |
323 | int setjmp_pre_handler(struct kprobe *, struct pt_regs *); |
324 | int longjmp_break_handler(struct kprobe *, struct pt_regs *); |
325 | int register_jprobe(struct jprobe *p); |
326 | void unregister_jprobe(struct jprobe *p); |
327 | int register_jprobes(struct jprobe **jps, int num); |
328 | void unregister_jprobes(struct jprobe **jps, int num); |
329 | void jprobe_return(void); |
330 | unsigned long arch_deref_entry_point(void *); |
331 | |
332 | int register_kretprobe(struct kretprobe *rp); |
333 | void unregister_kretprobe(struct kretprobe *rp); |
334 | int register_kretprobes(struct kretprobe **rps, int num); |
335 | void unregister_kretprobes(struct kretprobe **rps, int num); |
336 | |
337 | void kprobe_flush_task(struct task_struct *tk); |
338 | void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head); |
339 | |
340 | int disable_kprobe(struct kprobe *kp); |
341 | int enable_kprobe(struct kprobe *kp); |
342 | |
343 | void dump_kprobe(struct kprobe *kp); |
344 | |
345 | #else /* !CONFIG_KPROBES: */ |
346 | |
347 | static inline int kprobes_built_in(void) |
348 | { |
349 | return 0; |
350 | } |
351 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
352 | { |
353 | return 0; |
354 | } |
355 | static inline struct kprobe *get_kprobe(void *addr) |
356 | { |
357 | return NULL; |
358 | } |
359 | static inline struct kprobe *kprobe_running(void) |
360 | { |
361 | return NULL; |
362 | } |
363 | static inline int register_kprobe(struct kprobe *p) |
364 | { |
365 | return -ENOSYS; |
366 | } |
367 | static inline int register_kprobes(struct kprobe **kps, int num) |
368 | { |
369 | return -ENOSYS; |
370 | } |
371 | static inline void unregister_kprobe(struct kprobe *p) |
372 | { |
373 | } |
374 | static inline void unregister_kprobes(struct kprobe **kps, int num) |
375 | { |
376 | } |
377 | static inline int register_jprobe(struct jprobe *p) |
378 | { |
379 | return -ENOSYS; |
380 | } |
381 | static inline int register_jprobes(struct jprobe **jps, int num) |
382 | { |
383 | return -ENOSYS; |
384 | } |
385 | static inline void unregister_jprobe(struct jprobe *p) |
386 | { |
387 | } |
388 | static inline void unregister_jprobes(struct jprobe **jps, int num) |
389 | { |
390 | } |
391 | static inline void jprobe_return(void) |
392 | { |
393 | } |
394 | static inline int register_kretprobe(struct kretprobe *rp) |
395 | { |
396 | return -ENOSYS; |
397 | } |
398 | static inline int register_kretprobes(struct kretprobe **rps, int num) |
399 | { |
400 | return -ENOSYS; |
401 | } |
402 | static inline void unregister_kretprobe(struct kretprobe *rp) |
403 | { |
404 | } |
405 | static inline void unregister_kretprobes(struct kretprobe **rps, int num) |
406 | { |
407 | } |
408 | static inline void kprobe_flush_task(struct task_struct *tk) |
409 | { |
410 | } |
411 | static inline int disable_kprobe(struct kprobe *kp) |
412 | { |
413 | return -ENOSYS; |
414 | } |
415 | static inline int enable_kprobe(struct kprobe *kp) |
416 | { |
417 | return -ENOSYS; |
418 | } |
419 | #endif /* CONFIG_KPROBES */ |
420 | static inline int disable_kretprobe(struct kretprobe *rp) |
421 | { |
422 | return disable_kprobe(&rp->kp); |
423 | } |
424 | static inline int enable_kretprobe(struct kretprobe *rp) |
425 | { |
426 | return enable_kprobe(&rp->kp); |
427 | } |
428 | static inline int disable_jprobe(struct jprobe *jp) |
429 | { |
430 | return disable_kprobe(&jp->kp); |
431 | } |
432 | static inline int enable_jprobe(struct jprobe *jp) |
433 | { |
434 | return enable_kprobe(&jp->kp); |
435 | } |
436 | |
437 | #endif /* _LINUX_KPROBES_H */ |
438 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9