16e12e72dcca85a3aedc9c31bd0b7ef9117668a1
[kernel/swap-modules.git] / uprobe / swap_uprobes.h
1 /**
2  * @file uprobe/swap_uprobes.h
3  * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial
4  * implementation; Support x86/ARM/MIPS for both user and kernel spaces.
5  * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for
6  * separating core and arch parts
7  *
8  * @section LICENSE
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  *
24  * @section COPYRIGHT
25  *
26  * Copyright (C) Samsung Electronics, 2006-2010
27  *
28  * @section DESCRIPTION
29  *
30  * Uprobes interface declaration.
31  */
32
33 #ifndef _SWAP_UPROBES_H
34 #define _SWAP_UPROBES_H
35
36
37 #include <kprobe/swap_kprobes.h>
38
39 #include <swap-asm/swap_uprobes.h>
40
41 /**
42  * @brief Uprobe pre-handler pointer.
43  */
44 typedef int (*uprobe_pre_handler_t) (struct uprobe *, struct pt_regs *);
45
46 /**
47  * @brief Uprobe break handler pointer.
48  */
49 typedef int (*uprobe_break_handler_t) (struct uprobe *, struct pt_regs *);
50
51 /**
52  * @brief Uprobe post handler pointer.
53  */
54 typedef void (*uprobe_post_handler_t) (struct uprobe *,
55                                        struct pt_regs *,
56                                        unsigned long flags);
57
58 /**
59  * @brief Uprobe fault handler pointer.
60  */
61 typedef int (*uprobe_fault_handler_t) (struct uprobe *,
62                                        struct pt_regs *,
63                                        int trapnr);
64
65 /**
66  * @struct uprobe
67  * @brief Stores uprobe data.
68  */
69 struct uprobe {
70         struct hlist_node hlist; /**< Hash list.*/
71         /** List of probes to search by instruction slot.*/
72         struct hlist_node is_hlist;
73         /** List of uprobes for multi-handler support.*/
74         struct list_head list;
75         /** Location of the probe point. */
76         uprobe_opcode_t *addr;
77         /** Called before addr is executed.*/
78         uprobe_pre_handler_t pre_handler;
79         /** Called after addr is executed, unless...*/
80         uprobe_post_handler_t post_handler;
81         /** ... called if executing addr causes a fault (eg. page fault).*/
82         uprobe_fault_handler_t fault_handler;
83         /** Return 1 if it handled fault, otherwise kernel will see it.*/
84         uprobe_break_handler_t break_handler;
85         /** Saved opcode (which has been replaced with breakpoint).*/
86         uprobe_opcode_t opcode;
87         /** Override single-step target address, may be used to redirect
88          * control-flow to arbitrary address after probe point without
89          * invocation of original instruction; useful for functions
90          * replacement. If jprobe.entry should return address of function or
91          * NULL if original function should be called.
92          * Not supported for X86, not tested for MIPS. */
93         uprobe_opcode_t *ss_addr[NR_CPUS];
94 #ifdef CONFIG_ARM
95         /** Safe/unsafe to use probe on ARM.*/
96         unsigned safe_arm:1;
97         /** Safe/unsafe to use probe on Thumb.*/
98         unsigned safe_thumb:1;
99 #endif
100         struct arch_insn ainsn;              /**< Copy of the original instruction.*/
101         struct arch_tramp atramp;            /**< Stores trampoline */
102         struct task_struct *task;            /**< Pointer to the task struct */
103         struct slot_manager *sm;             /**< Pointer to slot manager */
104         bool atomic_ctx;                    /**< Handler context */
105 };
106
107 struct uinst_info {
108         struct hlist_node hlist;
109
110         unsigned long vaddr;
111         kprobe_opcode_t opcode;
112 };
113
114 struct urinst_info {
115         struct hlist_node hlist;
116
117         struct task_struct *task;
118         unsigned long sp;
119         unsigned long tramp;
120         unsigned long ret_addr;
121 };
122
123 struct uinst_info *uinst_info_create(unsigned long vaddr,
124                                      kprobe_opcode_t opcode);
125 void uinst_info_destroy(struct uinst_info *uinst);
126 void uinst_info_disarm(struct uinst_info *uinst, struct task_struct *task);
127
128
129 void urinst_info_get_current_hlist(struct hlist_head *head, bool recycle);
130 void urinst_info_put_current_hlist(struct hlist_head *head,
131                                   struct task_struct *task);
132
133
134 /**
135  * @brief Uprobe pre-entry handler.
136  */
137 typedef unsigned long (*uprobe_pre_entry_handler_t)(void *priv_arg,
138                                                     struct pt_regs *regs);
139
140 /**
141  * @struct ujprobe
142  * @brief Stores ujprobe data, based on uprobe.
143  */
144 struct ujprobe {
145         struct uprobe up;       /**< Uprobe for this ujprobe */
146         void *entry;            /**< Probe handling code to jump to */
147         /** Handler which will be called before 'entry' */
148         uprobe_pre_entry_handler_t pre_entry;
149         void *priv_arg;         /**< Private args for handler */
150         char *args;             /**< Function args format string */
151 };
152
153 struct uretprobe_instance;
154
155 /**
156  * @brief Uretprobe handler.
157  */
158 typedef int (*uretprobe_handler_t)(struct uretprobe_instance *,
159                                    struct pt_regs *);
160
161 /**
162  * @strict uretprobe
163  * @brief Function-return probe.
164  *
165  * Note:
166  * User needs to provide a handler function, and initialize maxactive.
167  */
168 struct uretprobe {
169         struct uprobe up;                   /**< Uprobe for this uretprobe */
170         uretprobe_handler_t handler;        /**< Uretprobe handler */
171         uretprobe_handler_t entry_handler;  /**< Uretprobe entry handler */
172         /** Maximum number of instances of the probed function that can be
173          * active concurrently. */
174         int maxactive;
175         /** Tracks the number of times the probed function's return was
176          * ignored, due to maxactive being too low. */
177         int nmissed;
178         size_t data_size;                   /**< Instance data size */
179         struct hlist_head free_instances;   /**< Free instances list */
180         struct hlist_head used_instances;   /**< Used instances list */
181
182 #ifdef CONFIG_ARM
183         unsigned arm_noret:1;               /**< No-return flag for ARM */
184         unsigned thumb_noret:1;             /**< No-return flag for Thumb */
185 #endif
186 };
187
188 /**
189  * @struct uretprobe_instance
190  * @brief Structure for each uretprobe instance.
191  */
192 struct uretprobe_instance {
193         /* either on free list or used list */
194         struct hlist_node uflist;           /**< Free list */
195         struct hlist_node hlist;            /**< Used list */
196         struct uretprobe *rp;               /**< Pointer to the parent uretprobe */
197         uprobe_opcode_t *ret_addr;          /**< Return address */
198         uprobe_opcode_t *sp;                /**< Pointer to stack */
199         struct task_struct *task;           /**< Pointer to the task struct */
200 #ifdef CONFIG_ARM
201         /* FIXME Preload: if this flag is set then ignore the thumb_mode(regs)
202          * check in arch_prepare_uretprobe and use thumb trampoline. For the
203          * moment we have to explicitly force arm mode when jumping to preload
204          * handlers but we need the correct (i.e. original) retprobe tramp set
205          * anyway. */
206         int preload_thumb;
207 #endif
208         char data[0];                       /**< Custom data */
209 };
210
211 int swap_register_uprobe(struct uprobe *p);
212 void swap_unregister_uprobe(struct uprobe *p);
213 void __swap_unregister_uprobe(struct uprobe *up, int disarm);
214
215 int swap_register_ujprobe(struct ujprobe *jp);
216 void swap_unregister_ujprobe(struct ujprobe *jp);
217 void __swap_unregister_ujprobe(struct ujprobe *jp, int disarm);
218
219 int swap_register_uretprobe(struct uretprobe *rp);
220 void swap_unregister_uretprobe(struct uretprobe *rp);
221 void __swap_unregister_uretprobe(struct uretprobe *rp, int disarm);
222
223 void swap_unregister_all_uprobes(struct task_struct *task);
224
225 void swap_ujprobe_return(void);
226 struct uprobe *get_uprobe(void *addr, pid_t tgid);
227 struct uprobe *get_uprobe_by_insn_slot(void *addr,
228                                         pid_t tgid,
229                                         struct pt_regs *regs);
230
231 void disarm_uprobe(struct uprobe *p, struct task_struct *task);
232
233 int trampoline_uprobe_handler(struct uprobe *p, struct pt_regs *regs);
234
235 void add_uprobe_table(struct uprobe *p);
236
237 #endif /*  _SWAP_UPROBES_H */