[CLEAN] remove arch_tramp struct
[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 task_struct *task;            /**< Pointer to the task struct */
102         struct slot_manager *sm;             /**< Pointer to slot manager */
103         bool atomic_ctx;                    /**< Handler context */
104 };
105
106 struct uinst_info {
107         struct hlist_node hlist;
108
109         unsigned long vaddr;
110         kprobe_opcode_t opcode;
111 };
112
113 struct urinst_info {
114         struct hlist_node hlist;
115
116         struct task_struct *task;
117         unsigned long sp;
118         unsigned long tramp;
119         unsigned long ret_addr;
120 };
121
122 struct uinst_info *uinst_info_create(unsigned long vaddr,
123                                      kprobe_opcode_t opcode);
124 void uinst_info_destroy(struct uinst_info *uinst);
125 void uinst_info_disarm(struct uinst_info *uinst, struct task_struct *task);
126
127
128 void urinst_info_get_current_hlist(struct hlist_head *head, bool recycle);
129 void urinst_info_put_current_hlist(struct hlist_head *head,
130                                   struct task_struct *task);
131
132
133 /**
134  * @brief Uprobe pre-entry handler.
135  */
136 typedef unsigned long (*uprobe_pre_entry_handler_t)(void *priv_arg,
137                                                     struct pt_regs *regs);
138
139 /**
140  * @struct ujprobe
141  * @brief Stores ujprobe data, based on uprobe.
142  */
143 struct ujprobe {
144         struct uprobe up;       /**< Uprobe for this ujprobe */
145         void *entry;            /**< Probe handling code to jump to */
146         /** Handler which will be called before 'entry' */
147         uprobe_pre_entry_handler_t pre_entry;
148         void *priv_arg;         /**< Private args for handler */
149         char *args;             /**< Function args format string */
150 };
151
152 struct uretprobe_instance;
153
154 /**
155  * @brief Uretprobe handler.
156  */
157 typedef int (*uretprobe_handler_t)(struct uretprobe_instance *,
158                                    struct pt_regs *);
159
160 /**
161  * @strict uretprobe
162  * @brief Function-return probe.
163  *
164  * Note:
165  * User needs to provide a handler function, and initialize maxactive.
166  */
167 struct uretprobe {
168         struct uprobe up;                   /**< Uprobe for this uretprobe */
169         uretprobe_handler_t handler;        /**< Uretprobe handler */
170         uretprobe_handler_t entry_handler;  /**< Uretprobe entry handler */
171         /** Maximum number of instances of the probed function that can be
172          * active concurrently. */
173         int maxactive;
174         /** Tracks the number of times the probed function's return was
175          * ignored, due to maxactive being too low. */
176         int nmissed;
177         size_t data_size;                   /**< Instance data size */
178         struct hlist_head free_instances;   /**< Free instances list */
179         struct hlist_head used_instances;   /**< Used instances list */
180
181 #ifdef CONFIG_ARM
182         unsigned arm_noret:1;               /**< No-return flag for ARM */
183         unsigned thumb_noret:1;             /**< No-return flag for Thumb */
184 #endif
185 };
186
187 /**
188  * @struct uretprobe_instance
189  * @brief Structure for each uretprobe instance.
190  */
191 struct uretprobe_instance {
192         /* either on free list or used list */
193         struct hlist_node uflist;           /**< Free list */
194         struct hlist_node hlist;            /**< Used list */
195         struct uretprobe *rp;               /**< Pointer to the parent uretprobe */
196         uprobe_opcode_t *ret_addr;          /**< Return address */
197         uprobe_opcode_t *sp;                /**< Pointer to stack */
198         struct task_struct *task;           /**< Pointer to the task struct */
199 #ifdef CONFIG_ARM
200         /* FIXME Preload: if this flag is set then ignore the thumb_mode(regs)
201          * check in arch_prepare_uretprobe and use thumb trampoline. For the
202          * moment we have to explicitly force arm mode when jumping to preload
203          * handlers but we need the correct (i.e. original) retprobe tramp set
204          * anyway. */
205         int preload_thumb;
206 #endif
207         char data[0];                       /**< Custom data */
208 };
209
210 int swap_register_uprobe(struct uprobe *p);
211 void swap_unregister_uprobe(struct uprobe *p);
212 void __swap_unregister_uprobe(struct uprobe *up, int disarm);
213
214 int swap_register_ujprobe(struct ujprobe *jp);
215 void swap_unregister_ujprobe(struct ujprobe *jp);
216 void __swap_unregister_ujprobe(struct ujprobe *jp, int disarm);
217
218 int swap_register_uretprobe(struct uretprobe *rp);
219 void swap_unregister_uretprobe(struct uretprobe *rp);
220 void __swap_unregister_uretprobe(struct uretprobe *rp, int disarm);
221
222 void swap_unregister_all_uprobes(struct task_struct *task);
223
224 void swap_ujprobe_return(void);
225 struct uprobe *get_uprobe(void *addr, pid_t tgid);
226 struct uprobe *get_uprobe_by_insn_slot(void *addr,
227                                         pid_t tgid,
228                                         struct pt_regs *regs);
229
230 void disarm_uprobe(struct uprobe *p, struct task_struct *task);
231
232 int trampoline_uprobe_handler(struct uprobe *p, struct pt_regs *regs);
233
234 void add_uprobe_table(struct uprobe *p);
235
236 #endif /*  _SWAP_UPROBES_H */