Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * builtin-probe.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Builtin probe command: Set up probe events by C expression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Written by Masami Hiramatsu <mhiramat@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <sys/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "namespaces.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "util/build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "util/strlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "util/strfilter.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "util/symbol_conf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "util/probe-finder.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "util/probe-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "util/probe-file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define DEFAULT_FUNC_FILTER "!_*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define DEFAULT_LIST_FILTER "*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /* Session management structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	int command;	/* Command short_name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	bool list_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	bool uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	bool quiet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	bool target_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	int nevents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct perf_probe_event events[MAX_PROBES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct line_range line_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	char *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	struct strfilter *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	struct nsinfo *nsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) } params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* Parse an event definition. Note that any error must die. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static int parse_probe_event(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct perf_probe_event *pev = &params.events[params.nevents];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	pr_debug("probe-definition(%d): %s\n", params.nevents, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (++params.nevents == MAX_PROBES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		pr_err("Too many probes (> %d) were specified.", MAX_PROBES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	pev->uprobes = params.uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (params.target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		pev->target = strdup(params.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		if (!pev->target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		params.target_used = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	pev->nsi = nsinfo__get(params.nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	/* Parse a perf-probe command into event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	ret = parse_perf_probe_command(str, pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	pr_debug("%d arguments\n", pev->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static int params_add_filter(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	const char *err = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	pr_debug2("Add filter: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (!params.filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		params.filter = strfilter__new(str, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		if (!params.filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			ret = err ? -EINVAL : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		ret = strfilter__or(params.filter, str, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (ret == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		pr_err("Filter parse error at %td.\n", err - str + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		pr_err("Source: \"%s\"\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		pr_err("         %*c\n", (int)(err - str + 1), '^');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int set_target(const char *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	const char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	 * The first argument after options can be an absolute path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	 * to an executable / library or kernel module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 * TODO: Support relative path, and $PATH, $LD_LIBRARY_PATH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	 * short module name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (!params.target && ptr && *ptr == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		params.target = strdup(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		if (!params.target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		params.target_used = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		buf = ptr + (strlen(ptr) - 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		if (strcmp(buf, ".ko"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			params.uprobes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int parse_probe_event_argv(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	int i, len, ret, found_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	found_target = set_target(argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (found_target < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return found_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if (found_target && argc == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	/* Bind up rest arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		if (i == 0 && found_target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		len += strlen(argv[i]) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	buf = zalloc(len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		if (i == 0 && found_target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		len += sprintf(&buf[len], "%s ", argv[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	ret = parse_probe_event(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int opt_set_target(const struct option *opt, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	if  (str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (!strcmp(opt->long_name, "exec"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			params.uprobes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		else if (!strcmp(opt->long_name, "module"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			params.uprobes = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		/* Expand given path to absolute path, except for modulename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		if (params.uprobes || strchr(str, '/')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			tmp = nsinfo__realpath(str, params.nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			if (!tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 				pr_warning("Failed to get the absolute path of %s: %m\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			tmp = strdup(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		free(params.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		params.target = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		params.target_used = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int opt_set_target_ns(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			     const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	pid_t ns_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	struct nsinfo *nsip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		ns_pid = (pid_t)strtol(str, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		if (errno != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			pr_warning("Failed to parse %s as a pid: %s\n", str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				   strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		nsip = nsinfo__new(ns_pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		if (nsip && nsip->need_setns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			params.nsi = nsinfo__get(nsip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		nsinfo__put(nsip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Command option callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int opt_show_lines(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			  const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (params.command == 'L') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		pr_warning("Warning: more than one --line options are"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			   " detected. Only the first one is valid.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	ret = parse_line_range_desc(str, &params.line_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int opt_show_vars(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			 const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	struct perf_probe_event *pev = &params.events[params.nevents];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	ret = parse_probe_event(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	if (!ret && pev->nargs != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		pr_err("  Error: '--vars' doesn't accept arguments.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) # define opt_show_lines NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) # define opt_show_vars NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int opt_add_probe_event(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			      const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		return parse_probe_event(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int opt_set_filter_with_command(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				       const char *str, int unset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (!unset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		return params_add_filter(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int opt_set_filter(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			  const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		return params_add_filter(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int init_params(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	return line_range__init(&params.line_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static void cleanup_params(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	for (i = 0; i < params.nevents; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		clear_perf_probe_event(params.events + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	line_range__clear(&params.line_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	free(params.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	strfilter__delete(params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	nsinfo__put(params.nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static void pr_err_with_code(const char *msg, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	pr_err("%s", msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	pr_debug(" Reason: %s (Code: %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		 str_error_r(-err, sbuf, sizeof(sbuf)), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	pr_err("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	int i, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	const char *event = NULL, *group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	ret = init_probe_symbol_maps(pevs->uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	ret = convert_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		goto out_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	if (params.command == 'D') {	/* it shows definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		ret = show_probe_trace_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		goto out_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	ret = apply_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		goto out_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	for (i = k = 0; i < npevs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		k += pevs[i].ntevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	pr_info("Added new event%s\n", (k > 1) ? "s:" : ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	for (i = 0; i < npevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		struct perf_probe_event *pev = &pevs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		for (k = 0; k < pev->ntevs; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			struct probe_trace_event *tev = &pev->tevs[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			/* Skipped events have no event name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			if (!tev->event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			/* We use tev's name for showing new events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			show_perf_probe_event(tev->group, tev->event, pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 					      tev->point.module, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			/* Save the last valid name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			event = tev->event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			group = tev->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	/* Note that it is possible to skip all events because of blacklist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		/* Show how to use the event. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		pr_info("\nYou can now use it in all perf tools, such as:\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) out_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	cleanup_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	exit_probe_symbol_maps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int del_perf_probe_caches(struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	struct probe_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	struct strlist *bidlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct str_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	bidlist = build_id_cache__list_all(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	if (!bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		pr_debug("Failed to get buildids: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		return ret ?: -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	strlist__for_each_entry(nd, bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		cache = probe_cache__new(nd->s, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		if (!cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		if (probe_cache__filter_purge(cache, filter) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		    probe_cache__commit(cache) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			pr_warning("Failed to remove entries for %s\n", nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		probe_cache__delete(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int perf_del_probe_events(struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	int ret, ret2, ufd = -1, kfd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	char *str = strfilter__string(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	struct strlist *klist = NULL, *ulist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	struct str_node *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	pr_debug("Delete filter: \'%s\'\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	if (probe_conf.cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		return del_perf_probe_caches(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	/* Get current event names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	klist = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	ulist = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (!klist || !ulist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	ret = probe_file__get_events(kfd, filter, klist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		strlist__for_each_entry(ent, klist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			pr_info("Removed event: %s\n", ent->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		ret = probe_file__del_strlist(kfd, klist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	} else if (ret == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	ret2 = probe_file__get_events(ufd, filter, ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (ret2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		strlist__for_each_entry(ent, ulist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			pr_info("Removed event: %s\n", ent->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		ret2 = probe_file__del_strlist(ufd, ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		if (ret2 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	} else if (ret2 == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (ret == -ENOENT && ret2 == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		pr_warning("\"%s\" does not hit any event.\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	if (kfd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		close(kfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	if (ufd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		close(ufd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	strlist__delete(klist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	strlist__delete(ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #define PROBEDEF_STR	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT [[NAME=]ARG ...]"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) #define PROBEDEF_STR	"[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) __cmd_probe(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	const char * const probe_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		"perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		"perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		"perf probe [<options>] --del '[GROUP:]EVENT' ...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		"perf probe --list [GROUP:]EVENT ...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		"perf probe [<options>] --line 'LINEDESC'",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		"perf probe [<options>] --vars 'PROBEPOINT'",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		"perf probe [<options>] --funcs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	struct option options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	OPT_INCR('v', "verbose", &verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		    "be more verbose (show parsed arguments, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	OPT_BOOLEAN('q', "quiet", &params.quiet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		    "be quiet (do not show any messages)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	OPT_CALLBACK_DEFAULT('l', "list", NULL, "[GROUP:]EVENT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 			     "list up probe events",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			     opt_set_filter_with_command, DEFAULT_LIST_FILTER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		     opt_set_filter_with_command),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	OPT_CALLBACK('a', "add", NULL, PROBEDEF_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		"probe point definition, where\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		"\t\tGROUP:\tGroup name (optional)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		"\t\tEVENT:\tEvent name\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		"\t\tFUNC:\tFunction name\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		"\t\tOFF:\tOffset from function entry (in byte)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		"\t\t%return:\tPut the probe at function return\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		"\t\tSRC:\tSource code path\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		"\t\tRL:\tRelative line number from function entry.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		"\t\tAL:\tAbsolute line number in file.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		"\t\tPT:\tLazy expression of line code.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		"\t\tARG:\tProbe argument (local variable name or\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		"\t\t\tkprobe-tracer argument format.)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		"\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		opt_add_probe_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	OPT_CALLBACK('D', "definition", NULL, PROBEDEF_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		"Show trace event definition of given traceevent for k/uprobe_events.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		opt_add_probe_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		    " with existing name"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	OPT_CALLBACK('L', "line", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		     "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		     "Show source code lines.", opt_show_lines),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	OPT_CALLBACK('V', "vars", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		     "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		     "Show accessible variables on PROBEDEF", opt_show_vars),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	OPT_BOOLEAN('\0', "externs", &probe_conf.show_ext_vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		    "Show external variables too (with --vars only)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	OPT_BOOLEAN('\0', "range", &probe_conf.show_location_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		"Show variables location range in scope (with --vars only)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		   "file", "vmlinux pathname"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	OPT_STRING('s', "source", &symbol_conf.source_prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		   "directory", "path to kernel source"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		"Don't search inlined functions"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	OPT__DRY_RUN(&probe_event_dry_run),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		 "Set how many probe points can be found for a probe."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	OPT_CALLBACK_DEFAULT('F', "funcs", NULL, "[FILTER]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			     "Show potential probe-able functions.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			     opt_set_filter_with_command, DEFAULT_FUNC_FILTER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	OPT_CALLBACK('\0', "filter", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		     "[!]FILTER", "Set a filter (with --vars/funcs only)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		     "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		     "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		     opt_set_filter),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	OPT_CALLBACK('x', "exec", NULL, "executable|path",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			"target executable name or path", opt_set_target),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	OPT_CALLBACK('m', "module", NULL, "modname|path",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		"target module name (for online) or path (for offline)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		opt_set_target),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		    "Enable symbol demangling"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		    "Enable kernel symbol demangling"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		   "Look for files with symbols relative to this directory"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	OPT_CALLBACK(0, "target-ns", NULL, "pid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		     "target pid for namespace contexts", opt_set_target_ns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	set_option_flag(options, 'a', "add", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	set_option_flag(options, 'd', "del", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	set_option_flag(options, 'D', "definition", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	set_option_flag(options, 'l', "list", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) # define set_nobuild(s, l, c) set_option_nobuild(options, s, l, "NO_DWARF=1", c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	set_nobuild('L', "line", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	set_nobuild('V', "vars", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	set_nobuild('\0', "externs", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	set_nobuild('\0', "range", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	set_nobuild('k', "vmlinux", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	set_nobuild('s', "source", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	set_nobuild('\0', "no-inlines", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) # undef set_nobuild
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	set_option_flag(options, 'F', "funcs", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	argc = parse_options(argc, argv, options, probe_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			     PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	if (argc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		if (strcmp(argv[0], "-") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 			usage_with_options_msg(probe_usage, options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 				"'-' is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		if (params.command && params.command != 'a') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			usage_with_options_msg(probe_usage, options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 				"another command except --add is set.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		ret = parse_probe_event_argv(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			pr_err_with_code("  Error: Command Parse Error.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		params.command = 'a';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	if (params.quiet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		if (verbose != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 			pr_err("  Error: -v and -q are exclusive.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		verbose = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (probe_conf.max_probes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		probe_conf.max_probes = MAX_PROBES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	 * Only consider the user's kernel image path if given.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	 * Except for --list, --del and --add, other command doesn't depend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	 * nor change running kernel. So if user gives offline vmlinux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	 * ignore its buildid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	if (!strchr("lda", params.command) && symbol_conf.vmlinux_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		symbol_conf.ignore_vmlinux_buildid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	switch (params.command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		if (params.uprobes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			pr_err("  Error: Don't use --list with --exec.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 			parse_options_usage(probe_usage, options, "l", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			parse_options_usage(NULL, options, "x", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		ret = show_perf_probe_events(params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			pr_err_with_code("  Error: Failed to show event list.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		ret = show_available_funcs(params.target, params.nsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 					   params.filter, params.uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			pr_err_with_code("  Error: Failed to show functions.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		ret = show_line_range(&params.line_range, params.target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 				      params.nsi, params.uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 			pr_err_with_code("  Error: Failed to show lines.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	case 'V':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		if (!params.filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 			params.filter = strfilter__new(DEFAULT_VAR_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 						       NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		ret = show_available_vars(params.events, params.nevents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 					  params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 			pr_err_with_code("  Error: Failed to show vars.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		ret = perf_del_probe_events(params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 			pr_err_with_code("  Error: Failed to delete events.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	case 'D':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		/* Ensure the last given target is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		if (params.target && !params.target_used) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 			pr_err("  Error: -x/-m must follow the probe definitions.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 			parse_options_usage(probe_usage, options, "m", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 			parse_options_usage(NULL, options, "x", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		ret = perf_add_probe_events(params.events, params.nevents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 			 * When perf_add_probe_events() fails it calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 			 * cleanup_perf_probe_events(pevs, npevs), i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 			 * cleanup_perf_probe_events(params.events, params.nevents), which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 			 * will call clear_perf_probe_event(), so set nevents to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 			 * to avoid cleanup_params() to call clear_perf_probe_event() again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 			 * on the same pevs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 			params.nevents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 			pr_err_with_code("  Error: Failed to add events.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		usage_with_options(probe_usage, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int cmd_probe(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	ret = init_params();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		ret = __cmd_probe(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		cleanup_params();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }