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 task_struct *task; /**< Pointer to the task struct */
102 struct slot_manager *sm; /**< Pointer to slot manager */
103 bool atomic_ctx; /**< Handler context */
107 struct hlist_node hlist;
110 kprobe_opcode_t opcode;
114 struct hlist_node hlist;
116 struct task_struct *task;
119 unsigned long ret_addr;
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);
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);
134 * @brief Uprobe pre-entry handler.
136 typedef unsigned long (*uprobe_pre_entry_handler_t)(void *priv_arg,
137 struct pt_regs *regs);
141 * @brief Stores ujprobe data, based on uprobe.
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 */
152 struct uretprobe_instance;
155 * @brief Uretprobe handler.
157 typedef int (*uretprobe_handler_t)(struct uretprobe_instance *,
162 * @brief Function-return probe.
165 * User needs to provide a handler function, and initialize maxactive.
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. */
174 /** Tracks the number of times the probed function's return was
175 * ignored, due to maxactive being too low. */
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 */
182 unsigned arm_noret:1; /**< No-return flag for ARM */
183 unsigned thumb_noret:1; /**< No-return flag for Thumb */
188 * @struct uretprobe_instance
189 * @brief Structure for each uretprobe instance.
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 */
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
207 char data[0]; /**< Custom data */
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);
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);
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);
222 void swap_unregister_all_uprobes(struct task_struct *task);
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,
228 struct pt_regs *regs);
230 void disarm_uprobe(struct uprobe *p, struct task_struct *task);
232 int trampoline_uprobe_handler(struct uprobe *p, struct pt_regs *regs);
234 void add_uprobe_table(struct uprobe *p);
236 #endif /* _SWAP_UPROBES_H */