2 * uprobe/swap_uprobes.c
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 implementation.
34 #include <linux/hash.h>
35 #include <linux/mempolicy.h>
36 #include <linux/module.h>
38 #include <kprobe/swap_slots.h>
39 #include <kprobe/swap_kdebug.h>
40 #include <kprobe/swap_kprobes_deps.h>
42 #include <swap-asm/swap_uprobes.h>
44 #include "swap_uprobes.h"
48 UPROBE_HASH_BITS = 10,
49 UPROBE_TABLE_SIZE = (1 << UPROBE_HASH_BITS)
52 struct hlist_head uprobe_insn_slot_table[UPROBE_TABLE_SIZE];
53 struct hlist_head uprobe_table[UPROBE_TABLE_SIZE];
55 DEFINE_SPINLOCK(uretprobe_lock); /* Protects uretprobe_inst_table */
56 static struct hlist_head uretprobe_inst_table[UPROBE_TABLE_SIZE];
58 #define DEBUG_PRINT_HASH_TABLE 0
60 #if DEBUG_PRINT_HASH_TABLE
61 void print_uprobe_hash_table(void)
64 struct hlist_head *head;
66 DECLARE_NODE_PTR_FOR_HLIST(node);
69 for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
70 head = &uprobe_insn_slot_table[i];
71 swap_hlist_for_each_entry_rcu(p, node, head, is_hlist_arm) {
72 printk("####### find U tgid=%u, addr=%x\n",
80 * Keep all fields in the uprobe consistent
82 static inline void copy_uprobe(struct kprobe *old_p, struct kprobe *p)
84 memcpy(&p->opcode, &old_p->opcode, sizeof(kprobe_opcode_t));
85 memcpy(&p->ainsn, &old_p->ainsn, sizeof(struct arch_specific_insn));
87 p->safe_arm = old_p->safe_arm;
88 p->safe_thumb = old_p->safe_thumb;
93 * Aggregate handlers for multiple uprobes support - these handlers
94 * take care of invoking the individual uprobe handlers on p->list
96 static int aggr_pre_uhandler(struct kprobe *p, struct pt_regs *regs)
101 list_for_each_entry_rcu(kp, &p->list, list) {
102 if (kp->pre_handler) {
103 ret = kp->pre_handler(kp, regs);
113 static void aggr_post_uhandler(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
117 list_for_each_entry_rcu(kp, &p->list, list) {
118 if (kp->post_handler) {
119 kp->post_handler(kp, regs, flags);
124 static int aggr_fault_uhandler(struct kprobe *p, struct pt_regs *regs, int trapnr)
129 static int aggr_break_uhandler(struct kprobe *p, struct pt_regs *regs)
135 * Add the new probe to old_p->list. Fail if this is the
136 * second ujprobe at the address - two ujprobes can't coexist
138 static int add_new_uprobe(struct kprobe *old_p, struct kprobe *p)
140 if (p->break_handler) {
141 if (old_p->break_handler) {
145 list_add_tail_rcu(&p->list, &old_p->list);
146 old_p->break_handler = aggr_break_uhandler;
148 list_add_rcu (&p->list, &old_p->list);
151 if (p->post_handler && !old_p->post_handler) {
152 old_p->post_handler = aggr_post_uhandler;
159 * Fill in the required fields of the "manager uprobe". Replace the
160 * earlier uprobe in the hlist with the manager uprobe
162 static inline void add_aggr_uprobe(struct kprobe *ap, struct kprobe *p)
167 ap->pre_handler = aggr_pre_uhandler;
168 ap->fault_handler = aggr_fault_uhandler;
170 if (p->post_handler) {
171 ap->post_handler = aggr_post_uhandler;
174 if (p->break_handler) {
175 ap->break_handler = aggr_break_uhandler;
178 INIT_LIST_HEAD(&ap->list);
179 list_add_rcu(&p->list, &ap->list);
181 hlist_replace_rcu(&p->hlist, &ap->hlist);
185 * This is the second or subsequent uprobe at the address - handle
188 static int register_aggr_uprobe(struct kprobe *old_p, struct kprobe *p)
193 if (old_p->pre_handler == aggr_pre_uhandler) {
194 copy_uprobe(old_p, p);
195 ret = add_new_uprobe(old_p, p);
197 struct uprobe *uap = kzalloc(sizeof(*uap), GFP_KERNEL);
202 uap->task = kp2up(p)->task;
204 add_aggr_uprobe(ap, old_p);
206 ret = add_new_uprobe(ap, p);
212 static void arm_uprobe(struct uprobe *p)
214 kprobe_opcode_t insn = BREAKPOINT_INSTRUCTION;
215 int ret = write_proc_vm_atomic(p->task, (unsigned long)p->kp.addr,
216 &insn, sizeof(insn));
218 panic("arm_uprobe: failed to write memory "
219 "tgid=%u addr=%p!\n", p->task->tgid, p->kp.addr);
224 * @brief Disarms uprobe.
226 * @param p Pointer to the uprobe's kprobe.
227 * @param task Pointer to the target task.
230 void disarm_uprobe(struct kprobe *p, struct task_struct *task)
232 int ret = write_proc_vm_atomic(task, (unsigned long)p->addr,
233 &p->opcode, sizeof(p->opcode));
235 panic("disarm_uprobe: failed to write memory "
236 "tgid=%u, addr=%p!\n", task->tgid, p->addr);
239 EXPORT_SYMBOL_GPL(disarm_uprobe);
241 static void init_uprobes_insn_slots(void)
244 for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
245 INIT_HLIST_HEAD(&uprobe_insn_slot_table[i]);
249 static void init_uprobe_table(void)
252 for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
253 INIT_HLIST_HEAD(&uprobe_table[i]);
257 static void init_uretprobe_inst_table(void)
260 for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
261 INIT_HLIST_HEAD (&uretprobe_inst_table[i]);
266 * @brief Gets uprobe's kprobe.
268 * @param addr Probe's address.
269 * @param tgid Probes's thread group ID.
270 * @return Pointer to the kprobe on success,\n
273 struct kprobe *get_ukprobe(void *addr, pid_t tgid)
275 struct hlist_head *head;
277 DECLARE_NODE_PTR_FOR_HLIST(node);
279 head = &uprobe_table[hash_ptr(addr, UPROBE_HASH_BITS)];
280 swap_hlist_for_each_entry_rcu(p, node, head, hlist) {
281 if (p->addr == addr && kp2up(p)->task->tgid == tgid) {
290 * @brief Adds uprobe to hlist when trampoline have been made.
292 * @param p Pointer to the uprobe's kprobe.
295 void add_uprobe_table(struct kprobe *p)
297 INIT_HLIST_NODE(&p->is_hlist);
298 hlist_add_head_rcu(&p->is_hlist, &uprobe_insn_slot_table[hash_ptr(p->ainsn.insn, UPROBE_HASH_BITS)]);
302 * @brief Gets kprobe by insn slot.
304 * @param addr Probe's address.
305 * @param tgit Probe's thread group ID.
306 * @param regs Pointer to CPU registers data.
307 * @return Pointer to the kprobe on success,\n
310 struct kprobe *get_ukprobe_by_insn_slot(void *addr, pid_t tgid, struct pt_regs *regs)
312 struct hlist_head *head;
314 DECLARE_NODE_PTR_FOR_HLIST(node);
316 /* TODO: test - two processes invokes instrumented function */
317 head = &uprobe_insn_slot_table[hash_ptr(addr, UPROBE_HASH_BITS)];
318 swap_hlist_for_each_entry_rcu(p, node, head, is_hlist) {
319 if (p->ainsn.insn == addr && kp2up(p)->task->tgid == tgid) {
328 static void remove_uprobe(struct uprobe *up)
330 arch_remove_uprobe(up);
333 static struct hlist_head *uretprobe_inst_table_head(void *hash_key)
335 return &uretprobe_inst_table[hash_ptr (hash_key, UPROBE_HASH_BITS)];
338 /* Called with uretprobe_lock held */
339 static void add_urp_inst(struct uretprobe_instance *ri)
342 * Remove rp inst off the free list -
343 * Add it back when probed function returns
345 hlist_del(&ri->uflist);
347 /* Add rp inst onto table */
348 INIT_HLIST_NODE(&ri->hlist);
349 hlist_add_head(&ri->hlist, uretprobe_inst_table_head(ri->task->mm));
351 /* Also add this rp inst to the used list. */
352 INIT_HLIST_NODE(&ri->uflist);
353 hlist_add_head(&ri->uflist, &ri->rp->used_instances);
356 /* Called with uretprobe_lock held */
357 static void recycle_urp_inst(struct uretprobe_instance *ri)
360 hlist_del(&ri->hlist);
361 /* remove rp inst off the used list */
362 hlist_del(&ri->uflist);
363 /* put rp inst back onto the free list */
364 INIT_HLIST_NODE(&ri->uflist);
365 hlist_add_head(&ri->uflist, &ri->rp->free_instances);
369 /* Called with uretprobe_lock held */
370 static struct uretprobe_instance *get_used_urp_inst(struct uretprobe *rp)
372 struct uretprobe_instance *ri;
373 DECLARE_NODE_PTR_FOR_HLIST(node);
375 swap_hlist_for_each_entry(ri, node, &rp->used_instances, uflist) {
383 * @brief Gets free uretprobe instanse for the specified uretprobe without
384 * allocation. Called with uretprobe_lock held.
386 * @param rp Pointer to the uretprobe.
387 * @return Pointer to the uretprobe_instance on success,\n
390 struct uretprobe_instance *get_free_urp_inst_no_alloc(struct uretprobe *rp)
392 struct uretprobe_instance *ri;
393 DECLARE_NODE_PTR_FOR_HLIST(node);
395 swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) {
402 /* Called with uretprobe_lock held */
403 static void free_urp_inst(struct uretprobe *rp)
405 struct uretprobe_instance *ri;
406 while ((ri = get_free_urp_inst_no_alloc(rp)) != NULL) {
407 hlist_del(&ri->uflist);
412 #define COMMON_URP_NR 10
414 static int alloc_nodes_uretprobe(struct uretprobe *rp)
417 struct uretprobe_instance *inst;
420 #if 1//def CONFIG_PREEMPT
421 rp->maxactive += max(COMMON_URP_NR, 2 * NR_CPUS);
423 rp->maxacpptive += NR_CPUS;
425 alloc_nodes = COMMON_URP_NR;
427 for (i = 0; i < alloc_nodes; ++i) {
428 inst = kmalloc(sizeof(*inst), GFP_ATOMIC);
433 INIT_HLIST_NODE(&inst->uflist);
434 hlist_add_head(&inst->uflist, &rp->free_instances);
440 /* Called with uretprobe_lock held */
441 static struct uretprobe_instance *get_free_urp_inst(struct uretprobe *rp)
443 struct uretprobe_instance *ri;
444 DECLARE_NODE_PTR_FOR_HLIST(node);
446 swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) {
450 if (!alloc_nodes_uretprobe(rp)) {
451 swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) {
458 // ===================================================================
461 * @brief Registers uprobe.
463 * @param up Pointer to the uprobe to register.
464 * @return 0 on success,\n
465 * negative error code on error.
467 int swap_register_uprobe(struct uprobe *up)
470 struct kprobe *p, *old_p;
477 DBPRINTF("p->addr = 0x%p p = 0x%p\n", p->addr, p);
479 // thumb address = address-1;
480 #if defined(CONFIG_ARM)
481 // TODO: must be corrected in 'bundle'
482 if ((unsigned long) p->addr & 0x01) {
483 p->addr = (kprobe_opcode_t *)((unsigned long)p->addr & 0xfffffffe);
487 p->ainsn.insn = NULL;
488 p->mod_refcounted = 0;
490 INIT_LIST_HEAD(&p->list);
491 #ifdef KPROBES_PROFILE
492 p->start_tm.tv_sec = p->start_tm.tv_usec = 0;
493 p->hnd_tm_sum.tv_sec = p->hnd_tm_sum.tv_usec = 0;
497 // get the first item
498 old_p = get_ukprobe(p->addr, kp2up(p)->task->tgid);
501 p->safe_arm = old_p->safe_arm;
502 p->safe_thumb = old_p->safe_thumb;
504 ret = register_aggr_uprobe(old_p, p);
505 DBPRINTF("goto out\n", ret);
509 ret = arch_prepare_uprobe(up);
511 DBPRINTF("goto out\n", ret);
515 DBPRINTF ("before out ret = 0x%x\n", ret);
517 // TODO: add uprobe (must be in function)
518 INIT_HLIST_NODE(&p->hlist);
519 hlist_add_head_rcu(&p->hlist, &uprobe_table[hash_ptr(p->addr, UPROBE_HASH_BITS)]);
523 DBPRINTF("out ret = 0x%x\n", ret);
528 * @brief Unregisters uprobe.
530 * @param up Pointer to the uprobe.
531 * @param disarm Disarm flag. When true uprobe is disarmed.
534 void __swap_unregister_uprobe(struct uprobe *up, int disarm)
536 struct kprobe *p, *old_p, *list_p;
540 old_p = get_ukprobe(p->addr, kp2up(p)->task->tgid);
541 if (unlikely(!old_p)) {
546 list_for_each_entry_rcu(list_p, &old_p->list, list) {
548 /* uprobe p is a valid probe */
557 if ((old_p == p) || ((old_p->pre_handler == aggr_pre_uhandler) &&
558 (p->list.next == &old_p->list) && (p->list.prev == &old_p->list))) {
559 /* Only probe on the hash list */
561 disarm_uprobe(&up->kp, up->task);
563 hlist_del_rcu(&old_p->hlist);
566 list_del_rcu(&p->list);
572 list_del_rcu(&p->list);
582 if (p->break_handler) {
583 old_p->break_handler = NULL;
586 if (p->post_handler) {
587 list_for_each_entry_rcu (list_p, &old_p->list, list) {
588 if (list_p->post_handler) {
594 if (cleanup_p == 0) {
595 old_p->post_handler = NULL;
600 EXPORT_SYMBOL_GPL(__swap_unregister_uprobe);
603 * @brief Unregisters uprobe. Main interface function, wrapper for
604 * __swap_unregister_uprobe.
606 * @param up Pointer to the uprobe.
609 void swap_unregister_uprobe(struct uprobe *up)
611 __swap_unregister_uprobe(up, 1);
615 * @brief Registers ujprobe.
617 * @param uj Pointer to the ujprobe function.
618 * @return 0 on success,\n
619 * error code on error.
621 int swap_register_ujprobe(struct ujprobe *jp)
625 /* Todo: Verify probepoint is a function entry point */
626 jp->up.kp.pre_handler = setjmp_upre_handler;
627 jp->up.kp.break_handler = longjmp_break_uhandler;
629 ret = swap_register_uprobe(&jp->up);
633 EXPORT_SYMBOL_GPL(swap_register_ujprobe);
636 * @brief Unregisters ujprobe.
638 * @param jp Pointer to the ujprobe.
639 * @param disarm Disarm flag, passed to __swap_unregister_uprobe.
642 void __swap_unregister_ujprobe(struct ujprobe *jp, int disarm)
644 __swap_unregister_uprobe(&jp->up, disarm);
646 * Here is an attempt to unregister even those probes that have not been
647 * installed (hence not added to the hlist).
648 * So if we try to delete them from the hlist we will get NULL pointer
649 * dereference error. That is why we check whether this node
650 * really belongs to the hlist.
652 if (!(hlist_unhashed(&jp->up.kp.is_hlist))) {
653 hlist_del_rcu(&jp->up.kp.is_hlist);
656 EXPORT_SYMBOL_GPL(__swap_unregister_ujprobe);
659 * @brief Unregisters ujprobe. Main interface function, wrapper for
660 * __swap_unregister_ujprobe.
662 * @param jp Pointer to the jprobe.
665 void swap_unregister_ujprobe(struct ujprobe *jp)
667 __swap_unregister_ujprobe(jp, 1);
669 EXPORT_SYMBOL_GPL(swap_unregister_ujprobe);
672 * @brief Trampoline uprobe handler.
674 * @param p Pointer to the uprobe's kprobe.
675 * @param regs Pointer to CPU register data.
678 int trampoline_uprobe_handler(struct kprobe *p, struct pt_regs *regs)
680 struct uretprobe_instance *ri = NULL;
682 struct hlist_head *head;
683 unsigned long flags, tramp_addr, orig_ret_addr = 0;
684 struct hlist_node *tmp;
685 DECLARE_NODE_PTR_FOR_HLIST(node);
687 tramp_addr = arch_get_trampoline_addr(p, regs);
688 spin_lock_irqsave(&uretprobe_lock, flags);
690 head = uretprobe_inst_table_head(current->mm);
693 * It is possible to have multiple instances associated with a given
694 * task either because an multiple functions in the call path
695 * have a return probe installed on them, and/or more then one
696 * return probe was registered for a target function.
698 * We can handle this because:
699 * - instances are always inserted at the head of the list
700 * - when multiple return probes are registered for the same
701 * function, the first instance's ret_addr will point to the
702 * real return address, and all the rest will point to
703 * uretprobe_trampoline
705 swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
706 if (ri->task != current) {
707 /* another task is sharing our hash bucket */
713 kp = up2kp(&ri->rp->up);
716 ri->rp->handler(ri, regs);
719 orig_ret_addr = (unsigned long)ri->ret_addr;
720 recycle_urp_inst(ri);
722 if ((orig_ret_addr != tramp_addr && kp == p) || kp == NULL) {
724 * This is the real return address. Any other
725 * instances associated with this task are for
726 * other calls deeper on the call stack
732 spin_unlock_irqrestore(&uretprobe_lock, flags);
733 arch_set_orig_ret_addr(orig_ret_addr, regs);
738 static int pre_handler_uretprobe(struct kprobe *p, struct pt_regs *regs)
740 struct uprobe *up = container_of(p, struct uprobe, kp);
741 struct uretprobe *rp = container_of(up, struct uretprobe, up);
743 int noret = thumb_mode(regs) ? rp->thumb_noret : rp->arm_noret;
745 struct uretprobe_instance *ri;
753 /* TODO: consider to only swap the RA after the last pre_handler fired */
754 spin_lock_irqsave(&uretprobe_lock, flags);
756 /* TODO: test - remove retprobe after func entry but before its exit */
757 if ((ri = get_free_urp_inst(rp)) != NULL) {
761 if (rp->entry_handler)
762 rp->entry_handler(ri, regs);
764 arch_prepare_uretprobe(ri, regs);
771 spin_unlock_irqrestore(&uretprobe_lock, flags);
777 * @brief Registers uretprobe.
779 * @param rp Pointer to the uretprobe.
780 * @return 0 on success,\n
781 * negative error code on error.
783 int swap_register_uretprobe(struct uretprobe *rp)
786 struct uretprobe_instance *inst;
788 DBPRINTF ("START\n");
790 rp->up.kp.pre_handler = pre_handler_uretprobe;
791 rp->up.kp.post_handler = NULL;
792 rp->up.kp.fault_handler = NULL;
793 rp->up.kp.break_handler = NULL;
795 /* Pre-allocate memory for max kretprobe instances */
796 if (rp->maxactive <= 0) {
797 #if 1//def CONFIG_PREEMPT
798 rp->maxactive = max(10, 2 * NR_CPUS);
800 rp->maxactive = NR_CPUS;
804 INIT_HLIST_HEAD(&rp->used_instances);
805 INIT_HLIST_HEAD(&rp->free_instances);
807 for (i = 0; i < rp->maxactive; i++) {
808 inst = kmalloc(sizeof(*inst), GFP_ATOMIC);
814 INIT_HLIST_NODE(&inst->uflist);
815 hlist_add_head(&inst->uflist, &rp->free_instances);
820 /* Establish function entry probe point */
821 ret = swap_register_uprobe(&rp->up);
825 arch_opcode_analysis_uretprobe(rp);
829 EXPORT_SYMBOL_GPL(swap_register_uretprobe);
832 * @brief Disarms uretprobe instances for the specified child task.
834 * @param parent Pointer to the parent task struct.
835 * @param task Pointer to the child task struct.
838 int swap_disarm_urp_inst_for_task(struct task_struct *parent, struct task_struct *task)
841 struct uretprobe_instance *ri;
842 struct hlist_head *head;
843 struct hlist_node *tmp;
844 DECLARE_NODE_PTR_FOR_HLIST(node);
846 spin_lock_irqsave(&uretprobe_lock, flags);
848 head = uretprobe_inst_table_head(parent->mm);
849 swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
850 if (parent == ri->task) {
851 arch_disarm_urp_inst(ri, task);
855 spin_unlock_irqrestore(&uretprobe_lock, flags);
859 EXPORT_SYMBOL_GPL(swap_disarm_urp_inst_for_task);
862 * @brief Disarms uretprobes for specified task.
864 * @param task Pointer to the task_struct.
867 void swap_discard_pending_uretprobes(struct task_struct *task)
870 struct uretprobe_instance *ri;
871 struct hlist_head *head;
872 struct hlist_node *tmp;
873 DECLARE_NODE_PTR_FOR_HLIST(node);
875 spin_lock_irqsave(&uretprobe_lock, flags);
877 head = uretprobe_inst_table_head(task->mm);
878 swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
879 if (ri->task == task) {
880 printk("%s (%d/%d): pending urp inst: %08lx\n",
881 task->comm, task->tgid, task->pid,
882 (unsigned long)ri->rp->up.kp.addr);
883 arch_disarm_urp_inst(ri, task);
884 recycle_urp_inst(ri);
888 spin_unlock_irqrestore(&uretprobe_lock, flags);
890 EXPORT_SYMBOL_GPL(swap_discard_pending_uretprobes);
893 * @brief Unregisters uretprobe.
895 * @param rp Pointer to the ureprobe.
896 * @param disarm Disarm flag, passed to __swap_unregister_uprobe
899 void __swap_unregister_uretprobe(struct uretprobe *rp, int disarm)
902 struct uretprobe_instance *ri;
904 __swap_unregister_uprobe(&rp->up, disarm);
905 spin_lock_irqsave (&uretprobe_lock, flags);
907 while ((ri = get_used_urp_inst(rp)) != NULL) {
908 if (arch_disarm_urp_inst(ri, ri->task) != 0)
909 printk("%s (%d/%d): cannot disarm urp instance (%08lx)\n",
910 ri->task->comm, ri->task->tgid, ri->task->pid,
911 (unsigned long)rp->up.kp.addr);
912 recycle_urp_inst(ri);
915 if (hlist_empty(&rp->used_instances)) {
916 struct kprobe *p = &rp->up.kp;
918 if (!(hlist_unhashed(&p->is_hlist))) {
919 hlist_del_rcu(&p->is_hlist);
923 while ((ri = get_used_urp_inst(rp)) != NULL) {
925 hlist_del(&ri->uflist);
928 spin_unlock_irqrestore(&uretprobe_lock, flags);
931 EXPORT_SYMBOL_GPL(__swap_unregister_uretprobe);
934 * @brief Unregistets uretprobe. Main interface function, wrapper for
935 * __swap_unregister_uretprobe.
937 * @param rp Pointer to the uretprobe.
940 void swap_unregister_uretprobe(struct uretprobe *rp)
942 __swap_unregister_uretprobe(rp, 1);
944 EXPORT_SYMBOL_GPL(swap_unregister_uretprobe);
947 * @brief Unregisters all uprobes for task's thread group ID.
949 * @param task Pointer to the task_struct
952 void swap_unregister_all_uprobes(struct task_struct *task)
954 struct hlist_head *head;
957 struct hlist_node *tnode;
958 DECLARE_NODE_PTR_FOR_HLIST(node);
960 for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
961 head = &uprobe_table[i];
962 swap_hlist_for_each_entry_safe(p, node, tnode, head, hlist) {
963 if (kp2up(p)->task->tgid == task->tgid) {
964 struct uprobe *up = container_of(p, struct uprobe, kp);
965 printk("%s: delete uprobe at %p[%lx] for "
966 "%s/%d\n", __func__, p->addr,
967 (unsigned long)p->opcode,
968 task->comm, task->pid);
969 swap_unregister_uprobe(up);
974 EXPORT_SYMBOL_GPL(swap_unregister_all_uprobes);
977 * @brief Arch-independent wrapper for arch_ujprobe_return.
981 void swap_ujprobe_return(void)
983 arch_ujprobe_return();
985 EXPORT_SYMBOL_GPL(swap_ujprobe_return);
987 static int __init init_uprobes(void)
990 init_uprobes_insn_slots();
991 init_uretprobe_inst_table();
993 return swap_arch_init_uprobes();
996 static void __exit exit_uprobes(void)
998 swap_arch_exit_uprobes();
1001 module_init(init_uprobes);
1002 module_exit(exit_uprobes);
1004 MODULE_LICENSE ("GPL");