Merge tag 'char-misc-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / tools / perf / builtin-probe.c
index 6ea9e85..7894888 100644 (file)
@@ -37,7 +37,7 @@
 #include "util/strfilter.h"
 #include "util/symbol.h"
 #include "util/debug.h"
-#include <lk/debugfs.h>
+#include <api/fs/debugfs.h>
 #include "util/parse-options.h"
 #include "util/probe-finder.h"
 #include "util/probe-event.h"
@@ -59,7 +59,7 @@ static struct {
        struct perf_probe_event events[MAX_PROBES];
        struct strlist *dellist;
        struct line_range line_range;
-       const char *target;
+       char *target;
        int max_probe_points;
        struct strfilter *filter;
 } params;
@@ -98,7 +98,10 @@ static int set_target(const char *ptr)
         * short module name.
         */
        if (!params.target && ptr && *ptr == '/') {
-               params.target = ptr;
+               params.target = strdup(ptr);
+               if (!params.target)
+                       return -ENOMEM;
+
                found = 1;
                buf = ptr + (strlen(ptr) - 3);
 
@@ -116,6 +119,9 @@ static int parse_probe_event_argv(int argc, const char **argv)
        char *buf;
 
        found_target = set_target(argv[0]);
+       if (found_target < 0)
+               return found_target;
+
        if (found_target && argc == 1)
                return 0;
 
@@ -169,6 +175,7 @@ static int opt_set_target(const struct option *opt, const char *str,
                        int unset __maybe_unused)
 {
        int ret = -ENOENT;
+       char *tmp;
 
        if  (str && !params.target) {
                if (!strcmp(opt->long_name, "exec"))
@@ -180,7 +187,19 @@ static int opt_set_target(const struct option *opt, const char *str,
                else
                        return ret;
 
-               params.target = str;
+               /* Expand given path to absolute path, except for modulename */
+               if (params.uprobes || strchr(str, '/')) {
+                       tmp = realpath(str, NULL);
+                       if (!tmp) {
+                               pr_warning("Failed to get the absolute path of %s: %m\n", str);
+                               return ret;
+                       }
+               } else {
+                       tmp = strdup(str);
+                       if (!tmp)
+                               return -ENOMEM;
+               }
+               params.target = tmp;
                ret = 0;
        }
 
@@ -204,7 +223,6 @@ static int opt_show_lines(const struct option *opt __maybe_unused,
 
        params.show_lines = true;
        ret = parse_line_range_desc(str, &params.line_range);
-       INIT_LIST_HEAD(&params.line_range.line_list);
 
        return ret;
 }
@@ -250,7 +268,28 @@ static int opt_set_filter(const struct option *opt __maybe_unused,
        return 0;
 }
 
-int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
+static void init_params(void)
+{
+       line_range__init(&params.line_range);
+}
+
+static void cleanup_params(void)
+{
+       int i;
+
+       for (i = 0; i < params.nevents; i++)
+               clear_perf_probe_event(params.events + i);
+       if (params.dellist)
+               strlist__delete(params.dellist);
+       line_range__clear(&params.line_range);
+       free(params.target);
+       if (params.filter)
+               strfilter__delete(params.filter);
+       memset(&params, 0, sizeof(params));
+}
+
+static int
+__cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 {
        const char * const probe_usage[] = {
                "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
@@ -404,6 +443,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                ret = show_available_funcs(params.target, params.filter,
                                        params.uprobes);
                strfilter__delete(params.filter);
+               params.filter = NULL;
                if (ret < 0)
                        pr_err("  Error: Failed to show functions."
                               " (%d)\n", ret);
@@ -411,7 +451,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
        }
 
 #ifdef HAVE_DWARF_SUPPORT
-       if (params.show_lines && !params.uprobes) {
+       if (params.show_lines) {
                if (params.mod_events) {
                        pr_err("  Error: Don't use --line with"
                               " --add/--del.\n");
@@ -443,6 +483,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                                          params.filter,
                                          params.show_ext_vars);
                strfilter__delete(params.filter);
+               params.filter = NULL;
                if (ret < 0)
                        pr_err("  Error: Failed to show vars. (%d)\n", ret);
                return ret;
@@ -451,7 +492,6 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 
        if (params.dellist) {
                ret = del_perf_probe_events(params.dellist);
-               strlist__delete(params.dellist);
                if (ret < 0) {
                        pr_err("  Error: Failed to delete events. (%d)\n", ret);
                        return ret;
@@ -470,3 +510,14 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
        }
        return 0;
 }
+
+int cmd_probe(int argc, const char **argv, const char *prefix)
+{
+       int ret;
+
+       init_params();
+       ret = __cmd_probe(argc, argv, prefix);
+       cleanup_params();
+
+       return ret;
+}