1*1da177e4SLinus Torvalds #ifndef _LINUX_KPROBES_H 2*1da177e4SLinus Torvalds #define _LINUX_KPROBES_H 3*1da177e4SLinus Torvalds /* 4*1da177e4SLinus Torvalds * Kernel Probes (KProbes) 5*1da177e4SLinus Torvalds * include/linux/kprobes.h 6*1da177e4SLinus Torvalds * 7*1da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 8*1da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 9*1da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 10*1da177e4SLinus Torvalds * (at your option) any later version. 11*1da177e4SLinus Torvalds * 12*1da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 13*1da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*1da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*1da177e4SLinus Torvalds * GNU General Public License for more details. 16*1da177e4SLinus Torvalds * 17*1da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 18*1da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 19*1da177e4SLinus Torvalds * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20*1da177e4SLinus Torvalds * 21*1da177e4SLinus Torvalds * Copyright (C) IBM Corporation, 2002, 2004 22*1da177e4SLinus Torvalds * 23*1da177e4SLinus Torvalds * 2002-Oct Created by Vamsi Krishna S <[email protected]> Kernel 24*1da177e4SLinus Torvalds * Probes initial implementation ( includes suggestions from 25*1da177e4SLinus Torvalds * Rusty Russell). 26*1da177e4SLinus Torvalds * 2004-July Suparna Bhattacharya <[email protected]> added jumper probes 27*1da177e4SLinus Torvalds * interface to access function arguments. 28*1da177e4SLinus Torvalds */ 29*1da177e4SLinus Torvalds #include <linux/config.h> 30*1da177e4SLinus Torvalds #include <linux/list.h> 31*1da177e4SLinus Torvalds #include <linux/notifier.h> 32*1da177e4SLinus Torvalds #include <linux/smp.h> 33*1da177e4SLinus Torvalds #include <asm/kprobes.h> 34*1da177e4SLinus Torvalds 35*1da177e4SLinus Torvalds struct kprobe; 36*1da177e4SLinus Torvalds struct pt_regs; 37*1da177e4SLinus Torvalds typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *); 38*1da177e4SLinus Torvalds typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *); 39*1da177e4SLinus Torvalds typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *, 40*1da177e4SLinus Torvalds unsigned long flags); 41*1da177e4SLinus Torvalds typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *, 42*1da177e4SLinus Torvalds int trapnr); 43*1da177e4SLinus Torvalds struct kprobe { 44*1da177e4SLinus Torvalds struct hlist_node hlist; 45*1da177e4SLinus Torvalds 46*1da177e4SLinus Torvalds /* location of the probe point */ 47*1da177e4SLinus Torvalds kprobe_opcode_t *addr; 48*1da177e4SLinus Torvalds 49*1da177e4SLinus Torvalds /* Called before addr is executed. */ 50*1da177e4SLinus Torvalds kprobe_pre_handler_t pre_handler; 51*1da177e4SLinus Torvalds 52*1da177e4SLinus Torvalds /* Called after addr is executed, unless... */ 53*1da177e4SLinus Torvalds kprobe_post_handler_t post_handler; 54*1da177e4SLinus Torvalds 55*1da177e4SLinus Torvalds /* ... called if executing addr causes a fault (eg. page fault). 56*1da177e4SLinus Torvalds * Return 1 if it handled fault, otherwise kernel will see it. */ 57*1da177e4SLinus Torvalds kprobe_fault_handler_t fault_handler; 58*1da177e4SLinus Torvalds 59*1da177e4SLinus Torvalds /* ... called if breakpoint trap occurs in probe handler. 60*1da177e4SLinus Torvalds * Return 1 if it handled break, otherwise kernel will see it. */ 61*1da177e4SLinus Torvalds kprobe_break_handler_t break_handler; 62*1da177e4SLinus Torvalds 63*1da177e4SLinus Torvalds /* Saved opcode (which has been replaced with breakpoint) */ 64*1da177e4SLinus Torvalds kprobe_opcode_t opcode; 65*1da177e4SLinus Torvalds 66*1da177e4SLinus Torvalds /* copy of the original instruction */ 67*1da177e4SLinus Torvalds struct arch_specific_insn ainsn; 68*1da177e4SLinus Torvalds }; 69*1da177e4SLinus Torvalds 70*1da177e4SLinus Torvalds /* 71*1da177e4SLinus Torvalds * Special probe type that uses setjmp-longjmp type tricks to resume 72*1da177e4SLinus Torvalds * execution at a specified entry with a matching prototype corresponding 73*1da177e4SLinus Torvalds * to the probed function - a trick to enable arguments to become 74*1da177e4SLinus Torvalds * accessible seamlessly by probe handling logic. 75*1da177e4SLinus Torvalds * Note: 76*1da177e4SLinus Torvalds * Because of the way compilers allocate stack space for local variables 77*1da177e4SLinus Torvalds * etc upfront, regardless of sub-scopes within a function, this mirroring 78*1da177e4SLinus Torvalds * principle currently works only for probes placed on function entry points. 79*1da177e4SLinus Torvalds */ 80*1da177e4SLinus Torvalds struct jprobe { 81*1da177e4SLinus Torvalds struct kprobe kp; 82*1da177e4SLinus Torvalds kprobe_opcode_t *entry; /* probe handling code to jump to */ 83*1da177e4SLinus Torvalds }; 84*1da177e4SLinus Torvalds 85*1da177e4SLinus Torvalds #ifdef CONFIG_KPROBES 86*1da177e4SLinus Torvalds /* Locks kprobe: irq must be disabled */ 87*1da177e4SLinus Torvalds void lock_kprobes(void); 88*1da177e4SLinus Torvalds void unlock_kprobes(void); 89*1da177e4SLinus Torvalds 90*1da177e4SLinus Torvalds /* kprobe running now on this CPU? */ 91*1da177e4SLinus Torvalds static inline int kprobe_running(void) 92*1da177e4SLinus Torvalds { 93*1da177e4SLinus Torvalds extern unsigned int kprobe_cpu; 94*1da177e4SLinus Torvalds return kprobe_cpu == smp_processor_id(); 95*1da177e4SLinus Torvalds } 96*1da177e4SLinus Torvalds 97*1da177e4SLinus Torvalds extern int arch_prepare_kprobe(struct kprobe *p); 98*1da177e4SLinus Torvalds extern void arch_copy_kprobe(struct kprobe *p); 99*1da177e4SLinus Torvalds extern void arch_remove_kprobe(struct kprobe *p); 100*1da177e4SLinus Torvalds extern void show_registers(struct pt_regs *regs); 101*1da177e4SLinus Torvalds 102*1da177e4SLinus Torvalds /* Get the kprobe at this addr (if any). Must have called lock_kprobes */ 103*1da177e4SLinus Torvalds struct kprobe *get_kprobe(void *addr); 104*1da177e4SLinus Torvalds 105*1da177e4SLinus Torvalds int register_kprobe(struct kprobe *p); 106*1da177e4SLinus Torvalds void unregister_kprobe(struct kprobe *p); 107*1da177e4SLinus Torvalds int setjmp_pre_handler(struct kprobe *, struct pt_regs *); 108*1da177e4SLinus Torvalds int longjmp_break_handler(struct kprobe *, struct pt_regs *); 109*1da177e4SLinus Torvalds int register_jprobe(struct jprobe *p); 110*1da177e4SLinus Torvalds void unregister_jprobe(struct jprobe *p); 111*1da177e4SLinus Torvalds void jprobe_return(void); 112*1da177e4SLinus Torvalds 113*1da177e4SLinus Torvalds #else 114*1da177e4SLinus Torvalds static inline int kprobe_running(void) 115*1da177e4SLinus Torvalds { 116*1da177e4SLinus Torvalds return 0; 117*1da177e4SLinus Torvalds } 118*1da177e4SLinus Torvalds static inline int register_kprobe(struct kprobe *p) 119*1da177e4SLinus Torvalds { 120*1da177e4SLinus Torvalds return -ENOSYS; 121*1da177e4SLinus Torvalds } 122*1da177e4SLinus Torvalds static inline void unregister_kprobe(struct kprobe *p) 123*1da177e4SLinus Torvalds { 124*1da177e4SLinus Torvalds } 125*1da177e4SLinus Torvalds static inline int register_jprobe(struct jprobe *p) 126*1da177e4SLinus Torvalds { 127*1da177e4SLinus Torvalds return -ENOSYS; 128*1da177e4SLinus Torvalds } 129*1da177e4SLinus Torvalds static inline void unregister_jprobe(struct jprobe *p) 130*1da177e4SLinus Torvalds { 131*1da177e4SLinus Torvalds } 132*1da177e4SLinus Torvalds static inline void jprobe_return(void) 133*1da177e4SLinus Torvalds { 134*1da177e4SLinus Torvalds } 135*1da177e4SLinus Torvalds #endif 136*1da177e4SLinus Torvalds #endif /* _LINUX_KPROBES_H */ 137