diff options
author | kenistoj <kenistoj> | 2007-10-08 21:52:12 +0000 |
---|---|---|
committer | kenistoj <kenistoj> | 2007-10-08 21:52:12 +0000 |
commit | 6274464ec4e095cd42238d0b4b5dc1d45bf100da (patch) | |
tree | e640a94f014c692f57e95ce087e87e1b2b301779 /runtime/uprobes | |
parent | a9e8f7e0533811be2cd7c9a88d9058da8caa1d11 (diff) | |
download | systemtap-steved-6274464ec4e095cd42238d0b4b5dc1d45bf100da.tar.gz systemtap-steved-6274464ec4e095cd42238d0b4b5dc1d45bf100da.tar.xz systemtap-steved-6274464ec4e095cd42238d0b4b5dc1d45bf100da.zip |
PR 5709
* main.cxx: Add pass 4.5: make uprobes.ko in runtime/uprobes
* buildrun.cxx: Add uprobes_enabled() and make_uprobes().
Factor run_make_cmd() out of compile_pass().
* buildrun.h: Add uprobes_enabled and make_uprobes decls.
* tapsets.cxx: Do correct #include for modprobed uprobes.ko;
set need_uprobes in pass 2.
* session.h: Add need_uprobes
* runtime/staprun/common.c: Add -u option -> need_uprobes
* runtime/staprun/staprun_funcs.c: Generalize insert_module()
to support inserting uprobes.ko.
* runtime/staprun/staprun.c: Add enable_uprobes(). insert_module
call becomes insert_stap_module().
* runtime/staprun/staprun.h: Reflect insert_module() and
need_uprobes changes
* runtime/uprobes/*.[c,h]: uprobes is built as a module,
rather than included into the source of the stap-generated
module.
* runtime/uprobes/Makefile: Added
Diffstat (limited to 'runtime/uprobes')
-rw-r--r-- | runtime/uprobes/Makefile | 10 | ||||
-rw-r--r-- | runtime/uprobes/uprobes.c | 112 | ||||
-rw-r--r-- | runtime/uprobes/uprobes.h | 8 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_i386.c | 6 |
4 files changed, 46 insertions, 90 deletions
diff --git a/runtime/uprobes/Makefile b/runtime/uprobes/Makefile new file mode 100644 index 00000000..806f7c48 --- /dev/null +++ b/runtime/uprobes/Makefile @@ -0,0 +1,10 @@ +obj-m := uprobes.o +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) + +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules + +clean: + rm -f *.mod.c *.ko *.o .*.cmd *~ + rm -rf .tmp_versions diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c index 41d0ef11..16c5e046 100644 --- a/runtime/uprobes/uprobes.c +++ b/runtime/uprobes/uprobes.c @@ -59,36 +59,22 @@ typedef void (*uprobe_handler_t)(struct uprobe*, struct pt_regs*); /* Point utask->active_probe at this while running uretprobe handler. */ static struct uprobe_probept uretprobe_trampoline_dummy_probe; -/* - * These data structures are shared by all SystemTap-generated modules - * that use uprobes. - */ -struct uprobe_globals { - struct hlist_head uproc_table[UPROBE_TABLE_SIZE]; - struct mutex uproc_mutex; - struct hlist_head utask_table[UPROBE_TABLE_SIZE]; - spinlock_t utask_table_lock; -}; -static struct uprobe_globals *globals; -static struct hlist_head *uproc_table; /* = globals->uproc_table */ -static struct hlist_head *utask_table; /* = globals->utask_table */ +/* Table of currently probed processes, hashed by tgid. */ +static struct hlist_head uproc_table[UPROBE_TABLE_SIZE]; -#define lock_uproc_table() mutex_lock(&globals->uproc_mutex) -#define unlock_uproc_table() mutex_unlock(&globals->uproc_mutex) +/* Protects uproc_table during uprobe (un)registration */ +static DEFINE_MUTEX(uproc_mutex); -#define lock_utask_table(flags) \ - spin_lock_irqsave(&globals->utask_table_lock, (flags)) -#define unlock_utask_table(flags) \ - spin_unlock_irqrestore(&globals->utask_table_lock, (flags)) +/* Table of uprobe_tasks, hashed by task_struct pointer. */ +static struct hlist_head utask_table[UPROBE_TABLE_SIZE]; +static DEFINE_SPINLOCK(utask_table_lock); -/* - * uprobes_data and uprobes_mutex are the only uprobes hooks in the kernel. - * A pointer to the uprobes_global area is stored in uprobe_data. - */ -extern void *uprobes_data; -extern struct mutex uprobes_mutex; +#define lock_uproc_table() mutex_lock(&uproc_mutex) +#define unlock_uproc_table() mutex_unlock(&uproc_mutex) -static int verify_uprobes(void); +#define lock_utask_table(flags) spin_lock_irqsave(&utask_table_lock, (flags)) +#define unlock_utask_table(flags) \ + spin_unlock_irqrestore(&utask_table_lock, (flags)) /* p_uprobe_utrace_ops = &uprobe_utrace_ops. Fwd refs are a pain w/o this. */ static const struct utrace_engine_ops *p_uprobe_utrace_ops; @@ -824,7 +810,6 @@ static int defer_registration(struct uprobe *u, int regflag, } /* See Documentation/uprobes.txt. */ -static int register_uprobe(struct uprobe *u) { struct task_struct *p; @@ -833,9 +818,6 @@ int register_uprobe(struct uprobe *u) struct uprobe_probept *ppt; struct uprobe_task *cur_utask, *cur_utask_quiescing = NULL; int survivors, ret = 0, uproc_is_new = 0; - if ((ret = verify_uprobes()) < 0) - return ret; - if (!u || !u->handler) return -EINVAL; @@ -982,9 +964,9 @@ fail_tsk: put_task_struct(p); return ret; } +EXPORT_SYMBOL_GPL(register_uprobe); /* See Documentation/uprobes.txt. */ -static void unregister_uprobe(struct uprobe *u) { struct task_struct *p; @@ -993,8 +975,6 @@ void unregister_uprobe(struct uprobe *u) struct uprobe_probept *ppt; struct uprobe_task *cur_utask, *cur_utask_quiescing = NULL; - if (verify_uprobes() < 0) - return; if (!u) return; p = uprobe_get_task(u->pid); @@ -1069,6 +1049,7 @@ done: up_write(&uproc->rwsem); uprobe_put_process(uproc); } +EXPORT_SYMBOL_GPL(unregister_uprobe); /* Find a surviving thread in uproc. Runs with uproc->rwsem locked. */ static struct task_struct *find_surviving_thread(struct uprobe_process *uproc) @@ -2071,64 +2052,26 @@ static const struct utrace_engine_ops uprobe_utrace_ops = .report_exec = uprobe_report_exec }; -/* - * Initialize the uprobes global data area, and return a pointer - * to it. Caller will initialize uprobes_data pointer afterward, to - * ensure that no other module sees a non-null uprobes_data until it's - * completely initialized. - */ -static struct uprobe_globals *init_uprobes(void) +static int __init init_uprobes(void) { int i; - struct uprobe_globals *g = kmalloc(sizeof(*g), GFP_USER); - if (!g) - return ERR_PTR(-ENOMEM); + for (i = 0; i < UPROBE_TABLE_SIZE; i++) { - INIT_HLIST_HEAD(&g->uproc_table[i]); - INIT_HLIST_HEAD(&g->utask_table[i]); + INIT_HLIST_HEAD(&uproc_table[i]); + INIT_HLIST_HEAD(&utask_table[i]); } - mutex_init(&g->uproc_mutex); - spin_lock_init(&g->utask_table_lock); - return g; + + p_uprobe_utrace_ops = &uprobe_utrace_ops; + return 0; } -/* - * Verify that the uprobes globals area has been set up, and that the - * current module's globals variable points at it. Returns 0 if the - * area is successfully set up, or a negative erro otherwise. - */ -static int verify_uprobes(void) +static void __exit exit_uprobes(void) { - if (unlikely(!globals)) { - /* - * First time through for this instrumentation module. - * uprobes_mutex protects both the global uprobes - * initialization and this module's local initialization. - */ - struct uprobe_globals *g; - - mutex_lock(&uprobes_mutex); - if (!uprobes_data) { - /* First time through since boot time */ - g = init_uprobes(); - uprobes_data = g; - } else - g = uprobes_data; - if (!IS_ERR(g)) { - p_uprobe_utrace_ops = &uprobe_utrace_ops; - uproc_table = g->uproc_table; - utask_table = g->utask_table; - } - - /* Set globals pointer to signify all is initialized. */ - globals = g; - mutex_unlock(&uprobes_mutex); - } - if (unlikely(IS_ERR(globals))) - return (int) PTR_ERR(globals); - return 0; } +module_init(init_uprobes); +module_exit(exit_uprobes); + #ifdef CONFIG_URETPROBES /* Called when the entry-point probe u is hit. */ @@ -2209,7 +2152,6 @@ static void uretprobe_handle_return(struct pt_regs *regs, arch_restore_uret_addr(orig_ret_addr, regs); } -static int register_uretprobe(struct uretprobe *rp) { if (!rp || !rp->handler) @@ -2217,6 +2159,7 @@ int register_uretprobe(struct uretprobe *rp) rp->u.handler = URETPROBE_HANDLE_ENTRY; return register_uprobe(&rp->u); } +EXPORT_SYMBOL_GPL(register_uretprobe); /* * The uretprobe containing u is being unregistered. Its uretprobe_instances @@ -2244,13 +2187,13 @@ static void zap_uretprobe_instances(struct uprobe *u, } } -static void unregister_uretprobe(struct uretprobe *rp) { if (!rp) return; unregister_uprobe(&rp->u); } +EXPORT_SYMBOL_GPL(unregister_uretprobe); /* * uproc->ssol_area has been successfully set up. Establish the @@ -2295,3 +2238,4 @@ static void zap_uretprobe_instances(struct uprobe *u, #endif /* CONFIG_URETPROBES */ #include "uprobes_arch.c" +MODULE_LICENSE("GPL"); diff --git a/runtime/uprobes/uprobes.h b/runtime/uprobes/uprobes.h index 574bee62..84dd0b2a 100644 --- a/runtime/uprobes/uprobes.h +++ b/runtime/uprobes/uprobes.h @@ -72,11 +72,11 @@ struct uretprobe_instance { unsigned long reserved2; }; -static int register_uprobe(struct uprobe *u); -static void unregister_uprobe(struct uprobe *u); +extern int register_uprobe(struct uprobe *u); +extern void unregister_uprobe(struct uprobe *u); /* For runtime, assume uprobes support includes uretprobes. */ -static int register_uretprobe(struct uretprobe *rp); -static void unregister_uretprobe(struct uretprobe *rp); +extern int register_uretprobe(struct uretprobe *rp); +extern void unregister_uretprobe(struct uretprobe *rp); #ifdef UPROBES_IMPLEMENTATION diff --git a/runtime/uprobes/uprobes_i386.c b/runtime/uprobes/uprobes_i386.c index 90d50ba0..21420681 100644 --- a/runtime/uprobes/uprobes_i386.c +++ b/runtime/uprobes/uprobes_i386.c @@ -18,8 +18,10 @@ * * Copyright (C) IBM Corporation, 2006 */ -#define UPROBES_IMPLEMENTATION 1 -#include "uprobes.h" +/* + * In versions of uprobes built in the SystemTap runtime, this file + * is #included at the end of uprobes.c. + */ #include <linux/uaccess.h> /* Adapted from arch/x86_64/kprobes.c */ |