1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * builtin-probe.c
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Builtin probe command: Set up probe events by C expression
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Written by Masami Hiramatsu <mhiramat@redhat.com>
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is free software; you can redistribute it and/or modify
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * it under the terms of the GNU General Public License as published by
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the Free Software Foundation; either version 2 of the License, or
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * (at your option) any later version.
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is distributed in the hope that it will be useful,
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * but WITHOUT ANY WARRANTY; without even the implied warranty of
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * GNU General Public License for more details.
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * You should have received a copy of the GNU General Public License
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * along with this program; if not, write to the Free Software
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/utsname.h>
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/types.h>
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/stat.h>
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <fcntl.h>
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <errno.h>
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h>
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <unistd.h>
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h>
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string.h>
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "perf.h"
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "builtin.h"
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/util.h"
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/strlist.h"
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/strfilter.h"
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/symbol.h"
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/debug.h"
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <lk/debugfs.h>
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/parse-options.h"
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/probe-finder.h"
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util/probe-event.h"
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define DEFAULT_FUNC_FILTER "!_*"
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Session management structure */
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct {
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool list_events;
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool force_add;
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool show_lines;
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool show_vars;
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool show_ext_vars;
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool show_funcs;
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool mod_events;
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool uprobes;
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int nevents;
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_probe_event events[MAX_PROBES];
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct strlist *dellist;
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct line_range line_range;
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *target;
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int max_probe_points;
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct strfilter *filter;
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} params;
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Parse an event definition. Note that any error must die. */
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int parse_probe_event(const char *str)
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_probe_event *pev = &params.events[params.nevents];
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pr_debug("probe-definition(%d): %s\n", params.nevents, str);
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (++params.nevents == MAX_PROBES) {
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_err("Too many probes (> %d) were specified.", MAX_PROBES);
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pev->uprobes = params.uprobes;
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Parse a perf-probe command into event */
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = parse_perf_probe_command(str, pev);
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pr_debug("%d arguments\n", pev->nargs);
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int set_target(const char *ptr)
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int found = 0;
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *buf;
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * The first argument after options can be an absolute path
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * to an executable / library or kernel module.
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 *
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * TODO: Support relative path, and $PATH, $LD_LIBRARY_PATH,
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * short module name.
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!params.target && ptr && *ptr == '/') {
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		params.target = ptr;
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		found = 1;
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		buf = ptr + (strlen(ptr) - 3);
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(buf, ".ko"))
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			params.uprobes = true;
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return found;
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int parse_probe_event_argv(int argc, const char **argv)
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i, len, ret, found_target;
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *buf;
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	found_target = set_target(argv[0]);
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (found_target && argc == 1)
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Bind up rest arguments */
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	len = 0;
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < argc; i++) {
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (i == 0 && found_target)
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		len += strlen(argv[i]) + 1;
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	buf = zalloc(len + 1);
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (buf == NULL)
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -ENOMEM;
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	len = 0;
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < argc; i++) {
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (i == 0 && found_target)
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		len += sprintf(&buf[len], "%s ", argv[i]);
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	params.mod_events = true;
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = parse_probe_event(buf);
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(buf);
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int opt_add_probe_event(const struct option *opt __maybe_unused,
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      const char *str, int unset __maybe_unused)
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (str) {
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		params.mod_events = true;
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return parse_probe_event(str);
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int opt_del_probe_event(const struct option *opt __maybe_unused,
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       const char *str, int unset __maybe_unused)
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (str) {
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		params.mod_events = true;
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!params.dellist)
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			params.dellist = strlist__new(true, NULL);
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strlist__add(params.dellist, str);
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int opt_set_target(const struct option *opt, const char *str,
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			int unset __maybe_unused)
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret = -ENOENT;
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if  (str && !params.target) {
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!strcmp(opt->long_name, "exec"))
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			params.uprobes = true;
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef DWARF_SUPPORT
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else if (!strcmp(opt->long_name, "module"))
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			params.uprobes = false;
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return ret;
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		params.target = str;
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = 0;
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef DWARF_SUPPORT
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int opt_show_lines(const struct option *opt __maybe_unused,
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			  const char *str, int unset __maybe_unused)
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret = 0;
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!str)
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.show_lines) {
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_warning("Warning: more than one --line options are"
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   " detected. Only the first one is valid.\n");
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	params.show_lines = true;
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = parse_line_range_desc(str, &params.line_range);
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	INIT_LIST_HEAD(&params.line_range.line_list);
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int opt_show_vars(const struct option *opt __maybe_unused,
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 const char *str, int unset __maybe_unused)
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_probe_event *pev = &params.events[params.nevents];
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!str)
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = parse_probe_event(str);
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!ret && pev->nargs != 0) {
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_err("  Error: '--vars' doesn't accept arguments.\n");
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -EINVAL;
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	params.show_vars = true;
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int opt_set_filter(const struct option *opt __maybe_unused,
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			  const char *str, int unset __maybe_unused)
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *err;
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (str) {
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_debug2("Set filter: %s\n", str);
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.filter)
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			strfilter__delete(params.filter);
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		params.filter = strfilter__new(str, &err);
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!params.filter) {
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("Filter parse error at %td.\n", err - str + 1);
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("Source: \"%s\"\n", str);
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("         %*c\n", (int)(err - str + 1), '^');
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -EINVAL;
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char * const probe_usage[] = {
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"perf probe [<options>] --del '[GROUP:]EVENT' ...",
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"perf probe --list",
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef DWARF_SUPPORT
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"perf probe [<options>] --line 'LINEDESC'",
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"perf probe [<options>] --vars 'PROBEPOINT'",
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		NULL
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct option options[] = {
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_INCR('v', "verbose", &verbose,
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    "be more verbose (show parsed arguments, etc)"),
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_BOOLEAN('l', "list", &params.list_events,
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    "list up current probe events"),
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		opt_del_probe_event),
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_CALLBACK('a', "add", NULL,
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef DWARF_SUPPORT
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		" [[NAME=]ARG ...]",
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#else
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]",
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"probe point definition, where\n"
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tGROUP:\tGroup name (optional)\n"
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tEVENT:\tEvent name\n"
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tFUNC:\tFunction name\n"
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tOFF:\tOffset from function entry (in byte)\n"
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\t%return:\tPut the probe at function return\n"
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef DWARF_SUPPORT
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tSRC:\tSource code path\n"
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tRL:\tRelative line number from function entry.\n"
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tAL:\tAbsolute line number in file.\n"
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tPT:\tLazy expression of line code.\n"
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tARG:\tProbe argument (local variable name or\n"
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\t\tkprobe-tracer argument format.)\n",
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#else
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		opt_add_probe_event),
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_BOOLEAN('f', "force", &params.force_add, "forcibly add events"
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    " with existing name"),
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef DWARF_SUPPORT
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_CALLBACK('L', "line", NULL,
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     "Show source code lines.", opt_show_lines),
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_CALLBACK('V', "vars", NULL,
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     "Show accessible variables on PROBEDEF", opt_show_vars),
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_BOOLEAN('\0', "externs", &params.show_ext_vars,
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    "Show external variables too (with --vars only)"),
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   "file", "vmlinux pathname"),
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_STRING('s', "source", &symbol_conf.source_prefix,
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   "directory", "path to kernel source"),
312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_CALLBACK('m', "module", NULL, "modname|path",
313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"target module name (for online) or path (for offline)",
314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		opt_set_target),
315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT__DRY_RUN(&probe_event_dry_run),
317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 "Set how many probe points can be found for a probe."),
319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_BOOLEAN('F', "funcs", &params.show_funcs,
320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    "Show potential probe-able functions."),
321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_CALLBACK('\0', "filter", NULL,
322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     "[!]FILTER", "Set a filter (with --vars/funcs only)\n"
323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     opt_set_filter),
326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_CALLBACK('x', "exec", NULL, "executable|path",
327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			"target executable name or path", opt_set_target),
328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	OPT_END()
329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	};
330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	argc = parse_options(argc, argv, options, probe_usage,
333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     PARSE_OPT_STOP_AT_NON_OPTION);
334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (argc > 0) {
335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(argv[0], "-") == 0) {
336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_warning("  Error: '-' is not supported.\n");
337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = parse_probe_event_argv(argc, argv);
340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0) {
341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Parse Error.  (%d)\n", ret);
342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return ret;
343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.max_probe_points == 0)
347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		params.max_probe_points = MAX_PROBES;
348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((!params.nevents && !params.dellist && !params.list_events &&
350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	     !params.show_lines && !params.show_funcs))
351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		usage_with_options(probe_usage, options);
352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * Only consider the user's kernel image path if given.
355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.list_events) {
359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.mod_events) {
360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --list with --add/--del.\n");
361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.show_lines) {
364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --list with --line.\n");
365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.show_vars) {
368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err(" Error: Don't use --list with --vars.\n");
369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.show_funcs) {
372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --list with --funcs.\n");
373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.uprobes) {
376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_warning("  Error: Don't use --list with --exec.\n");
377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = show_perf_probe_events();
380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0)
381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Failed to show event list. (%d)\n",
382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       ret);
383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ret;
384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.show_funcs) {
386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.nevents != 0 || params.dellist) {
387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --funcs with"
388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       " --add/--del.\n");
389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.show_lines) {
392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --funcs with --line.\n");
393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.show_vars) {
396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --funcs with --vars.\n");
397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!params.filter)
400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			params.filter = strfilter__new(DEFAULT_FUNC_FILTER,
401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						       NULL);
402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = show_available_funcs(params.target, params.filter,
403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					params.uprobes);
404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strfilter__delete(params.filter);
405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0)
406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Failed to show functions."
407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       " (%d)\n", ret);
408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ret;
409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef DWARF_SUPPORT
412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.show_lines && !params.uprobes) {
413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.mod_events) {
414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --line with"
415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       " --add/--del.\n");
416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.show_vars) {
419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err(" Error: Don't use --line with --vars.\n");
420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = show_line_range(&params.line_range, params.target);
424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0)
425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Failed to show lines. (%d)\n", ret);
426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ret;
427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.show_vars) {
429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (params.mod_events) {
430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Don't use --vars with"
431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       " --add/--del.\n");
432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			usage_with_options(probe_usage, options);
433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!params.filter)
435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			params.filter = strfilter__new(DEFAULT_VAR_FILTER,
436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						       NULL);
437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = show_available_vars(params.events, params.nevents,
439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					  params.max_probe_points,
440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					  params.target,
441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					  params.filter,
442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					  params.show_ext_vars);
443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strfilter__delete(params.filter);
444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0)
445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Failed to show vars. (%d)\n", ret);
446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ret;
447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.dellist) {
451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = del_perf_probe_events(params.dellist);
452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strlist__delete(params.dellist);
453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0) {
454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Failed to delete events. (%d)\n", ret);
455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return ret;
456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (params.nevents) {
460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = add_perf_probe_events(params.events, params.nevents,
461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					    params.max_probe_points,
462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					    params.target,
463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					    params.force_add);
464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0) {
465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_err("  Error: Failed to add events. (%d)\n", ret);
466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return ret;
467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
471