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
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.
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.
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.
26 * Copyright (C) Samsung Electronics, 2006-2010
28 * @section DESCRIPTION
30 * Uprobes interface declaration.
33 #ifndef _SWAP_UPROBES_H
34 #define _SWAP_UPROBES_H
37 #include <kprobe/swap_kprobes.h>
39 #include <swap-asm/swap_uprobes.h>
42 * @brief Uprobe pre-handler pointer.
44 typedef int (*uprobe_pre_handler_t) (struct uprobe *, struct pt_regs *);
47 * @brief Uprobe break handler pointer.
49 typedef int (*uprobe_break_handler_t) (struct uprobe *, struct pt_regs *);
52 * @brief Uprobe post handler pointer.
54 typedef void (*uprobe_post_handler_t) (struct uprobe *,
59 * @brief Uprobe fault handler pointer.
61 typedef int (*uprobe_fault_handler_t) (struct uprobe *,
67 * @brief Stores uprobe data.
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];
95 /** Safe/unsafe to use probe on ARM.*/
97 /** Safe/unsafe to use probe on Thumb.*/
98 unsigned safe_thumb:1;
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 */
108 struct hlist_node hlist;
111 kprobe_opcode_t opcode;
115 struct hlist_node hlist;
117 struct task_struct *task;
120 unsigned long ret_addr;
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);
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);
135 * @brief Uprobe pre-entry handler.
137 typedef unsigned long (*uprobe_pre_entry_handler_t)(void *priv_arg,
138 struct pt_regs *regs);
142 * @brief Stores ujprobe data, based on uprobe.
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 */
153 struct uretprobe_instance;
156 * @brief Uretprobe handler.
158 typedef int (*uretprobe_handler_t)(struct uretprobe_instance *,
163 * @brief Function-return probe.
166 * User needs to provide a handler function, and initialize maxactive.
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. */
175 /** Tracks the number of times the probed function's return was
176 * ignored, due to maxactive being too low. */
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 */
183 unsigned arm_noret:1; /**< No-return flag for ARM */
184 unsigned thumb_noret:1; /**< No-return flag for Thumb */
189 * @struct uretprobe_instance
190 * @brief Structure for each uretprobe instance.
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 */
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
208 char data[0]; /**< Custom data */
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);
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);
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);
223 void swap_unregister_all_uprobes(struct task_struct *task);
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,
229 struct pt_regs *regs);
231 void disarm_uprobe(struct uprobe *p, struct task_struct *task);
233 int trampoline_uprobe_handler(struct uprobe *p, struct pt_regs *regs);
235 void add_uprobe_table(struct uprobe *p);
237 #endif /* _SWAP_UPROBES_H */