perf probe: Add basic module support

Add basic module probe support on perf probe. This introduces "--module
<MODNAME>" option to perf probe for putting probes and showing lines and
variables in the given module.

Currently, this supports only probing on running modules.  Supporting off-line
module probing is the next step.

e.g.)
[show lines]
 # ./perf probe --module drm -L drm_vblank_info
<drm_vblank_info:0>
      0  int drm_vblank_info(struct seq_file *m, void *data)
      1  {
                struct drm_info_node *node = (struct drm_info_node *) m->private
      3         struct drm_device *dev = node->minor->dev;
 ...
[show vars]
 # ./perf probe --module drm -V drm_vblank_info:3
Available variables at drm_vblank_info:3
        @<drm_vblank_info+20>
                (unknown_type)  data
                struct drm_info_node*   node
                struct seq_file*        m
[put a probe]
 # ./perf probe --module drm drm_vblank_info:3 node m
Add new event:
  probe:drm_vblank_info (on drm_vblank_info:3 with node m)

You can now use it on all perf tools, such as:

        perf record -e probe:drm_vblank_info -aR sleep 1
[list probes]
 # ./perf probe -l
probe:drm_vblank_info (on drm_vblank_info:3@drivers/gpu/drm/drm_info.c with ...

Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20101021101341.3542.71638.stgit@ltc236.sdl.hitachi.co.jp>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index bdf60cf..2e000c0 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -57,6 +57,7 @@
 	struct perf_probe_event events[MAX_PROBES];
 	struct strlist *dellist;
 	struct line_range line_range;
+	const char *target_module;
 	int max_probe_points;
 } params;
 
@@ -162,8 +163,8 @@
 	"perf probe [<options>] --del '[GROUP:]EVENT' ...",
 	"perf probe --list",
 #ifdef DWARF_SUPPORT
-	"perf probe --line 'LINEDESC'",
-	"perf probe [--externs] --vars 'PROBEPOINT'",
+	"perf probe [<options>] --line 'LINEDESC'",
+	"perf probe [<options>] --vars 'PROBEPOINT'",
 #endif
 	NULL
 };
@@ -214,6 +215,8 @@
 		   "file", "vmlinux pathname"),
 	OPT_STRING('s', "source", &symbol_conf.source_prefix,
 		   "directory", "path to kernel source"),
+	OPT_STRING('m', "module", &params.target_module,
+		   "modname", "target module name"),
 #endif
 	OPT__DRY_RUN(&probe_event_dry_run),
 	OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -278,7 +281,7 @@
 			usage_with_options(probe_usage, options);
 		}
 
-		ret = show_line_range(&params.line_range);
+		ret = show_line_range(&params.line_range, params.target_module);
 		if (ret < 0)
 			pr_err("  Error: Failed to show lines. (%d)\n", ret);
 		return ret;
@@ -291,6 +294,7 @@
 		}
 		ret = show_available_vars(params.events, params.nevents,
 					  params.max_probe_points,
+					  params.target_module,
 					  params.show_ext_vars);
 		if (ret < 0)
 			pr_err("  Error: Failed to show vars. (%d)\n", ret);
@@ -310,6 +314,7 @@
 	if (params.nevents) {
 		ret = add_perf_probe_events(params.events, params.nevents,
 					    params.max_probe_points,
+					    params.target_module,
 					    params.force_add);
 		if (ret < 0) {
 			pr_err("  Error: Failed to add events. (%d)\n", ret);